class Sinatra::Helpers::Stream::Base
Constants
- URI_INSTANCE
Attributes
Public Class Methods
Sinatra::Helpers::Stream::Templates::new
# File lib/sinatra/base.rb 935 def initialize(app = nil, **kwargs) 936 super() 937 @app = app 938 @template_cache = Tilt::Cache.new 939 @pinned_response = nil # whether a before! filter pinned the content-type 940 yield self if block_given? 941 end
Access settings defined with Base.set
.
# File lib/sinatra/base.rb 971 def self.settings 972 self 973 end
Private Class Methods
add a filter
# File lib/sinatra/base.rb 1419 def add_filter(type, path = /.*/, **options, &block) 1420 filters[type] << compile!(type, path, block, **options) 1421 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 1414 def after(path = /.*/, **options, &block) 1415 add_filter(:after, path, **options, &block) 1416 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 1407 def before(path = /.*/, **options, &block) 1408 add_filter(:before, path, **options, &block) 1409 end
Creates a Rack::Builder
instance with all the middleware set up and the given app
as end point.
# File lib/sinatra/base.rb 1555 def build(app) 1556 builder = Rack::Builder.new 1557 setup_default_middleware builder 1558 setup_middleware builder 1559 builder.run app 1560 builder 1561 end
# File lib/sinatra/base.rb 1563 def call(env) 1564 synchronize { prototype.call(env) } 1565 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 1569 def caller_files 1570 cleaned_caller(1).flatten 1571 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 1575 def caller_locations 1576 cleaned_caller 2 1577 end
# File lib/sinatra/base.rb 1240 def callers_to_ignore 1241 CALLERS_TO_IGNORE 1242 end
Like Kernel#caller but excluding certain magic entries
# File lib/sinatra/base.rb 1790 def cleaned_caller(keep = 3) 1791 caller(1). 1792 map! { |line| line.split(/:(?=\d|in )/, 3)[0,keep] }. 1793 reject { |file, *_| callers_to_ignore.any? { |pattern| file =~ pattern } } 1794 end
# File lib/sinatra/base.rb 1702 def compile(path, route_mustermann_opts = {}) 1703 Mustermann.new(path, **mustermann_opts.merge(route_mustermann_opts)) 1704 end
# File lib/sinatra/base.rb 1683 def compile!(verb, path, block, **options) 1684 # Because of self.options.host 1685 host_name(options.delete(:host)) if options.key?(:host) 1686 # Pass Mustermann opts to compile() 1687 route_mustermann_opts = options.key?(:mustermann_opts) ? options.delete(:mustermann_opts) : {}.freeze 1688 1689 options.each_pair { |option, args| send(option, *args) } 1690 1691 pattern = compile(path, route_mustermann_opts) 1692 method_name = "#{verb} #{path}" 1693 unbound_method = generate_method(method_name, &block) 1694 conditions, @conditions = @conditions, [] 1695 wrapper = block.arity != 0 ? 1696 proc { |a, p| unbound_method.bind(a).call(*p) } : 1697 proc { |a, p| unbound_method.bind(a).call } 1698 1699 [ pattern, conditions, wrapper ] 1700 end
Add a route condition. The route is considered non-matching when the block returns false.
# File lib/sinatra/base.rb 1425 def condition(name = "#{caller.first[/`.*'/]} condition", &block) 1426 @conditions << generate_method(name, &block) 1427 end
Set configuration options for Sinatra
and/or the app. Allows scoping of settings for certain environments.
# File lib/sinatra/base.rb 1485 def configure(*envs) 1486 yield self if envs.empty? || envs.include?(environment.to_sym) 1487 end
Dynamically defines a method on settings.
# File lib/sinatra/base.rb 1621 def define_singleton(name, content = Proc.new) 1622 singleton_class.class_eval do 1623 undef_method(name) if method_defined? name 1624 String === content ? class_eval("def #{name}() #{content}; end") : define_method(name, &content) 1625 end 1626 end
# File lib/sinatra/base.rb 1454 def delete(path, opts = {}, &bk) route 'DELETE', path, opts, &bk end
# File lib/sinatra/base.rb 1479 def development?; environment == :development end
Same as calling `set :option, false` for each of the given options.
# File lib/sinatra/base.rb 1323 def disable(*opts) 1324 opts.each { |key| set(key, false) } 1325 end
Same as calling `set :option, true` for each of the given options.
# File lib/sinatra/base.rb 1318 def enable(*opts) 1319 opts.each { |key| set(key, true) } 1320 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 1330 def error(*codes, &block) 1331 args = compile! "ERROR", /.*/, block 1332 codes = codes.flat_map(&method(:Array)) 1333 codes << Exception if codes.empty? 1334 codes << Sinatra::NotFound if codes.include?(404) 1335 codes.each { |c| (@errors[c] ||= []) << args } 1336 end
Extension modules registered on this class and all superclasses.
# File lib/sinatra/base.rb 1263 def extensions 1264 if superclass.respond_to?(:extensions) 1265 (@extensions + superclass.extensions).uniq 1266 else 1267 @extensions 1268 end 1269 end
Force data to specified encoding. It defaults to settings.default_encoding which is UTF-8 by default
# File lib/sinatra/base.rb 1799 def self.force_encoding(data, encoding = default_encoding) 1800 return if data == settings || data.is_a?(Tempfile) 1801 if data.respond_to? :force_encoding 1802 data.force_encoding(encoding).encode! 1803 elsif data.respond_to? :each_value 1804 data.each_value { |v| force_encoding(v, encoding) } 1805 elsif data.respond_to? :each 1806 data.each { |v| force_encoding(v, encoding) } 1807 end 1808 data 1809 end
# File lib/sinatra/base.rb 1676 def generate_method(method_name, &block) 1677 define_method(method_name, &block) 1678 method = instance_method method_name 1679 remove_method method_name 1680 method 1681 end
Defining a `GET` handler also automatically defines a `HEAD` handler.
# File lib/sinatra/base.rb 1444 def get(path, opts = {}, &block) 1445 conditions = @conditions.dup 1446 route('GET', path, opts, &block) 1447 1448 @conditions = conditions 1449 route('HEAD', path, opts, &block) 1450 end
# File lib/sinatra/base.rb 1455 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 1463 def helpers(*extensions, &block) 1464 class_eval(&block) if block_given? 1465 include(*extensions) if extensions.any? 1466 end
Condition for matching host name. Parameter might be String or Regexp.
# File lib/sinatra/base.rb 1629 def host_name(pattern) 1630 condition { pattern === request.host } 1631 end
# File lib/sinatra/base.rb 1769 def inherited(subclass) 1770 subclass.reset! 1771 subclass.set :app_file, caller_files.first unless subclass.app_file? 1772 super 1773 end
Load embedded templates from the file; uses the caller's __FILE__ when no file is specified.
# File lib/sinatra/base.rb 1356 def inline_templates=(file = nil) 1357 file = (file.nil? || file == true) ? (caller_files.first || File.expand_path($0)) : file 1358 1359 begin 1360 io = ::IO.respond_to?(:binread) ? ::IO.binread(file) : ::IO.read(file) 1361 app, data = io.gsub("\r\n", "\n").split(/^__END__$/, 2) 1362 rescue Errno::ENOENT 1363 app, data = nil 1364 end 1365 1366 if data 1367 if app and app =~ /([^\n]*\n)?#[^\n]*coding: *(\S+)/m 1368 encoding = $2 1369 else 1370 encoding = settings.default_encoding 1371 end 1372 lines = app.count("\n") + 1 1373 template = nil 1374 force_encoding data, encoding 1375 data.each_line do |line| 1376 lines += 1 1377 if line =~ /^@@\s*(.*\S)\s*$/ 1378 template = force_encoding(String.new, encoding) 1379 templates[$1.to_sym] = [template, file, lines] 1380 elsif template 1381 template << line 1382 end 1383 end 1384 end 1385 end
# File lib/sinatra/base.rb 1672 def invoke_hook(name, *args) 1673 extensions.each { |e| e.send(name, *args) if e.respond_to?(name) } 1674 end
Define the layout template. The block must return the template source.
# File lib/sinatra/base.rb 1350 def layout(name = :layout, &block) 1351 template name, &block 1352 end
# File lib/sinatra/base.rb 1458 def link(path, opts = {}, &bk) route 'LINK', path, opts, &bk end
Middleware used in this class and all superclasses.
# File lib/sinatra/base.rb 1272 def middleware 1273 if superclass.respond_to?(:middleware) 1274 superclass.middleware + @middleware 1275 else 1276 @middleware 1277 end 1278 end
Lookup or register a mime type in Rack's mime registry.
# File lib/sinatra/base.rb 1388 def mime_type(type, value = nil) 1389 return type if type.nil? 1390 return type.to_s if type.to_s.include?('/') 1391 type = ".#{type}" unless type.to_s[0] == ?. 1392 return Rack::Mime.mime_type(type, nil) unless value 1393 Rack::Mime::MIME_TYPES[type] = value 1394 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 1399 def mime_types(type) 1400 type = mime_type type 1401 type =~ /^application\/(xml|javascript)$/ ? [type, "text/#$1"] : [type] 1402 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 1547 def new(*args, &bk) 1548 instance = new!(*args, &bk) 1549 Wrapper.new(build(instance).to_app, instance) 1550 end
Sugar for `error(404) { … }`
# File lib/sinatra/base.rb 1339 def not_found(&block) 1340 error(404, &block) 1341 end
# File lib/sinatra/base.rb 1456 def options(path, opts = {}, &bk) route 'OPTIONS', path, opts, &bk end
# File lib/sinatra/base.rb 1457 def patch(path, opts = {}, &bk) route 'PATCH', path, opts, &bk end
# File lib/sinatra/base.rb 1453 def post(path, opts = {}, &bk) route 'POST', path, opts, &bk end
# File lib/sinatra/base.rb 1480 def production?; environment == :production end
The prototype instance used to process requests.
# File lib/sinatra/base.rb 1537 def prototype 1538 @prototype ||= new 1539 end
Condition for matching mimetypes. Accepts file extensions.
# File lib/sinatra/base.rb 1648 def provides(*types) 1649 types.map! { |t| mime_types(t) } 1650 types.flatten! 1651 condition do 1652 if type = response['Content-Type'] 1653 types.include? type or types.include? type[/^[^;]+/] 1654 elsif type = request.preferred_type(types) 1655 params = (type.respond_to?(:params) ? type.params : {}) 1656 content_type(type, params) 1657 true 1658 else 1659 false 1660 end 1661 end 1662 end
# File lib/sinatra/base.rb 1429 def public=(value) 1430 warn ":public is no longer used to avoid overloading Module#public, use :public_folder or :public_dir instead" 1431 set(:public_folder, value) 1432 end
# File lib/sinatra/base.rb 1438 def public_dir 1439 public_folder 1440 end
# File lib/sinatra/base.rb 1434 def public_dir=(value) 1435 self.public_folder = value 1436 end
# File lib/sinatra/base.rb 1452 def put(path, opts = {}, &bk) route 'PUT', path, opts, &bk end
Stop the self-hosted server if running.
# File lib/sinatra/base.rb 1497 def quit! 1498 return unless running? 1499 # Use Thin's hard #stop! if available, otherwise just #stop. 1500 running_server.respond_to?(:stop!) ? running_server.stop! : running_server.stop 1501 $stderr.puts "== Sinatra has ended his set (crowd applauds)" unless suppress_messages? 1502 set :running_server, nil 1503 set :handler_name, nil 1504 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 1470 def register(*extensions, &block) 1471 extensions << Module.new(&block) if block_given? 1472 @extensions += extensions 1473 extensions.each do |extension| 1474 extend extension 1475 extension.registered(self) if extension.respond_to?(:registered) 1476 end 1477 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 1246 def reset! 1247 @conditions = [] 1248 @routes = {} 1249 @filters = {:before => [], :after => []} 1250 @errors = {} 1251 @middleware = [] 1252 @prototype = nil 1253 @extensions = [] 1254 1255 if superclass.respond_to?(:templates) 1256 @templates = Hash.new { |hash, key| superclass.templates[key] } 1257 else 1258 @templates = {} 1259 end 1260 end
# File lib/sinatra/base.rb 1664 def route(verb, path, options = {}, &block) 1665 enable :empty_path_info if path == "" and empty_path_info.nil? 1666 signature = compile!(verb, path, block, **options) 1667 (@routes[verb] ||= []) << signature 1668 invoke_hook(:route_added, verb, path, block) 1669 signature 1670 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 1511 def run!(options = {}, &block) 1512 return if running? 1513 set options 1514 handler = Rack::Handler.pick(server) 1515 handler_name = handler.name.gsub(/.*::/, '') 1516 server_settings = settings.respond_to?(:server_settings) ? settings.server_settings : {} 1517 server_settings.merge!(:Port => port, :Host => bind) 1518 1519 begin 1520 start_server(handler, server_settings, handler_name, &block) 1521 rescue Errno::EADDRINUSE 1522 $stderr.puts "== Someone is already performing on port #{port}!" 1523 raise 1524 ensure 1525 quit! 1526 end 1527 end
Check whether the self-hosted server is running or not.
# File lib/sinatra/base.rb 1532 def running? 1533 running_server? 1534 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 1282 def set(option, value = (not_set = true), ignore_setter = false, &block) 1283 raise ArgumentError if block and !not_set 1284 value, not_set = block, false if block 1285 1286 if not_set 1287 raise ArgumentError unless option.respond_to?(:each) 1288 option.each { |k,v| set(k, v) } 1289 return self 1290 end 1291 1292 if respond_to?("#{option}=") and not ignore_setter 1293 return __send__("#{option}=", value) 1294 end 1295 1296 setter = proc { |val| set option, val, true } 1297 getter = proc { value } 1298 1299 case value 1300 when Proc 1301 getter = value 1302 when Symbol, Integer, FalseClass, TrueClass, NilClass 1303 getter = value.inspect 1304 when Hash 1305 setter = proc do |val| 1306 val = value.merge val if Hash === val 1307 set option, val, true 1308 end 1309 end 1310 1311 define_singleton("#{option}=", setter) 1312 define_singleton(option, getter) 1313 define_singleton("#{option}?", "!!#{option}") unless method_defined? "#{option}?" 1314 self 1315 end
# File lib/sinatra/base.rb 1733 def setup_common_logger(builder) 1734 builder.use Sinatra::CommonLogger 1735 end
# File lib/sinatra/base.rb 1737 def setup_custom_logger(builder) 1738 if logging.respond_to? :to_int 1739 builder.use Rack::Logger, logging 1740 else 1741 builder.use Rack::Logger 1742 end 1743 end
# File lib/sinatra/base.rb 1706 def setup_default_middleware(builder) 1707 builder.use ExtendedRack 1708 builder.use ShowExceptions if show_exceptions? 1709 builder.use Rack::MethodOverride if method_override? 1710 builder.use Rack::Head 1711 setup_logging builder 1712 setup_sessions builder 1713 setup_protection builder 1714 end
# File lib/sinatra/base.rb 1720 def setup_logging(builder) 1721 if logging? 1722 setup_common_logger(builder) 1723 setup_custom_logger(builder) 1724 elsif logging == false 1725 setup_null_logger(builder) 1726 end 1727 end
# File lib/sinatra/base.rb 1716 def setup_middleware(builder) 1717 middleware.each { |c,a,b| builder.use(c, *a, &b) } 1718 end
# File lib/sinatra/base.rb 1729 def setup_null_logger(builder) 1730 builder.use Rack::NullLogger 1731 end
# File lib/sinatra/base.rb 1745 def setup_protection(builder) 1746 return unless protection? 1747 options = Hash === protection ? protection.dup : {} 1748 options = { 1749 img_src: "'self' data:", 1750 font_src: "'self'" 1751 }.merge options 1752 1753 protect_session = options.fetch(:session) { sessions? } 1754 options[:without_session] = !protect_session 1755 1756 options[:reaction] ||= :drop_session 1757 1758 builder.use Rack::Protection, options 1759 end
# File lib/sinatra/base.rb 1761 def setup_sessions(builder) 1762 return unless sessions? 1763 options = {} 1764 options[:secret] = session_secret if session_secret? 1765 options.merge! sessions.to_hash if sessions.respond_to? :to_hash 1766 builder.use session_store, options 1767 end
# File lib/sinatra/base.rb 1605 def setup_traps 1606 if traps? 1607 at_exit { quit! } 1608 1609 [:INT, :TERM].each do |signal| 1610 old_handler = trap(signal) do 1611 quit! 1612 old_handler.call if old_handler.respond_to?(:call) 1613 end 1614 end 1615 1616 set :traps, false 1617 end 1618 end
Starts the server by running the Rack
Handler.
# File lib/sinatra/base.rb 1582 def start_server(handler, server_settings, handler_name) 1583 # Ensure we initialize middleware before startup, to match standard Rack 1584 # behavior, by ensuring an instance exists: 1585 prototype 1586 # Run the instance we created: 1587 handler.run(self, **server_settings) do |server| 1588 unless suppress_messages? 1589 $stderr.puts "== Sinatra (v#{Sinatra::VERSION}) has taken the stage on #{port} for #{environment} with backup from #{handler_name}" 1590 end 1591 1592 setup_traps 1593 set :running_server, server 1594 set :handler_name, handler_name 1595 server.threaded = settings.threaded if server.respond_to? :threaded= 1596 1597 yield server if block_given? 1598 end 1599 end
# File lib/sinatra/base.rb 1601 def suppress_messages? 1602 handler_name =~ /cgi/i || quiet 1603 end
# File lib/sinatra/base.rb 1776 def synchronize(&block) 1777 if lock? 1778 @@mutex.synchronize(&block) 1779 else 1780 yield 1781 end 1782 end
Define a named template. The block must return the template source.
# File lib/sinatra/base.rb 1344 def template(name, &block) 1345 filename, line = caller_locations.first 1346 templates[name] = [block, filename, line.to_i] 1347 end
# File lib/sinatra/base.rb 1481 def test?; environment == :test end
# File lib/sinatra/base.rb 1459 def unlink(path, opts = {}, &bk) route 'UNLINK', path, opts, &bk end
Use the specified Rack
middleware
# File lib/sinatra/base.rb 1490 def use(middleware, *args, &block) 1491 @prototype = nil 1492 @middleware << [middleware, args, block] 1493 end
Condition for matching user agent. Parameter should be Regexp. Will set params.
# File lib/sinatra/base.rb 1635 def user_agent(pattern) 1636 condition do 1637 if request.user_agent.to_s =~ pattern 1638 @params[:agent] = $~[1..-1] 1639 true 1640 else 1641 false 1642 end 1643 end 1644 end
used for deprecation warnings
# File lib/sinatra/base.rb 1785 def warn(message) 1786 super message + "\n\tfrom #{cleaned_caller.first.join(':')}" 1787 end
Public Instance Methods
Rack
call interface.
# File lib/sinatra/base.rb 944 def call(env) 945 dup.call!(env) 946 end
Forward the request to the downstream app – middleware only.
# File lib/sinatra/base.rb 1001 def forward 1002 fail "downstream app not set" unless @app.respond_to? :call 1003 status, headers, body = @app.call env 1004 @response.status = status 1005 @response.body = body 1006 @response.headers.merge! headers 1007 nil 1008 end
Exit the current block, halts any further processing of the request, and returns the specified response.
# File lib/sinatra/base.rb 988 def halt(*response) 989 response = response.first if response.length == 1 990 throw :halt, response 991 end
# File lib/sinatra/base.rb 980 def options 981 warn "Sinatra::Base#options is deprecated and will be removed, " \ 982 "use #settings instead." 983 settings 984 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 996 def pass(&block) 997 throw :pass, block 998 end
Access settings defined with Base.set
.
# File lib/sinatra/base.rb 976 def settings 977 self.class.settings 978 end
Private Instance Methods
Dispatch a request with error handling.
# File lib/sinatra/base.rb 1134 def dispatch! 1135 # Avoid passing frozen string in force_encoding 1136 @params.merge!(@request.params).each do |key, val| 1137 next unless val.respond_to?(:force_encoding) 1138 val = val.dup if val.frozen? 1139 @params[key] = force_encoding(val) 1140 end 1141 1142 invoke do 1143 static! if settings.static? && (request.get? || request.head?) 1144 filter! :before do 1145 @pinned_response = !response['Content-Type'].nil? 1146 end 1147 route! 1148 end 1149 rescue ::Exception => boom 1150 invoke { handle_exception!(boom) } 1151 ensure 1152 begin 1153 filter! :after unless env['sinatra.static_file'] 1154 rescue ::Exception => boom 1155 invoke { handle_exception!(boom) } unless @env['sinatra.error'] 1156 end 1157 end
# File lib/sinatra/base.rb 1215 def dump_errors!(boom) 1216 msg = ["#{Time.now.strftime("%Y-%m-%d %H:%M:%S")} - #{boom.class} - #{boom.message}:", *boom.backtrace].join("\n\t") 1217 @env['rack.errors'].puts(msg) 1218 end
Find an custom error block for the key(s) specified.
# File lib/sinatra/base.rb 1200 def error_block!(key, *block_params) 1201 base = settings 1202 while base.respond_to?(:errors) 1203 next base = base.superclass unless args_array = base.errors[key] 1204 args_array.reverse_each do |args| 1205 first = args == args_array.first 1206 args += [block_params] 1207 resp = process_route(*args) 1208 return resp unless resp.nil? && !first 1209 end 1210 end 1211 return false unless key.respond_to? :superclass and key.superclass < Exception 1212 error_block!(key.superclass, *block_params) 1213 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 1014 def filter!(type, base = settings, &block) 1015 filter!(type, base.superclass, &block) if base.superclass.respond_to?(:filters) 1016 base.filters[type].each do |args| 1017 result = process_route(*args) 1018 block.call(result) if block_given? 1019 end 1020 end
# File lib/sinatra/base.rb 1811 def force_encoding(*args) settings.force_encoding(*args) end
Error handling during requests.
# File lib/sinatra/base.rb 1160 def handle_exception!(boom) 1161 if error_params = @env['sinatra.error.params'] 1162 @params = @params.merge(error_params) 1163 end 1164 @env['sinatra.error'] = boom 1165 1166 if boom.respond_to? :http_status and boom.http_status.between? 400, 599 1167 status(boom.http_status) 1168 elsif settings.use_code? and boom.respond_to? :code and boom.code.between? 400, 599 1169 status(boom.code) 1170 else 1171 status(500) 1172 end 1173 1174 if server_error? 1175 dump_errors! boom if settings.dump_errors? 1176 raise boom if settings.show_exceptions? and settings.show_exceptions != :after_handler 1177 elsif not_found? 1178 headers['X-Cascade'] = 'pass' if settings.x_cascade? 1179 end 1180 1181 if res = error_block!(boom.class, boom) || error_block!(status, boom) 1182 return res 1183 end 1184 1185 if not_found? || bad_request? 1186 if boom.message && boom.message != boom.class.name 1187 body Rack::Utils.escape_html(boom.message) 1188 else 1189 content_type 'text/html' 1190 body '<h1>' + (not_found? ? 'Not Found' : 'Bad Request') + '</h1>' 1191 end 1192 end 1193 1194 return unless server_error? 1195 raise boom if settings.raise_errors? or settings.show_exceptions? 1196 error_block! Exception, boom 1197 end
Run the block with 'throw :halt' support and apply result to the response.
# File lib/sinatra/base.rb 1118 def invoke 1119 res = catch(:halt) { yield } 1120 1121 res = [res] if Integer === res or String === res 1122 if Array === res and Integer === res.first 1123 res = res.dup 1124 status(res.shift) 1125 body(res.pop) 1126 headers(*res) 1127 elsif res.respond_to? :each 1128 body res 1129 end 1130 nil # avoid double setting the same response tuple twice 1131 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 1057 def process_route(pattern, conditions, block = nil, values = []) 1058 route = @request.path_info 1059 route = '/' if route.empty? and not settings.empty_path_info? 1060 route = route[0..-2] if !settings.strict_paths? && route != '/' && route.end_with?('/') 1061 return unless params = pattern.params(route) 1062 1063 params.delete("ignore") # TODO: better params handling, maybe turn it into "smart" object or detect changes 1064 force_encoding(params) 1065 @params = @params.merge(params) if params.any? 1066 1067 regexp_exists = pattern.is_a?(Mustermann::Regular) || (pattern.respond_to?(:patterns) && pattern.patterns.any? {|subpattern| subpattern.is_a?(Mustermann::Regular)} ) 1068 if regexp_exists 1069 captures = pattern.match(route).captures.map { |c| URI_INSTANCE.unescape(c) if c } 1070 values += captures 1071 @params[:captures] = force_encoding(captures) unless captures.nil? || captures.empty? 1072 else 1073 values += params.values.flatten 1074 end 1075 1076 catch(:pass) do 1077 conditions.each { |c| throw :pass if c.bind(self).call == false } 1078 block ? block[self, values] : yield(self, values) 1079 end 1080 rescue 1081 @env['sinatra.error.params'] = @params 1082 raise 1083 ensure 1084 params ||= {} 1085 params.each { |k, _| @params.delete(k) } unless @env['sinatra.error.params'] 1086 end
Run routes defined on the class and all superclasses.
# File lib/sinatra/base.rb 1023 def route!(base = settings, pass_block = nil) 1024 if routes = base.routes[@request.request_method] 1025 routes.each do |pattern, conditions, block| 1026 response.delete_header('Content-Type') unless @pinned_response 1027 1028 returned_pass_block = process_route(pattern, conditions) do |*args| 1029 env['sinatra.route'] = "#{@request.request_method} #{pattern}" 1030 route_eval { block[*args] } 1031 end 1032 1033 # don't wipe out pass_block in superclass 1034 pass_block = returned_pass_block if returned_pass_block 1035 end 1036 end 1037 1038 # Run routes defined in superclass. 1039 if base.superclass.respond_to?(:routes) 1040 return route!(base.superclass, pass_block) 1041 end 1042 1043 route_eval(&pass_block) if pass_block 1044 route_missing 1045 end
Run a route block and throw :halt with the result.
# File lib/sinatra/base.rb 1048 def route_eval 1049 throw :halt, yield 1050 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 1093 def route_missing 1094 if @app 1095 forward 1096 else 1097 raise NotFound, "#{request.request_method} #{request.path_info}" 1098 end 1099 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 1103 def static!(options = {}) 1104 return if (public_dir = settings.public_folder).nil? 1105 path = "#{public_dir}#{URI_INSTANCE.unescape(request.path_info)}" 1106 return unless valid_path?(path) 1107 1108 path = File.expand_path(path) 1109 return unless path.start_with?(File.expand_path(public_dir) + '/') 1110 return unless File.file?(path) 1111 1112 env['sinatra.static_file'] = path 1113 cache_control(*settings.static_cache_control) if settings.static_cache_control? 1114 send_file path, options.merge(:disposition => nil) 1115 end