class Sinatra::Helpers::Stream::Base
Constants
- URI_INSTANCE
Attributes
Public Class Methods
Sinatra::Helpers::Stream::Templates::new
# File lib/sinatra/base.rb 922 def initialize(app = nil) 923 super() 924 @app = app 925 @template_cache = Tilt::Cache.new 926 @pinned_response = nil # whether a before! filter pinned the content-type 927 yield self if block_given? 928 end
Access settings defined with Base.set
.
# File lib/sinatra/base.rb 957 def self.settings 958 self 959 end
Private Class Methods
add a filter
# File lib/sinatra/base.rb 1403 def add_filter(type, path = /.*/, **options, &block) 1404 filters[type] << compile!(type, path, block, **options) 1405 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 1398 def after(path = /.*/, **options, &block) 1399 add_filter(:after, path, **options, &block) 1400 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 1391 def before(path = /.*/, **options, &block) 1392 add_filter(:before, path, **options, &block) 1393 end
Creates a Rack::Builder
instance with all the middleware set up and the given app
as end point.
# File lib/sinatra/base.rb 1537 def build(app) 1538 builder = Rack::Builder.new 1539 setup_default_middleware builder 1540 setup_middleware builder 1541 builder.run app 1542 builder 1543 end
# File lib/sinatra/base.rb 1545 def call(env) 1546 synchronize { prototype.call(env) } 1547 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 1551 def caller_files 1552 cleaned_caller(1).flatten 1553 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 1557 def caller_locations 1558 cleaned_caller 2 1559 end
Like Kernel#caller but excluding certain magic entries
# File lib/sinatra/base.rb 1783 def cleaned_caller(keep = 3) 1784 caller(1). 1785 map! { |line| line.split(/:(?=\d|in )/, 3)[0,keep] }. 1786 reject { |file, *_| CALLERS_TO_IGNORE.any? { |pattern| file =~ pattern } } 1787 end
# File lib/sinatra/base.rb 1684 def compile(path, route_mustermann_opts = {}) 1685 Mustermann.new(path, **mustermann_opts.merge(route_mustermann_opts)) 1686 end
# File lib/sinatra/base.rb 1665 def compile!(verb, path, block, **options) 1666 # Because of self.options.host 1667 host_name(options.delete(:host)) if options.key?(:host) 1668 # Pass Mustermann opts to compile() 1669 route_mustermann_opts = options.key?(:mustermann_opts) ? options.delete(:mustermann_opts) : {}.freeze 1670 1671 options.each_pair { |option, args| send(option, *args) } 1672 1673 pattern = compile(path, route_mustermann_opts) 1674 method_name = "#{verb} #{path}" 1675 unbound_method = generate_method(method_name, &block) 1676 conditions, @conditions = @conditions, [] 1677 wrapper = block.arity != 0 ? 1678 proc { |a, p| unbound_method.bind(a).call(*p) } : 1679 proc { |a, p| unbound_method.bind(a).call } 1680 1681 [ pattern, conditions, wrapper ] 1682 end
Add a route condition. The route is considered non-matching when the block returns false.
# File lib/sinatra/base.rb 1409 def condition(name = "#{caller.first[/`.*'/]} condition", &block) 1410 @conditions << generate_method(name, &block) 1411 end
Set configuration options for Sinatra
and/or the app. Allows scoping of settings for certain environments.
# File lib/sinatra/base.rb 1469 def configure(*envs) 1470 yield self if envs.empty? || envs.include?(environment.to_sym) 1471 end
Dynamically defines a method on settings.
# File lib/sinatra/base.rb 1603 def define_singleton(name, content = Proc.new) 1604 singleton_class.class_eval do 1605 undef_method(name) if method_defined? name 1606 String === content ? class_eval("def #{name}() #{content}; end") : define_method(name, &content) 1607 end 1608 end
# File lib/sinatra/base.rb 1438 def delete(path, opts = {}, &bk) route 'DELETE', path, opts, &bk end
# File lib/sinatra/base.rb 1751 def detect_rack_handler 1752 servers = Array(server) 1753 servers.each do |server_name| 1754 begin 1755 return Rack::Handler.get(server_name.to_s) 1756 rescue LoadError, NameError 1757 end 1758 end 1759 fail "Server handler (#{servers.join(',')}) not found." 1760 end
# File lib/sinatra/base.rb 1463 def development?; environment == :development end
Same as calling ‘set :option, false` for each of the given options.
# File lib/sinatra/base.rb 1307 def disable(*opts) 1308 opts.each { |key| set(key, false) } 1309 end
Same as calling ‘set :option, true` for each of the given options.
# File lib/sinatra/base.rb 1302 def enable(*opts) 1303 opts.each { |key| set(key, true) } 1304 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 1314 def error(*codes, &block) 1315 args = compile! "ERROR", /.*/, block 1316 codes = codes.flat_map(&method(:Array)) 1317 codes << Exception if codes.empty? 1318 codes << Sinatra::NotFound if codes.include?(404) 1319 codes.each { |c| (@errors[c] ||= []) << args } 1320 end
Extension modules registered on this class and all superclasses.
# File lib/sinatra/base.rb 1247 def extensions 1248 if superclass.respond_to?(:extensions) 1249 (@extensions + superclass.extensions).uniq 1250 else 1251 @extensions 1252 end 1253 end
Force data to specified encoding. It defaults to settings.default_encoding which is UTF-8 by default
# File lib/sinatra/base.rb 1792 def self.force_encoding(data, encoding = default_encoding) 1793 return if data == settings || data.is_a?(Tempfile) 1794 if data.respond_to? :force_encoding 1795 data.force_encoding(encoding).encode! 1796 elsif data.respond_to? :each_value 1797 data.each_value { |v| force_encoding(v, encoding) } 1798 elsif data.respond_to? :each 1799 data.each { |v| force_encoding(v, encoding) } 1800 end 1801 data 1802 end
# File lib/sinatra/base.rb 1658 def generate_method(method_name, &block) 1659 define_method(method_name, &block) 1660 method = instance_method method_name 1661 remove_method method_name 1662 method 1663 end
Defining a ‘GET` handler also automatically defines a `HEAD` handler.
# File lib/sinatra/base.rb 1428 def get(path, opts = {}, &block) 1429 conditions = @conditions.dup 1430 route('GET', path, opts, &block) 1431 1432 @conditions = conditions 1433 route('HEAD', path, opts, &block) 1434 end
# File lib/sinatra/base.rb 1439 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 1447 def helpers(*extensions, &block) 1448 class_eval(&block) if block_given? 1449 prepend(*extensions) if extensions.any? 1450 end
Condition for matching host name. Parameter might be String or Regexp.
# File lib/sinatra/base.rb 1611 def host_name(pattern) 1612 condition { pattern === request.host } 1613 end
# File lib/sinatra/base.rb 1762 def inherited(subclass) 1763 subclass.reset! 1764 subclass.set :app_file, caller_files.first unless subclass.app_file? 1765 super 1766 end
Load embedded templates from the file; uses the caller’s __FILE__ when no file is specified.
# File lib/sinatra/base.rb 1340 def inline_templates=(file = nil) 1341 file = (file.nil? || file == true) ? (caller_files.first || File.expand_path($0)) : file 1342 1343 begin 1344 io = ::IO.respond_to?(:binread) ? ::IO.binread(file) : ::IO.read(file) 1345 app, data = io.gsub("\r\n", "\n").split(/^__END__$/, 2) 1346 rescue Errno::ENOENT 1347 app, data = nil 1348 end 1349 1350 if data 1351 if app and app =~ /([^\n]*\n)?#[^\n]*coding: *(\S+)/m 1352 encoding = $2 1353 else 1354 encoding = settings.default_encoding 1355 end 1356 lines = app.count("\n") + 1 1357 template = nil 1358 force_encoding data, encoding 1359 data.each_line do |line| 1360 lines += 1 1361 if line =~ /^@@\s*(.*\S)\s*$/ 1362 template = force_encoding(String.new, encoding) 1363 templates[$1.to_sym] = [template, file, lines] 1364 elsif template 1365 template << line 1366 end 1367 end 1368 end 1369 end
# File lib/sinatra/base.rb 1654 def invoke_hook(name, *args) 1655 extensions.each { |e| e.send(name, *args) if e.respond_to?(name) } 1656 end
Define the layout template. The block must return the template source.
# File lib/sinatra/base.rb 1334 def layout(name = :layout, &block) 1335 template name, &block 1336 end
# File lib/sinatra/base.rb 1442 def link(path, opts = {}, &bk) route 'LINK', path, opts, &bk end
Middleware used in this class and all superclasses.
# File lib/sinatra/base.rb 1256 def middleware 1257 if superclass.respond_to?(:middleware) 1258 superclass.middleware + @middleware 1259 else 1260 @middleware 1261 end 1262 end
Lookup or register a mime type in Rack’s mime registry.
# File lib/sinatra/base.rb 1372 def mime_type(type, value = nil) 1373 return type if type.nil? 1374 return type.to_s if type.to_s.include?('/') 1375 type = ".#{type}" unless type.to_s[0] == ?. 1376 return Rack::Mime.mime_type(type, nil) unless value 1377 Rack::Mime::MIME_TYPES[type] = value 1378 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 1383 def mime_types(type) 1384 type = mime_type type 1385 type =~ /^application\/(xml|javascript)$/ ? [type, "text/#$1"] : [type] 1386 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 1530 def new(*args, &bk) 1531 instance = new!(*args, &bk) 1532 Wrapper.new(build(instance).to_app, instance) 1533 end
Sugar for ‘error(404) { … }`
# File lib/sinatra/base.rb 1323 def not_found(&block) 1324 error(404, &block) 1325 end
# File lib/sinatra/base.rb 1440 def options(path, opts = {}, &bk) route 'OPTIONS', path, opts, &bk end
# File lib/sinatra/base.rb 1441 def patch(path, opts = {}, &bk) route 'PATCH', path, opts, &bk end
# File lib/sinatra/base.rb 1437 def post(path, opts = {}, &bk) route 'POST', path, opts, &bk end
# File lib/sinatra/base.rb 1464 def production?; environment == :production end
The prototype instance used to process requests.
# File lib/sinatra/base.rb 1520 def prototype 1521 @prototype ||= new 1522 end
Condition for matching mimetypes. Accepts file extensions.
# File lib/sinatra/base.rb 1630 def provides(*types) 1631 types.map! { |t| mime_types(t) } 1632 types.flatten! 1633 condition do 1634 if type = response['Content-Type'] 1635 types.include? type or types.include? type[/^[^;]+/] 1636 elsif type = request.preferred_type(types) 1637 params = (type.respond_to?(:params) ? type.params : {}) 1638 content_type(type, params) 1639 true 1640 else 1641 false 1642 end 1643 end 1644 end
# File lib/sinatra/base.rb 1413 def public=(value) 1414 warn ":public is no longer used to avoid overloading Module#public, use :public_folder or :public_dir instead" 1415 set(:public_folder, value) 1416 end
# File lib/sinatra/base.rb 1422 def public_dir 1423 public_folder 1424 end
# File lib/sinatra/base.rb 1418 def public_dir=(value) 1419 self.public_folder = value 1420 end
# File lib/sinatra/base.rb 1436 def put(path, opts = {}, &bk) route 'PUT', path, opts, &bk end
Stop the self-hosted server if running.
# File lib/sinatra/base.rb 1480 def quit! 1481 return unless running? 1482 # Use Thin's hard #stop! if available, otherwise just #stop. 1483 running_server.respond_to?(:stop!) ? running_server.stop! : running_server.stop 1484 $stderr.puts "== Sinatra has ended his set (crowd applauds)" unless suppress_messages? 1485 set :running_server, nil 1486 set :handler_name, nil 1487 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 1454 def register(*extensions, &block) 1455 extensions << Module.new(&block) if block_given? 1456 @extensions += extensions 1457 extensions.each do |extension| 1458 extend extension 1459 extension.registered(self) if extension.respond_to?(:registered) 1460 end 1461 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 1230 def reset! 1231 @conditions = [] 1232 @routes = {} 1233 @filters = {:before => [], :after => []} 1234 @errors = {} 1235 @middleware = [] 1236 @prototype = nil 1237 @extensions = [] 1238 1239 if superclass.respond_to?(:templates) 1240 @templates = Hash.new { |hash, key| superclass.templates[key] } 1241 else 1242 @templates = {} 1243 end 1244 end
# File lib/sinatra/base.rb 1646 def route(verb, path, options = {}, &block) 1647 enable :empty_path_info if path == "" and empty_path_info.nil? 1648 signature = compile!(verb, path, block, **options) 1649 (@routes[verb] ||= []) << signature 1650 invoke_hook(:route_added, verb, path, block) 1651 signature 1652 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 1494 def run!(options = {}, &block) 1495 return if running? 1496 set options 1497 handler = detect_rack_handler 1498 handler_name = handler.name.gsub(/.*::/, '') 1499 server_settings = settings.respond_to?(:server_settings) ? settings.server_settings : {} 1500 server_settings.merge!(:Port => port, :Host => bind) 1501 1502 begin 1503 start_server(handler, server_settings, handler_name, &block) 1504 rescue Errno::EADDRINUSE 1505 $stderr.puts "== Someone is already performing on port #{port}!" 1506 raise 1507 ensure 1508 quit! 1509 end 1510 end
Check whether the self-hosted server is running or not.
# File lib/sinatra/base.rb 1515 def running? 1516 running_server? 1517 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 1266 def set(option, value = (not_set = true), ignore_setter = false, &block) 1267 raise ArgumentError if block and !not_set 1268 value, not_set = block, false if block 1269 1270 if not_set 1271 raise ArgumentError unless option.respond_to?(:each) 1272 option.each { |k,v| set(k, v) } 1273 return self 1274 end 1275 1276 if respond_to?("#{option}=") and not ignore_setter 1277 return __send__("#{option}=", value) 1278 end 1279 1280 setter = proc { |val| set option, val, true } 1281 getter = proc { value } 1282 1283 case value 1284 when Proc 1285 getter = value 1286 when Symbol, Integer, FalseClass, TrueClass, NilClass 1287 getter = value.inspect 1288 when Hash 1289 setter = proc do |val| 1290 val = value.merge val if Hash === val 1291 set option, val, true 1292 end 1293 end 1294 1295 define_singleton("#{option}=", setter) 1296 define_singleton(option, getter) 1297 define_singleton("#{option}?", "!!#{option}") unless method_defined? "#{option}?" 1298 self 1299 end
# File lib/sinatra/base.rb 1715 def setup_common_logger(builder) 1716 builder.use Sinatra::CommonLogger 1717 end
# File lib/sinatra/base.rb 1719 def setup_custom_logger(builder) 1720 if logging.respond_to? :to_int 1721 builder.use Rack::Logger, logging 1722 else 1723 builder.use Rack::Logger 1724 end 1725 end
# File lib/sinatra/base.rb 1688 def setup_default_middleware(builder) 1689 builder.use ExtendedRack 1690 builder.use ShowExceptions if show_exceptions? 1691 builder.use Rack::MethodOverride if method_override? 1692 builder.use Rack::Head 1693 setup_logging builder 1694 setup_sessions builder 1695 setup_protection builder 1696 end
# File lib/sinatra/base.rb 1702 def setup_logging(builder) 1703 if logging? 1704 setup_common_logger(builder) 1705 setup_custom_logger(builder) 1706 elsif logging == false 1707 setup_null_logger(builder) 1708 end 1709 end
# File lib/sinatra/base.rb 1698 def setup_middleware(builder) 1699 middleware.each { |c,a,b| builder.use(c, *a, &b) } 1700 end
# File lib/sinatra/base.rb 1711 def setup_null_logger(builder) 1712 builder.use Rack::NullLogger 1713 end
# File lib/sinatra/base.rb 1727 def setup_protection(builder) 1728 return unless protection? 1729 options = Hash === protection ? protection.dup : {} 1730 options = { 1731 img_src: "'self' data:", 1732 font_src: "'self'" 1733 }.merge options 1734 1735 protect_session = options.fetch(:session) { sessions? } 1736 options[:without_session] = !protect_session 1737 1738 options[:reaction] ||= :drop_session 1739 1740 builder.use Rack::Protection, options 1741 end
# File lib/sinatra/base.rb 1743 def setup_sessions(builder) 1744 return unless sessions? 1745 options = {} 1746 options[:secret] = session_secret if session_secret? 1747 options.merge! sessions.to_hash if sessions.respond_to? :to_hash 1748 builder.use session_store, options 1749 end
# File lib/sinatra/base.rb 1587 def setup_traps 1588 if traps? 1589 at_exit { quit! } 1590 1591 [:INT, :TERM].each do |signal| 1592 old_handler = trap(signal) do 1593 quit! 1594 old_handler.call if old_handler.respond_to?(:call) 1595 end 1596 end 1597 1598 set :traps, false 1599 end 1600 end
Starts the server by running the Rack
Handler.
# File lib/sinatra/base.rb 1564 def start_server(handler, server_settings, handler_name) 1565 # Ensure we initialize middleware before startup, to match standard Rack 1566 # behavior, by ensuring an instance exists: 1567 prototype 1568 # Run the instance we created: 1569 handler.run(self, **server_settings) do |server| 1570 unless suppress_messages? 1571 $stderr.puts "== Sinatra (v#{Sinatra::VERSION}) has taken the stage on #{port} for #{environment} with backup from #{handler_name}" 1572 end 1573 1574 setup_traps 1575 set :running_server, server 1576 set :handler_name, handler_name 1577 server.threaded = settings.threaded if server.respond_to? :threaded= 1578 1579 yield server if block_given? 1580 end 1581 end
# File lib/sinatra/base.rb 1583 def suppress_messages? 1584 handler_name =~ /cgi/i || quiet 1585 end
# File lib/sinatra/base.rb 1769 def synchronize(&block) 1770 if lock? 1771 @@mutex.synchronize(&block) 1772 else 1773 yield 1774 end 1775 end
Define a named template. The block must return the template source.
# File lib/sinatra/base.rb 1328 def template(name, &block) 1329 filename, line = caller_locations.first 1330 templates[name] = [block, filename, line.to_i] 1331 end
# File lib/sinatra/base.rb 1465 def test?; environment == :test end
# File lib/sinatra/base.rb 1443 def unlink(path, opts = {}, &bk) route 'UNLINK', path, opts, &bk end
Use the specified Rack
middleware
# File lib/sinatra/base.rb 1474 def use(middleware, *args, &block) 1475 @prototype = nil 1476 @middleware << [middleware, args, block] 1477 end
Condition for matching user agent. Parameter should be Regexp. Will set params.
# File lib/sinatra/base.rb 1617 def user_agent(pattern) 1618 condition do 1619 if request.user_agent.to_s =~ pattern 1620 @params[:agent] = $~[1..-1] 1621 true 1622 else 1623 false 1624 end 1625 end 1626 end
used for deprecation warnings
# File lib/sinatra/base.rb 1778 def warn(message) 1779 super message + "\n\tfrom #{cleaned_caller.first.join(':')}" 1780 end
Public Instance Methods
Rack
call interface.
# File lib/sinatra/base.rb 931 def call(env) 932 dup.call!(env) 933 end
Forward the request to the downstream app – middleware only.
# File lib/sinatra/base.rb 987 def forward 988 fail "downstream app not set" unless @app.respond_to? :call 989 status, headers, body = @app.call env 990 @response.status = status 991 @response.body = body 992 @response.headers.merge! headers 993 nil 994 end
Exit the current block, halts any further processing of the request, and returns the specified response.
# File lib/sinatra/base.rb 974 def halt(*response) 975 response = response.first if response.length == 1 976 throw :halt, response 977 end
# File lib/sinatra/base.rb 966 def options 967 warn "Sinatra::Base#options is deprecated and will be removed, " \ 968 "use #settings instead." 969 settings 970 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 982 def pass(&block) 983 throw :pass, block 984 end
Access settings defined with Base.set
.
# File lib/sinatra/base.rb 962 def settings 963 self.class.settings 964 end
Private Instance Methods
Dispatch a request with error handling.
# File lib/sinatra/base.rb 1119 def dispatch! 1120 # Avoid passing frozen string in force_encoding 1121 @params.merge!(@request.params).each do |key, val| 1122 next unless val.respond_to?(:force_encoding) 1123 val = val.dup if val.frozen? 1124 @params[key] = force_encoding(val) 1125 end 1126 1127 invoke do 1128 static! if settings.static? && (request.get? || request.head?) 1129 filter! :before do 1130 @pinned_response = !@response['Content-Type'].nil? 1131 end 1132 route! 1133 end 1134 rescue ::Exception => boom 1135 invoke { handle_exception!(boom) } 1136 ensure 1137 begin 1138 filter! :after unless env['sinatra.static_file'] 1139 rescue ::Exception => boom 1140 invoke { handle_exception!(boom) } unless @env['sinatra.error'] 1141 end 1142 end
# File lib/sinatra/base.rb 1203 def dump_errors!(boom) 1204 msg = ["#{Time.now.strftime("%Y-%m-%d %H:%M:%S")} - #{boom.class} - #{boom.message}:", *boom.backtrace].join("\n\t") 1205 @env['rack.errors'].puts(msg) 1206 end
Find an custom error block for the key(s) specified.
# File lib/sinatra/base.rb 1188 def error_block!(key, *block_params) 1189 base = settings 1190 while base.respond_to?(:errors) 1191 next base = base.superclass unless args_array = base.errors[key] 1192 args_array.reverse_each do |args| 1193 first = args == args_array.first 1194 args += [block_params] 1195 resp = process_route(*args) 1196 return resp unless resp.nil? && !first 1197 end 1198 end 1199 return false unless key.respond_to? :superclass and key.superclass < Exception 1200 error_block!(key.superclass, *block_params) 1201 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 1000 def filter!(type, base = settings) 1001 filter! type, base.superclass if base.superclass.respond_to?(:filters) 1002 base.filters[type].each do |args| 1003 result = process_route(*args) 1004 yield result if block_given? 1005 end 1006 end
# File lib/sinatra/base.rb 1804 def force_encoding(*args) settings.force_encoding(*args) end
Error
handling during requests.
# File lib/sinatra/base.rb 1145 def handle_exception!(boom) 1146 if error_params = @env['sinatra.error.params'] 1147 @params = @params.merge(error_params) 1148 end 1149 @env['sinatra.error'] = boom 1150 1151 http_status = if boom.kind_of? Sinatra::Error 1152 if boom.respond_to? :http_status 1153 boom.http_status 1154 elsif settings.use_code? && boom.respond_to?(:code) 1155 boom.code 1156 end 1157 end 1158 1159 http_status = 500 unless http_status && http_status.between?(400, 599) 1160 status(http_status) 1161 1162 if server_error? 1163 dump_errors! boom if settings.dump_errors? 1164 raise boom if settings.show_exceptions? and settings.show_exceptions != :after_handler 1165 elsif not_found? 1166 headers['X-Cascade'] = 'pass' if settings.x_cascade? 1167 end 1168 1169 if res = error_block!(boom.class, boom) || error_block!(status, boom) 1170 return res 1171 end 1172 1173 if not_found? || bad_request? 1174 if boom.message && boom.message != boom.class.name 1175 body boom.message 1176 else 1177 content_type 'text/html' 1178 body '<h1>' + (not_found? ? 'Not Found' : 'Bad Request') + '</h1>' 1179 end 1180 end 1181 1182 return unless server_error? 1183 raise boom if settings.raise_errors? or settings.show_exceptions? 1184 error_block! Exception, boom 1185 end
Run the block with ‘throw :halt’ support and apply result to the response.
# File lib/sinatra/base.rb 1103 def invoke 1104 res = catch(:halt) { yield } 1105 1106 res = [res] if Integer === res or String === res 1107 if Array === res and Integer === res.first 1108 res = res.dup 1109 status(res.shift) 1110 body(res.pop) 1111 headers(*res) 1112 elsif res.respond_to? :each 1113 body res 1114 end 1115 nil # avoid double setting the same response tuple twice 1116 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 1043 def process_route(pattern, conditions, block = nil, values = []) 1044 route = @request.path_info 1045 route = '/' if route.empty? and not settings.empty_path_info? 1046 route = route[0..-2] if !settings.strict_paths? && route != '/' && route.end_with?('/') 1047 return unless params = pattern.params(route) 1048 1049 params.delete("ignore") # TODO: better params handling, maybe turn it into "smart" object or detect changes 1050 force_encoding(params) 1051 @params = @params.merge(params) if params.any? 1052 1053 regexp_exists = pattern.is_a?(Mustermann::Regular) || (pattern.respond_to?(:patterns) && pattern.patterns.any? {|subpattern| subpattern.is_a?(Mustermann::Regular)} ) 1054 if regexp_exists 1055 captures = pattern.match(route).captures.map { |c| URI_INSTANCE.unescape(c) if c } 1056 values += captures 1057 @params[:captures] = force_encoding(captures) unless captures.nil? || captures.empty? 1058 else 1059 values += params.values.flatten 1060 end 1061 1062 catch(:pass) do 1063 conditions.each { |c| throw :pass if c.bind(self).call == false } 1064 block ? block[self, values] : yield(self, values) 1065 end 1066 rescue 1067 @env['sinatra.error.params'] = @params 1068 raise 1069 ensure 1070 params ||= {} 1071 params.each { |k, _| @params.delete(k) } unless @env['sinatra.error.params'] 1072 end
Run routes defined on the class and all superclasses.
# File lib/sinatra/base.rb 1009 def route!(base = settings, pass_block = nil) 1010 if routes = base.routes[@request.request_method] 1011 routes.each do |pattern, conditions, block| 1012 @response.delete_header('Content-Type') unless @pinned_response 1013 1014 returned_pass_block = process_route(pattern, conditions) do |*args| 1015 env['sinatra.route'] = "#{@request.request_method} #{pattern}" 1016 route_eval { block[*args] } 1017 end 1018 1019 # don't wipe out pass_block in superclass 1020 pass_block = returned_pass_block if returned_pass_block 1021 end 1022 end 1023 1024 # Run routes defined in superclass. 1025 if base.superclass.respond_to?(:routes) 1026 return route!(base.superclass, pass_block) 1027 end 1028 1029 route_eval(&pass_block) if pass_block 1030 route_missing 1031 end
Run a route block and throw :halt with the result.
# File lib/sinatra/base.rb 1034 def route_eval 1035 throw :halt, yield 1036 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 1079 def route_missing 1080 if @app 1081 forward 1082 else 1083 raise NotFound, "#{request.request_method} #{request.path_info}" 1084 end 1085 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 1089 def static!(options = {}) 1090 return if (public_dir = settings.public_folder).nil? 1091 path = "#{public_dir}#{URI_INSTANCE.unescape(request.path_info)}" 1092 return unless valid_path?(path) 1093 1094 path = File.expand_path(path) 1095 return unless File.file?(path) 1096 1097 env['sinatra.static_file'] = path 1098 cache_control(*settings.static_cache_control) if settings.static_cache_control? 1099 send_file path, options.merge(:disposition => nil) 1100 end