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

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

add a filter

     # File lib/sinatra/base.rb
1496 def add_filter(type, path = /.*/, **options, &block)
1497   filters[type] << compile!(type, path, block, **options)
1498 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
1491 def after(path = /.*/, **options, &block)
1492   add_filter(:after, path, **options, &block)
1493 end
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
1484 def before(path = /.*/, **options, &block)
1485   add_filter(:before, path, **options, &block)
1486 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
1668 def build(app)
1669   builder = Rack::Builder.new
1670   setup_default_middleware builder
1671   setup_middleware builder
1672   builder.run app
1673   builder
1674 end
call(env) click to toggle source
     # File lib/sinatra/base.rb
1676 def call(env)
1677   synchronize { prototype.call(env) }
1678 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
1682 def caller_files
1683   cleaned_caller(1).flatten
1684 end
callers_to_ignore() click to toggle source
     # File lib/sinatra/base.rb
1303 def callers_to_ignore
1304   CALLERS_TO_IGNORE
1305 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
1510 def condition(name = "#{caller.first[/`.*'/]} condition", &block)
1511   @conditions << generate_method(name, &block)
1512 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
1577 def configure(*envs)
1578   yield self if envs.empty? || envs.include?(environment.to_sym)
1579 end
delete(path, opts = {}, &block) click to toggle source
     # File lib/sinatra/base.rb
1541 def delete(path, opts = {}, &block)  route 'DELETE',  path, opts, &block end
development?() click to toggle source
     # File lib/sinatra/base.rb
1571 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
1391 def disable(*opts)
1392   opts.each { |key| set(key, false) }
1393 end
enable(*opts) click to toggle source

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

     # File lib/sinatra/base.rb
1386 def enable(*opts)
1387   opts.each { |key| set(key, true) }
1388 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
1398 def error(*codes, &block)
1399   args  = compile! 'ERROR', /.*/, block
1400   codes = codes.flat_map(&method(:Array))
1401   codes << Exception if codes.empty?
1402   codes << Sinatra::NotFound if codes.include?(404)
1403   codes.each { |c| (@errors[c] ||= []) << args }
1404 end
extensions() click to toggle source

Extension modules registered on this class and all superclasses.

     # File lib/sinatra/base.rb
1326 def extensions
1327   if superclass.respond_to?(:extensions)
1328     (@extensions + superclass.extensions).uniq
1329   else
1330     @extensions
1331   end
1332 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
1917 def self.force_encoding(data, encoding = default_encoding)
1918   return if data == settings || data.is_a?(Tempfile)
1919 
1920   if data.respond_to? :force_encoding
1921     data.force_encoding(encoding).encode!
1922   elsif data.respond_to? :each_value
1923     data.each_value { |v| force_encoding(v, encoding) }
1924   elsif data.respond_to? :each
1925     data.each { |v| force_encoding(v, encoding) }
1926   end
1927   data
1928 end
get(path, opts = {}, &block) click to toggle source

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

     # File lib/sinatra/base.rb
1529 def get(path, opts = {}, &block)
1530   conditions = @conditions.dup
1531   route('GET', path, opts, &block)
1532 
1533   @conditions = conditions
1534   route('HEAD', path, opts, &block)
1535 end
head(path, opts = {}, &block) click to toggle source
     # File lib/sinatra/base.rb
1543 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
1555 def helpers(*extensions, &block)
1556   class_eval(&block)   if block_given?
1557   include(*extensions) if extensions.any?
1558 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
1424 def inline_templates=(file = nil)
1425   file = (caller_files.first || File.expand_path($0)) if file.nil? || file == true
1426 
1427   begin
1428     io = ::IO.respond_to?(:binread) ? ::IO.binread(file) : ::IO.read(file)
1429     app, data = io.gsub("\r\n", "\n").split(/^__END__$/, 2)
1430   rescue Errno::ENOENT
1431     app, data = nil
1432   end
1433 
1434   return unless data
1435 
1436   encoding = if app && app =~ /([^\n]*\n)?#[^\n]*coding: *(\S+)/m
1437                $2
1438              else
1439                settings.default_encoding
1440              end
1441 
1442   lines = app.count("\n") + 1
1443   template = nil
1444   force_encoding data, encoding
1445   data.each_line do |line|
1446     lines += 1
1447     if line =~ /^@@\s*(.*\S)\s*$/
1448       template = force_encoding(String.new, encoding)
1449       templates[$1.to_sym] = [template, file, lines]
1450     elsif template
1451       template << line
1452     end
1453   end
1454 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
1418 def layout(name = :layout, &block)
1419   template name, &block
1420 end
middleware() click to toggle source

