class Sinatra::Helpers::Stream::Base
Constants
- URI_INSTANCE
Attributes
Public Class Methods
Sinatra::Helpers::Stream::Templates::new
# File lib/sinatra/base.rb 919 def initialize(app = nil) 920 super() 921 @app = app 922 @template_cache = Tilt::Cache.new 923 @pinned_response = nil # whether a before! filter pinned the content-type 924 yield self if block_given? 925 end
Access settings defined with Base.set
.
# File lib/sinatra/base.rb 954 def self.settings 955 self 956 end
Private Class Methods
add a filter
# File lib/sinatra/base.rb 1399 def add_filter(type, path = /.*/, **options, &block) 1400 filters[type] << compile!(type, path, block, **options) 1401 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 1394 def after(path = /.*/, **options, &block) 1395 add_filter(:after, path, **options, &block) 1396 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 1387 def before(path = /.*/, **options, &block) 1388 add_filter(:before, path, **options, &block) 1389 end
Creates a Rack::Builder
instance with all the middleware set up and the given app
as end point.
# File lib/sinatra/base.rb 1533 def build(app) 1534 builder = Rack::Builder.new 1535 setup_default_middleware builder 1536 setup_middleware builder 1537 builder.run app 1538 builder 1539 end
# File lib/sinatra/base.rb 1541 def call(env) 1542 synchronize { prototype.call(env) } 1543 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 1547 def caller_files 1548 cleaned_caller(1).flatten 1549 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 1553 def caller_locations 1554 cleaned_caller 2 1555 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 1680 def compile(path, route_mustermann_opts = {}) 1681 Mustermann.new(path, **mustermann_opts.merge(route_mustermann_opts)) 1682 end
# File lib/sinatra/base.rb 1661 def compile!(verb, path, block, **options) 1662 # Because of self.options.host 1663 host_name(options.delete(:host)) if options.key?(:host) 1664 # Pass Mustermann opts to compile() 1665 route_mustermann_opts = options.key?(:mustermann_opts) ? options.delete(:mustermann_opts) : {}.freeze 1666 1667 options.each_pair { |option, args| send(option, *args) } 1668 1669 pattern = compile(path, route_mustermann_opts) 1670 method_name = "#{verb} #{path}" 1671 unbound_method = generate_method(method_name, &block) 1672 conditions, @conditions = @conditions, [] 1673 wrapper = block.arity != 0 ? 1674 proc { |a, p| unbound_method.bind(a).call(*p) } : 1675 proc { |a, p| unbound_method.bind(a).call } 1676 1677 [ pattern, conditions, wrapper ] 1678 end
Add a route condition. The route is considered non-matching when the block returns false.
# File lib/sinatra/base.rb 1405 def condition(name = "#{caller.first[/`.*'/]} condition", &block) 1406 @conditions << generate_method(name, &block) 1407 end
Set configuration options for Sinatra
and/or the app. Allows scoping of settings for certain environments.
# File lib/sinatra/base.rb 1465 def configure(*envs) 1466 yield self if envs.empty? || envs.include?(environment.to_sym) 1467 end
Dynamically defines a method on settings.
# File lib/sinatra/base.rb 1599 def define_singleton(name, content = Proc.new) 1600 singleton_class.class_eval do 1601 undef_method(name) if method_defined? name 1602 String === content ? class_eval("def #{name}() #{content}; end") : define_method(name, &content) 1603 end 1604 end
# File lib/sinatra/base.rb 1434 def delete(path, opts = {}, &bk) route 'DELETE', path, opts, &bk end
# File lib/sinatra/base.rb 1747 def detect_rack_handler 1748 servers = Array(server) 1749 servers.each do |server_name| 1750 begin 1751 return Rack::Handler.get(server_name.to_s) 1752 rescue LoadError, NameError 1753 end 1754 end 1755 fail "Server handler (#{servers.join(',')}) not found." 1756 end
# File lib/sinatra/base.rb 1459 def development?; environment == :development end
Same as calling `set :option, false` for each of the given options.
# File lib/sinatra/base.rb 1303 def disable(*opts) 1304 opts.each { |key| set(key, false) } 1305 end
Same as calling `set :option, true` for each of the given options.
# File lib/sinatra/base.rb 1298 def enable(*opts) 1299 opts.each { |key| set(key, true) } 1300 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 1310 def error(*codes, &block) 1311 args = compile! "ERROR", /.*/, block 1312 codes = codes.flat_map(&method(:Array)) 1313 codes << Exception if codes.empty? 1314 codes << Sinatra::NotFound if codes.include?(404) 1315 codes.each { |c| (@errors[c] ||= []) << args } 1316 end
Extension modules registered on this class and all superclasses.
# File lib/sinatra/base.rb 1243 def extensions 1244 if superclass.respond_to?(:extensions) 1245 (@extensions + superclass.extensions).uniq 1246 else 1247 @extensions 1248 end 1249 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 1654 def generate_method(method_name, &block) 1655 define_method(method_name, &block) 1656 method = instance_method method_name 1657 remove_method method_name 1658 method 1659 end
Defining a `GET` handler also automatically defines a `HEAD` handler.
# File lib/sinatra/base.rb 1424 def get(path, opts = {}, &block) 1425 conditions = @conditions.dup 1426 route('GET', path, opts, &block) 1427 1428 @conditions = conditions 1429 route('HEAD', path, opts, &block) 1430 end
# File lib/sinatra/base.rb 1435 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 1443 def helpers(*extensions, &block) 1444 class_eval(&block) if block_given? 1445 prepend(*extensions) if extensions.any? 1446 end
Condition for matching host name. Parameter might be String or Regexp.
# File lib/sinatra/base.rb 1607 def host_name(pattern) 1608 condition { pattern === request.host } 1609 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 1336 def inline_templates=(file = nil) 1337 file = (file.nil? || file == true) ? (caller_files.first || File.expand_path($0)) : file 1338 1339 begin 1340 io = ::IO.respond_to?(:binread) ? ::IO.binread(file) : ::IO.read(file) 1341 app, data = io.gsub("\r\n", "\n").split(/^__END__$/, 2) 1342 rescue Errno::ENOENT 1343 app, data = nil 1344 end 1345 1346 if data 1347 if app and app =~ /([^\n]*\n)?#[^\n]*coding: *(\S+)/m 1348 encoding = $2 1349 else 1350 encoding = settings.default_encoding 1351 end 1352 lines = app.count("\n") + 1 1353 template = nil 1354 force_encoding data, encoding 1355 data.each_line do |line| 1356 lines += 1 1357 if line =~ /^@@\s*(.*\S)\s*$/ 1358 template = force_encoding(String.new, encoding) 1359 templates[$1.to_sym] = [template, file, lines] 1360 elsif template 1361 template << line 1362 end 1363 end 1364 end 1365 end
# File lib/sinatra/base.rb 1650 def invoke_hook(name, *args) 1651 extensions.each { |e| e.send(name, *args) if e.respond_to?(name) } 1652 end
Define the layout template. The block must return the template source.
# File lib/sinatra/base.rb 1330 def layout(name = :layout, &block) 1331 template name, &block 1332 end
# File lib/sinatra/base.rb 1438 def link(path, opts = {}, &bk) route 'LINK', path, opts, &bk end
Middleware used in this class and all superclasses.
# File lib/sinatra/base.rb 1252 def middleware 1253 if superclass.respond_to?(:middleware) 1254 superclass.middleware + @middleware 1255 else 1256 @middleware 1257 end 1258 end
Lookup or register a mime type in Rack's mime registry.
# File lib/sinatra/base.rb 1368 def mime_type(type, value = nil) 1369 return type if type.nil? 1370 return type.to_s if type.to_s.include?('/') 1371 type = ".#{type}" unless type.to_s[0] == ?. 1372 return Rack::Mime.mime_type(type, nil) unless value 1373 Rack::Mime::MIME_TYPES[type] = value 1374 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 1379 def mime_types(type) 1380 type = mime_type type 1381 type =~ /^application\/(xml|javascript)$/ ? [type, "text/#$1"] : [type] 1382 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 1526 def new(*args, &bk) 1527 instance = new!(*args, &bk) 1528 Wrapper.new(build(instance).to_app, instance) 1529 end
Sugar for `error(404) { … }`
# File lib/sinatra/base.rb 1319 def not_found(&block) 1320 error(404, &block) 1321 end
# File lib/sinatra/base.rb 1436 def options(path, opts = {}, &bk) route 'OPTIONS', path, opts, &bk end
# File lib/sinatra/base.rb 1437 def patch(path, opts = {}, &bk) route 'PATCH', path, opts, &bk end
# File lib/sinatra/base.rb 1433 def post(path, opts = {}, &bk) route 'POST', path, opts, &bk end
# File lib/sinatra/base.rb 1460 def production?; environment == :production end
The prototype instance used to process requests.
# File lib/sinatra/base.rb 1516 def prototype 1517 @prototype ||= new 1518 end
Condition for matching mimetypes. Accepts file extensions.
# File lib/sinatra/base.rb 1626 def provides(*types) 1627 types.map! { |t| mime_types(t) } 1628 types.flatten! 1629 condition do 1630 if type = response['Content-Type'] 1631 types.include? type or types.include? type[/^[^;]+/] 1632 elsif type = request.preferred_type(types) 1633 params = (type.respond_to?(:params) ? type.params : {}) 1634 content_type(type, params) 1635 true 1636 else 1637 false 1638 end 1639 end 1640 end
# File lib/sinatra/base.rb 1409 def public=(value) 1410 warn ":public is no longer used to avoid overloading Module#public, use :public_folder or :public_dir instead" 1411 set(:public_folder, value) 1412 end
# File lib/sinatra/base.rb 1418 def public_dir 1419 public_folder 1420 end
# File lib/sinatra/base.rb 1414 def public_dir=(value) 1415 self.public_folder = value 1416 end
# File lib/sinatra/base.rb 1432 def put(path, opts = {}, &bk) route 'PUT', path, opts, &bk end
Stop the self-hosted server if running.
# File lib/sinatra/base.rb 1476 def quit! 1477 return unless running? 1478 # Use Thin's hard #stop! if available, otherwise just #stop. 1479 running_server.respond_to?(:stop!) ? running_server.stop! : running_server.stop 1480 $stderr.puts "== Sinatra has ended his set (crowd applauds)" unless suppress_messages? 1481 set :running_server, nil 1482 set :handler_name, nil 1483 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 1450 def register(*extensions, &block) 1451 extensions << Module.new(&block) if block_given? 1452 @extensions += extensions 1453 extensions.each do |extension| 1454 extend extension 1455 extension.registered(self) if extension.respond_to?(:registered) 1456 end 1457 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 1226 def reset! 1227 @conditions = [] 1228 @routes = {} 1229 @filters = {:before => [], :after => []} 1230 @errors = {} 1231 @middleware = [] 1232 @prototype = nil 1233 @extensions = [] 1234 1235 if superclass.respond_to?(:templates) 1236 @templates = Hash.new { |hash, key| superclass.templates[key] } 1237 else 1238 @templates = {} 1239 end 1240 end
# File lib/sinatra/base.rb 1642 def route(verb, path, options = {}, &block) 1643 enable :empty_path_info if path == "" and empty_path_info.nil? 1644 signature = compile!(verb, path, block, **options) 1645 (@routes[verb] ||= []) << signature 1646 invoke_hook(:route_added, verb, path, block) 1647 signature 1648 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 1490 def run!(options = {}, &block) 1491 return if running? 1492 set options 1493 handler = detect_rack_handler 1494 handler_name = handler.name.gsub(/.*::/, '') 1495 server_settings = settings.respond_to?(:server_settings) ? settings.server_settings : {} 1496 server_settings.merge!(:Port => port, :Host => bind) 1497 1498 begin 1499 start_server(handler, server_settings, handler_name, &block) 1500 rescue Errno::EADDRINUSE 1501 $stderr.puts "== Someone is already performing on port #{port}!" 1502 raise 1503 ensure 1504 quit! 1505 end 1506 end
Check whether the self-hosted server is running or not.
# File lib/sinatra/base.rb 1511 def running? 1512 running_server? 1513 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 1262 def set(option, value = (not_set = true), ignore_setter = false, &block) 1263 raise ArgumentError if block and !not_set 1264 value, not_set = block, false if block 1265 1266 if not_set 1267 raise ArgumentError unless option.respond_to?(:each) 1268 option.each { |k,v| set(k, v) } 1269 return self 1270 end 1271 1272 if respond_to?("#{option}=") and not ignore_setter 1273 return __send__("#{option}=", value) 1274 end 1275 1276 setter = proc { |val| set option, val, true } 1277 getter = proc { value } 1278 1279 case value 1280 when Proc 1281 getter = value 1282 when Symbol, Integer, FalseClass, TrueClass, NilClass 1283 getter = value.inspect 1284 when Hash 1285 setter = proc do |val| 1286 val = value.merge val if Hash === val 1287 set option, val, true 1288 end 1289 end 1290 1291 define_singleton("#{option}=", setter) 1292 define_singleton(option, getter) 1293 define_singleton("#{option}?", "!!#{option}") unless method_defined? "#{option}?" 1294 self 1295 end
# File lib/sinatra/base.rb 1711 def setup_common_logger(builder) 1712 builder.use Sinatra::CommonLogger 1713 end
# File lib/sinatra/base.rb 1715 def setup_custom_logger(builder) 1716 if logging.respond_to? :to_int 1717 builder.use Rack::Logger, logging 1718 else 1719 builder.use Rack::Logger 1720 end 1721 end
# File lib/sinatra/base.rb 1684 def setup_default_middleware(builder) 1685 builder.use ExtendedRack 1686 builder.use ShowExceptions if show_exceptions? 1687 builder.use Rack::MethodOverride if method_override? 1688 builder.use Rack::Head 1689 setup_logging builder 1690 setup_sessions builder 1691 setup_protection builder 1692 end
# File lib/sinatra/base.rb 1698 def setup_logging(builder) 1699 if logging? 1700 setup_common_logger(builder) 1701 setup_custom_logger(builder) 1702 elsif logging == false 1703 setup_null_logger(builder) 1704 end 1705 end
# File lib/sinatra/base.rb 1694 def setup_middleware(builder) 1695 middleware.each { |c,a,b| builder.use(c, *a, &b) } 1696 end
# File lib/sinatra/base.rb 1707 def setup_null_logger(builder) 1708 builder.use Rack::NullLogger 1709 end
# File lib/sinatra/base.rb 1723 def setup_protection(builder) 1724 return unless protection? 1725 options = Hash === protection ? protection.dup : {} 1726 options = { 1727 img_src: "'self' data:", 1728 font_src: "'self'" 1729 }.merge options 1730 1731 protect_session = options.fetch(:session) { sessions? } 1732 options[:without_session] = !protect_session 1733 1734 options[:reaction] ||= :drop_session 1735 1736 builder.use Rack::Protection, options 1737 end
# File lib/sinatra/base.rb 1739 def setup_sessions(builder) 1740 return unless sessions? 1741 options = {} 1742 options[:secret] = session_secret if session_secret? 1743 options.merge! sessions.to_hash if sessions.respond_to? :to_hash 1744 builder.use session_store, options 1745 end
# File lib/sinatra/base.rb 1583 def setup_traps 1584 if traps? 1585 at_exit { quit! } 1586 1587 [:INT, :TERM].each do |signal| 1588 old_handler = trap(signal) do 1589 quit! 1590 old_handler.call if old_handler.respond_to?(:call) 1591 end 1592 end 1593 1594 set :traps, false 1595 end 1596 end
Starts the server by running the Rack
Handler.
# File lib/sinatra/base.rb 1560 def start_server(handler, server_settings, handler_name) 1561 # Ensure we initialize middleware before startup, to match standard Rack 1562 # behavior, by ensuring an instance exists: 1563 prototype 1564 # Run the instance we created: 1565 handler.run(self, **server_settings) do |server| 1566 unless suppress_messages? 1567 $stderr.puts "== Sinatra (v#{Sinatra::VERSION}) has taken the stage on #{port} for #{environment} with backup from #{handler_name}" 1568 end 1569 1570 setup_traps 1571 set :running_server, server 1572 set :handler_name, handler_name 1573 server.threaded = settings.threaded if server.respond_to? :threaded= 1574 1575 yield server if block_given? 1576 end 1577 end
# File lib/sinatra/base.rb 1579 def suppress_messages? 1580 handler_name =~ /cgi/i || quiet 1581 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 1324 def template(name, &block) 1325 filename, line = caller_locations.first 1326 templates[name] = [block, filename, line.to_i] 1327 end
# File lib/sinatra/base.rb 1461 def test?; environment == :test end
# File lib/sinatra/base.rb 1439 def unlink(path, opts = {}, &bk) route 'UNLINK', path, opts, &bk end
Use the specified Rack
middleware
# File lib/sinatra/base.rb 1470 def use(middleware, *args, &block) 1471 @prototype = nil 1472 @middleware << [middleware, args, block] 1473 end
Condition for matching user agent. Parameter should be Regexp. Will set params.
# File lib/sinatra/base.rb 1613 def user_agent(pattern) 1614 condition do 1615 if request.user_agent.to_s =~ pattern 1616 @params[:agent] = $~[1..-1] 1617 true 1618 else 1619 false 1620 end 1621 end 1622 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 928 def call(env) 929 dup.call!(env) 930 end
Forward the request to the downstream app – middleware only.
# File lib/sinatra/base.rb 984 def forward 985 fail "downstream app not set" unless @app.respond_to? :call 986 status, headers, body = @app.call env 987 @response.status = status 988 @response.body = body 989 @response.headers.merge! headers 990 nil 991 end
Exit the current block, halts any further processing of the request, and returns the specified response.
# File lib/sinatra/base.rb 971 def halt(*response) 972 response = response.first if response.length == 1 973 throw :halt, response 974 end
# File lib/sinatra/base.rb 963 def options 964 warn "Sinatra::Base#options is deprecated and will be removed, " \ 965 "use #settings instead." 966 settings 967 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 979 def pass(&block) 980 throw :pass, block 981 end
Access settings defined with Base.set
.
# File lib/sinatra/base.rb 959 def settings 960 self.class.settings 961 end
Private Instance Methods
Dispatch a request with error handling.
# File lib/sinatra/base.rb 1116 def dispatch! 1117 # Avoid passing frozen string in force_encoding 1118 @params.merge!(@request.params).each do |key, val| 1119 next unless val.respond_to?(:force_encoding) 1120 val = val.dup if val.frozen? 1121 @params[key] = force_encoding(val) 1122 end 1123 1124 invoke do 1125 static! if settings.static? && (request.get? || request.head?) 1126 filter! :before do 1127 @pinned_response = !@response['Content-Type'].nil? 1128 end 1129 route! 1130 end 1131 rescue ::Exception => boom 1132 invoke { handle_exception!(boom) } 1133 ensure 1134 begin 1135 filter! :after unless env['sinatra.static_file'] 1136 rescue ::Exception => boom 1137 invoke { handle_exception!(boom) } unless @env['sinatra.error'] 1138 end 1139 end
# File lib/sinatra/base.rb 1199 def dump_errors!(boom) 1200 msg = ["#{Time.now.strftime("%Y-%m-%d %H:%M:%S")} - #{boom.class} - #{boom.message}:", *boom.backtrace].join("\n\t") 1201 @env['rack.errors'].puts(msg) 1202 end
Find an custom error block for the key(s) specified.
# File lib/sinatra/base.rb 1184 def error_block!(key, *block_params) 1185 base = settings 1186 while base.respond_to?(:errors) 1187 next base = base.superclass unless args_array = base.errors[key] 1188 args_array.reverse_each do |args| 1189 first = args == args_array.first 1190 args += [block_params] 1191 resp = process_route(*args) 1192 return resp unless resp.nil? && !first 1193 end 1194 end 1195 return false unless key.respond_to? :superclass and key.superclass < Exception 1196 error_block!(key.superclass, *block_params) 1197 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 997 def filter!(type, base = settings) 998 filter! type, base.superclass if base.superclass.respond_to?(:filters) 999 base.filters[type].each do |args| 1000 result = process_route(*args) 1001 yield result if block_given? 1002 end 1003 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 1142 def handle_exception!(boom) 1143 if error_params = @env['sinatra.error.params'] 1144 @params = @params.merge(error_params) 1145 end 1146 @env['sinatra.error'] = boom 1147 1148 if boom.respond_to? :http_status 1149 status(boom.http_status) 1150 elsif settings.use_code? and boom.respond_to? :code and boom.code.between? 400, 599 1151 status(boom.code) 1152 else 1153 status(500) 1154 end 1155 1156 status(500) unless status.between? 400, 599 1157 1158 if server_error? 1159 dump_errors! boom if settings.dump_errors? 1160 raise boom if settings.show_exceptions? and settings.show_exceptions != :after_handler 1161 elsif not_found? 1162 headers['X-Cascade'] = 'pass' if settings.x_cascade? 1163 end 1164 1165 if res = error_block!(boom.class, boom) || error_block!(status, boom) 1166 return res 1167 end 1168 1169 if not_found? || bad_request? 1170 if boom.message && boom.message != boom.class.name 1171 body boom.message 1172 else 1173 content_type 'text/html' 1174 body '<h1>' + (not_found? ? 'Not Found' : 'Bad Request') + '</h1>' 1175 end 1176 end 1177 1178 return unless server_error? 1179 raise boom if settings.raise_errors? or settings.show_exceptions? 1180 error_block! Exception, boom 1181 end
Run the block with 'throw :halt' support and apply result to the response.
# File lib/sinatra/base.rb 1100 def invoke 1101 res = catch(:halt) { yield } 1102 1103 res = [res] if Integer === res or String === res 1104 if Array === res and Integer === res.first 1105 res = res.dup 1106 status(res.shift) 1107 body(res.pop) 1108 headers(*res) 1109 elsif res.respond_to? :each 1110 body res 1111 end 1112 nil # avoid double setting the same response tuple twice 1113 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 1040 def process_route(pattern, conditions, block = nil, values = []) 1041 route = @request.path_info 1042 route = '/' if route.empty? and not settings.empty_path_info? 1043 route = route[0..-2] if !settings.strict_paths? && route != '/' && route.end_with?('/') 1044 return unless params = pattern.params(route) 1045 1046 params.delete("ignore") # TODO: better params handling, maybe turn it into "smart" object or detect changes 1047 force_encoding(params) 1048 @params = @params.merge(params) if params.any? 1049 1050 regexp_exists = pattern.is_a?(Mustermann::Regular) || (pattern.respond_to?(:patterns) && pattern.patterns.any? {|subpattern| subpattern.is_a?(Mustermann::Regular)} ) 1051 if regexp_exists 1052 captures = pattern.match(route).captures.map { |c| URI_INSTANCE.unescape(c) if c } 1053 values += captures 1054 @params[:captures] = force_encoding(captures) unless captures.nil? || captures.empty? 1055 else 1056 values += params.values.flatten 1057 end 1058 1059 catch(:pass) do 1060 conditions.each { |c| throw :pass if c.bind(self).call == false } 1061 block ? block[self, values] : yield(self, values) 1062 end 1063 rescue 1064 @env['sinatra.error.params'] = @params 1065 raise 1066 ensure 1067 params ||= {} 1068 params.each { |k, _| @params.delete(k) } unless @env['sinatra.error.params'] 1069 end
Run routes defined on the class and all superclasses.
# File lib/sinatra/base.rb 1006 def route!(base = settings, pass_block = nil) 1007 if routes = base.routes[@request.request_method] 1008 routes.each do |pattern, conditions, block| 1009 @response.delete_header('Content-Type') unless @pinned_response 1010 1011 returned_pass_block = process_route(pattern, conditions) do |*args| 1012 env['sinatra.route'] = "#{@request.request_method} #{pattern}" 1013 route_eval { block[*args] } 1014 end 1015 1016 # don't wipe out pass_block in superclass 1017 pass_block = returned_pass_block if returned_pass_block 1018 end 1019 end 1020 1021 # Run routes defined in superclass. 1022 if base.superclass.respond_to?(:routes) 1023 return route!(base.superclass, pass_block) 1024 end 1025 1026 route_eval(&pass_block) if pass_block 1027 route_missing 1028 end
Run a route block and throw :halt with the result.
# File lib/sinatra/base.rb 1031 def route_eval 1032 throw :halt, yield 1033 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 1076 def route_missing 1077 if @app 1078 forward 1079 else 1080 raise NotFound, "#{request.request_method} #{request.path_info}" 1081 end 1082 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 1086 def static!(options = {}) 1087 return if (public_dir = settings.public_folder).nil? 1088 path = "#{public_dir}#{URI_INSTANCE.unescape(request.path_info)}" 1089 return unless valid_path?(path) 1090 1091 path = File.expand_path(path) 1092 return unless File.file?(path) 1093 1094 env['sinatra.static_file'] = path 1095 cache_control(*settings.static_cache_control) if settings.static_cache_control? 1096 send_file path, options.merge(:disposition => nil) 1097 end