class Sinatra::Helpers::Stream::Base

Base class for all Sinatra applications and middleware.

Constants

URI_INSTANCE

Attributes

errors[R]
filters[R]
on_start_callback[R]
on_stop_callback[R]
routes[R]
templates[R]
app[RW]
env[RW]
params[RW]
request[RW]
response[RW]
template_cache[R]

Public Class Methods

new(app = nil, **_kwargs) { |self| ... } click to toggle source
    # File lib/sinatra/base.rb
974 def initialize(app = nil, **_kwargs)
975   super()
976   @app = app
977   @template_cache = TemplateCache.new
978   @pinned_response = nil # whether a before! filter pinned the content-type
979   yield self if block_given?
980 end
Also aliased as: new!
settings() click to toggle source

Access settings defined with Base.set.

     # File lib/sinatra/base.rb
1010 def self.settings
1011   self
1012 end

Private Class Methods

add_filter(type, path = /.*/, **options, &block) click to toggle source

add a filter

     # File lib/sinatra/base.rb
1481 def add_filter(type, path = /.*/, **options, &block)
1482   filters[type] << compile!(type, path, block, **options)
1483 end
after(path = /.*/, **options, &block) click to toggle source

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
1476 def after(path = /.*/, **options, &block)
1477   add_filter(:after, path, **options, &block)
1478 end
agent(pattern)
Alias for: user_agent
before(path = /.*/, **options, &block) click to toggle source

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
1469 def before(path = /.*/, **options, &block)
1470   add_filter(:before, path, **options, &block)
1471 end
build(app) click to toggle source

Creates a Rack::Builder instance with all the middleware set up and the given app as end point.

     # File lib/sinatra/base.rb
1636 def build(app)
1637   builder = Rack::Builder.new
1638   setup_default_middleware builder
1639   setup_middleware builder
1640   builder.run app
1641   builder
1642 end
call(env) click to toggle source
     # File lib/sinatra/base.rb
1644 def call(env)
1645   synchronize { prototype.call(env) }
1646 end
caller_files() click to toggle source

Like Kernel#caller but excluding certain magic entries and without line / method information; the resulting array contains filenames only.

     # File lib/sinatra/base.rb
1650 def caller_files
1651   cleaned_caller(1).flatten
1652 end
callers_to_ignore() click to toggle source
     # File lib/sinatra/base.rb
1294 def callers_to_ignore
1295   CALLERS_TO_IGNORE
1296 end
cleaned_caller(keep = 3) click to toggle source

Like Kernel#caller but excluding certain magic entries

     # File lib/sinatra/base.rb
1871 def cleaned_caller(keep = 3)
1872   caller(1)
1873     .map! { |line| line.split(/:(?=\d|in )/, 3)[0, keep] }
1874     .reject { |file, *_| callers_to_ignore.any? { |pattern| file =~ pattern } }
1875 end
compile(path, route_mustermann_opts = {}) click to toggle source
     # File lib/sinatra/base.rb
1781 def compile(path, route_mustermann_opts = {})
1782   Mustermann.new(path, **mustermann_opts.merge(route_mustermann_opts))
1783 end
compile!(verb, path, block, **options) click to toggle source
     # File lib/sinatra/base.rb