Middleware used in this class and all superclasses.

     # File lib/sinatra/base.rb
1335 def middleware
1336   if superclass.respond_to?(:middleware)
1337     superclass.middleware + @middleware
1338   else
1339     @middleware
1340   end
1341 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
1457 def mime_type(type, value = nil)
1458   return type      if type.nil?
1459   return type.to_s if type.to_s.include?('/')
1460 
1461   type = ".#{type}" unless type.to_s[0] == '.'
1462   return Rack::Mime.mime_type(type, nil) unless value
1463 
1464   Rack::Mime::MIME_TYPES[type] = value
1465 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
1470 def mime_types(type)
1471   type = mime_type type
1472   if type =~ %r{^application/(xml|javascript)$}
1473     [type, "text/#{$1}"]
1474   elsif type =~ %r{^text/(xml|javascript)$}
1475     [type, "application/#{$1}"]
1476   else
1477     [type]
1478   end
1479 end
new(app = nil, **_kwargs) { |self| ... } click to toggle source
    # File lib/sinatra/base.rb
983 def initialize(app = nil, **_kwargs)
984   super()
985   @app = app
986   @template_cache = TemplateCache.new
987   @pinned_response = nil # whether a before! filter pinned the content-type
988   yield self if block_given?
989 end
Also aliased as: new!
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
1660 def new(*args, &block)
1661   instance = new!(*args, &block)
1662   Wrapper.new(build(instance).to_app, instance)
1663 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
1407 def not_found(&block)
1408   error(404, &block)
1409 end
on_start(&on_start_callback) click to toggle source
     # File lib/sinatra/base.rb
1500 def on_start(&on_start_callback)
1501   @on_start_callback = on_start_callback
1502 end
on_stop(&on_stop_callback) click to toggle source
     # File lib/sinatra/base.rb
1504 def on_stop(&on_stop_callback)
1505   @on_stop_callback = on_stop_callback
1506 end
options(path, opts = {}, &block) click to toggle source
     # File lib/sinatra/base.rb
1545 def options(path, opts = {}, &block) route 'OPTIONS', path, opts, &block end
patch(path, opts = {}, &block) click to toggle source
     # File lib/sinatra/base.rb
1547 def patch(path, opts = {}, &block)   route 'PATCH',   path, opts, &block end
post(path, opts = {}, &block) click to toggle source
     # File lib/sinatra/base.rb
1539 def post(path, opts = {}, &block)    route 'POST',    path, opts, &block end
production?() click to toggle source
     # File lib/sinatra/base.rb
1572 def production?;  environment == :production  end
prototype() click to toggle source

The prototype instance used to process requests.

     # File lib/sinatra/base.rb
1650 def prototype
1651   @prototype ||= new
1652 end
public=(value) click to toggle source
     # File lib/sinatra/base.rb
1514 def public=(value)
1515   warn_for_deprecation ':public is no longer used to avoid overloading Module#public, use :public_folder or :public_dir instead'
1516   set(:public_folder, value)
1517 end
public_dir() click to toggle source
     # File lib/sinatra/base.rb
1523 def public_dir
1524   public_folder
1525 end
public_dir=(value) click to toggle source
     # File lib/sinatra/base.rb
1519 def public_dir=(value)
1520   self.public_folder = value
1521 end
put(path, opts = {}, &block) click to toggle source
     # File lib/sinatra/base.rb
1537 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
1589 def quit!
1590   return unless running?
1591 
1592   # Use Thin's hard #stop! if available, otherwise just #stop.
1593   running_server.respond_to?(:stop!) ? running_server.stop! : running_server.stop
1594   warn '== Sinatra has ended his set (crowd applauds)' unless suppress_messages?
1595   set :running_server, nil
1596   set :handler_name, nil
1597 
1598   on_stop_callback.call unless on_stop_callback.nil?
1599 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
1562 def register(*extensions, &block)
1563   extensions << Module.new(&block) if block_given?
1564   @extensions += extensions
1565   extensions.each do |extension|
1566     extend extension
1567     extension.registered(self) if extension.respond_to?(:registered)
1568   end
1569 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
1309 def reset!
1310   @conditions     = []
1311   @routes         = {}
1312   @filters        = { before: [], after: [] }
1313   @errors         = {}
1314   @middleware     = []
1315   @prototype      = nil
1316   @extensions     = []
1317 
1318   @templates = if superclass.respond_to?(:templates)
1319                  Hash.new { |_hash, key| superclass.templates[key] }
1320                else
1321                  {}
1322                end
1323 end
run!(options = {}, &block) click to toggle source

