class Sinatra::Helpers::Stream::Base
Constants
- URI_INSTANCE
Attributes
Public Class Methods
Sinatra::Helpers::Stream::Templates::new
# File lib/sinatra/base.rb 909 def initialize(app = nil) 910 super() 911 @app = app 912 @template_cache = Tilt::Cache.new 913 yield self if block_given? 914 end
Access settings defined with Base.set
.
# File lib/sinatra/base.rb 944 def self.settings 945 self 946 end
Private Class Methods
add a filter
# File lib/sinatra/base.rb 1371 def add_filter(type, path = /.*/, **options, &block) 1372 filters[type] << compile!(type, path, block, **options) 1373 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 1366 def after(path = /.*/, **options, &block) 1367 add_filter(:after, path, **options, &block) 1368 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 1359 def before(path = /.*/, **options, &block) 1360 add_filter(:before, path, **options, &block) 1361 end
Creates a Rack::Builder
instance with all the middleware set up and the given app
as end point.
# File lib/sinatra/base.rb 1505 def build(app) 1506 builder = Rack::Builder.new 1507 setup_default_middleware builder 1508 setup_middleware builder 1509 builder.run app 1510 builder 1511 end
# File lib/sinatra/base.rb 1513 def call(env) 1514 synchronize { prototype.call(env) } 1515 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 1519 def caller_files 1520 cleaned_caller(1).flatten 1521 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 1525 def caller_locations 1526 cleaned_caller 2 1527 end
Like Kernel#caller but excluding certain magic entries
# File lib/sinatra/base.rb 1751 def cleaned_caller(keep = 3) 1752 caller(1). 1753 map! { |line| line.split(/:(?=\d|in )/, 3)[0,keep] }. 1754 reject { |file, *_| CALLERS_TO_IGNORE.any? { |pattern| file =~ pattern } } 1755 end
# File lib/sinatra/base.rb 1652 def compile(path, route_mustermann_opts = {}) 1653 Mustermann.new(path, **mustermann_opts.merge(route_mustermann_opts)) 1654 end
# File lib/sinatra/base.rb 1633 def compile!(verb, path, block, **options) 1634 # Because of self.options.host 1635 host_name(options.delete(:host)) if options.key?(:host) 1636 # Pass Mustermann opts to compile() 1637 route_mustermann_opts = options.key?(:mustermann_opts) ? options.delete(:mustermann_opts) : {}.freeze 1638 1639 options.each_pair { |option, args| send(option, *args) } 1640 1641 pattern = compile(path, route_mustermann_opts) 1642 method_name = "#{verb} #{path}" 1643 unbound_method = generate_method(method_name, &block) 1644 conditions, @conditions = @conditions, [] 1645 wrapper = block.arity != 0 ? 1646 proc { |a, p| unbound_method.bind(a).call(*p) } : 1647 proc { |a, p| unbound_method.bind(a).call } 1648 1649 [ pattern, conditions, wrapper ] 1650 end
Add a route condition. The route is considered non-matching when the block returns false.
# File lib/sinatra/base.rb 1377 def condition(name = "#{caller.first[/`.*'/]} condition", &block) 1378 @conditions << generate_method(name, &block) 1379 end
Set configuration options for Sinatra
and/or the app. Allows scoping of settings for certain environments.
# File lib/sinatra/base.rb 1437 def configure(*envs) 1438 yield self if envs.empty? || envs.include?(environment.to_sym) 1439 end
Dynamically defines a method on settings.
# File lib/sinatra/base.rb 1571 def define_singleton(name, content = Proc.new) 1572 singleton_class.class_eval do 1573 undef_method(name) if method_defined? name 1574 String === content ? class_eval("def #{name}() #{content}; end") : define_method(name, &content) 1575 end 1576 end
# File lib/sinatra/base.rb 1406 def delete(path, opts = {}, &bk) route 'DELETE', path, opts, &bk end
# File lib/sinatra/base.rb 1719 def detect_rack_handler 1720 servers = Array(server) 1721 servers.each do |server_name| 1722 begin 1723 return Rack::Handler.get(server_name.to_s) 1724 rescue LoadError, NameError 1725 end 1726 end 1727 fail "Server handler (#{servers.join(',')}) not found." 1728 end
# File lib/sinatra/base.rb 1431 def development?; environment == :development end
Same as calling `set :option, false` for each of the given options.
# File lib/sinatra/base.rb 1275 def disable(*opts) 1276 opts.each { |key| set(key, false) } 1277 end
Same as calling `set :option, true` for each of the given options.
# File lib/sinatra/base.rb 1270 def enable(*opts) 1271 opts.each { |key| set(key, true) } 1272 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 1282 def error(*codes, &block) 1283 args = compile! "ERROR", /.*/, block 1284 codes = codes.flat_map(&method(:Array)) 1285 codes << Exception if codes.empty? 1286 codes << Sinatra::NotFound if codes.include?(404) 1287 codes.each { |c| (@errors[c] ||= []) << args } 1288 end
Extension modules registered on this class and all superclasses.
# File lib/sinatra/base.rb 1215 def extensions 1216 if superclass.respond_to?(:extensions) 1217 (@extensions + superclass.extensions).uniq 1218 else 1219 @extensions 1220 end 1221 end
Force data to specified encoding. It defaults to settings.default_encoding which is UTF-8 by default
# File lib/sinatra/base.rb 1760 def self.force_encoding(data, encoding = default_encoding) 1761 return if data == settings || data.is_a?(Tempfile) 1762 if data.respond_to? :force_encoding 1763 data.force_encoding(encoding).encode! 1764 elsif data.respond_to? :each_value 1765 data.each_value { |v| force_encoding(v, encoding) } 1766 elsif data.respond_to? :each 1767 data.each { |v| force_encoding(v, encoding) } 1768 end 1769 data 1770 end
# File lib/sinatra/base.rb 1626 def generate_method(method_name, &block) 1627 define_method(method_name, &block) 1628 method = instance_method method_name 1629 remove_method method_name 1630 method 1631 end
Defining a `GET` handler also automatically defines a `HEAD` handler.
# File lib/sinatra/base.rb 1396 def get(path, opts = {}, &block) 1397 conditions = @conditions.dup 1398 route('GET', path, opts, &block) 1399 1400 @conditions = conditions 1401 route('HEAD', path, opts, &block) 1402 end
# File lib/sinatra/base.rb 1407 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 1415 def helpers(*extensions, &block) 1416 class_eval(&block) if block_given? 1417 include(*extensions) if extensions.any? 1418 end
Condition for matching host name. Parameter might be String or Regexp.
# File lib/sinatra/base.rb 1579 def host_name(pattern) 1580 condition { pattern === request.host } 1581 end
# File lib/sinatra/base.rb 1730 def inherited(subclass) 1731 subclass.reset! 1732 subclass.set :app_file, caller_files.first unless subclass.app_file? 1733 super 1734 end
Load embedded templates from the file; uses the caller's __FILE__ when no file is specified.
# File lib/sinatra/base.rb 1308 def inline_templates=(file = nil) 1309 file = (file.nil? || file == true) ? (caller_files.first || File.expand_path($0)) : file 1310 1311 begin 1312 io = ::IO.respond_to?(:binread) ? ::IO.binread(file) : ::IO.read(file) 1313 app, data = io.gsub("\r\n", "\n").split(/^__END__$/, 2) 1314 rescue Errno::ENOENT 1315 app, data = nil 1316 end 1317 1318 if data 1319 if app and app =~ /([^\n]*\n)?#[^\n]*coding: *(\S+)/m 1320 encoding = $2 1321 else 1322 encoding = settings.default_encoding 1323 end 1324 lines = app.count("\n") + 1 1325 template = nil 1326 force_encoding data, encoding 1327 data.each_line do |line| 1328 lines += 1 1329 if line =~ /^@@\s*(.*\S)\s*$/ 1330 template = force_encoding(String.new, encoding) 1331 templates[$1.to_sym] = [template, file, lines] 1332 elsif template 1333 template << line 1334 end 1335 end 1336 end 1337 end
# File lib/sinatra/base.rb 1622 def invoke_hook(name, *args) 1623 extensions.each { |e| e.send(name, *args) if e.respond_to?(name) } 1624 end
Define the layout template. The block must return the template source.
# File lib/sinatra/base.rb 1302 def layout(name = :layout, &block) 1303 template name, &block 1304 end
# File lib/sinatra/base.rb 1410 def link(path, opts = {}, &bk) route 'LINK', path, opts, &bk end
Middleware used in this class and all superclasses.
# File lib/sinatra/base.rb 1224 def middleware 1225 if superclass.respond_to?(:middleware) 1226 superclass.middleware + @middleware 1227 else 1228 @middleware 1229 end 1230 end
Lookup or register a mime type in Rack's mime registry.
# File lib/sinatra/base.rb 1340 def mime_type(type, value = nil) 1341 return type if type.nil? 1342 return type.to_s if type.to_s.include?('/') 1343 type = ".#{type}" unless type.to_s[0] == ?. 1344 return Rack::Mime.mime_type(type, nil) unless value 1345 Rack::Mime::MIME_TYPES[type] = value 1346 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 1351 def mime_types(type) 1352 type = mime_type type 1353 type =~ /^application\/(xml|javascript)$/ ? [type, "text/#$1"] : [type] 1354 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 1498 def new(*args, &bk) 1499 instance = new!(*args, &bk) 1500 Wrapper.new(build(instance).to_app, instance) 1501 end
Sugar for `error(404) { … }`
# File lib/sinatra/base.rb 1291 def not_found(&block) 1292 error(404, &block) 1293 end
# File lib/sinatra/base.rb 1408 def options(path, opts = {}, &bk) route 'OPTIONS', path, opts, &bk end
# File lib/sinatra/base.rb 1409 def patch(path, opts = {}, &bk) route 'PATCH', path, opts, &bk end
# File lib/sinatra/base.rb 1405 def post(path, opts = {}, &bk) route 'POST', path, opts, &bk end
# File lib/sinatra/base.rb 1432 def production?; environment == :production end
The prototype instance used to process requests.
# File lib/sinatra/base.rb 1488 def prototype 1489 @prototype ||= new 1490 end
Condition for matching mimetypes. Accepts file extensions.
# File lib/sinatra/base.rb 1598 def provides(*types) 1599 types.map! { |t| mime_types(t) } 1600 types.flatten! 1601 condition do 1602 if type = response['Content-Type'] 1603 types.include? type or types.include? type[/^[^;]+/] 1604 elsif type = request.preferred_type(types) 1605 params = (type.respond_to?(:params) ? type.params : {}) 1606 content_type(type, params) 1607 true 1608 else 1609 false 1610 end 1611 end 1612 end
# File lib/sinatra/base.rb 1381 def public=(value) 1382 warn ":public is no longer used to avoid overloading Module#public, use :public_folder or :public_dir instead" 1383 set(:public_folder, value) 1384 end
# File lib/sinatra/base.rb 1390 def public_dir 1391 public_folder 1392 end
# File lib/sinatra/base.rb 1386 def public_dir=(value) 1387 self.public_folder = value 1388 end
# File lib/sinatra/base.rb 1404 def put(path, opts = {}, &bk) route 'PUT', path, opts, &bk end
Stop the self-hosted server if running.
# File lib/sinatra/base.rb 1448 def quit! 1449 return unless running? 1450 # Use Thin's hard #stop! if available, otherwise just #stop. 1451 running_server.respond_to?(:stop!) ? running_server.stop! : running_server.stop 1452 $stderr.puts "== Sinatra has ended his set (crowd applauds)" unless suppress_messages? 1453 set :running_server, nil 1454 set :handler_name, nil 1455 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 1422 def register(*extensions, &block) 1423 extensions << Module.new(&block) if block_given? 1424 @extensions += extensions 1425 extensions.each do |extension| 1426 extend extension 1427 extension.registered(self) if extension.respond_to?(:registered) 1428 end 1429 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 1198 def reset! 1199 @conditions = [] 1200 @routes = {} 1201 @filters = {:before => [], :after => []} 1202 @errors = {} 1203 @middleware = [] 1204 @prototype = nil 1205 @extensions = [] 1206 1207 if superclass.respond_to?(:templates) 1208 @templates = Hash.new { |hash, key| superclass.templates[key] } 1209 else 1210 @templates = {} 1211 end 1212 end
# File lib/sinatra/base.rb 1614 def route(verb, path, options = {}, &block) 1615 enable :empty_path_info if path == "" and empty_path_info.nil? 1616 signature = compile!(verb, path, block, **options) 1617 (@routes[verb] ||= []) << signature 1618 invoke_hook(:route_added, verb, path, block) 1619 signature 1620 end
Run the Sinatra
app as a self-hosted server using Thin, 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 1462 def run!(options = {}, &block) 1463 return if running? 1464 set options 1465 handler = detect_rack_handler 1466 handler_name = handler.name.gsub(/.*::/, '') 1467 server_settings = settings.respond_to?(:server_settings) ? settings.server_settings : {} 1468 server_settings.merge!(:Port => port, :Host => bind) 1469 1470 begin 1471 start_server(handler, server_settings, handler_name, &block) 1472 rescue Errno::EADDRINUSE 1473 $stderr.puts "== Someone is already performing on port #{port}!" 1474 raise 1475 ensure 1476 quit! 1477 end 1478 end
Check whether the self-hosted server is running or not.
# File lib/sinatra/base.rb 1483 def running? 1484 running_server? 1485 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 1234 def set(option, value = (not_set = true), ignore_setter = false, &block) 1235 raise ArgumentError if block and !not_set 1236 value, not_set = block, false if block 1237 1238 if not_set 1239 raise ArgumentError unless option.respond_to?(:each) 1240 option.each { |k,v| set(k, v) } 1241 return self 1242 end 1243 1244 if respond_to?("#{option}=") and not ignore_setter 1245 return __send__("#{option}=", value) 1246 end 1247 1248 setter = proc { |val| set option, val, true } 1249 getter = proc { value } 1250 1251 case value 1252 when Proc 1253 getter = value 1254 when Symbol, Integer, FalseClass, TrueClass, NilClass 1255 getter = value.inspect 1256 when Hash 1257 setter = proc do |val| 1258 val = value.merge val if Hash === val 1259 set option, val, true 1260 end 1261 end 1262 1263 define_singleton("#{option}=", setter) 1264 define_singleton(option, getter) 1265 define_singleton("#{option}?", "!!#{option}") unless method_defined? "#{option}?" 1266 self 1267 end
# File lib/sinatra/base.rb 1683 def setup_common_logger(builder) 1684 builder.use Sinatra::CommonLogger 1685 end
# File lib/sinatra/base.rb 1687 def setup_custom_logger(builder) 1688 if logging.respond_to? :to_int 1689 builder.use Rack::Logger, logging 1690 else 1691 builder.use Rack::Logger 1692 end 1693 end
# File lib/sinatra/base.rb 1656 def setup_default_middleware(builder) 1657 builder.use ExtendedRack 1658 builder.use ShowExceptions if show_exceptions? 1659 builder.use Rack::MethodOverride if method_override? 1660 builder.use Rack::Head 1661 setup_logging builder 1662 setup_sessions builder 1663 setup_protection builder 1664 end
# File lib/sinatra/base.rb 1670 def setup_logging(builder) 1671 if logging? 1672 setup_common_logger(builder) 1673 setup_custom_logger(builder) 1674 elsif logging == false 1675 setup_null_logger(builder) 1676 end 1677 end
# File lib/sinatra/base.rb 1666 def setup_middleware(builder) 1667 middleware.each { |c,a,b| builder.use(c, *a, &b) } 1668 end
# File lib/sinatra/base.rb 1679 def setup_null_logger(builder) 1680 builder.use Rack::NullLogger 1681 end
# File lib/sinatra/base.rb 1695 def setup_protection(builder) 1696 return unless protection? 1697 options = Hash === protection ? protection.dup : {} 1698 options = { 1699 img_src: "'self' data:", 1700 font_src: "'self'" 1701 }.merge options 1702 1703 protect_session = options.fetch(:session) { sessions? } 1704 options[:without_session] = !protect_session 1705 1706 options[:reaction] ||= :drop_session 1707 1708 builder.use Rack::Protection, options 1709 end
# File lib/sinatra/base.rb 1711 def setup_sessions(builder) 1712 return unless sessions? 1713 options = {} 1714 options[:secret] = session_secret if session_secret? 1715 options.merge! sessions.to_hash if sessions.respond_to? :to_hash 1716 builder.use session_store, options 1717 end
# File lib/sinatra/base.rb 1555 def setup_traps 1556 if traps? 1557 at_exit { quit! } 1558 1559 [:INT, :TERM].each do |signal| 1560 old_handler = trap(signal) do 1561 quit! 1562 old_handler.call if old_handler.respond_to?(:call) 1563 end 1564 end 1565 1566 set :traps, false 1567 end 1568 end
Starts the server by running the Rack
Handler.
# File lib/sinatra/base.rb 1532 def start_server(handler, server_settings, handler_name) 1533 # Ensure we initialize middleware before startup, to match standard Rack 1534 # behavior, by ensuring an instance exists: 1535 prototype 1536 # Run the instance we created: 1537 handler.run(self, server_settings) do |server| 1538 unless suppress_messages? 1539 $stderr.puts "== Sinatra (v#{Sinatra::VERSION}) has taken the stage on #{port} for #{environment} with backup from #{handler_name}" 1540 end 1541 1542 setup_traps 1543 set :running_server, server 1544 set :handler_name, handler_name 1545 server.threaded = settings.threaded if server.respond_to? :threaded= 1546 1547 yield server if block_given? 1548 end 1549 end
# File lib/sinatra/base.rb 1551 def suppress_messages? 1552 handler_name =~ /cgi/i || quiet 1553 end
# File lib/sinatra/base.rb 1737 def synchronize(&block) 1738 if lock? 1739 @@mutex.synchronize(&block) 1740 else 1741 yield 1742 end 1743 end
Define a named template. The block must return the template source.
# File lib/sinatra/base.rb 1296 def template(name, &block) 1297 filename, line = caller_locations.first 1298 templates[name] = [block, filename, line.to_i] 1299 end
# File lib/sinatra/base.rb 1433 def test?; environment == :test end
# File lib/sinatra/base.rb 1411 def unlink(path, opts = {}, &bk) route 'UNLINK', path, opts, &bk end
Use the specified Rack
middleware
# File lib/sinatra/base.rb 1442 def use(middleware, *args, &block) 1443 @prototype = nil 1444 @middleware << [middleware, args, block] 1445 end
Condition for matching user agent. Parameter should be Regexp. Will set params.
# File lib/sinatra/base.rb 1585 def user_agent(pattern) 1586 condition do 1587 if request.user_agent.to_s =~ pattern 1588 @params[:agent] = $~[1..-1] 1589 true 1590 else 1591 false 1592 end 1593 end 1594 end
used for deprecation warnings
# File lib/sinatra/base.rb 1746 def warn(message) 1747 super message + "\n\tfrom #{cleaned_caller.first.join(':')}" 1748 end
Public Instance Methods
Rack
call interface.
# File lib/sinatra/base.rb 917 def call(env) 918 dup.call!(env) 919 end
Forward the request to the downstream app – middleware only.
# File lib/sinatra/base.rb 974 def forward 975 fail "downstream app not set" unless @app.respond_to? :call 976 status, headers, body = @app.call env 977 @response.status = status 978 @response.body = body 979 @response.headers.merge! headers 980 nil 981 end
Exit the current block, halts any further processing of the request, and returns the specified response.
# File lib/sinatra/base.rb 961 def halt(*response) 962 response = response.first if response.length == 1 963 throw :halt, response 964 end
# File lib/sinatra/base.rb 953 def options 954 warn "Sinatra::Base#options is deprecated and will be removed, " \ 955 "use #settings instead." 956 settings 957 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 969 def pass(&block) 970 throw :pass, block 971 end
Access settings defined with Base.set
.
# File lib/sinatra/base.rb 949 def settings 950 self.class.settings 951 end
Private Instance Methods
Dispatch a request with error handling.
# File lib/sinatra/base.rb 1097 def dispatch! 1098 # Avoid passing frozen string in force_encoding 1099 @params.merge!(@request.params).each do |key, val| 1100 next unless val.respond_to?(:force_encoding) 1101 val = val.dup if val.frozen? 1102 @params[key] = force_encoding(val) 1103 end 1104 1105 invoke do 1106 static! if settings.static? && (request.get? || request.head?) 1107 filter! :before 1108 route! 1109 end 1110 rescue ::Exception => boom 1111 invoke { handle_exception!(boom) } 1112 ensure 1113 begin 1114 filter! :after unless env['sinatra.static_file'] 1115 rescue ::Exception => boom 1116 invoke { handle_exception!(boom) } unless @env['sinatra.error'] 1117 end 1118 end
# File lib/sinatra/base.rb 1171 def dump_errors!(boom) 1172 msg = ["#{Time.now.strftime("%Y-%m-%d %H:%M:%S")} - #{boom.class} - #{boom.message}:", *boom.backtrace].join("\n\t") 1173 @env['rack.errors'].puts(msg) 1174 end
Find an custom error block for the key(s) specified.
# File lib/sinatra/base.rb 1156 def error_block!(key, *block_params) 1157 base = settings 1158 while base.respond_to?(:errors) 1159 next base = base.superclass unless args_array = base.errors[key] 1160 args_array.reverse_each do |args| 1161 first = args == args_array.first 1162 args += [block_params] 1163 resp = process_route(*args) 1164 return resp unless resp.nil? && !first 1165 end 1166 end 1167 return false unless key.respond_to? :superclass and key.superclass < Exception 1168 error_block!(key.superclass, *block_params) 1169 end
Run filters defined on the class and all superclasses.
# File lib/sinatra/base.rb 986 def filter!(type, base = settings) 987 filter! type, base.superclass if base.superclass.respond_to?(:filters) 988 base.filters[type].each { |args| process_route(*args) } 989 end
# File lib/sinatra/base.rb 1772 def force_encoding(*args) settings.force_encoding(*args) end
Error
handling during requests.
# File lib/sinatra/base.rb 1121 def handle_exception!(boom) 1122 if error_params = @env['sinatra.error.params'] 1123 @params = @params.merge(error_params) 1124 end 1125 @env['sinatra.error'] = boom 1126 1127 http_status = if boom.kind_of? Sinatra::Error 1128 if boom.respond_to? :http_status 1129 boom.http_status 1130 elsif settings.use_code? && boom.respond_to?(:code) 1131 boom.code 1132 end 1133 end 1134 1135 http_status = 500 unless http_status && http_status.between?(400, 599) 1136 status(http_status) 1137 1138 boom_message = boom.message if boom.message && boom.message != boom.class.name 1139 if server_error? 1140 dump_errors! boom if settings.dump_errors? 1141 raise boom if settings.show_exceptions? and settings.show_exceptions != :after_handler 1142 elsif not_found? 1143 headers['X-Cascade'] = 'pass' if settings.x_cascade? 1144 body boom_message || '<h1>Not Found</h1>' 1145 elsif bad_request? 1146 body boom_message || '<h1>Bad Request</h1>' 1147 end 1148 1149 res = error_block!(boom.class, boom) || error_block!(status, boom) 1150 return res if res or not server_error? 1151 raise boom if settings.raise_errors? or settings.show_exceptions? 1152 error_block! Exception, boom 1153 end
Run the block with 'throw :halt' support and apply result to the response.
# File lib/sinatra/base.rb 1081 def invoke 1082 res = catch(:halt) { yield } 1083 1084 res = [res] if Integer === res or String === res 1085 if Array === res and Integer === res.first 1086 res = res.dup 1087 status(res.shift) 1088 body(res.pop) 1089 headers(*res) 1090 elsif res.respond_to? :each 1091 body res 1092 end 1093 nil # avoid double setting the same response tuple twice 1094 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 1024 def process_route(pattern, conditions, block = nil, values = []) 1025 route = @request.path_info 1026 route = '/' if route.empty? and not settings.empty_path_info? 1027 route = route[0..-2] if !settings.strict_paths? && route != '/' && route.end_with?('/') 1028 return unless params = pattern.params(route) 1029 1030 params.delete("ignore") # TODO: better params handling, maybe turn it into "smart" object or detect changes 1031 force_encoding(params) 1032 @params = @params.merge(params) if params.any? 1033 1034 regexp_exists = pattern.is_a?(Mustermann::Regular) || (pattern.respond_to?(:patterns) && pattern.patterns.any? {|subpattern| subpattern.is_a?(Mustermann::Regular)} ) 1035 if regexp_exists 1036 captures = pattern.match(route).captures.map { |c| URI_INSTANCE.unescape(c) if c } 1037 values += captures 1038 @params[:captures] = force_encoding(captures) unless captures.nil? || captures.empty? 1039 else 1040 values += params.values.flatten 1041 end 1042 1043 catch(:pass) do 1044 conditions.each { |c| throw :pass if c.bind(self).call == false } 1045 block ? block[self, values] : yield(self, values) 1046 end 1047 rescue 1048 @env['sinatra.error.params'] = @params 1049 raise 1050 ensure 1051 params ||= {} 1052 params.each { |k, _| @params.delete(k) } unless @env['sinatra.error.params'] 1053 end
Run routes defined on the class and all superclasses.
# File lib/sinatra/base.rb 992 def route!(base = settings, pass_block = nil) 993 if routes = base.routes[@request.request_method] 994 routes.each do |pattern, conditions, block| 995 returned_pass_block = process_route(pattern, conditions) do |*args| 996 env['sinatra.route'] = "#{@request.request_method} #{pattern}" 997 route_eval { block[*args] } 998 end 999 1000 # don't wipe out pass_block in superclass 1001 pass_block = returned_pass_block if returned_pass_block 1002 end 1003 end 1004 1005 # Run routes defined in superclass. 1006 if base.superclass.respond_to?(:routes) 1007 return route!(base.superclass, pass_block) 1008 end 1009 1010 route_eval(&pass_block) if pass_block 1011 route_missing 1012 end
Run a route block and throw :halt with the result.
# File lib/sinatra/base.rb 1015 def route_eval 1016 throw :halt, yield 1017 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 1060 def route_missing 1061 if @app 1062 forward 1063 else 1064 raise NotFound, "#{request.request_method} #{request.path_info}" 1065 end 1066 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 1070 def static!(options = {}) 1071 return if (public_dir = settings.public_folder).nil? 1072 path = File.expand_path("#{public_dir}#{URI_INSTANCE.unescape(request.path_info)}" ) 1073 return unless File.file?(path) 1074 1075 env['sinatra.static_file'] = path 1076 cache_control(*settings.static_cache_control) if settings.static_cache_control? 1077 send_file path, options.merge(:disposition => nil) 1078 end