class Sinatra::Helpers::Stream::Base
Constants
- URI_INSTANCE
Attributes
Public Class Methods
Sinatra::Helpers::Stream::Templates::new
# File lib/sinatra/base.rb 931 def initialize(app = nil, **kwargs) 932 super() 933 @app = app 934 @template_cache = Tilt::Cache.new 935 @pinned_response = nil # whether a before! filter pinned the content-type 936 yield self if block_given? 937 end
Access settings defined with Base.set
.
# File lib/sinatra/base.rb 967 def self.settings 968 self 969 end
Private Class Methods
add a filter
# File lib/sinatra/base.rb 1414 def add_filter(type, path = /.*/, **options, &block) 1415 filters[type] << compile!(type, path, block, **options) 1416 end
Define an after filter; runs after all requests within the same context as route handlers and may access/modify the request and response.
# File lib/sinatra/base.rb 1409 def after(path = /.*/, **options, &block) 1410 add_filter(:after, path, **options, &block) 1411 end
Define a before filter; runs before all requests within the same context as route handlers and may access/modify the request and response.
# File lib/sinatra/base.rb 1402 def before(path = /.*/, **options, &block) 1403 add_filter(:before, path, **options, &block) 1404 end
Creates a Rack::Builder
instance with all the middleware set up and the given app
as end point.
# File lib/sinatra/base.rb 1549 def build(app) 1550 builder = Rack::Builder.new 1551 setup_default_middleware builder 1552 setup_middleware builder 1553 builder.run app 1554 builder 1555 end
# File lib/sinatra/base.rb 1557 def call(env) 1558 synchronize { prototype.call(env) } 1559 end
Like Kernel#caller but excluding certain magic entries and without line / method information; the resulting array contains filenames only.
# File lib/sinatra/base.rb 1563 def caller_files 1564 cleaned_caller(1).flatten 1565 end
Like caller_files
, but containing Arrays rather than strings with the first element being the file, and the second being the line.
# File lib/sinatra/base.rb 1569 def caller_locations 1570 cleaned_caller 2 1571 end
Like Kernel#caller but excluding certain magic entries
# File lib/sinatra/base.rb 1784 def cleaned_caller(keep = 3) 1785 caller(1). 1786 map! { |line| line.split(/:(?=\d|in )/, 3)[0,keep] }. 1787 reject { |file, *_| CALLERS_TO_IGNORE.any? { |pattern| file =~ pattern } } 1788 end
# File lib/sinatra/base.rb 1696 def compile(path, route_mustermann_opts = {}) 1697 Mustermann.new(path, **mustermann_opts.merge(route_mustermann_opts)) 1698 end
# File lib/sinatra/base.rb 1677 def compile!(verb, path, block, **options) 1678 # Because of self.options.host 1679 host_name(options.delete(:host)) if options.key?(:host) 1680 # Pass Mustermann opts to compile() 1681 route_mustermann_opts = options.key?(:mustermann_opts) ? options.delete(:mustermann_opts) : {}.freeze 1682 1683 options.each_pair { |option, args| send(option, *args) } 1684 1685 pattern = compile(path, route_mustermann_opts) 1686 method_name = "#{verb} #{path}" 1687 unbound_method = generate_method(method_name, &block) 1688 conditions, @conditions = @conditions, [] 1689 wrapper = block.arity != 0 ? 1690 proc { |a, p| unbound_method.bind(a).call(*p) } : 1691 proc { |a, p| unbound_method.bind(a).call } 1692 1693 [ pattern, conditions, wrapper ] 1694 end
Add a route condition. The route is considered non-matching when the block returns false.
# File lib/sinatra/base.rb 1420 def condition(name = "#{caller.first[/`.*'/]} condition", &block) 1421 @conditions << generate_method(name, &block) 1422 end
Set configuration options for Sinatra
and/or the app. Allows scoping of settings for certain environments.
# File lib/sinatra/base.rb 1480 def configure(*envs) 1481 yield self if envs.empty? || envs.include?(environment.to_sym) 1482 end
Dynamically defines a method on settings.
# File lib/sinatra/base.rb 1615 def define_singleton(name, content = Proc.new) 1616 singleton_class.class_eval do 1617 undef_method(name) if method_defined? name 1618 String === content ? class_eval("def #{name}() #{content}; end") : define_method(name, &content) 1619 end 1620 end
# File lib/sinatra/base.rb 1449 def delete(path, opts = {}, &bk) route 'DELETE', path, opts, &bk end
# File lib/sinatra/base.rb 1474 def development?; environment == :development end
Same as calling ‘set :option, false` for each of the given options.
# File lib/sinatra/base.rb 1318 def disable(*opts) 1319 opts.each { |key| set(key, false) } 1320 end
Same as calling ‘set :option, true` for each of the given options.
# File lib/sinatra/base.rb 1313 def enable(*opts) 1314 opts.each { |key| set(key, true) } 1315 end
Define a custom error handler. Optionally takes either an Exception class, or an HTTP status code to specify which errors should be handled.
# File lib/sinatra/base.rb 1325 def error(*codes, &block) 1326 args = compile! "ERROR", /.*/, block 1327 codes = codes.flat_map(&method(:Array)) 1328 codes << Exception if codes.empty? 1329 codes << Sinatra::NotFound if codes.include?(404) 1330 codes.each { |c| (@errors[c] ||= []) << args } 1331 end
Extension modules registered on this class and all superclasses.
# File lib/sinatra/base.rb 1258 def extensions 1259 if superclass.respond_to?(:extensions) 1260 (@extensions + superclass.extensions).uniq 1261 else 1262 @extensions 1263 end 1264 end
Force data to specified encoding. It defaults to settings.default_encoding which is UTF-8 by default
# File lib/sinatra/base.rb 1793 def self.force_encoding(data, encoding = default_encoding) 1794 return if data == settings || data.is_a?(Tempfile) 1795 if data.respond_to? :force_encoding 1796 data.force_encoding(encoding).encode! 1797 elsif data.respond_to? :each_value 1798 data.each_value { |v| force_encoding(v, encoding) } 1799 elsif data.respond_to? :each 1800 data.each { |v| force_encoding(v, encoding) } 1801 end 1802 data 1803 end
# File lib/sinatra/base.rb 1670 def generate_method(method_name, &block) 1671 define_method(method_name, &block) 1672 method = instance_method method_name 1673 remove_method method_name 1674 method 1675 end
Defining a ‘GET` handler also automatically defines a `HEAD` handler.
# File lib/sinatra/base.rb 1439 def get(path, opts = {}, &block) 1440 conditions = @conditions.dup 1441 route('GET', path, opts, &block) 1442 1443 @conditions = conditions 1444 route('HEAD', path, opts, &block) 1445 end
# File lib/sinatra/base.rb 1450 def head(path, opts = {}, &bk) route 'HEAD', path, opts, &bk end
Makes the methods defined in the block and in the Modules given in ‘extensions` available to the handlers and templates
# File lib/sinatra/base.rb 1458 def helpers(*extensions, &block) 1459 class_eval(&block) if block_given? 1460 include(*extensions) if extensions.any? 1461 end
Condition for matching host name. Parameter might be String or Regexp.
# File lib/sinatra/base.rb 1623 def host_name(pattern) 1624 condition { pattern === request.host } 1625 end
# File lib/sinatra/base.rb 1763 def inherited(subclass) 1764 subclass.reset! 1765 subclass.set :app_file, caller_files.first unless subclass.app_file? 1766 super 1767 end
Load embedded templates from the file; uses the caller’s __FILE__ when no file is specified.
# File lib/sinatra/base.rb 1351 def inline_templates=(file = nil) 1352 file = (file.nil? || file == true) ? (caller_files.first || File.expand_path($0)) : file 1353 1354 begin 1355 io = ::IO.respond_to?(:binread) ? ::IO.binread(file) : ::IO.read(file) 1356 app, data = io.gsub("\r\n", "\n").split(/^__END__$/, 2) 1357 rescue Errno::ENOENT 1358 app, data = nil 1359 end 1360 1361 if data 1362 if app and app =~ /([^\n]*\n)?#[^\n]*coding: *(\S+)/m 1363 encoding = $2 1364 else 1365 encoding = settings.default_encoding 1366 end 1367 lines = app.count("\n") + 1 1368 template = nil 1369 force_encoding data, encoding 1370 data.each_line do |line| 1371 lines += 1 1372 if line =~ /^@@\s*(.*\S)\s*$/ 1373 template = force_encoding(String.new, encoding) 1374 templates[$1.to_sym] = [template, file, lines] 1375 elsif template 1376 template << line 1377 end 1378 end 1379 end 1380 end
# File lib/sinatra/base.rb 1666 def invoke_hook(name, *args) 1667 extensions.each { |e| e.send(name, *args) if e.respond_to?(name) } 1668 end
Define the layout template. The block must return the template source.
# File lib/sinatra/base.rb 1345 def layout(name = :layout, &block) 1346 template name, &block 1347 end
# File lib/sinatra/base.rb 1453 def link(path, opts = {}, &bk) route 'LINK', path, opts, &bk end
Middleware used in this class and all superclasses.
# File lib/sinatra/base.rb 1267 def middleware 1268 if superclass.respond_to?(:middleware) 1269 superclass.middleware + @middleware 1270 else 1271 @middleware 1272 end 1273 end
Lookup or register a mime type in Rack’s mime registry.
# File lib/sinatra/base.rb 1383 def mime_type(type, value = nil) 1384 return type if type.nil? 1385 return type.to_s if type.to_s.include?('/') 1386 type = ".#{type}" unless type.to_s[0] == ?. 1387 return Rack::Mime.mime_type(type, nil) unless value 1388 Rack::Mime::MIME_TYPES[type] = value 1389 end
provides all mime types matching type, including deprecated types:
mime_types :html # => ['text/html'] mime_types :js # => ['application/javascript', 'text/javascript']
# File lib/sinatra/base.rb 1394 def mime_types(type) 1395 type = mime_type type 1396 type =~ /^application\/(xml|javascript)$/ ? [type, "text/#$1"] : [type] 1397 end
Create a new instance of the class fronted by its middleware pipeline. The object is guaranteed to respond to call
but may not be an instance of the class new was called on.
# File lib/sinatra/base.rb 1542 def new(*args, **kwargs, &bk) 1543 instance = new!(*args, **kwargs, &bk) 1544 Wrapper.new(build(instance).to_app, instance) 1545 end
Sugar for ‘error(404) { … }`
# File lib/sinatra/base.rb 1334 def not_found(&block) 1335 error(404, &block) 1336 end
# File lib/sinatra/base.rb 1451 def options(path, opts = {}, &bk) route 'OPTIONS', path, opts, &bk end
# File lib/sinatra/base.rb 1452 def patch(path, opts = {}, &bk) route 'PATCH', path, opts, &bk end
# File lib/sinatra/base.rb 1448 def post(path, opts = {}, &bk) route 'POST', path, opts, &bk end
# File lib/sinatra/base.rb 1475 def production?; environment == :production end
The prototype instance used to process requests.
# File lib/sinatra/base.rb 1532 def prototype 1533 @prototype ||= new 1534 end
Condition for matching mimetypes. Accepts file extensions.
# File lib/sinatra/base.rb 1642 def provides(*types) 1643 types.map! { |t| mime_types(t) } 1644 types.flatten! 1645 condition do 1646 if type = response['Content-Type'] 1647 types.include? type or types.include? type[/^[^;]+/] 1648 elsif type = request.preferred_type(types) 1649 params = (type.respond_to?(:params) ? type.params : {}) 1650 content_type(type, params) 1651 true 1652 else 1653 false 1654 end 1655 end 1656 end
# File lib/sinatra/base.rb 1424 def public=(value) 1425 warn ":public is no longer used to avoid overloading Module#public, use :public_folder or :public_dir instead" 1426 set(:public_folder, value) 1427 end
# File lib/sinatra/base.rb 1433 def public_dir 1434 public_folder 1435 end
# File lib/sinatra/base.rb 1429 def public_dir=(value) 1430 self.public_folder = value 1431 end
# File lib/sinatra/base.rb 1447 def put(path, opts = {}, &bk) route 'PUT', path, opts, &bk end
Stop the self-hosted server if running.
# File lib/sinatra/base.rb 1492 def quit! 1493 return unless running? 1494 # Use Thin's hard #stop! if available, otherwise just #stop. 1495 running_server.respond_to?(:stop!) ? running_server.stop! : running_server.stop 1496 $stderr.puts "== Sinatra has ended his set (crowd applauds)" unless suppress_messages? 1497 set :running_server, nil 1498 set :handler_name, nil 1499 end
Register an extension. Alternatively take a block from which an extension will be created and registered on the fly.
# File lib/sinatra/base.rb 1465 def register(*extensions, &block) 1466 extensions << Module.new(&block) if block_given? 1467 @extensions += extensions 1468 extensions.each do |extension| 1469 extend extension 1470 extension.registered(self) if extension.respond_to?(:registered) 1471 end 1472 end
Removes all routes, filters, middleware and extension hooks from the current class (not routes/filters/… defined by its superclass).
# File lib/sinatra/base.rb 1241 def reset! 1242 @conditions = [] 1243 @routes = {} 1244 @filters = {:before => [], :after => []} 1245 @errors = {} 1246 @middleware = [] 1247 @prototype = nil 1248 @extensions = [] 1249 1250 if superclass.respond_to?(:templates) 1251 @templates = Hash.new { |hash, key| superclass.templates[key] } 1252 else 1253 @templates = {} 1254 end 1255 end
# File lib/sinatra/base.rb 1658 def route(verb, path, options = {}, &block) 1659 enable :empty_path_info if path == "" and empty_path_info.nil? 1660 signature = compile!(verb, path, block, **options) 1661 (@routes[verb] ||= []) << signature 1662 invoke_hook(:route_added, verb, path, block) 1663 signature 1664 end
Run the Sinatra
app as a self-hosted server using Puma, Mongrel, or WEBrick (in that order). If given a block, will call with the constructed handler once we have taken the stage.
# File lib/sinatra/base.rb 1506 def run!(options = {}, &block) 1507 return if running? 1508 set options 1509 handler = Rack::Handler.pick(server) 1510 handler_name = handler.name.gsub(/.*::/, '') 1511 server_settings = settings.respond_to?(:server_settings) ? settings.server_settings : {} 1512 server_settings.merge!(:Port => port, :Host => bind) 1513 1514 begin 1515 start_server(handler, server_settings, handler_name, &block) 1516 rescue Errno::EADDRINUSE 1517 $stderr.puts "== Someone is already performing on port #{port}!" 1518 raise 1519 ensure 1520 quit! 1521 end 1522 end
Check whether the self-hosted server is running or not.
# File lib/sinatra/base.rb 1527 def running? 1528 running_server? 1529 end
Sets an option to the given value. If the value is a proc, the proc will be called every time the option is accessed.
# File lib/sinatra/base.rb 1277 def set(option, value = (not_set = true), ignore_setter = false, &block) 1278 raise ArgumentError if block and !not_set 1279 value, not_set = block, false if block 1280 1281 if not_set 1282 raise ArgumentError unless option.respond_to?(:each) 1283 option.each { |k,v| set(k, v) } 1284 return self 1285 end 1286 1287 if respond_to?("#{option}=") and not ignore_setter 1288 return __send__("#{option}=", value) 1289 end 1290 1291 setter = proc { |val| set option, val, true } 1292 getter = proc { value } 1293 1294 case value 1295 when Proc 1296 getter = value 1297 when Symbol, Integer, FalseClass, TrueClass, NilClass 1298 getter = value.inspect 1299 when Hash 1300 setter = proc do |val| 1301 val = value.merge val if Hash === val 1302 set option, val, true 1303 end 1304 end 1305 1306 define_singleton("#{option}=", setter) 1307 define_singleton(option, getter) 1308 define_singleton("#{option}?", "!!#{option}") unless method_defined? "#{option}?" 1309 self 1310 end
# File lib/sinatra/base.rb 1727 def setup_common_logger(builder) 1728 builder.use Sinatra::CommonLogger 1729 end
# File lib/sinatra/base.rb 1731 def setup_custom_logger(builder) 1732 if logging.respond_to? :to_int 1733 builder.use Rack::Logger, logging 1734 else 1735 builder.use Rack::Logger 1736 end 1737 end
# File lib/sinatra/base.rb 1700 def setup_default_middleware(builder) 1701 builder.use ExtendedRack 1702 builder.use ShowExceptions if show_exceptions? 1703 builder.use Rack::MethodOverride if method_override? 1704 builder.use Rack::Head 1705 setup_logging builder 1706 setup_sessions builder 1707 setup_protection builder 1708 end
# File lib/sinatra/base.rb 1714 def setup_logging(builder) 1715 if logging? 1716 setup_common_logger(builder) 1717 setup_custom_logger(builder) 1718 elsif logging == false 1719 setup_null_logger(builder) 1720 end 1721 end
# File lib/sinatra/base.rb 1710 def setup_middleware(builder) 1711 middleware.each { |c,a,b| builder.use(c, *a, &b) } 1712 end
# File lib/sinatra/base.rb 1723 def setup_null_logger(builder) 1724 builder.use Rack::NullLogger 1725 end
# File lib/sinatra/base.rb 1739 def setup_protection(builder) 1740 return unless protection? 1741 options = Hash === protection ? protection.dup : {} 1742 options = { 1743 img_src: "'self' data:", 1744 font_src: "'self'" 1745 }.merge options 1746 1747 protect_session = options.fetch(:session) { sessions? } 1748 options[:without_session] = !protect_session 1749 1750 options[:reaction] ||= :drop_session 1751 1752 builder.use Rack::Protection, options 1753 end
# File lib/sinatra/base.rb 1755 def setup_sessions(builder) 1756 return unless sessions? 1757 options = {} 1758 options[:secret] = session_secret if session_secret? 1759 options.merge! sessions.to_hash if sessions.respond_to? :to_hash 1760 builder.use session_store, options 1761 end
# File lib/sinatra/base.rb 1599 def setup_traps 1600 if traps? 1601 at_exit { quit! } 1602 1603 [:INT, :TERM].each do |signal| 1604 old_handler = trap(signal) do 1605 quit! 1606 old_handler.call if old_handler.respond_to?(:call) 1607 end 1608 end 1609 1610 set :traps, false 1611 end 1612 end
Starts the server by running the Rack
Handler.
# File lib/sinatra/base.rb 1576 def start_server(handler, server_settings, handler_name) 1577 # Ensure we initialize middleware before startup, to match standard Rack 1578 # behavior, by ensuring an instance exists: 1579 prototype 1580 # Run the instance we created: 1581 handler.run(self, **server_settings) do |server| 1582 unless suppress_messages? 1583 $stderr.puts "== Sinatra (v#{Sinatra::VERSION}) has taken the stage on #{port} for #{environment} with backup from #{handler_name}" 1584 end 1585 1586 setup_traps 1587 set :running_server, server 1588 set :handler_name, handler_name 1589 server.threaded = settings.threaded if server.respond_to? :threaded= 1590 1591 yield server if block_given? 1592 end 1593 end
# File lib/sinatra/base.rb 1595 def suppress_messages? 1596 handler_name =~ /cgi/i || quiet 1597 end
# File lib/sinatra/base.rb 1770 def synchronize(&block) 1771 if lock? 1772 @@mutex.synchronize(&block) 1773 else 1774 yield 1775 end 1776 end
Define a named template. The block must return the template source.
# File lib/sinatra/base.rb 1339 def template(name, &block) 1340 filename, line = caller_locations.first 1341 templates[name] = [block, filename, line.to_i] 1342 end
# File lib/sinatra/base.rb 1476 def test?; environment == :test end
# File lib/sinatra/base.rb 1454 def unlink(path, opts = {}, &bk) route 'UNLINK', path, opts, &bk end
Use the specified Rack
middleware
# File lib/sinatra/base.rb 1485 def use(middleware, *args, &block) 1486 @prototype = nil 1487 @middleware << [middleware, args, block] 1488 end
Condition for matching user agent. Parameter should be Regexp. Will set params.
# File lib/sinatra/base.rb 1629 def user_agent(pattern) 1630 condition do 1631 if request.user_agent.to_s =~ pattern 1632 @params[:agent] = $~[1..-1] 1633 true 1634 else 1635 false 1636 end 1637 end 1638 end
used for deprecation warnings
# File lib/sinatra/base.rb 1779 def warn(message) 1780 super message + "\n\tfrom #{cleaned_caller.first.join(':')}" 1781 end
Public Instance Methods
Rack
call interface.
# File lib/sinatra/base.rb 940 def call(env) 941 dup.call!(env) 942 end
Forward the request to the downstream app – middleware only.
# File lib/sinatra/base.rb 997 def forward 998 fail "downstream app not set" unless @app.respond_to? :call 999 status, headers, body = @app.call env 1000 @response.status = status 1001 @response.body = body 1002 @response.headers.merge! headers 1003 nil 1004 end
Exit the current block, halts any further processing of the request, and returns the specified response.
# File lib/sinatra/base.rb 984 def halt(*response) 985 response = response.first if response.length == 1 986 throw :halt, response 987 end
# File lib/sinatra/base.rb 976 def options 977 warn "Sinatra::Base#options is deprecated and will be removed, " \ 978 "use #settings instead." 979 settings 980 end
Pass control to the next matching route. If there are no more matching routes, Sinatra
will return a 404 response.
# File lib/sinatra/base.rb 992 def pass(&block) 993 throw :pass, block 994 end
Access settings defined with Base.set
.
# File lib/sinatra/base.rb 972 def settings 973 self.class.settings 974 end
Private Instance Methods
Dispatch a request with error handling.
# File lib/sinatra/base.rb 1130 def dispatch! 1131 # Avoid passing frozen string in force_encoding 1132 @params.merge!(@request.params).each do |key, val| 1133 next unless val.respond_to?(:force_encoding) 1134 val = val.dup if val.frozen? 1135 @params[key] = force_encoding(val) 1136 end 1137 1138 invoke do 1139 static! if settings.static? && (request.get? || request.head?) 1140 filter! :before do 1141 @pinned_response = !response['Content-Type'].nil? 1142 end 1143 route! 1144 end 1145 rescue ::Exception => boom 1146 invoke { handle_exception!(boom) } 1147 ensure 1148 begin 1149 filter! :after unless env['sinatra.static_file'] 1150 rescue ::Exception => boom 1151 invoke { handle_exception!(boom) } unless @env['sinatra.error'] 1152 end 1153 end
# File lib/sinatra/base.rb 1214 def dump_errors!(boom) 1215 msg = ["#{Time.now.strftime("%Y-%m-%d %H:%M:%S")} - #{boom.class} - #{boom.message}:", *boom.backtrace].join("\n\t") 1216 @env['rack.errors'].puts(msg) 1217 end
Find an custom error block for the key(s) specified.
# File lib/sinatra/base.rb 1199 def error_block!(key, *block_params) 1200 base = settings 1201 while base.respond_to?(:errors) 1202 next base = base.superclass unless args_array = base.errors[key] 1203 args_array.reverse_each do |args| 1204 first = args == args_array.first 1205 args += [block_params] 1206 resp = process_route(*args) 1207 return resp unless resp.nil? && !first 1208 end 1209 end 1210 return false unless key.respond_to? :superclass and key.superclass < Exception 1211 error_block!(key.superclass, *block_params) 1212 end
Run filters defined on the class and all superclasses. Accepts an optional block to call after each filter is applied.
# File lib/sinatra/base.rb 1010 def filter!(type, base = settings, &block) 1011 filter!(type, base.superclass, &block) if base.superclass.respond_to?(:filters) 1012 base.filters[type].each do |args| 1013 result = process_route(*args) 1014 block.call(result) if block_given? 1015 end 1016 end
# File lib/sinatra/base.rb 1805 def force_encoding(*args) settings.force_encoding(*args) end
Error
handling during requests.
# File lib/sinatra/base.rb 1156 def handle_exception!(boom) 1157 if error_params = @env['sinatra.error.params'] 1158 @params = @params.merge(error_params) 1159 end 1160 @env['sinatra.error'] = boom 1161 1162 http_status = if boom.kind_of? Sinatra::Error 1163 if boom.respond_to? :http_status 1164 boom.http_status 1165 elsif settings.use_code? && boom.respond_to?(:code) 1166 boom.code 1167 end 1168 end 1169 1170 http_status = 500 unless http_status && http_status.between?(400, 599) 1171 status(http_status) 1172 1173 if server_error? 1174 dump_errors! boom if settings.dump_errors? 1175 raise boom if settings.show_exceptions? and settings.show_exceptions != :after_handler 1176 elsif not_found? 1177 headers['X-Cascade'] = 'pass' if settings.x_cascade? 1178 end 1179 1180 if res = error_block!(boom.class, boom) || error_block!(status, boom) 1181 return res 1182 end 1183 1184 if not_found? || bad_request? 1185 if boom.message && boom.message != boom.class.name 1186 body Rack::Utils.escape_html(boom.message) 1187 else 1188 content_type 'text/html' 1189 body '<h1>' + (not_found? ? 'Not Found' : 'Bad Request') + '</h1>' 1190 end 1191 end 1192 1193 return unless server_error? 1194 raise boom if settings.raise_errors? or settings.show_exceptions? 1195 error_block! Exception, boom 1196 end
Run the block with ‘throw :halt’ support and apply result to the response.
# File lib/sinatra/base.rb 1114 def invoke 1115 res = catch(:halt) { yield } 1116 1117 res = [res] if Integer === res or String === res 1118 if Array === res and Integer === res.first 1119 res = res.dup 1120 status(res.shift) 1121 body(res.pop) 1122 headers(*res) 1123 elsif res.respond_to? :each 1124 body res 1125 end 1126 nil # avoid double setting the same response tuple twice 1127 end
If the current request matches pattern and conditions, fill params with keys and call the given block. Revert params afterwards.
Returns pass block.
# File lib/sinatra/base.rb 1053 def process_route(pattern, conditions, block = nil, values = []) 1054 route = @request.path_info 1055 route = '/' if route.empty? and not settings.empty_path_info? 1056 route = route[0..-2] if !settings.strict_paths? && route != '/' && route.end_with?('/') 1057 return unless params = pattern.params(route) 1058 1059 params.delete("ignore") # TODO: better params handling, maybe turn it into "smart" object or detect changes 1060 force_encoding(params) 1061 @params = @params.merge(params) if params.any? 1062 1063 regexp_exists = pattern.is_a?(Mustermann::Regular) || (pattern.respond_to?(:patterns) && pattern.patterns.any? {|subpattern| subpattern.is_a?(Mustermann::Regular)} ) 1064 if regexp_exists 1065 captures = pattern.match(route).captures.map { |c| URI_INSTANCE.unescape(c) if c } 1066 values += captures 1067 @params[:captures] = force_encoding(captures) unless captures.nil? || captures.empty? 1068 else 1069 values += params.values.flatten 1070 end 1071 1072 catch(:pass) do 1073 conditions.each { |c| throw :pass if c.bind(self).call == false } 1074 block ? block[self, values] : yield(self, values) 1075 end 1076 rescue 1077 @env['sinatra.error.params'] = @params 1078 raise 1079 ensure 1080 params ||= {} 1081 params.each { |k, _| @params.delete(k) } unless @env['sinatra.error.params'] 1082 end
Run routes defined on the class and all superclasses.
# File lib/sinatra/base.rb 1019 def route!(base = settings, pass_block = nil) 1020 if routes = base.routes[@request.request_method] 1021 routes.each do |pattern, conditions, block| 1022 response.delete_header('Content-Type') unless @pinned_response 1023 1024 returned_pass_block = process_route(pattern, conditions) do |*args| 1025 env['sinatra.route'] = "#{@request.request_method} #{pattern}" 1026 route_eval { block[*args] } 1027 end 1028 1029 # don't wipe out pass_block in superclass 1030 pass_block = returned_pass_block if returned_pass_block 1031 end 1032 end 1033 1034 # Run routes defined in superclass. 1035 if base.superclass.respond_to?(:routes) 1036 return route!(base.superclass, pass_block) 1037 end 1038 1039 route_eval(&pass_block) if pass_block 1040 route_missing 1041 end
Run a route block and throw :halt with the result.
# File lib/sinatra/base.rb 1044 def route_eval 1045 throw :halt, yield 1046 end
No matching route was found or all routes passed. The default implementation is to forward the request downstream when running as middleware (@app is non-nil); when no downstream app is set, raise a NotFound
exception. Subclasses can override this method to perform custom route miss logic.
# File lib/sinatra/base.rb 1089 def route_missing 1090 if @app 1091 forward 1092 else 1093 raise NotFound, "#{request.request_method} #{request.path_info}" 1094 end 1095 end
Attempt to serve static files from public directory. Throws :halt when a matching file is found, returns nil otherwise.
# File lib/sinatra/base.rb 1099 def static!(options = {}) 1100 return if (public_dir = settings.public_folder).nil? 1101 path = "#{public_dir}#{URI_INSTANCE.unescape(request.path_info)}" 1102 return unless valid_path?(path) 1103 1104 path = File.expand_path(path) 1105 return unless path.start_with?(File.expand_path(public_dir) + '/') 1106 return unless File.file?(path) 1107 1108 env['sinatra.static_file'] = path 1109 cache_control(*settings.static_cache_control) if settings.static_cache_control? 1110 send_file path, options.merge(:disposition => nil) 1111 end