Run the Sinatra app as a self-hosted server using Puma, Falcon (in that order). If given a block, will call with the constructed handler once we have taken the stage.

     # File lib/sinatra/base.rb
1606       def run!(options = {}, &block)
1607         unless defined?(Rackup::Handler)
1608           rackup_warning = <<~MISSING_RACKUP
1609             Sinatra could not start, the required gems weren't found!
1610 
1611             Add them to your bundle with:
1612 
1613                 bundle add rackup puma
1614 
1615             or install them with:
1616 
1617                 gem install rackup puma
1618 
1619           MISSING_RACKUP
1620           warn rackup_warning
1621           exit 1
1622         end
1623 
1624         return if running?
1625 
1626         set options
1627         handler         = Rackup::Handler.pick(server)
1628         handler_name    = handler.name.gsub(/.*::/, '')
1629         server_settings = settings.respond_to?(:server_settings) ? settings.server_settings : {}
1630         server_settings.merge!(Port: port, Host: bind)
1631 
1632         begin
1633           start_server(handler, server_settings, handler_name, &block)
1634         rescue Errno::EADDRINUSE
1635           warn "== Someone is already performing on port #{port}!"
1636           raise
1637         ensure
1638           quit!
1639         end
1640       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
1645 def running?
1646   running_server?
1647 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
1345 def set(option, value = (not_set = true), ignore_setter = false, &block)
1346   raise ArgumentError if block && !not_set
1347 
1348   if block
1349     value = block
1350     not_set = false
1351   end
1352 
1353   if not_set
1354     raise ArgumentError unless option.respond_to?(:each)
1355 
1356     option.each { |k, v| set(k, v) }
1357     return self
1358   end
1359 
1360   if respond_to?("#{option}=") && !ignore_setter
1361     return __send__("#{option}=", value)
1362   end
1363 
1364   setter = proc { |val| set option, val, true }
1365   getter = proc { value }
1366 
1367   case value
1368   when Proc
1369     getter = value
1370   when Symbol, Integer, FalseClass, TrueClass, NilClass
1371     getter = value.inspect
1372   when Hash
1373     setter = proc do |val|
1374       val = value.merge val if Hash === val
1375       set option, val, true
1376     end
1377   end
1378 
1379   define_singleton("#{option}=", setter)
1380   define_singleton(option, getter)
1381   define_singleton("#{option}?", "!!#{option}") unless method_defined? "#{option}?"
1382   self
1383 end
settings() click to toggle source

Access settings defined with Base.set.

     # File lib/sinatra/base.rb
1019 def self.settings
1020   self
1021 end
start!(options = {}, &block)
Alias for: run!
stop!()
Alias for: quit!
template(name, &block) click to toggle source

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

     # File lib/sinatra/base.rb
1412 def template(name, &block)
1413   filename, line = caller_locations.first
1414   templates[name] = [block, filename, line.to_i]
1415 end
test?() click to toggle source
     # File lib/sinatra/base.rb
1573 def test?;        environment == :test        end
use(middleware, *args, &block) click to toggle source

Use the specified Rack middleware

     # File lib/sinatra/base.rb
1582 def use(middleware, *args, &block)
1583   @prototype = nil
1584   @middleware << [middleware, args, block]
1585 end

Private Class Methods

agent(pattern)
Alias for: user_agent
cleaned_caller(keep = 3) click to toggle source

Like Kernel#caller but excluding certain magic entries

     # File lib/sinatra/base.rb
1908 def cleaned_caller(keep = 3)
1909   caller(1)
1910     .map! { |line| line.split(/:(?=\d|in )/, 3)[0, keep] }
1911     .reject { |file, *_| callers_to_ignore.any? { |pattern| file =~ pattern } }
1912 end
compile(path, route_mustermann_opts = {}) click to toggle source
     # File lib/sinatra/base.rb
