class Sinatra::Helpers::Stream::Base
Constants
- URI_INSTANCE
Attributes
Public Class Methods
Sinatra::Helpers::Stream::Templates::new
# File lib/sinatra/base.rb 928 def initialize(app = nil, **kwargs) 929 super() 930 @app = app 931 @template_cache = Tilt::Cache.new 932 @pinned_response = nil # whether a before! filter pinned the content-type 933 yield self if block_given? 934 end
Access settings defined with Base.set
.
# File lib/sinatra/base.rb 964 def self.settings 965 self 966 end
Private Class Methods
add a filter
# File lib/sinatra/base.rb 1408 def add_filter(type, path = /.*/, **options, &block) 1409 filters[type] << compile!(type, path, block, **options) 1410 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 1403 def after(path = /.*/, **options, &block) 1404 add_filter(:after, path, **options, &block) 1405 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 1396 def before(path = /.*/, **options, &block) 1397 add_filter(:before, path, **options, &block) 1398 end
Creates a Rack::Builder
instance with all the middleware set up and the given app
as end point.
# File lib/sinatra/base.rb 1544 def build(app) 1545 builder = Rack::Builder.new 1546 setup_default_middleware builder 1547 setup_middleware builder 1548 builder.run app 1549 builder 1550 end
# File lib/sinatra/base.rb 1552 def call(env) 1553 synchronize { prototype.call(env) } 1554 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 1558 def caller_files 1559 cleaned_caller(1).flatten 1560 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 1564 def caller_locations 1565 cleaned_caller 2 1566 end
Like Kernel#caller but excluding certain magic entries
# File lib/sinatra/base.rb 1779 def cleaned_caller(keep = 3) 1780 caller(1). 1781 map! { |line| line.split(/:(?=\d|in )/, 3)[0,keep] }. 1782 reject { |file, *_| CALLERS_TO_IGNORE.any? { |pattern| file =~ pattern } } 1783 end
# File lib/sinatra/base.rb 1691 def compile(path, route_mustermann_opts = {}) 1692 Mustermann.new(path, **mustermann_opts.merge(route_mustermann_opts)) 1693 end
# File lib/sinatra/base.rb 1672 def compile!(verb, path, block, **options) 1673 # Because of self.options.host 1674 host_name(options.delete(:host)) if options.key?(:host) 1675 # Pass Mustermann opts to compile() 1676 route_mustermann_opts = options.key?(:mustermann_opts) ? options.delete(:mustermann_opts) : {}.freeze 1677 1678 options.each_pair { |option, args| send(option, *args) } 1679 1680 pattern = compile(path, route_mustermann_opts) 1681 method_name = "#{verb} #{path}" 1682 unbound_method = generate_method(method_name, &block) 1683 conditions, @conditions = @conditions, [] 1684 wrapper = block.arity != 0 ? 1685 proc { |a, p| unbound_method.bind(a).call(*p) } : 1686 proc { |a, p| unbound_method.bind(a).call } 1687 1688 [ pattern, conditions, wrapper ] 1689 end
Add a route condition. The route is considered non-matching when the block returns false.
# File lib/sinatra/base.rb 1414 def condition(name = "#{caller.first[/`.*'/]} condition", &block) 1415 @conditions << generate_method(name, &block) 1416 end
Set configuration options for Sinatra
and/or the app. Allows scoping of settings for certain environments.
# File lib/sinatra/base.rb 1474 def configure(*envs) 1475 yield self if envs.empty? || envs.include?(environment.to_sym) 1476 end
Dynamically defines a method on settings.
# File lib/sinatra/base.rb 1610 def define_singleton(name, content = Proc.new) 1611 singleton_class.class_eval do 1612 undef_method(name) if method_defined? name 1613 String === content ? class_eval("def #{name}() #{content}; end") : define_method(name, &content) 1614 end 1615 end
# File lib/sinatra/base.rb 1443 def delete(path, opts = {}, &bk) route 'DELETE', path, opts, &bk end
# File lib/sinatra/base.rb 1468 def development?; environment == :development end
Same as calling `set :option, false` for each of the given options.
# File lib/sinatra/base.rb 1312 def disable(*opts) 1313 opts.each { |key| set(key, false) } 1314 end
Same as calling `set :option, true` for each of the given options.
# File lib/sinatra/base.rb 1307 def enable(*opts) 1308 opts.each { |key| set(key, true) } 1309 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 1319 def error(*codes, &block) 1320 args = compile! "ERROR", /.*/, block 1321 codes = codes.flat_map(&method(:Array)) 1322 codes << Exception if codes.empty? 1323 codes << Sinatra::NotFound if codes.include?(404) 1324 codes.each { |c| (@errors[c] ||= []) << args } 1325 end
Extension modules registered on this class and all superclasses.
# File lib/sinatra/base.rb 1252 def extensions 1253 if superclass.respond_to?(:extensions) 1254 (@extensions + superclass.extensions).uniq 1255 else 1256 @extensions 1257 end 1258 end
Force data to specified encoding. It defaults to settings.default_encoding which is UTF-8 by default
# File lib/sinatra/base.rb 1788 def self.force_encoding(data, encoding = default_encoding) 1789 return if data == settings || data.is_a?(Tempfile) 1790 if data.respond_to? :force_encoding 1791 data.force_encoding(encoding).encode! 1792 elsif data.respond_to? :each_value 1793 data.each_value { |v| force_encoding(v, encoding) } 1794 elsif data.respond_to? :each 1795 data.each { |v| force_encoding(v, encoding) } 1796 end 1797 data 1798 end
# File lib/sinatra/base.rb 1665 def generate_method(method_name, &block) 1666 define_method(method_name, &block) 1667 method = instance_method method_name 1668 remove_method method_name 1669 method 1670 end
Defining a `GET` handler also automatically defines a `HEAD` handler.
# File lib/sinatra/base.rb 1433 def get(path, opts = {}, &block) 1434 conditions = @conditions.dup 1435 route('GET', path, opts, &block) 1436 1437 @conditions = conditions 1438 route('HEAD', path, opts, &block) 1439 end
# File lib/sinatra/base.rb 1444 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 1452 def helpers(*extensions, &block) 1453 class_eval(&block) if block_given? 1454 include(*extensions) if extensions.any? 1455 end
Condition for matching host name. Parameter might be String or Regexp.
# File lib/sinatra/base.rb 1618 def host_name(pattern) 1619 condition { pattern === request.host } 1620 end
# File lib/sinatra/base.rb 1758 def inherited(subclass) 1759 subclass.reset! 1760 subclass.set :app_file, caller_files.first unless subclass.app_file? 1761 super 1762 end
Load embedded templates from the file; uses the caller's __FILE__ when no file is specified.
# File lib/sinatra/base.rb 1345 def inline_templates=(file = nil) 1346 file = (file.nil? || file == true) ? (caller_files.first || File.expand_path($0)) : file 1347 1348 begin 1349 io = ::IO.respond_to?(:binread) ? ::IO.binread(file) : ::IO.read(file) 1350 app, data = io.gsub("\r\n", "\n").split(/^__END__$/, 2) 1351 rescue Errno::ENOENT 1352 app, data = nil 1353 end 1354 1355 if data 1356 if app and app =~ /([^\n]*\n)?#[^\n]*coding: *(\S+)/m 1357 encoding = $2 1358 else 1359 encoding = settings.default_encoding 1360 end 1361 lines = app.count("\n") + 1 1362 template = nil 1363 force_encoding data, encoding 1364 data.each_line do |line| 1365 lines += 1 1366 if line =~ /^@@\s*(.*\S)\s*$/ 1367 template = force_encoding(String.new, encoding) 1368 templates[$1.to_sym] = [template, file, lines] 1369 elsif template 1370 template << line 1371 end 1372 end 1373 end 1374 end
# File lib/sinatra/base.rb 1661 def invoke_hook(name, *args) 1662 extensions.each { |e| e.send(name, *args) if e.respond_to?(name) } 1663 end
Define the layout template. The block must return the template source.
# File lib/sinatra/base.rb 1339 def layout(name = :layout, &block) 1340 template name, &block 1341 end
# File lib/sinatra/base.rb 1447 def link(path, opts = {}, &bk) route 'LINK', path, opts, &bk end
Middleware used in this class and all superclasses.
# File lib/sinatra/base.rb 1261 def middleware 1262 if superclass.respond_to?(:middleware) 1263 superclass.middleware + @middleware 1264 else 1265 @middleware 1266 end 1267 end
Lookup or register a mime type in Rack's mime registry.
# File lib/sinatra/base.rb 1377 def mime_type(type, value = nil) 1378 return type if type.nil? 1379 return type.to_s if type.to_s.include?('/') 1380 type = ".#{type}" unless type.to_s[0] == ?. 1381 return Rack::Mime.mime_type(type, nil) unless value 1382 Rack::Mime::MIME_TYPES[type] = value 1383 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 1388 def mime_types(type) 1389 type = mime_type type 1390 type =~ /^application\/(xml|javascript)$/ ? [type, "text/#$1"] : [type] 1391 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 1536 def new(*args, &bk) 1537 instance = new!(*args, &bk) 1538 Wrapper.new(build(instance).to_app, instance) 1539 end
Sugar for `error(404) { … }`
# File lib/sinatra/base.rb 1328 def not_found(&block) 1329 error(404, &block) 1330 end
# File lib/sinatra/base.rb 1445 def options(path, opts = {}, &bk) route 'OPTIONS', path, opts, &bk end
# File lib/sinatra/base.rb 1446 def patch(path, opts = {}, &bk) route 'PATCH', path, opts, &bk end
# File lib/sinatra/base.rb 1442 def post(path, opts = {}, &bk) route 'POST', path, opts, &bk end
# File lib/sinatra/base.rb 1469 def production?; environment == :production end
The prototype instance used to process requests.
# File lib/sinatra/base.rb 1526 def prototype 1527 @prototype ||= new 1528 end
Condition for matching mimetypes. Accepts file extensions.
# File lib/sinatra/base.rb 1637 def provides(*types) 1638 types.map! { |t| mime_types(t) } 1639 types.flatten! 1640 condition do 1641 if type = response['Content-Type'] 1642 types.include? type or types.include? type[/^[^;]+/] 1643 elsif type = request.preferred_type(types) 1644 params = (type.respond_to?(:params) ? type.params : {}) 1645 content_type(type, params) 1646 true 1647 else 1648 false 1649 end 1650 end 1651 end
# File lib/sinatra/base.rb 1418 def public=(value) 1419 warn ":public is no longer used to avoid overloading Module#public, use :public_folder or :public_dir instead" 1420 set(:public_folder, value) 1421 end
# File lib/sinatra/base.rb 1427 def public_dir 1428 public_folder 1429 end
# File lib/sinatra/base.rb 1423 def public_dir=(value) 1424 self.public_folder = value 1425 end
# File lib/sinatra/base.rb 1441 def put(path, opts = {}, &bk) route 'PUT', path, opts, &bk end
Stop the self-hosted server if running.
# File lib/sinatra/base.rb 1486 def quit! 1487 return unless running? 1488 # Use Thin's hard #stop! if available, otherwise just #stop. 1489 running_server.respond_to?(:stop!) ? running_server.stop! : running_server.stop 1490 $stderr.puts "== Sinatra has ended his set (crowd applauds)" unless suppress_messages? 1491 set :running_server, nil 1492 set :handler_name, nil 1493 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 1459 def register(*extensions, &block) 1460 extensions << Module.new(&block) if block_given? 1461 @extensions += extensions 1462 extensions.each do |extension| 1463 extend extension 1464 extension.registered(self) if extension.respond_to?(:registered) 1465 end 1466 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 1235 def reset! 1236 @conditions = [] 1237 @routes = {} 1238 @filters = {:before => [], :after => []} 1239 @errors = {} 1240 @middleware = [] 1241 @prototype = nil 1242 @extensions = [] 1243 1244 if superclass.respond_to?(:templates) 1245 @templates = Hash.new { |hash, key| superclass.templates[key] } 1246 else 1247 @templates = {} 1248 end 1249 end
# File lib/sinatra/base.rb 1653 def route(verb, path, options = {}, &block) 1654 enable :empty_path_info if path == "" and empty_path_info.nil? 1655 signature = compile!(verb, path, block, **options) 1656 (@routes[verb] ||= []) << signature 1657 invoke_hook(:route_added, verb, path, block) 1658 signature 1659 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 1500 def run!(options = {}, &block) 1501 return if running? 1502 set options 1503 handler = Rack::Handler.pick(server) 1504 handler_name = handler.name.gsub(/.*::/, '') 1505 server_settings = settings.respond_to?(:server_settings) ? settings.server_settings : {} 1506 server_settings.merge!(:Port => port, :Host => bind) 1507 1508 begin 1509 start_server(handler, server_settings, handler_name, &block) 1510 rescue Errno::EADDRINUSE 1511 $stderr.puts "== Someone is already performing on port #{port}!" 1512 raise 1513 ensure 1514 quit! 1515 end 1516 end
Check whether the self-hosted server is running or not.
# File lib/sinatra/base.rb 1521 def running? 1522 running_server? 1523 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 1271 def set(option, value = (not_set = true), ignore_setter = false, &block) 1272 raise ArgumentError if block and !not_set 1273 value, not_set = block, false if block 1274 1275 if not_set 1276 raise ArgumentError unless option.respond_to?(:each) 1277 option.each { |k,v| set(k, v) } 1278 return self 1279 end 1280 1281 if respond_to?("#{option}=") and not ignore_setter 1282 return __send__("#{option}=", value) 1283 end 1284 1285 setter = proc { |val| set option, val, true } 1286 getter = proc { value } 1287 1288 case value 1289 when Proc 1290 getter = value 1291 when Symbol, Integer, FalseClass, TrueClass, NilClass 1292 getter = value.inspect 1293 when Hash 1294 setter = proc do |val| 1295 val = value.merge val if Hash === val 1296 set option, val, true 1297 end 1298 end 1299 1300 define_singleton("#{option}=", setter) 1301 define_singleton(option, getter) 1302 define_singleton("#{option}?", "!!#{option}") unless method_defined? "#{option}?" 1303 self 1304 end
# File lib/sinatra/base.rb 1722 def setup_common_logger(builder) 1723 builder.use Sinatra::CommonLogger 1724 end
# File lib/sinatra/base.rb 1726 def setup_custom_logger(builder) 1727 if logging.respond_to? :to_int 1728 builder.use Rack::Logger, logging 1729 else 1730 builder.use Rack::Logger 1731 end 1732 end
# File lib/sinatra/base.rb 1695 def setup_default_middleware(builder) 1696 builder.use ExtendedRack 1697 builder.use ShowExceptions if show_exceptions? 1698 builder.use Rack::MethodOverride if method_override? 1699 builder.use Rack::Head 1700 setup_logging builder 1701 setup_sessions builder 1702 setup_protection builder 1703 end
# File lib/sinatra/base.rb 1709 def setup_logging(builder) 1710 if logging? 1711 setup_common_logger(builder) 1712 setup_custom_logger(builder) 1713 elsif logging == false 1714 setup_null_logger(builder) 1715 end 1716 end
# File lib/sinatra/base.rb 1705 def setup_middleware(builder) 1706 middleware.each { |c,a,b| builder.use(c, *a, &b) } 1707 end
# File lib/sinatra/base.rb 1718 def setup_null_logger(builder) 1719 builder.use Rack::NullLogger 1720 end
# File lib/sinatra/base.rb 1734 def setup_protection(builder) 1735 return unless protection? 1736 options = Hash === protection ? protection.dup : {} 1737 options = { 1738 img_src: "'self' data:", 1739 font_src: "'self'" 1740 }.merge options 1741 1742 protect_session = options.fetch(:session) { sessions? } 1743 options[:without_session] = !protect_session 1744 1745 options[:reaction] ||= :drop_session 1746 1747 builder.use Rack::Protection, options 1748 end
# File lib/sinatra/base.rb 1750 def setup_sessions(builder) 1751 return unless sessions? 1752 options = {} 1753 options[:secret] = session_secret if session_secret? 1754 options.merge! sessions.to_hash if sessions.respond_to? :to_hash 1755 builder.use session_store, options 1756 end
# File lib/sinatra/base.rb 1594 def setup_traps 1595 if traps? 1596 at_exit { quit! } 1597 1598 [:INT, :TERM].each do |signal| 1599 old_handler = trap(signal) do 1600 quit! 1601 old_handler.call if old_handler.respond_to?(:call) 1602 end 1603 end 1604 1605 set :traps, false 1606 end 1607 end
Starts the server by running the Rack
Handler.
# File lib/sinatra/base.rb 1571 def start_server(handler, server_settings, handler_name) 1572 # Ensure we initialize middleware before startup, to match standard Rack 1573 # behavior, by ensuring an instance exists: 1574 prototype 1575 # Run the instance we created: 1576 handler.run(self, **server_settings) do |server| 1577 unless suppress_messages? 1578 $stderr.puts "== Sinatra (v#{Sinatra::VERSION}) has taken the stage on #{port} for #{environment} with backup from #{handler_name}" 1579 end 1580 1581 setup_traps 1582 set :running_server, server 1583 set :handler_name, handler_name 1584 server.threaded = settings.threaded if server.respond_to? :threaded= 1585 1586 yield server if block_given? 1587 end 1588 end
# File lib/sinatra/base.rb 1590 def suppress_messages? 1591 handler_name =~ /cgi/i || quiet 1592 end
# File lib/sinatra/base.rb 1765 def synchronize(&block) 1766 if lock? 1767 @@mutex.synchronize(&block) 1768 else 1769 yield 1770 end 1771 end
Define a named template. The block must return the template source.
# File lib/sinatra/base.rb 1333 def template(name, &block) 1334 filename, line = caller_locations.first 1335 templates[name] = [block, filename, line.to_i] 1336 end
# File lib/sinatra/base.rb 1470 def test?; environment == :test end
# File lib/sinatra/base.rb 1448 def unlink(path, opts = {}, &bk) route 'UNLINK', path, opts, &bk end
Use the specified Rack
middleware
# File lib/sinatra/base.rb 1479 def use(middleware, *args, &block) 1480 @prototype = nil 1481 @middleware << [middleware, args, block] 1482 end
Condition for matching user agent. Parameter should be Regexp. Will set params.
# File lib/sinatra/base.rb 1624 def user_agent(pattern) 1625 condition do 1626 if request.user_agent.to_s =~ pattern 1627 @params[:agent] = $~[1..-1] 1628 true 1629 else 1630 false 1631 end 1632 end 1633 end
used for deprecation warnings
# File lib/sinatra/base.rb 1774 def warn(message) 1775 super message + "\n\tfrom #{cleaned_caller.first.join(':')}" 1776 end
Public Instance Methods
Rack
call interface.
# File lib/sinatra/base.rb 937 def call(env) 938 dup.call!(env) 939 end
Forward the request to the downstream app – middleware only.
# File lib/sinatra/base.rb 994 def forward 995 fail "downstream app not set" unless @app.respond_to? :call 996 status, headers, body = @app.call env 997 @response.status = status 998 @response.body = body 999 @response.headers.merge! headers 1000 nil 1001 end
Exit the current block, halts any further processing of the request, and returns the specified response.
# File lib/sinatra/base.rb 981 def halt(*response) 982 response = response.first if response.length == 1 983 throw :halt, response 984 end
# File lib/sinatra/base.rb 973 def options 974 warn "Sinatra::Base#options is deprecated and will be removed, " \ 975 "use #settings instead." 976 settings 977 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 989 def pass(&block) 990 throw :pass, block 991 end
Access settings defined with Base.set
.
# File lib/sinatra/base.rb 969 def settings 970 self.class.settings 971 end
Private Instance Methods
Dispatch a request with error handling.
# File lib/sinatra/base.rb 1127 def dispatch! 1128 # Avoid passing frozen string in force_encoding 1129 @params.merge!(@request.params).each do |key, val| 1130 next unless val.respond_to?(:force_encoding) 1131 val = val.dup if val.frozen? 1132 @params[key] = force_encoding(val) 1133 end 1134 1135 invoke do 1136 static! if settings.static? && (request.get? || request.head?) 1137 filter! :before do 1138 @pinned_response = !response['Content-Type'].nil? 1139 end 1140 route! 1141 end 1142 rescue ::Exception => boom 1143 invoke { handle_exception!(boom) } 1144 ensure 1145 begin 1146 filter! :after unless env['sinatra.static_file'] 1147 rescue ::Exception => boom 1148 invoke { handle_exception!(boom) } unless @env['sinatra.error'] 1149 end 1150 end
# File lib/sinatra/base.rb 1208 def dump_errors!(boom) 1209 msg = ["#{Time.now.strftime("%Y-%m-%d %H:%M:%S")} - #{boom.class} - #{boom.message}:", *boom.backtrace].join("\n\t") 1210 @env['rack.errors'].puts(msg) 1211 end
Find an custom error block for the key(s) specified.
# File lib/sinatra/base.rb 1193 def error_block!(key, *block_params) 1194 base = settings 1195 while base.respond_to?(:errors) 1196 next base = base.superclass unless args_array = base.errors[key] 1197 args_array.reverse_each do |args| 1198 first = args == args_array.first 1199 args += [block_params] 1200 resp = process_route(*args) 1201 return resp unless resp.nil? && !first 1202 end 1203 end 1204 return false unless key.respond_to? :superclass and key.superclass < Exception 1205 error_block!(key.superclass, *block_params) 1206 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 1007 def filter!(type, base = settings, &block) 1008 filter!(type, base.superclass, &block) if base.superclass.respond_to?(:filters) 1009 base.filters[type].each do |args| 1010 result = process_route(*args) 1011 block.call(result) if block_given? 1012 end 1013 end
# File lib/sinatra/base.rb 1800 def force_encoding(*args) settings.force_encoding(*args) end
Error handling during requests.
# File lib/sinatra/base.rb 1153 def handle_exception!(boom) 1154 if error_params = @env['sinatra.error.params'] 1155 @params = @params.merge(error_params) 1156 end 1157 @env['sinatra.error'] = boom 1158 1159 if boom.respond_to? :http_status and boom.http_status.between? 400, 599 1160 status(boom.http_status) 1161 elsif settings.use_code? and boom.respond_to? :code and boom.code.between? 400, 599 1162 status(boom.code) 1163 else 1164 status(500) 1165 end 1166 1167 if server_error? 1168 dump_errors! boom if settings.dump_errors? 1169 raise boom if settings.show_exceptions? and settings.show_exceptions != :after_handler 1170 elsif not_found? 1171 headers['X-Cascade'] = 'pass' if settings.x_cascade? 1172 end 1173 1174 if res = error_block!(boom.class, boom) || error_block!(status, boom) 1175 return res 1176 end 1177 1178 if not_found? || bad_request? 1179 if boom.message && boom.message != boom.class.name 1180 body Rack::Utils.escape_html(boom.message) 1181 else 1182 content_type 'text/html' 1183 body '<h1>' + (not_found? ? 'Not Found' : 'Bad Request') + '</h1>' 1184 end 1185 end 1186 1187 return unless server_error? 1188 raise boom if settings.raise_errors? or settings.show_exceptions? 1189 error_block! Exception, boom 1190 end
Run the block with 'throw :halt' support and apply result to the response.
# File lib/sinatra/base.rb 1111 def invoke 1112 res = catch(:halt) { yield } 1113 1114 res = [res] if Integer === res or String === res 1115 if Array === res and Integer === res.first 1116 res = res.dup 1117 status(res.shift) 1118 body(res.pop) 1119 headers(*res) 1120 elsif res.respond_to? :each 1121 body res 1122 end 1123 nil # avoid double setting the same response tuple twice 1124 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 1050 def process_route(pattern, conditions, block = nil, values = []) 1051 route = @request.path_info 1052 route = '/' if route.empty? and not settings.empty_path_info? 1053 route = route[0..-2] if !settings.strict_paths? && route != '/' && route.end_with?('/') 1054 return unless params = pattern.params(route) 1055 1056 params.delete("ignore") # TODO: better params handling, maybe turn it into "smart" object or detect changes 1057 force_encoding(params) 1058 @params = @params.merge(params) if params.any? 1059 1060 regexp_exists = pattern.is_a?(Mustermann::Regular) || (pattern.respond_to?(:patterns) && pattern.patterns.any? {|subpattern| subpattern.is_a?(Mustermann::Regular)} ) 1061 if regexp_exists 1062 captures = pattern.match(route).captures.map { |c| URI_INSTANCE.unescape(c) if c } 1063 values += captures 1064 @params[:captures] = force_encoding(captures) unless captures.nil? || captures.empty? 1065 else 1066 values += params.values.flatten 1067 end 1068 1069 catch(:pass) do 1070 conditions.each { |c| throw :pass if c.bind(self).call == false } 1071 block ? block[self, values] : yield(self, values) 1072 end 1073 rescue 1074 @env['sinatra.error.params'] = @params 1075 raise 1076 ensure 1077 params ||= {} 1078 params.each { |k, _| @params.delete(k) } unless @env['sinatra.error.params'] 1079 end
Run routes defined on the class and all superclasses.
# File lib/sinatra/base.rb 1016 def route!(base = settings, pass_block = nil) 1017 if routes = base.routes[@request.request_method] 1018 routes.each do |pattern, conditions, block| 1019 response.delete_header('Content-Type') unless @pinned_response 1020 1021 returned_pass_block = process_route(pattern, conditions) do |*args| 1022 env['sinatra.route'] = "#{@request.request_method} #{pattern}" 1023 route_eval { block[*args] } 1024 end 1025 1026 # don't wipe out pass_block in superclass 1027 pass_block = returned_pass_block if returned_pass_block 1028 end 1029 end 1030 1031 # Run routes defined in superclass. 1032 if base.superclass.respond_to?(:routes) 1033 return route!(base.superclass, pass_block) 1034 end 1035 1036 route_eval(&pass_block) if pass_block 1037 route_missing 1038 end
Run a route block and throw :halt with the result.
# File lib/sinatra/base.rb 1041 def route_eval 1042 throw :halt, yield 1043 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 1086 def route_missing 1087 if @app 1088 forward 1089 else 1090 raise NotFound, "#{request.request_method} #{request.path_info}" 1091 end 1092 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 1096 def static!(options = {}) 1097 return if (public_dir = settings.public_folder).nil? 1098 path = "#{public_dir}#{URI_INSTANCE.unescape(request.path_info)}" 1099 return unless valid_path?(path) 1100 1101 path = File.expand_path(path) 1102 return unless path.start_with?(File.expand_path(public_dir) + '/') 1103 return unless File.file?(path) 1104 1105 env['sinatra.static_file'] = path 1106 cache_control(*settings.static_cache_control) if settings.static_cache_control? 1107 send_file path, options.merge(:disposition => nil) 1108 end