class Sinatra::Helpers::Stream::Base
Constants
- URI_INSTANCE
Attributes
Public Class Methods
Sinatra::Helpers::Stream::Templates::new
# File lib/sinatra/base.rb 950 def initialize(app = nil, **kwargs) 951 super() 952 @app = app 953 @template_cache = Tilt::Cache.new 954 @pinned_response = nil # whether a before! filter pinned the content-type 955 yield self if block_given? 956 end
Access settings defined with Base.set.
# File lib/sinatra/base.rb 986 def self.settings 987 self 988 end
Private Class Methods
add a filter
# File lib/sinatra/base.rb 1434 def add_filter(type, path = /.*/, **options, &block) 1435 filters[type] << compile!(type, path, block, **options) 1436 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 1429 def after(path = /.*/, **options, &block) 1430 add_filter(:after, path, **options, &block) 1431 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 1422 def before(path = /.*/, **options, &block) 1423 add_filter(:before, path, **options, &block) 1424 end
Creates a Rack::Builder instance with all the middleware set up and the given app as end point.
# File lib/sinatra/base.rb 1570 def build(app) 1571 builder = Rack::Builder.new 1572 setup_default_middleware builder 1573 setup_middleware builder 1574 builder.run app 1575 builder 1576 end
# File lib/sinatra/base.rb 1578 def call(env) 1579 synchronize { prototype.call(env) } 1580 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 1584 def caller_files 1585 cleaned_caller(1).flatten 1586 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 1590 def caller_locations 1591 cleaned_caller 2 1592 end
# File lib/sinatra/base.rb 1255 def callers_to_ignore 1256 CALLERS_TO_IGNORE 1257 end
Like Kernel#caller but excluding certain magic entries
# File lib/sinatra/base.rb 1805 def cleaned_caller(keep = 3) 1806 caller(1). 1807 map! { |line| line.split(/:(?=\d|in )/, 3)[0,keep] }. 1808 reject { |file, *_| callers_to_ignore.any? { |pattern| file =~ pattern } } 1809 end
# File lib/sinatra/base.rb 1717 def compile(path, route_mustermann_opts = {}) 1718 Mustermann.new(path, **mustermann_opts.merge(route_mustermann_opts)) 1719 end
# File lib/sinatra/base.rb 1698 def compile!(verb, path, block, **options) 1699 # Because of self.options.host 1700 host_name(options.delete(:host)) if options.key?(:host) 1701 # Pass Mustermann opts to compile() 1702 route_mustermann_opts = options.key?(:mustermann_opts) ? options.delete(:mustermann_opts) : {}.freeze 1703 1704 options.each_pair { |option, args| send(option, *args) } 1705 1706 pattern = compile(path, route_mustermann_opts) 1707 method_name = "#{verb} #{path}" 1708 unbound_method = generate_method(method_name, &block) 1709 conditions, @conditions = @conditions, [] 1710 wrapper = block.arity != 0 ? 1711 proc { |a, p| unbound_method.bind(a).call(*p) } : 1712 proc { |a, p| unbound_method.bind(a).call } 1713 1714 [ pattern, conditions, wrapper ] 1715 end
Add a route condition. The route is considered non-matching when the block returns false.
# File lib/sinatra/base.rb 1440 def condition(name = "#{caller.first[/`.*'/]} condition", &block) 1441 @conditions << generate_method(name, &block) 1442 end
Set configuration options for Sinatra and/or the app. Allows scoping of settings for certain environments.
# File lib/sinatra/base.rb 1500 def configure(*envs) 1501 yield self if envs.empty? || envs.include?(environment.to_sym) 1502 end
Dynamically defines a method on settings.
# File lib/sinatra/base.rb 1636 def define_singleton(name, content = Proc.new) 1637 singleton_class.class_eval do 1638 undef_method(name) if method_defined? name 1639 String === content ? class_eval("def #{name}() #{content}; end") : define_method(name, &content) 1640 end 1641 end
# File lib/sinatra/base.rb 1469 def delete(path, opts = {}, &bk) route 'DELETE', path, opts, &bk end
# File lib/sinatra/base.rb 1494 def development?; environment == :development end
Same as calling ‘set :option, false` for each of the given options.
# File lib/sinatra/base.rb 1338 def disable(*opts) 1339 opts.each { |key| set(key, false) } 1340 end
Same as calling ‘set :option, true` for each of the given options.
# File lib/sinatra/base.rb 1333 def enable(*opts) 1334 opts.each { |key| set(key, true) } 1335 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 1345 def error(*codes, &block) 1346 args = compile! "ERROR", /.*/, block 1347 codes = codes.flat_map(&method(:Array)) 1348 codes << Exception if codes.empty? 1349 codes << Sinatra::NotFound if codes.include?(404) 1350 codes.each { |c| (@errors[c] ||= []) << args } 1351 end
Extension modules registered on this class and all superclasses.
# File lib/sinatra/base.rb 1278 def extensions 1279 if superclass.respond_to?(:extensions) 1280 (@extensions + superclass.extensions).uniq 1281 else 1282 @extensions 1283 end 1284 end
Force data to specified encoding. It defaults to settings.default_encoding which is UTF-8 by default
# File lib/sinatra/base.rb 1814 def self.force_encoding(data, encoding = default_encoding) 1815 return if data == settings || data.is_a?(Tempfile) 1816 if data.respond_to? :force_encoding 1817 data.force_encoding(encoding).encode! 1818 elsif data.respond_to? :each_value 1819 data.each_value { |v| force_encoding(v, encoding) } 1820 elsif data.respond_to? :each 1821 data.each { |v| force_encoding(v, encoding) } 1822 end 1823 data 1824 end
# File lib/sinatra/base.rb 1691 def generate_method(method_name, &block) 1692 define_method(method_name, &block) 1693 method = instance_method method_name 1694 remove_method method_name 1695 method 1696 end
Defining a ‘GET` handler also automatically defines a `HEAD` handler.
# File lib/sinatra/base.rb 1459 def get(path, opts = {}, &block) 1460 conditions = @conditions.dup 1461 route('GET', path, opts, &block) 1462 1463 @conditions = conditions 1464 route('HEAD', path, opts, &block) 1465 end
# File lib/sinatra/base.rb 1470 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 1478 def helpers(*extensions, &block) 1479 class_eval(&block) if block_given? 1480 include(*extensions) if extensions.any? 1481 end
Condition for matching host name. Parameter might be String or Regexp.
# File lib/sinatra/base.rb 1644 def host_name(pattern) 1645 condition { pattern === request.host } 1646 end
# File lib/sinatra/base.rb 1784 def inherited(subclass) 1785 subclass.reset! 1786 subclass.set :app_file, caller_files.first unless subclass.app_file? 1787 super 1788 end
Load embedded templates from the file; uses the caller’s __FILE__ when no file is specified.
# File lib/sinatra/base.rb 1371 def inline_templates=(file = nil) 1372 file = (file.nil? || file == true) ? (caller_files.first || File.expand_path($0)) : file 1373 1374 begin 1375 io = ::IO.respond_to?(:binread) ? ::IO.binread(file) : ::IO.read(file) 1376 app, data = io.gsub("\r\n", "\n").split(/^__END__$/, 2) 1377 rescue Errno::ENOENT 1378 app, data = nil 1379 end 1380 1381 if data 1382 if app and app =~ /([^\n]*\n)?#[^\n]*coding: *(\S+)/m 1383 encoding = $2 1384 else 1385 encoding = settings.default_encoding 1386 end 1387 lines = app.count("\n") + 1 1388 template = nil 1389 force_encoding data, encoding 1390 data.each_line do |line| 1391 lines += 1 1392 if line =~ /^@@\s*(.*\S)\s*$/ 1393 template = force_encoding(String.new, encoding) 1394 templates[$1.to_sym] = [template, file, lines] 1395 elsif template 1396 template << line 1397 end 1398 end 1399 end 1400 end
# File lib/sinatra/base.rb 1687 def invoke_hook(name, *args) 1688 extensions.each { |e| e.send(name, *args) if e.respond_to?(name) } 1689 end
Define the layout template. The block must return the template source.
# File lib/sinatra/base.rb 1365 def layout(name = :layout, &block) 1366 template name, &block 1367 end
# File lib/sinatra/base.rb 1473 def link(path, opts = {}, &bk) route 'LINK', path, opts, &bk end
Middleware used in this class and all superclasses.
# File lib/sinatra/base.rb 1287 def middleware 1288 if superclass.respond_to?(:middleware) 1289 superclass.middleware + @middleware 1290 else 1291 @middleware 1292 end 1293 end
Lookup or register a mime type in Rack’s mime registry.
# File lib/sinatra/base.rb 1403 def mime_type(type, value = nil) 1404 return type if type.nil? 1405 return type.to_s if type.to_s.include?('/') 1406 type = ".#{type}" unless type.to_s[0] == ?. 1407 return Rack::Mime.mime_type(type, nil) unless value 1408 Rack::Mime::MIME_TYPES[type] = value 1409 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 1414 def mime_types(type) 1415 type = mime_type type 1416 type =~ /^application\/(xml|javascript)$/ ? [type, "text/#$1"] : [type] 1417 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 1562 def new(*args, &bk) 1563 instance = new!(*args, &bk) 1564 Wrapper.new(build(instance).to_app, instance) 1565 end
Sugar for ‘error(404) { … }`
# File lib/sinatra/base.rb 1354 def not_found(&block) 1355 error(404, &block) 1356 end
# File lib/sinatra/base.rb 1471 def options(path, opts = {}, &bk) route 'OPTIONS', path, opts, &bk end
# File lib/sinatra/base.rb 1472 def patch(path, opts = {}, &bk) route 'PATCH', path, opts, &bk end
# File lib/sinatra/base.rb 1468 def post(path, opts = {}, &bk) route 'POST', path, opts, &bk end
# File lib/sinatra/base.rb 1495 def production?; environment == :production end
The prototype instance used to process requests.
# File lib/sinatra/base.rb 1552 def prototype 1553 @prototype ||= new 1554 end
Condition for matching mimetypes. Accepts file extensions.
# File lib/sinatra/base.rb 1663 def provides(*types) 1664 types.map! { |t| mime_types(t) } 1665 types.flatten! 1666 condition do 1667 if type = response['Content-Type'] 1668 types.include? type or types.include? type[/^[^;]+/] 1669 elsif type = request.preferred_type(types) 1670 params = (type.respond_to?(:params) ? type.params : {}) 1671 content_type(type, params) 1672 true 1673 else 1674 false 1675 end 1676 end 1677 end
# File lib/sinatra/base.rb 1444 def public=(value) 1445 warn ":public is no longer used to avoid overloading Module#public, use :public_folder or :public_dir instead" 1446 set(:public_folder, value) 1447 end
# File lib/sinatra/base.rb 1453 def public_dir 1454 public_folder 1455 end
# File lib/sinatra/base.rb 1449 def public_dir=(value) 1450 self.public_folder = value 1451 end
# File lib/sinatra/base.rb 1467 def put(path, opts = {}, &bk) route 'PUT', path, opts, &bk end
Stop the self-hosted server if running.
# File lib/sinatra/base.rb 1512 def quit! 1513 return unless running? 1514 # Use Thin's hard #stop! if available, otherwise just #stop. 1515 running_server.respond_to?(:stop!) ? running_server.stop! : running_server.stop 1516 $stderr.puts "== Sinatra has ended his set (crowd applauds)" unless suppress_messages? 1517 set :running_server, nil 1518 set :handler_name, nil 1519 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 1485 def register(*extensions, &block) 1486 extensions << Module.new(&block) if block_given? 1487 @extensions += extensions 1488 extensions.each do |extension| 1489 extend extension 1490 extension.registered(self) if extension.respond_to?(:registered) 1491 end 1492 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 1261 def reset! 1262 @conditions = [] 1263 @routes = {} 1264 @filters = {:before => [], :after => []} 1265 @errors = {} 1266 @middleware = [] 1267 @prototype = nil 1268 @extensions = [] 1269 1270 if superclass.respond_to?(:templates) 1271 @templates = Hash.new { |hash, key| superclass.templates[key] } 1272 else 1273 @templates = {} 1274 end 1275 end
# File lib/sinatra/base.rb 1679 def route(verb, path, options = {}, &block) 1680 enable :empty_path_info if path == "" and empty_path_info.nil? 1681 signature = compile!(verb, path, block, **options) 1682 (@routes[verb] ||= []) << signature 1683 invoke_hook(:route_added, verb, path, block) 1684 signature 1685 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 1526 def run!(options = {}, &block) 1527 return if running? 1528 set options 1529 handler = Rack::Handler.pick(server) 1530 handler_name = handler.name.gsub(/.*::/, '') 1531 server_settings = settings.respond_to?(:server_settings) ? settings.server_settings : {} 1532 server_settings.merge!(:Port => port, :Host => bind) 1533 1534 begin 1535 start_server(handler, server_settings, handler_name, &block) 1536 rescue Errno::EADDRINUSE 1537 $stderr.puts "== Someone is already performing on port #{port}!" 1538 raise 1539 ensure 1540 quit! 1541 end 1542 end
Check whether the self-hosted server is running or not.
# File lib/sinatra/base.rb 1547 def running? 1548 running_server? 1549 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 1297 def set(option, value = (not_set = true), ignore_setter = false, &block) 1298 raise ArgumentError if block and !not_set 1299 value, not_set = block, false if block 1300 1301 if not_set 1302 raise ArgumentError unless option.respond_to?(:each) 1303 option.each { |k,v| set(k, v) } 1304 return self 1305 end 1306 1307 if respond_to?("#{option}=") and not ignore_setter 1308 return __send__("#{option}=", value) 1309 end 1310 1311 setter = proc { |val| set option, val, true } 1312 getter = proc { value } 1313 1314 case value 1315 when Proc 1316 getter = value 1317 when Symbol, Integer, FalseClass, TrueClass, NilClass 1318 getter = value.inspect 1319 when Hash 1320 setter = proc do |val| 1321 val = value.merge val if Hash === val 1322 set option, val, true 1323 end 1324 end 1325 1326 define_singleton("#{option}=", setter) 1327 define_singleton(option, getter) 1328 define_singleton("#{option}?", "!!#{option}") unless method_defined? "#{option}?" 1329 self 1330 end
# File lib/sinatra/base.rb 1748 def setup_common_logger(builder) 1749 builder.use Sinatra::CommonLogger 1750 end
# File lib/sinatra/base.rb 1752 def setup_custom_logger(builder) 1753 if logging.respond_to? :to_int 1754 builder.use Rack::Logger, logging 1755 else 1756 builder.use Rack::Logger 1757 end 1758 end
# File lib/sinatra/base.rb 1721 def setup_default_middleware(builder) 1722 builder.use ExtendedRack 1723 builder.use ShowExceptions if show_exceptions? 1724 builder.use Rack::MethodOverride if method_override? 1725 builder.use Rack::Head 1726 setup_logging builder 1727 setup_sessions builder 1728 setup_protection builder 1729 end
# File lib/sinatra/base.rb 1735 def setup_logging(builder) 1736 if logging? 1737 setup_common_logger(builder) 1738 setup_custom_logger(builder) 1739 elsif logging == false 1740 setup_null_logger(builder) 1741 end 1742 end
# File lib/sinatra/base.rb 1731 def setup_middleware(builder) 1732 middleware.each { |c,a,b| builder.use(c, *a, &b) } 1733 end
# File lib/sinatra/base.rb 1744 def setup_null_logger(builder) 1745 builder.use Rack::NullLogger 1746 end
# File lib/sinatra/base.rb 1760 def setup_protection(builder) 1761 return unless protection? 1762 options = Hash === protection ? protection.dup : {} 1763 options = { 1764 img_src: "'self' data:", 1765 font_src: "'self'" 1766 }.merge options 1767 1768 protect_session = options.fetch(:session) { sessions? } 1769 options[:without_session] = !protect_session 1770 1771 options[:reaction] ||= :drop_session 1772 1773 builder.use Rack::Protection, options 1774 end
# File lib/sinatra/base.rb 1776 def setup_sessions(builder) 1777 return unless sessions? 1778 options = {} 1779 options[:secret] = session_secret if session_secret? 1780 options.merge! sessions.to_hash if sessions.respond_to? :to_hash 1781 builder.use session_store, options 1782 end
# File lib/sinatra/base.rb 1620 def setup_traps 1621 if traps? 1622 at_exit { quit! } 1623 1624 [:INT, :TERM].each do |signal| 1625 old_handler = trap(signal) do 1626 quit! 1627 old_handler.call if old_handler.respond_to?(:call) 1628 end 1629 end 1630 1631 set :traps, false 1632 end 1633 end
Starts the server by running the Rack Handler.
# File lib/sinatra/base.rb 1597 def start_server(handler, server_settings, handler_name) 1598 # Ensure we initialize middleware before startup, to match standard Rack 1599 # behavior, by ensuring an instance exists: 1600 prototype 1601 # Run the instance we created: 1602 handler.run(self, **server_settings) do |server| 1603 unless suppress_messages? 1604 $stderr.puts "== Sinatra (v#{Sinatra::VERSION}) has taken the stage on #{port} for #{environment} with backup from #{handler_name}" 1605 end 1606 1607 setup_traps 1608 set :running_server, server 1609 set :handler_name, handler_name 1610 server.threaded = settings.threaded if server.respond_to? :threaded= 1611 1612 yield server if block_given? 1613 end 1614 end
# File lib/sinatra/base.rb 1616 def suppress_messages? 1617 handler_name =~ /cgi/i || quiet 1618 end
# File lib/sinatra/base.rb 1791 def synchronize(&block) 1792 if lock? 1793 @@mutex.synchronize(&block) 1794 else 1795 yield 1796 end 1797 end
Define a named template. The block must return the template source.
# File lib/sinatra/base.rb 1359 def template(name, &block) 1360 filename, line = caller_locations.first 1361 templates[name] = [block, filename, line.to_i] 1362 end
# File lib/sinatra/base.rb 1496 def test?; environment == :test end
# File lib/sinatra/base.rb 1474 def unlink(path, opts = {}, &bk) route 'UNLINK', path, opts, &bk end
Use the specified Rack middleware
# File lib/sinatra/base.rb 1505 def use(middleware, *args, &block) 1506 @prototype = nil 1507 @middleware << [middleware, args, block] 1508 end
Condition for matching user agent. Parameter should be Regexp. Will set params.
# File lib/sinatra/base.rb 1650 def user_agent(pattern) 1651 condition do 1652 if request.user_agent.to_s =~ pattern 1653 @params[:agent] = $~[1..-1] 1654 true 1655 else 1656 false 1657 end 1658 end 1659 end
used for deprecation warnings
# File lib/sinatra/base.rb 1800 def warn(message) 1801 super message + "\n\tfrom #{cleaned_caller.first.join(':')}" 1802 end
Public Instance Methods
Rack call interface.
# File lib/sinatra/base.rb 959 def call(env) 960 dup.call!(env) 961 end
Forward the request to the downstream app – middleware only.
# File lib/sinatra/base.rb 1016 def forward 1017 fail "downstream app not set" unless @app.respond_to? :call 1018 status, headers, body = @app.call env 1019 @response.status = status 1020 @response.body = body 1021 @response.headers.merge! headers 1022 nil 1023 end
Exit the current block, halts any further processing of the request, and returns the specified response.
# File lib/sinatra/base.rb 1003 def halt(*response) 1004 response = response.first if response.length == 1 1005 throw :halt, response 1006 end
# File lib/sinatra/base.rb 995 def options 996 warn "Sinatra::Base#options is deprecated and will be removed, " \ 997 "use #settings instead." 998 settings 999 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 1011 def pass(&block) 1012 throw :pass, block 1013 end
Access settings defined with Base.set.
# File lib/sinatra/base.rb 991 def settings 992 self.class.settings 993 end
Private Instance Methods
Dispatch a request with error handling.
# File lib/sinatra/base.rb 1149 def dispatch! 1150 # Avoid passing frozen string in force_encoding 1151 @params.merge!(@request.params).each do |key, val| 1152 next unless val.respond_to?(:force_encoding) 1153 val = val.dup if val.frozen? 1154 @params[key] = force_encoding(val) 1155 end 1156 1157 invoke do 1158 static! if settings.static? && (request.get? || request.head?) 1159 filter! :before do 1160 @pinned_response = !response['Content-Type'].nil? 1161 end 1162 route! 1163 end 1164 rescue ::Exception => boom 1165 invoke { handle_exception!(boom) } 1166 ensure 1167 begin 1168 filter! :after unless env['sinatra.static_file'] 1169 rescue ::Exception => boom 1170 invoke { handle_exception!(boom) } unless @env['sinatra.error'] 1171 end 1172 end
# File lib/sinatra/base.rb 1230 def dump_errors!(boom) 1231 msg = ["#{Time.now.strftime("%Y-%m-%d %H:%M:%S")} - #{boom.class} - #{boom.message}:", *boom.backtrace].join("\n\t") 1232 @env['rack.errors'].puts(msg) 1233 end
Find an custom error block for the key(s) specified.
# File lib/sinatra/base.rb 1215 def error_block!(key, *block_params) 1216 base = settings 1217 while base.respond_to?(:errors) 1218 next base = base.superclass unless args_array = base.errors[key] 1219 args_array.reverse_each do |args| 1220 first = args == args_array.first 1221 args += [block_params] 1222 resp = process_route(*args) 1223 return resp unless resp.nil? && !first 1224 end 1225 end 1226 return false unless key.respond_to? :superclass and key.superclass < Exception 1227 error_block!(key.superclass, *block_params) 1228 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 1029 def filter!(type, base = settings, &block) 1030 filter!(type, base.superclass, &block) if base.superclass.respond_to?(:filters) 1031 base.filters[type].each do |args| 1032 result = process_route(*args) 1033 block.call(result) if block_given? 1034 end 1035 end
# File lib/sinatra/base.rb 1826 def force_encoding(*args) settings.force_encoding(*args) end
Error handling during requests.
# File lib/sinatra/base.rb 1175 def handle_exception!(boom) 1176 if error_params = @env['sinatra.error.params'] 1177 @params = @params.merge(error_params) 1178 end 1179 @env['sinatra.error'] = boom 1180 1181 if boom.respond_to? :http_status and boom.http_status.between? 400, 599 1182 status(boom.http_status) 1183 elsif settings.use_code? and boom.respond_to? :code and boom.code.between? 400, 599 1184 status(boom.code) 1185 else 1186 status(500) 1187 end 1188 1189 if server_error? 1190 dump_errors! boom if settings.dump_errors? 1191 raise boom if settings.show_exceptions? and settings.show_exceptions != :after_handler 1192 elsif not_found? 1193 headers['X-Cascade'] = 'pass' if settings.x_cascade? 1194 end 1195 1196 if res = error_block!(boom.class, boom) || error_block!(status, boom) 1197 return res 1198 end 1199 1200 if not_found? || bad_request? 1201 if boom.message && boom.message != boom.class.name 1202 body Rack::Utils.escape_html(boom.message) 1203 else 1204 content_type 'text/html' 1205 body '<h1>' + (not_found? ? 'Not Found' : 'Bad Request') + '</h1>' 1206 end 1207 end 1208 1209 return unless server_error? 1210 raise boom if settings.raise_errors? or settings.show_exceptions? 1211 error_block! Exception, boom 1212 end
Run the block with ‘throw :halt’ support and apply result to the response.
# File lib/sinatra/base.rb 1133 def invoke 1134 res = catch(:halt) { yield } 1135 1136 res = [res] if Integer === res or String === res 1137 if Array === res and Integer === res.first 1138 res = res.dup 1139 status(res.shift) 1140 body(res.pop) 1141 headers(*res) 1142 elsif res.respond_to? :each 1143 body res 1144 end 1145 nil # avoid double setting the same response tuple twice 1146 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 1072 def process_route(pattern, conditions, block = nil, values = []) 1073 route = @request.path_info 1074 route = '/' if route.empty? and not settings.empty_path_info? 1075 route = route[0..-2] if !settings.strict_paths? && route != '/' && route.end_with?('/') 1076 return unless params = pattern.params(route) 1077 1078 params.delete("ignore") # TODO: better params handling, maybe turn it into "smart" object or detect changes 1079 force_encoding(params) 1080 @params = @params.merge(params) if params.any? 1081 1082 regexp_exists = pattern.is_a?(Mustermann::Regular) || (pattern.respond_to?(:patterns) && pattern.patterns.any? {|subpattern| subpattern.is_a?(Mustermann::Regular)} ) 1083 if regexp_exists 1084 captures = pattern.match(route).captures.map { |c| URI_INSTANCE.unescape(c) if c } 1085 values += captures 1086 @params[:captures] = force_encoding(captures) unless captures.nil? || captures.empty? 1087 else 1088 values += params.values.flatten 1089 end 1090 1091 catch(:pass) do 1092 conditions.each { |c| throw :pass if c.bind(self).call == false } 1093 block ? block[self, values] : yield(self, values) 1094 end 1095 rescue 1096 @env['sinatra.error.params'] = @params 1097 raise 1098 ensure 1099 params ||= {} 1100 params.each { |k, _| @params.delete(k) } unless @env['sinatra.error.params'] 1101 end
Run routes defined on the class and all superclasses.
# File lib/sinatra/base.rb 1038 def route!(base = settings, pass_block = nil) 1039 if routes = base.routes[@request.request_method] 1040 routes.each do |pattern, conditions, block| 1041 response.delete_header('Content-Type') unless @pinned_response 1042 1043 returned_pass_block = process_route(pattern, conditions) do |*args| 1044 env['sinatra.route'] = "#{@request.request_method} #{pattern}" 1045 route_eval { block[*args] } 1046 end 1047 1048 # don't wipe out pass_block in superclass 1049 pass_block = returned_pass_block if returned_pass_block 1050 end 1051 end 1052 1053 # Run routes defined in superclass. 1054 if base.superclass.respond_to?(:routes) 1055 return route!(base.superclass, pass_block) 1056 end 1057 1058 route_eval(&pass_block) if pass_block 1059 route_missing 1060 end
Run a route block and throw :halt with the result.
# File lib/sinatra/base.rb 1063 def route_eval 1064 throw :halt, yield 1065 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 1108 def route_missing 1109 if @app 1110 forward 1111 else 1112 raise NotFound, "#{request.request_method} #{request.path_info}" 1113 end 1114 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 1118 def static!(options = {}) 1119 return if (public_dir = settings.public_folder).nil? 1120 path = "#{public_dir}#{URI_INSTANCE.unescape(request.path_info)}" 1121 return unless valid_path?(path) 1122 1123 path = File.expand_path(path) 1124 return unless path.start_with?(File.expand_path(public_dir) + '/') 1125 return unless File.file?(path) 1126 1127 env['sinatra.static_file'] = path 1128 cache_control(*settings.static_cache_control) if settings.static_cache_control? 1129 send_file path, options.merge(:disposition => nil) 1130 end