1813 def compile(path, route_mustermann_opts = {})
1814   Mustermann.new(path, **mustermann_opts.merge(route_mustermann_opts))
1815 end
compile!(verb, path, block, **options) click to toggle source
     # File lib/sinatra/base.rb
1793 def compile!(verb, path, block, **options)
1794   # Because of self.options.host
1795   host_name(options.delete(:host)) if options.key?(:host)
1796   # Pass Mustermann opts to compile()
1797   route_mustermann_opts = options.key?(:mustermann_opts) ? options.delete(:mustermann_opts) : {}.freeze
1798 
1799   options.each_pair { |option, args| send(option, *args) }
1800 
1801   pattern                 = compile(path, route_mustermann_opts)
1802   method_name             = "#{verb} #{path}"
1803   unbound_method          = generate_method(method_name, &block)
1804   conditions = @conditions
1805   @conditions = []
1806   wrapper = block.arity.zero? ?
1807     proc { |a, _p| unbound_method.bind(a).call } :
1808     proc { |a, p| unbound_method.bind(a).call(*p) }
1809 
1810   [pattern, conditions, wrapper]
1811 end
define_singleton(name, content = Proc.new) click to toggle source

Dynamically defines a method on settings.

     # File lib/sinatra/base.rb
1728 def define_singleton(name, content = Proc.new)
1729   singleton_class.class_eval do
1730     undef_method(name) if method_defined? name
1731     String === content ? class_eval("def #{name}() #{content}; end") : define_method(name, &content)
1732   end
1733 end
generate_method(method_name, &block) click to toggle source
     # File lib/sinatra/base.rb
1786 def generate_method(method_name, &block)
1787   define_method(method_name, &block)
1788   method = instance_method method_name
1789   remove_method method_name
1790   method
1791 end
host_name(pattern) click to toggle source

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

     # File lib/sinatra/base.rb
1736 def host_name(pattern)
1737   condition { pattern === request.host }
1738 end
inherited(subclass) click to toggle source
Calls superclass method
     # File lib/sinatra/base.rb
1887 def inherited(subclass)
1888   subclass.reset!
1889   subclass.set :app_file, caller_files.first unless subclass.app_file?
1890   super
1891 end
invoke_hook(name, *args) click to toggle source
     # File lib/sinatra/base.rb
1782 def invoke_hook(name, *args)
1783   extensions.each { |e| e.send(name, *args) if e.respond_to?(name) }
1784 end
provides(*types) click to toggle source

Condition for matching mimetypes. Accepts file extensions.

     # File lib/sinatra/base.rb
1755 def provides(*types)
1756   types.map! { |t| mime_types(t) }
1757   types.flatten!
1758   condition do
1759     response_content_type = response['content-type']
1760     preferred_type = request.preferred_type(types)
1761 
1762     if response_content_type
1763       types.include?(response_content_type) || types.include?(response_content_type[/^[^;]+/])
1764     elsif preferred_type
1765       params = (preferred_type.respond_to?(:params) ? preferred_type.params : {})
1766       content_type(preferred_type, params)
1767       true
1768     else
1769       false
1770     end
1771   end
1772 end
route(verb, path, options = {}, &block) click to toggle source
     # File lib/sinatra/base.rb
1774 def route(verb, path, options = {}, &block)
1775   enable :empty_path_info if path == '' && empty_path_info.nil?
1776   signature = compile!(verb, path, block, **options)
1777   (@routes[verb] ||= []) << signature
1778   invoke_hook(:route_added, verb, path, block)
1779   signature
1780 end
setup_common_logger(builder) click to toggle source
     # File lib/sinatra/base.rb
1845 def setup_common_logger(builder)
1846   builder.use Sinatra::CommonLogger
1847 end
setup_custom_logger(builder) click to toggle source
     # File lib/sinatra/base.rb
1849 def setup_custom_logger(builder)
1850   if logging.respond_to? :to_int
1851     builder.use Sinatra::Middleware::Logger, logging
1852   else
1853     builder.use Sinatra::Middleware::Logger
1854   end
1855 end
setup_default_middleware(builder) click to toggle source
     # File lib/sinatra/base.rb