1761 def compile!(verb, path, block, **options)
1762   # Because of self.options.host
1763   host_name(options.delete(:host)) if options.key?(:host)
1764   # Pass Mustermann opts to compile()
1765   route_mustermann_opts = options.key?(:mustermann_opts) ? options.delete(:mustermann_opts) : {}.freeze
1766 
1767   options.each_pair { |option, args| send(option, *args) }
1768 
1769   pattern                 = compile(path, route_mustermann_opts)
1770   method_name             = "#{verb} #{path}"
1771   unbound_method          = generate_method(method_name, &block)
1772   conditions = @conditions
1773   @conditions = []
1774   wrapper = block.arity.zero? ?
1775     proc { |a, _p| unbound_method.bind(a).call } :
1776     proc { |a, p| unbound_method.bind(a).call(*p) }
1777 
1778   [pattern, conditions, wrapper]
1779 end
condition(name = " click to toggle source

Add a route condition. The route is considered non-matching when the block returns false.

     # File lib/sinatra/base.rb
1495 def condition(name = "#{caller.first[/`.*'/]} condition", &block)
1496   @conditions << generate_method(name, &block)
1497 end
configure(*envs) { |self| ... } click to toggle source

Set configuration options for Sinatra and/or the app. Allows scoping of settings for certain environments.

     # File lib/sinatra/base.rb
1562 def configure(*envs)
1563   yield self if envs.empty? || envs.include?(environment.to_sym)
1564 end
define_singleton(name, content = Proc.new) click to toggle source

Dynamically defines a method on settings.

     # File lib/sinatra/base.rb
1696 def define_singleton(name, content = Proc.new)
1697   singleton_class.class_eval do
1698     undef_method(name) if method_defined? name
1699     String === content ? class_eval("def #{name}() #{content}; end") : define_method(name, &content)
1700   end
1701 end
delete(path, opts = {}, &block) click to toggle source
     # File lib/sinatra/base.rb
1526 def delete(path, opts = {}, &block)  route 'DELETE',  path, opts, &block end
development?() click to toggle source
     # File lib/sinatra/base.rb
1556 def development?; environment == :development end
disable(*opts) click to toggle source

Same as calling ‘set :option, false` for each of the given options.

     # File lib/sinatra/base.rb
1382 def disable(*opts)
1383   opts.each { |key| set(key, false) }
1384 end
enable(*opts) click to toggle source

Same as calling ‘set :option, true` for each of the given options.

     # File lib/sinatra/base.rb
1377 def enable(*opts)
1378   opts.each { |key| set(key, true) }
1379 end
error(*codes, &block) click to toggle source

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
1389 def error(*codes, &block)
1390   args  = compile! 'ERROR', /.*/, block
1391   codes = codes.flat_map(&method(:Array))
1392   codes << Exception if codes.empty?
1393   codes << Sinatra::NotFound if codes.include?(404)
1394   codes.each { |c| (@errors[c] ||= []) << args }
1395 end
extensions() click to toggle source

Extension modules registered on this class and all superclasses.

     # File lib/sinatra/base.rb
1317 def extensions
1318   if superclass.respond_to?(:extensions)
1319     (@extensions + superclass.extensions).uniq
1320   else
1321     @extensions
1322   end
1323 end
force_encoding(data, encoding = default_encoding) click to toggle source

Force data to specified encoding. It defaults to settings.default_encoding which is UTF-8 by default

     # File lib/sinatra/base.rb
1880 def self.force_encoding(data, encoding = default_encoding)
1881   return if data == settings || data.is_a?(Tempfile)
1882 
1883   if data.respond_to? :force_encoding
1884     data.force_encoding(encoding).encode!
1885   elsif data.respond_to? :each_value
1886     data.each_value { |v| force_encoding(v, encoding) }
1887   elsif data.respond_to? :each
1888     data.each { |v| force_encoding(v, encoding) }
1889   end
1890   data
1891 end
generate_method(method_name, &block) click to toggle source
     # File lib/sinatra/base.rb
1754 def generate_method(method_name, &block)
1755   define_method(method_name, &block)
1756   method = instance_method method_name
1757   remove_method method_name
1758   method
1759 end
get(path, opts = {}, &block) click to toggle source

Defining a ‘GET` handler also automatically defines a `HEAD` handler.

     # File lib/sinatra/base.rb
1514 def get(path, opts = {}, &block)
1515   conditions = @conditions.dup
1516   route('GET', path, opts, &block)
1517 
1518   @conditions = conditions
1519   route('HEAD', path, opts, &block)
1520 end
head(path, opts = {}, &block) click to toggle source
     # File lib/sinatra/base.rb
1528 def head(path, opts = {}, &block)    route 'HEAD',    path, opts, &block end
helpers(*extensions, &block) click to toggle source

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
1540 def helpers(*extensions, &block)
1541   class_eval(&block)   if block_given?
1542   include(*extensions) if extensions.any?
1543 end
host_name(pattern) click to toggle source

Condition for matching host name. Parameter might be String or Regexp.

     # File lib/sinatra/base.rb
1704 def host_name(pattern)
1705   condition { pattern === request.host }
1706 end
inherited(subclass) click to toggle source
Calls superclass method
     # File lib/sinatra/base.rb
1850 def inherited(subclass)
1851   subclass.reset!
1852   subclass.set :app_file, caller_files.first unless subclass.app_file?
1853   super
1854 end
inline_templates=(file = nil) click to toggle source

Load embedded templates from the file; uses the caller’s __FILE__ when no file is specified.

     # File lib/sinatra/base.rb
1415 def inline_templates=(file = nil)
1416   file = (caller_files.first || File.expand_path($0)) if file.nil? || file == true
1417 
1418   begin
1419     io = ::IO.respond_to?(:binread) ? ::IO.binread(file) : ::IO.read(file)
1420     app, data = io.gsub("\r\n", "\n").split(/^__END__$/, 2)
1421   rescue Errno::ENOENT
1422     app, data = nil
1423   end
1424 
1425   return unless data
1426 
1427   encoding = if app && app =~ /([^\n]*\n)?#[^\n]*coding: *(\S+)/m
1428                $2
1429              else
1430                settings.default_encoding
1431              end
1432 
1433   lines = app.count("\n") + 1
1434   template = nil
1435   force_encoding data, encoding
1436   data.each_line do |line|
1437     lines += 1
1438     if line =~ /^@@\s*(.*\S)\s*$/
1439       template = force_encoding(String.new, encoding)
1440       templates[$1.to_sym] = [template, file, lines]
1441     elsif template
1442       template << line
1443     end
1444   end
1445 end
invoke_hook(name, *args) click to toggle source
     # File lib/sinatra/base.rb
1750 def invoke_hook(name, *args)
1751   extensions.each { |e| e.send(name, *args) if e.respond_to?(name) }
1752 end
layout(name = :layout, &block) click to toggle source

Define the layout template. The block must return the template source.

     # File lib/sinatra/base.rb
1409 def layout(name = :layout, &block)
1410   template name, &block
1411 end
middleware() click to toggle source

Middleware used in this class and all superclasses.

     # File lib/sinatra/base.rb
1326 def middleware
1327   if superclass.respond_to?(:middleware)
1328     superclass.middleware + @middleware
1329   else
1330     @middleware
1331   end
1332 end
mime_type(type, value = nil) click to toggle source

Lookup or register a mime type in Rack’s mime registry.

     # File lib/sinatra/base.rb
1448 def mime_type(type, value = nil)
1449   return type      if type.nil?
1450   return type.to_s if type.to_s.include?('/')
1451 
1452   type = ".#{type}" unless type.to_s[0] == '.'
1453   return Rack::Mime.mime_type(type, nil) unless value
1454 
1455   Rack::Mime::MIME_TYPES[type] = value
1456 end
mime_types(type) click to toggle source

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
1461 def mime_types(type)
1462   type = mime_type type
1463   type =~ %r{^application/(xml|javascript)$} ? [type, "text/#{$1}"] : [type]
1464 end
new(*args, &block) click to toggle source

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
1628 def new(*args, &block)
1629   instance = new!(*args, &block)
1630   Wrapper.new(build(instance).to_app, instance)
1631 end
new!(app = nil, **_kwargs)

Create a new instance without middleware in front of it.

Alias for: new
not_found(&block) click to toggle source

Sugar for ‘error(404) { … }`

     # File lib/sinatra/base.rb
1398 def not_found(&block)
1399   error(404, &block)
1400 end
on_start(&on_start_callback) click to toggle source
     # File lib/sinatra/base.rb
1485 def on_start(&on_start_callback)
1486   @on_start_callback = on_start_callback
1487 end
on_stop(&on_stop_callback) click to toggle source
     # File lib/sinatra/base.rb
1489 def on_stop(&on_stop_callback)
1490   @on_stop_callback = on_stop_callback
1491 end
options(path, opts = {}, &block) click to toggle source
     # File lib/sinatra/base.rb
1530 def options(path, opts = {}, &block) route 'OPTIONS', path, opts, &block end
patch(path, opts = {}, &block) click to toggle source
     # File lib/sinatra/base.rb
1532 def patch(path, opts = {}, &block)   route 'PATCH',   path, opts, &block end
post(path, opts = {}, &block) click to toggle source
     # File lib/sinatra/base.rb
1524 def post(path, opts = {}, &block)    route 'POST',    path, opts, &block end
production?() click to toggle source
     # File lib/sinatra/base.rb
1557 def production?;  environment == :production  end
prototype() click to toggle source

The prototype instance used to process requests.

     # File lib/sinatra/base.rb
1618 def prototype
1619   @prototype ||= new
1620 end
provides(*types) click to toggle source

Condition for matching mimetypes. Accepts file extensions.

     # File lib/sinatra/base.rb
1723 def provides(*types)
1724   types.map! { |t| mime_types(t) }
1725   types.flatten!
1726   condition do
1727     response_content_type = response['Content-Type']
1728     preferred_type = request.preferred_type(types)
1729 
1730     if response_content_type
1731       types.include?(response_content_type) || types.include?(response_content_type[/^[^;]+/])
1732     elsif preferred_type
1733       params = (preferred_type.respond_to?(:params) ? preferred_type.params : {})
1734       content_type(preferred_type, params)
1735       true
1736     else
1737       false
1738     end
1739   end
1740 end
public=(value) click to toggle source
     # File lib/sinatra/base.rb
1499 def public=(value)
1500   warn_for_deprecation ':public is no longer used to avoid overloading Module#public, use :public_folder or :public_dir instead'
1501   set(:public_folder, value)
1502 end
public_dir() click to toggle source
     # File lib/sinatra/base.rb
1508 def public_dir
1509   public_folder
1510 end
public_dir=(value) click to toggle source
     # File lib/sinatra/base.rb
1504 def public_dir=(value)
1505   self.public_folder = value
1506 end
put(path, opts = {}, &block) click to toggle source
     # File lib/sinatra/base.rb
1522 def put(path, opts = {}, &block)     route 'PUT',     path, opts, &block end
quit!() click to toggle source

Stop the self-hosted server if running.

     # File lib/sinatra/base.rb
1574 def quit!
1575   return unless running?
1576 
1577   # Use Thin's hard #stop! if available, otherwise just #stop.
1578   running_server.respond_to?(:stop!) ? running_server.stop! : running_server.stop
1579   warn '== Sinatra has ended his set (crowd applauds)' unless suppress_messages?
1580   set :running_server, nil
1581   set :handler_name, nil
1582 
1583   on_stop_callback.call unless on_stop_callback.nil?
1584 end
Also aliased as: stop!
register(*extensions, &block) click to toggle source

Register an extension. Alternatively take a block from which an extension will be created and registered on the fly.

     # File lib/sinatra/base.rb
1547 def register(*extensions, &block)
1548   extensions << Module.new(&block) if block_given?
1549   @extensions += extensions
1550   extensions.each do |extension|
1551     extend extension
1552     extension.registered(self) if extension.respond_to?(:registered)
1553   end
1554 end
reset!() click to toggle source

Removes all routes, filters, middleware and extension hooks from the current class (not routes/filters/… defined by its superclass).

     # File lib/sinatra/base.rb
1300 def reset!
1301   @conditions     = []
1302   @routes         = {}
1303   @filters        = { before: [], after: [] }
1304   @errors         = {}
1305   @middleware     = []
1306   @prototype      = nil
1307   @extensions     = []
1308 
1309   @templates = if superclass.respond_to?(:templates)
1310                  Hash.new { |_hash, key| superclass.templates[key] }
1311                else
1312                  {}
1313                end
1314 end
route(verb, path, options = {}, &block) click to toggle source
     # File lib/sinatra/base.rb
1742 def route(verb, path, options = {}, &block)
1743   enable :empty_path_info if path == '' && empty_path_info.nil?
1744   signature = compile!(verb, path, block, **options)
1745   (@routes[verb] ||= []) << signature
1746   invoke_hook(:route_added, verb, path, block)
1747   signature
1748 end
run!(options = {}, &block) click to toggle source

Run the Sinatra app as a self-hosted server using Puma, Falcon, 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
1591 def run!(options = {}, &block)
1592   return if running?
1593 
1594   set options
1595   handler         = Rack::Handler.pick(server)
1596   handler_name    = handler.name.gsub(/.*::/, '')
1597   server_settings = settings.respond_to?(:server_settings) ? settings.server_settings : {}
1598   server_settings.merge!(Port: port, Host: bind)
1599 
1600   begin
1601     start_server(handler, server_settings, handler_name, &block)
1602   rescue Errno::EADDRINUSE
1603     warn "== Someone is already performing on port #{port}!"
1604     raise
1605   ensure
1606     quit!
1607   end
1608 end
Also aliased as: start!
running?() click to toggle source

Check whether the self-hosted server is running or not.

     # File lib/sinatra/base.rb
1613 def running?
1614   running_server?
1615 end
set(option, value = (not_set = true), ignore_setter = false, &block) click to toggle source

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
1336 def set(option, value = (not_set = true), ignore_setter = false, &block)
1337   raise ArgumentError if block && !not_set
1338 
1339   if block
1340     value = block
1341     not_set = false
1342   end
1343 
1344   if not_set
1345     raise ArgumentError unless option.respond_to?(:each)
1346 
1347     option.each { |k, v| set(k, v) }
1348     return self
1349   end
1350 
1351   if respond_to?("#{option}=") && !ignore_setter
1352     return __send__("#{option}=", value)
1353   end
1354 
1355   setter = proc { |val| set option, val, true }
1356   getter = proc { value }
1357 
1358   case value
1359   when Proc
1360     getter = value
1361   when Symbol, Integer, FalseClass, TrueClass, NilClass
1362     getter = value.inspect
1363   when Hash
1364     setter = proc do |val|
1365       val = value.merge val if Hash === val
1366       set option, val, true
1367     end
1368   end
1369 
1370   define_singleton("#{option}=", setter)
1371   define_singleton(option, getter)
1372   define_singleton("#{option}?", "!!#{option}") unless method_defined? "#{option}?"
1373   self
1374 end
setup_common_logger(builder) click to toggle source
     # File lib/sinatra/base.rb
1812 def setup_common_logger(builder)
1813   builder.use Sinatra::CommonLogger
1814 end
setup_custom_logger(builder) click to toggle source
     # File lib/sinatra/base.rb
1816 def setup_custom_logger(builder)
1817   if logging.respond_to? :to_int
1818     builder.use Rack::Logger, logging
1819   else
1820     builder.use Rack::Logger
1821   end
1822 end
setup_default_middleware(builder) click to toggle source
     # File lib/sinatra/base.rb
1785 def setup_default_middleware(builder)
1786   builder.use ExtendedRack
1787   builder.use ShowExceptions       if show_exceptions?
1788   builder.use Rack::MethodOverride if method_override?
1789   builder.use Rack::Head
1790   setup_logging    builder
1791   setup_sessions   builder
1792   setup_protection builder
1793 end
setup_logging(builder) click to toggle source
     # File lib/sinatra/base.rb
1799 def setup_logging(builder)
1800   if logging?
1801     setup_common_logger(builder)
1802     setup_custom_logger(builder)
1803   elsif logging == false
1804     setup_null_logger(builder)
1805   end
1806 end
setup_middleware(builder) click to toggle source
     # File lib/sinatra/base.rb
1795 def setup_middleware(builder)
1796   middleware.each { |c, a, b| builder.use(c, *a, &b) }
1797 end
setup_null_logger(builder) click to toggle source
     # File lib/sinatra/base.rb
1808 def setup_null_logger(builder)
1809   builder.use Rack::NullLogger
1810 end
setup_protection(builder) click to toggle source
     # File lib/sinatra/base.rb
1824 def setup_protection(builder)
1825   return unless protection?
1826 
1827   options = Hash === protection ? protection.dup : {}
1828   options = {
1829     img_src: "'self' data:",
1830     font_src: "'self'"
1831   }.merge options
1832 
1833   protect_session = options.fetch(:session) { sessions? }
1834   options[:without_session] = !protect_session
1835 
1836   options[:reaction] ||= :drop_session
1837 
1838   builder.use Rack::Protection, options
1839 end
setup_sessions(builder) click to toggle source
     # File lib/sinatra/base.rb
1841 def setup_sessions(builder)
1842   return unless sessions?
1843 
1844   options = {}
1845   options[:secret] = session_secret if session_secret?
1846   options.merge! sessions.to_hash if sessions.respond_to? :to_hash
1847   builder.use session_store, options
1848 end
setup_traps() click to toggle source
     # File lib/sinatra/base.rb
1680 def setup_traps
1681   return unless traps?
1682 
1683   at_exit { quit! }
1684 
1685   %i[INT TERM].each do |signal|
1686     old_handler = trap(signal) do
1687       quit!
1688       old_handler.call if old_handler.respond_to?(:call)
1689     end
1690   end
1691 
1692   set :traps, false
1693 end
start!(options = {}, &block)
Alias for: run!
start_server(handler, server_settings, handler_name) { |server| ... } click to toggle source

Starts the server by running the Rack Handler.

     # File lib/sinatra/base.rb
1657 def start_server(handler, server_settings, handler_name)
1658   # Ensure we initialize middleware before startup, to match standard Rack
1659   # behavior, by ensuring an instance exists:
1660   prototype
1661   # Run the instance we created:
1662   handler.run(self, **server_settings) do |server|
1663     unless suppress_messages?
1664       warn "== Sinatra (v#{Sinatra::VERSION}) has taken the stage on #{port} for #{environment} with backup from #{handler_name}"
1665     end
1666 
1667     setup_traps
1668     set :running_server, server
1669     set :handler_name,   handler_name
1670     server.threaded = settings.threaded if server.respond_to? :threaded=
1671     on_start_callback.call unless on_start_callback.nil?
1672     yield server if block_given?
1673   end
1674 end
stop!()
Alias for: quit!
suppress_messages?() click to toggle source
     # File lib/sinatra/base.rb
1676 def suppress_messages?
1677   handler_name =~ /cgi/i || quiet
1678 end
synchronize() { || ... } click to toggle source
     # File lib/sinatra/base.rb
1857 def synchronize(&block)
1858   if lock?
1859     @@mutex.synchronize(&block)
1860   else
1861     yield
1862   end
1863 end
template(name, &block) click to toggle source

Define a named template. The block must return the template source.

     # File lib/sinatra/base.rb
1403 def template(name, &block)
1404   filename, line = caller_locations.first
1405   templates[name] = [block, filename, line.to_i]
1406 end
test?() click to toggle source
     # File lib/sinatra/base.rb
1558 def test?;        environment == :test        end
use(middleware, *args, &block) click to toggle source

Use the specified Rack middleware

     # File lib/sinatra/base.rb
1567 def use(middleware, *args, &block)
1568   @prototype = nil
1569   @middleware << [middleware, args, block]
1570 end
user_agent(pattern) click to toggle source

Condition for matching user agent. Parameter should be Regexp. Will set params.

     # File lib/sinatra/base.rb
1710 def user_agent(pattern)
1711   condition do
1712     if request.user_agent.to_s =~ pattern
1713       @params[:agent] = $~[1..-1]
1714       true
1715     else
1716       false
1717     end
1718   end
1719 end
Also aliased as: agent
warn_for_deprecation(message) click to toggle source

used for deprecation warnings

     # File lib/sinatra/base.rb
1866 def warn_for_deprecation(message)
1867   warn message + "\n\tfrom #{cleaned_caller.first.join(':')}"
1868 end

Public Instance Methods

call(env) click to toggle source

Rack call interface.

    # File lib/sinatra/base.rb
983 def call(env)
984   dup.call!(env)
985 end
forward() click to toggle source

Forward the request to the downstream app – middleware only.

     # File lib/sinatra/base.rb
1034 def forward
1035   raise 'downstream app not set' unless @app.respond_to? :call
1036 
1037   status, headers, body = @app.call env
1038   @response.status = status
1039   @response.body = body
1040   @response.headers.merge! headers
1041   nil
1042 end
halt(*response) click to toggle source

Exit the current block, halts any further processing of the request, and returns the specified response.

     # File lib/sinatra/base.rb
1021 def halt(*response)
1022   response = response.first if response.length == 1
1023   throw :halt, response
1024 end
pass(&block) click to toggle source

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
1029 def pass(&block)
1030   throw :pass, block
1031 end
settings() click to toggle source

Access settings defined with Base.set.

     # File lib/sinatra/base.rb
1015 def settings
1016   self.class.settings
1017 end

Private Instance Methods

dispatch!() click to toggle source

Dispatch a request with error handling.

     # File lib/sinatra/base.rb
1170 def dispatch!
1171   # Avoid passing frozen string in force_encoding
1172   @params.merge!(@request.params).each do |key, val|
1173     next unless val.respond_to?(:force_encoding)
1174 
1175     val = val.dup if val.frozen?
1176     @params[key] = force_encoding(val)
1177   end
1178 
1179   invoke do
1180     static! if settings.static? && (request.get? || request.head?)
1181     filter! :before do
1182       @pinned_response = !response['Content-Type'].nil?
1183     end
1184     route!
1185   end
1186 rescue ::Exception => e
1187   invoke { handle_exception!(e) }
1188 ensure
1189   begin
1190     filter! :after unless env['sinatra.static_file']
1191   rescue ::Exception => e
1192     invoke { handle_exception!(e) } unless @env['sinatra.error']
1193   end
1194 end
dump_errors!(boom) click to toggle source
     # File lib/sinatra/base.rb
1262 def dump_errors!(boom)
1263   if boom.respond_to?(:detailed_message)
1264     msg = boom.detailed_message(highlight: false)
1265     if msg =~ /\A(.*?)(?: \(#{ Regexp.quote(boom.class.to_s) }\))?\n/
1266       msg = $1
1267       additional_msg = $'.lines(chomp: true)
1268     else
1269       additional_msg = []
1270     end
1271   else
1272     msg = boom.message
1273     additional_msg = []
1274   end
1275   msg = ["#{Time.now.strftime('%Y-%m-%d %H:%M:%S')} - #{boom.class} - #{msg}:", *additional_msg, *boom.backtrace].join("\n\t")
1276   @env['rack.errors'].puts(msg)
1277 end
error_block!(key, *block_params) click to toggle source

Find an custom error block for the key(s) specified.

     # File lib/sinatra/base.rb
1243 def error_block!(key, *block_params)
1244   base = settings
1245   while base.respond_to?(:errors)
1246     args_array = base.errors[key]
1247 
1248     next base = base.superclass unless args_array
1249 
1250     args_array.reverse_each do |args|
1251       first = args == args_array.first
1252       args += [block_params]
1253       resp = process_route(*args)
1254       return resp unless resp.nil? && !first
1255     end
1256   end
1257   return false unless key.respond_to?(:superclass) && (key.superclass < Exception)
1258 
1259   error_block!(key.superclass, *block_params)
1260 end
filter!(type, base = settings, &block) click to toggle source

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
1048 def filter!(type, base = settings, &block)
1049   filter!(type, base.superclass, &block) if base.superclass.respond_to?(:filters)
1050   base.filters[type].each do |args|
1051     result = process_route(*args)
1052     block.call(result) if block_given?
1053   end
1054 end
force_encoding(*args) click to toggle source
     # File lib/sinatra/base.rb
1893 def force_encoding(*args)
1894   settings.force_encoding(*args)
1895 end
handle_exception!(boom) click to toggle source

Error handling during requests.

     # File lib/sinatra/base.rb
1197 def handle_exception!(boom)
1198   error_params = @env['sinatra.error.params']
1199 
1200   @params = @params.merge(error_params) if error_params
1201 
1202   @env['sinatra.error'] = boom
1203 
1204   http_status = if boom.is_a? Sinatra::Error
1205                   if boom.respond_to? :http_status
1206                     boom.http_status
1207                   elsif settings.use_code? && boom.respond_to?(:code)
1208                     boom.code
1209                   end
1210                 end
1211 
1212   http_status = 500 unless http_status&.between?(400, 599)
1213   status(http_status)
1214 
1215   if server_error?
1216     dump_errors! boom if settings.dump_errors?
1217     raise boom if settings.show_exceptions? && (settings.show_exceptions != :after_handler)
1218   elsif not_found?
1219     headers['X-Cascade'] = 'pass' if settings.x_cascade?
1220   end
1221 
1222   if (res = error_block!(boom.class, boom) || error_block!(status, boom))
1223     return res
1224   end
1225 
1226   if not_found? || bad_request?
1227     if boom.message && boom.message != boom.class.name
1228       body Rack::Utils.escape_html(boom.message)
1229     else
1230       content_type 'text/html'
1231       body "<h1>#{not_found? ? 'Not Found' : 'Bad Request'}</h1>"
1232     end
1233   end
1234 
1235   return unless server_error?
1236 
1237   raise boom if settings.raise_errors? || settings.show_exceptions?
1238 
1239   error_block! Exception, boom
1240 end
invoke(&block) click to toggle source

Run the block with ‘throw :halt’ support and apply result to the response.

     # File lib/sinatra/base.rb
1154 def invoke(&block)
1155   res = catch(:halt, &block)
1156 
1157   res = [res] if (Integer === res) || (String === res)
1158   if (Array === res) && (Integer === res.first)
1159     res = res.dup
1160     status(res.shift)
1161     body(res.pop)
1162     headers(*res)
1163   elsif res.respond_to? :each
1164     body res
1165   end
1166   nil # avoid double setting the same response tuple twice
1167 end
process_route(pattern, conditions, block = nil, values = []) { |self, values| ... } click to toggle source

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
1091 def process_route(pattern, conditions, block = nil, values = [])
1092   route = @request.path_info
1093   route = '/' if route.empty? && !settings.empty_path_info?
1094   route = route[0..-2] if !settings.strict_paths? && route != '/' && route.end_with?('/')
1095 
1096   params = pattern.params(route)
1097   return unless params
1098 
1099   params.delete('ignore') # TODO: better params handling, maybe turn it into "smart" object or detect changes
1100   force_encoding(params)
1101   @params = @params.merge(params) { |_k, v1, v2| v2 || v1 } if params.any?
1102 
1103   regexp_exists = pattern.is_a?(Mustermann::Regular) || (pattern.respond_to?(:patterns) && pattern.patterns.any? { |subpattern| subpattern.is_a?(Mustermann::Regular) })
1104   if regexp_exists
1105     captures           = pattern.match(route).captures.map { |c| URI_INSTANCE.unescape(c) if c }
1106     values            += captures
1107     @params[:captures] = force_encoding(captures) unless captures.nil? || captures.empty?
1108   else
1109     values += params.values.flatten
1110   end
1111 
1112   catch(:pass) do
1113     conditions.each { |c| throw :pass if c.bind(self).call == false }
1114     block ? block[self, values] : yield(self, values)
1115   end
1116 rescue StandardError
1117   @env['sinatra.error.params'] = @params
1118   raise
1119 ensure
1120   params ||= {}
1121   params.each { |k, _| @params.delete(k) } unless @env['sinatra.error.params']
1122 end
route!(base = settings, pass_block = nil) click to toggle source

Run routes defined on the class and all superclasses.

     # File lib/sinatra/base.rb
1057 def route!(base = settings, pass_block = nil)
1058   routes = base.routes[@request.request_method]
1059 
1060   routes&.each do |pattern, conditions, block|
1061     response.delete_header('Content-Type') unless @pinned_response
1062 
1063     returned_pass_block = process_route(pattern, conditions) do |*args|
1064       env['sinatra.route'] = "#{@request.request_method} #{pattern}"
1065       route_eval { block[*args] }
1066     end
1067 
1068     # don't wipe out pass_block in superclass
1069     pass_block = returned_pass_block if returned_pass_block
1070   end
1071 
1072   # Run routes defined in superclass.
1073   if base.superclass.respond_to?(:routes)
1074     return route!(base.superclass, pass_block)
1075   end
1076 
1077   route_eval(&pass_block) if pass_block
1078   route_missing
1079 end
route_eval() { || ... } click to toggle source

Run a route block and throw :halt with the result.

     # File lib/sinatra/base.rb
1082 def route_eval
1083   throw :halt, yield
1084 end
route_missing() click to toggle source

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
1129 def route_missing
1130   raise NotFound unless @app
1131 
1132   forward
1133 end
static!(options = {}) click to toggle source

Attempt to serve static files from public directory. Throws :halt when a matching file is found, returns nil otherwise.

     # File lib/sinatra/base.rb
1137 def static!(options = {})
1138   return if (public_dir = settings.public_folder).nil?
1139 
1140   path = "#{public_dir}#{URI_INSTANCE.unescape(request.path_info)}"
1141   return unless valid_path?(path)
1142 
1143   path = File.expand_path(path)
1144   return unless path.start_with?("#{File.expand_path(public_dir)}/")
1145 
1146   return unless File.file?(path)
1147 
1148   env['sinatra.static_file'] = path
1149   cache_control(*settings.static_cache_control) if settings.static_cache_control?
1150   send_file path, options.merge(disposition: nil)
1151 end