1817 def setup_default_middleware(builder)
1818   builder.use ExtendedRack
1819   builder.use ShowExceptions       if show_exceptions?
1820   builder.use Rack::MethodOverride if method_override?
1821   builder.use Rack::Head
1822   setup_logging    builder
1823   setup_sessions   builder
1824   setup_protection builder
1825   setup_host_authorization builder
1826 end
setup_host_authorization(builder) click to toggle source
     # File lib/sinatra/base.rb
1874 def setup_host_authorization(builder)
1875   builder.use Rack::Protection::HostAuthorization, host_authorization
1876 end
setup_logging(builder) click to toggle source
     # File lib/sinatra/base.rb
1832 def setup_logging(builder)
1833   if logging?
1834     setup_common_logger(builder)
1835     setup_custom_logger(builder)
1836   elsif logging == false
1837     setup_null_logger(builder)
1838   end
1839 end
setup_middleware(builder) click to toggle source
     # File lib/sinatra/base.rb
1828 def setup_middleware(builder)
1829   middleware.each { |c, a, b| builder.use(c, *a, &b) }
1830 end
setup_null_logger(builder) click to toggle source
     # File lib/sinatra/base.rb
1841 def setup_null_logger(builder)
1842   builder.use Sinatra::Middleware::Logger, ::Logger::FATAL
1843 end
setup_protection(builder) click to toggle source
     # File lib/sinatra/base.rb
1857 def setup_protection(builder)
1858   return unless protection?
1859 
1860   options = Hash === protection ? protection.dup : {}
1861   options = {
1862     img_src: "'self' data:",
1863     font_src: "'self'"
1864   }.merge options
1865 
1866   protect_session = options.fetch(:session) { sessions? }
1867   options[:without_session] = !protect_session
1868 
1869   options[:reaction] ||= :drop_session
1870 
1871   builder.use Rack::Protection, options
1872 end
setup_sessions(builder) click to toggle source
     # File lib/sinatra/base.rb
1878 def setup_sessions(builder)
1879   return unless sessions?
1880 
1881   options = {}
1882   options[:secret] = session_secret if session_secret?
1883   options.merge! sessions.to_hash if sessions.respond_to? :to_hash
1884   builder.use session_store, options
1885 end
setup_traps() click to toggle source
     # File lib/sinatra/base.rb
1712 def setup_traps
1713   return unless traps?
1714 
1715   at_exit { quit! }
1716 
1717   %i[INT TERM].each do |signal|
1718     old_handler = trap(signal) do
1719       quit!
1720       old_handler.call if old_handler.respond_to?(:call)
1721     end
1722   end
1723 
1724   set :traps, false
1725 end
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
1689 def start_server(handler, server_settings, handler_name)
1690   # Ensure we initialize middleware before startup, to match standard Rack
1691   # behavior, by ensuring an instance exists:
1692   prototype
1693   # Run the instance we created:
1694   handler.run(self, **server_settings) do |server|
1695     unless suppress_messages?
1696       warn "== Sinatra (v#{Sinatra::VERSION}) has taken the stage on #{port} for #{environment} with backup from #{handler_name}"
1697     end
1698 
1699     setup_traps
1700     set :running_server, server
1701     set :handler_name,   handler_name
1702     server.threaded = settings.threaded if server.respond_to? :threaded=
1703     on_start_callback.call unless on_start_callback.nil?
1704     yield server if block_given?
1705   end
1706 end
suppress_messages?() click to toggle source
     # File lib/sinatra/base.rb
1708 def suppress_messages?
1709   handler_name =~ /cgi/i || quiet
1710 end
synchronize() { || ... } click to toggle source
     # File lib/sinatra/base.rb
1894 def synchronize(&block)
1895   if lock?
1896     @@mutex.synchronize(&block)
1897   else
1898     yield
1899   end
1900 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
1742 def user_agent(pattern)
1743   condition do
1744     if request.user_agent.to_s =~ pattern
1745       @params[:agent] = $~[1..-1]
1746       true
1747     else
1748       false
1749     end
1750   end
1751 end
Also aliased as: agent
warn_for_deprecation(message) click to toggle source

used for deprecation warnings

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

Public Instance Methods

call(env) click to toggle source

Rack call interface.

    # File lib/sinatra/base.rb
992 def call(env)
993   dup.call!(env)
994 end
forward() click to toggle source

Forward the request to the downstream app – middleware only.

     # File lib/sinatra/base.rb
1043 def forward
1044   raise 'downstream app not set' unless @app.respond_to? :call
1045 
1046   status, headers, body = @app.call env
1047   @response.status = status
1048   @response.body = body
1049   @response.headers.merge! headers
1050   nil
1051 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
1030 def halt(*response)
1031   response = response.first if response.length == 1
1032   throw :halt, response
1033 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
1038 def pass(&block)
1039   throw :pass, block
1040 end
settings() click to toggle source

Access settings defined with Base.set.

     # File lib/sinatra/base.rb
1024 def settings
1025   self.class.settings
1026 end

Private Instance Methods

dispatch!() click to toggle source

Dispatch a request with error handling.

     # File lib/sinatra/base.rb
1179 def dispatch!
1180   # Avoid passing frozen string in force_encoding
1181   @params.merge!(@request.params).each do |key, val|
1182     next unless val.respond_to?(:force_encoding)
1183 
1184     val = val.dup if val.frozen?
1185     @params[key] = force_encoding(val)
1186   end
1187 
1188   invoke do
1189     static! if settings.static? && (request.get? || request.head?)
1190     filter! :before do
1191       @pinned_response = !response['content-type'].nil?
1192     end
1193     route!
1194   end
1195 rescue ::Exception => e
1196   invoke { handle_exception!(e) }
1197 ensure
1198   begin
1199     filter! :after unless env['sinatra.static_file']
1200   rescue ::Exception => e
1201     invoke { handle_exception!(e) } unless @env['sinatra.error']
1202   end
1203 end
dump_errors!(boom) click to toggle source
     # File lib/sinatra/base.rb
1271 def dump_errors!(boom)
1272   if boom.respond_to?(:detailed_message)
1273     msg = boom.detailed_message(highlight: false)
1274     if msg =~ /\A(.*?)(?: \(#{ Regexp.quote(boom.class.to_s) }\))?\n/
1275       msg = $1
1276       additional_msg = $'.lines(chomp: true)
1277     else
1278       additional_msg = []
1279     end
1280   else
1281     msg = boom.message
1282     additional_msg = []
1283   end
1284   msg = ["#{Time.now.strftime('%Y-%m-%d %H:%M:%S')} - #{boom.class} - #{msg}:", *additional_msg, *boom.backtrace].join("\n\t")
1285   @env['rack.errors'].puts(msg)
1286 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
1252 def error_block!(key, *block_params)
1253   base = settings
1254   while base.respond_to?(:errors)
1255     args_array = base.errors[key]
1256 
1257     next base = base.superclass unless args_array
1258 
1259     args_array.reverse_each do |args|
1260       first = args == args_array.first
1261       args += [block_params]
1262       resp = process_route(*args)
1263       return resp unless resp.nil? && !first
1264     end
1265   end
1266   return false unless key.respond_to?(:superclass) && (key.superclass < Exception)
1267 
1268   error_block!(key.superclass, *block_params)
1269 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
1057 def filter!(type, base = settings, &block)
1058   filter!(type, base.superclass, &block) if base.superclass.respond_to?(:filters)
1059   base.filters[type].each do |args|
1060     result = process_route(*args)
1061     block.call(result) if block_given?
1062   end
1063 end
force_encoding(*args) click to toggle source
     # File lib/sinatra/base.rb
1930 def force_encoding(*args)
1931   settings.force_encoding(*args)
1932 end
handle_exception!(boom) click to toggle source

Error handling during requests.

     # File lib/sinatra/base.rb
1206 def handle_exception!(boom)
1207   error_params = @env['sinatra.error.params']
1208 
1209   @params = @params.merge(error_params) if error_params
1210 
1211   @env['sinatra.error'] = boom
1212 
1213   http_status = if boom.is_a? Sinatra::Error
1214                   if boom.respond_to? :http_status
1215                     boom.http_status
1216                   elsif settings.use_code? && boom.respond_to?(:code)
1217                     boom.code
1218                   end
1219                 end
1220 
1221   http_status = 500 unless http_status&.between?(400, 599)
1222   status(http_status)
1223 
1224   if server_error?
1225     dump_errors! boom if settings.dump_errors?
1226     raise boom if settings.show_exceptions? && (settings.show_exceptions != :after_handler)
1227   elsif not_found?
1228     headers['X-Cascade'] = 'pass' if settings.x_cascade?
1229   end
1230 
1231   if (res = error_block!(boom.class, boom) || error_block!(status, boom))
1232     return res
1233   end
1234 
1235   if not_found? || bad_request?
1236     if boom.message && boom.message != boom.class.name
1237       body Rack::Utils.escape_html(boom.message)
1238     else
1239       content_type 'text/html'
1240       body "<h1>#{not_found? ? 'Not Found' : 'Bad Request'}</h1>"
1241     end
1242   end
1243 
1244   return unless server_error?
1245 
1246   raise boom if settings.raise_errors? || settings.show_exceptions?
1247 
1248   error_block! Exception, boom
1249 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
1163 def invoke(&block)
1164   res = catch(:halt, &block)
1165 
1166   res = [res] if (Integer === res) || (String === res)
1167   if (Array === res) && (Integer === res.first)
1168     res = res.dup
1169     status(res.shift)
1170     body(res.pop)
1171     headers(*res)
1172   elsif res.respond_to? :each
1173     body res
1174   end
1175   nil # avoid double setting the same response tuple twice
1176 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
1100 def process_route(pattern, conditions, block = nil, values = [])
1101   route = @request.path_info
1102   route = '/' if route.empty? && !settings.empty_path_info?
1103   route = route[0..-2] if !settings.strict_paths? && route != '/' && route.end_with?('/')
1104 
1105   params = pattern.params(route)
1106   return unless params
1107 
1108   params.delete('ignore') # TODO: better params handling, maybe turn it into "smart" object or detect changes
1109   force_encoding(params)
1110   @params = @params.merge(params) { |_k, v1, v2| v2 || v1 } if params.any?
1111 
1112   regexp_exists = pattern.is_a?(Mustermann::Regular) || (pattern.respond_to?(:patterns) && pattern.patterns.any? { |subpattern| subpattern.is_a?(Mustermann::Regular) })
1113   if regexp_exists
1114     captures           = pattern.match(route).captures.map { |c| URI_INSTANCE.unescape(c) if c }
1115     values            += captures
1116     @params[:captures] = force_encoding(captures) unless captures.nil? || captures.empty?
1117   else
1118     values += params.values.flatten
1119   end
1120 
1121   catch(:pass) do
1122     conditions.each { |c| throw :pass if c.bind(self).call == false }
1123     block ? block[self, values] : yield(self, values)
1124   end
1125 rescue StandardError
1126   @env['sinatra.error.params'] = @params
1127   raise
1128 ensure
1129   params ||= {}
1130   params.each { |k, _| @params.delete(k) } unless @env['sinatra.error.params']
1131 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
1066 def route!(base = settings, pass_block = nil)
1067   routes = base.routes[@request.request_method]
1068 
1069   routes&.each do |pattern, conditions, block|
1070     response.delete_header('content-type') unless @pinned_response
1071 
1072     returned_pass_block = process_route(pattern, conditions) do |*args|
1073       env['sinatra.route'] = "#{@request.request_method} #{pattern}"
1074       route_eval { block[*args] }
1075     end
1076 
1077     # don't wipe out pass_block in superclass
1078     pass_block = returned_pass_block if returned_pass_block
1079   end
1080 
1081   # Run routes defined in superclass.
1082   if base.superclass.respond_to?(:routes)
1083     return route!(base.superclass, pass_block)
1084   end
1085 
1086   route_eval(&pass_block) if pass_block
1087   route_missing
1088 end
route_eval() { || ... } click to toggle source

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

     # File lib/sinatra/base.rb
1091 def route_eval
1092   throw :halt, yield
1093 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
1138 def route_missing
1139   raise NotFound unless @app
1140 
1141   forward
1142 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
1146 def static!(options = {})
1147   return if (public_dir = settings.public_folder).nil?
1148 
1149   path = "#{public_dir}#{URI_INSTANCE.unescape(request.path_info)}"
1150   return unless valid_path?(path)
1151 
1152   path = File.expand_path(path)
1153   return unless path.start_with?("#{File.expand_path(public_dir)}/")
1154 
1155   return unless File.file?(path)
1156 
1157   env['sinatra.static_file'] = path
1158   cache_control(*settings.static_cache_control) if settings.static_cache_control?
1159   send_file path, options.merge(disposition: nil)
1160 end