class Sinatra::Helpers::Stream::Base

Base class for all Sinatra applications and middleware.

Constants

URI_INSTANCE

Attributes

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

Public Class Methods

new(app = nil) { |self| ... } click to toggle source
Calls superclass method Sinatra::Helpers::Stream::Templates.new
# File lib/sinatra/base.rb, line 917
def initialize(app = nil)
  super()
  @app = app
  @template_cache = Tilt::Cache.new
  @pinned_response = nil # whether a before! filter pinned the content-type
  yield self if block_given?
end
Also aliased as: new!
settings() click to toggle source

Access settings defined with ::set.

# File lib/sinatra/base.rb, line 952
def self.settings
  self
end

Private Class Methods

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

add a filter

# File lib/sinatra/base.rb, line 1397
def add_filter(type, path = /.*/, **options, &block)
  filters[type] << compile!(type, path, block, **options)
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, line 1392
def after(path = /.*/, **options, &block)
  add_filter(:after, path, **options, &block)
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, line 1385
def before(path = /.*/, **options, &block)
  add_filter(:before, path, **options, &block)
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, line 1531
def build(app)
  builder = Rack::Builder.new
  setup_default_middleware builder
  setup_middleware builder
  builder.run app
  builder
end
call(env) click to toggle source
# File lib/sinatra/base.rb, line 1539
def call(env)
  synchronize { prototype.call(env) }
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, line 1545
def caller_files
  cleaned_caller(1).flatten
end
caller_locations() click to toggle source

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, line 1551
def caller_locations
  cleaned_caller 2
end
cleaned_caller(keep = 3) click to toggle source

Like Kernel#caller but excluding certain magic entries

# File lib/sinatra/base.rb, line 1777
def cleaned_caller(keep = 3)
  caller(1).
    map!    { |line| line.split(/:(?=\d|in )/, 3)[0,keep] }.
    reject { |file, *_| CALLERS_TO_IGNORE.any? { |pattern| file =~ pattern } }
end
compile(path, route_mustermann_opts = {}) click to toggle source
# File lib/sinatra/base.rb, line 1678
def compile(path, route_mustermann_opts = {})
  Mustermann.new(path, **mustermann_opts.merge(route_mustermann_opts))
end
compile!(verb, path, block, **options) click to toggle source
# File lib/sinatra/base.rb, line 1659
def compile!(verb, path, block, **options)
  # Because of self.options.host
  host_name(options.delete(:host)) if options.key?(:host)
  # Pass Mustermann opts to compile()
  route_mustermann_opts = options.key?(:mustermann_opts) ? options.delete(:mustermann_opts) : {}.freeze

  options.each_pair { |option, args| send(option, *args) }

  pattern                 = compile(path, route_mustermann_opts)
  method_name             = "#{verb} #{path}"
  unbound_method          = generate_method(method_name, &block)
  conditions, @conditions = @conditions, []
  wrapper                 = block.arity != 0 ?
    proc { |a, p| unbound_method.bind(a).call(*p) } :
    proc { |a, p| unbound_method.bind(a).call }

  [ pattern, conditions, wrapper ]
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, line 1403
def condition(name = "#{caller.first[/`.*'/]} condition", &block)
  @conditions << generate_method(name, &block)
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, line 1463
def configure(*envs)
  yield self if envs.empty? || envs.include?(environment.to_sym)
end
define_singleton(name, content = Proc.new) click to toggle source

Dynamically defines a method on settings.

# File lib/sinatra/base.rb, line 1597
def define_singleton(name, content = Proc.new)
  singleton_class.class_eval do
    undef_method(name) if method_defined? name
    String === content ? class_eval("def #{name}() #{content}; end") : define_method(name, &content)
  end
end
delete(path, opts = {}, &bk) click to toggle source
# File lib/sinatra/base.rb, line 1432
def delete(path, opts = {}, &bk)  route 'DELETE',  path, opts, &bk end
detect_rack_handler() click to toggle source
# File lib/sinatra/base.rb, line 1745
def detect_rack_handler
  servers = Array(server)
  servers.each do |server_name|
    begin
      return Rack::Handler.get(server_name.to_s)
    rescue LoadError, NameError
    end
  end
  fail "Server handler (#{servers.join(',')}) not found."
end
development?() click to toggle source
# File lib/sinatra/base.rb, line 1457
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, line 1301
def disable(*opts)
  opts.each { |key| set(key, false) }
end
enable(*opts) click to toggle source

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

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

Extension modules registered on this class and all superclasses.

# File lib/sinatra/base.rb, line 1241
def extensions
  if superclass.respond_to?(:extensions)
    (@extensions + superclass.extensions).uniq
  else
    @extensions
  end
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, line 1786
def self.force_encoding(data, encoding = default_encoding)
  return if data == settings || data.is_a?(Tempfile)
  if data.respond_to? :force_encoding
    data.force_encoding(encoding).encode!
  elsif data.respond_to? :each_value
    data.each_value { |v| force_encoding(v, encoding) }
  elsif data.respond_to? :each
    data.each { |v| force_encoding(v, encoding) }
  end
  data
end
generate_method(method_name, &block) click to toggle source
# File lib/sinatra/base.rb, line 1652
def generate_method(method_name, &block)
  define_method(method_name, &block)
  method = instance_method method_name
  remove_method method_name
  method
end
get(path, opts = {}, &block) click to toggle source

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

# File lib/sinatra/base.rb, line 1422
def get(path, opts = {}, &block)
  conditions = @conditions.dup
  route('GET', path, opts, &block)

  @conditions = conditions
  route('HEAD', path, opts, &block)
end
head(path, opts = {}, &bk) click to toggle source
# File lib/sinatra/base.rb, line 1433
def head(path, opts = {}, &bk)    route 'HEAD',    path, opts, &bk 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, line 1441
def helpers(*extensions, &block)
  class_eval(&block)   if block_given?
  prepend(*extensions) if extensions.any?
end
host_name(pattern) click to toggle source

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

# File lib/sinatra/base.rb, line 1605
def host_name(pattern)
  condition { pattern === request.host }
end
inherited(subclass) click to toggle source
Calls superclass method
# File lib/sinatra/base.rb, line 1756
def inherited(subclass)
  subclass.reset!
  subclass.set :app_file, caller_files.first unless subclass.app_file?
  super
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, line 1334
def inline_templates=(file = nil)
  file = (file.nil? || file == true) ? (caller_files.first || File.expand_path($0)) : file

  begin
    io = ::IO.respond_to?(:binread) ? ::IO.binread(file) : ::IO.read(file)
    app, data = io.gsub("\r\n", "\n").split(/^__END__$/, 2)
  rescue Errno::ENOENT
    app, data = nil
  end

  if data
    if app and app =~ /([^\n]*\n)?#[^\n]*coding: *(\S+)/m
      encoding = $2
    else
      encoding = settings.default_encoding
    end
    lines = app.count("\n") + 1
    template = nil
    force_encoding data, encoding
    data.each_line do |line|
      lines += 1
      if line =~ /^@@\s*(.*\S)\s*$/
        template = force_encoding(String.new, encoding)
        templates[$1.to_sym] = [template, file, lines]
      elsif template
        template << line
      end
    end
  end
end
invoke_hook(name, *args) click to toggle source
# File lib/sinatra/base.rb, line 1648
def invoke_hook(name, *args)
  extensions.each { |e| e.send(name, *args) if e.respond_to?(name) }
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, line 1328
def layout(name = :layout, &block)
  template name, &block
end
middleware() click to toggle source

Middleware used in this class and all superclasses.

# File lib/sinatra/base.rb, line 1250
def middleware
  if superclass.respond_to?(:middleware)
    superclass.middleware + @middleware
  else
    @middleware
  end
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, line 1366
def mime_type(type, value = nil)
  return type      if type.nil?
  return type.to_s if type.to_s.include?('/')
  type = ".#{type}" unless type.to_s[0] == ?.
  return Rack::Mime.mime_type(type, nil) unless value
  Rack::Mime::MIME_TYPES[type] = value
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, line 1377
def mime_types(type)
  type = mime_type type
  type =~ /^application\/(xml|javascript)$/ ? [type, "text/#$1"] : [type]
end
new(*args, &bk) 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, line 1524
def new(*args, &bk)
  instance = new!(*args, &bk)
  Wrapper.new(build(instance).to_app, instance)
end
new!(app = nil)

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, line 1317
def not_found(&block)
  error(404, &block)
end
options(path, opts = {}, &bk) click to toggle source
# File lib/sinatra/base.rb, line 1434
def options(path, opts = {}, &bk) route 'OPTIONS', path, opts, &bk end
patch(path, opts = {}, &bk) click to toggle source
# File lib/sinatra/base.rb, line 1435
def patch(path, opts = {}, &bk)   route 'PATCH',   path, opts, &bk end
post(path, opts = {}, &bk) click to toggle source
# File lib/sinatra/base.rb, line 1431
def post(path, opts = {}, &bk)    route 'POST',    path, opts, &bk end
production?() click to toggle source
# File lib/sinatra/base.rb, line 1458
def production?;  environment == :production  end
prototype() click to toggle source

The prototype instance used to process requests.

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

Condition for matching mimetypes. Accepts file extensions.

# File lib/sinatra/base.rb, line 1624
def provides(*types)
  types.map! { |t| mime_types(t) }
  types.flatten!
  condition do
    if type = response['Content-Type']
      types.include? type or types.include? type[/^[^;]+/]
    elsif type = request.preferred_type(types)
      params = (type.respond_to?(:params) ? type.params : {})
      content_type(type, params)
      true
    else
      false
    end
  end
end
public=(value) click to toggle source
# File lib/sinatra/base.rb, line 1407
def public=(value)
  warn ":public is no longer used to avoid overloading Module#public, use :public_folder or :public_dir instead"
  set(:public_folder, value)
end
public_dir() click to toggle source
# File lib/sinatra/base.rb, line 1416
def public_dir
  public_folder
end
public_dir=(value) click to toggle source
# File lib/sinatra/base.rb, line 1412
def public_dir=(value)
  self.public_folder = value
end
put(path, opts = {}, &bk) click to toggle source
# File lib/sinatra/base.rb, line 1430
def put(path, opts = {}, &bk)     route 'PUT',     path, opts, &bk end
quit!() click to toggle source

Stop the self-hosted server if running.

# File lib/sinatra/base.rb, line 1474
def quit!
  return unless running?
  # Use Thin's hard #stop! if available, otherwise just #stop.
  running_server.respond_to?(:stop!) ? running_server.stop! : running_server.stop
  $stderr.puts "== Sinatra has ended his set (crowd applauds)" unless suppress_messages?
  set :running_server, nil
  set :handler_name, nil
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, line 1448
def register(*extensions, &block)
  extensions << Module.new(&block) if block_given?
  @extensions += extensions
  extensions.each do |extension|
    extend extension
    extension.registered(self) if extension.respond_to?(:registered)
  end
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, line 1224
def reset!
  @conditions     = []
  @routes         = {}
  @filters        = {:before => [], :after => []}
  @errors         = {}
  @middleware     = []
  @prototype      = nil
  @extensions     = []

  if superclass.respond_to?(:templates)
    @templates = Hash.new { |hash, key| superclass.templates[key] }
  else
    @templates = {}
  end
end
route(verb, path, options = {}, &block) click to toggle source
# File lib/sinatra/base.rb, line 1640
def route(verb, path, options = {}, &block)
  enable :empty_path_info if path == "" and empty_path_info.nil?
  signature = compile!(verb, path, block, **options)
  (@routes[verb] ||= []) << signature
  invoke_hook(:route_added, verb, path, block)
  signature
end
run!(options = {}, &block) click to toggle source

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, line 1488
def run!(options = {}, &block)
  return if running?
  set options
  handler         = detect_rack_handler
  handler_name    = handler.name.gsub(/.*::/, '')
  server_settings = settings.respond_to?(:server_settings) ? settings.server_settings : {}
  server_settings.merge!(:Port => port, :Host => bind)

  begin
    start_server(handler, server_settings, handler_name, &block)
  rescue Errno::EADDRINUSE
    $stderr.puts "== Someone is already performing on port #{port}!"
    raise
  ensure
    quit!
  end
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, line 1509
def running?
  running_server?
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, line 1260
def set(option, value = (not_set = true), ignore_setter = false, &block)
  raise ArgumentError if block and !not_set
  value, not_set = block, false if block

  if not_set
    raise ArgumentError unless option.respond_to?(:each)
    option.each { |k,v| set(k, v) }
    return self
  end

  if respond_to?("#{option}=") and not ignore_setter
    return __send__("#{option}=", value)
  end

  setter = proc { |val| set option, val, true }
  getter = proc { value }

  case value
  when Proc
    getter = value
  when Symbol, Integer, FalseClass, TrueClass, NilClass
    getter = value.inspect
  when Hash
    setter = proc do |val|
      val = value.merge val if Hash === val
      set option, val, true
    end
  end

  define_singleton("#{option}=", setter)
  define_singleton(option, getter)
  define_singleton("#{option}?", "!!#{option}") unless method_defined? "#{option}?"
  self
end
setup_common_logger(builder) click to toggle source
# File lib/sinatra/base.rb, line 1709
def setup_common_logger(builder)
  builder.use Sinatra::CommonLogger
end
setup_custom_logger(builder) click to toggle source
# File lib/sinatra/base.rb, line 1713
def setup_custom_logger(builder)
  if logging.respond_to? :to_int
    builder.use Rack::Logger, logging
  else
    builder.use Rack::Logger
  end
end
setup_default_middleware(builder) click to toggle source
# File lib/sinatra/base.rb, line 1682
def setup_default_middleware(builder)
  builder.use ExtendedRack
  builder.use ShowExceptions       if show_exceptions?
  builder.use Rack::MethodOverride if method_override?
  builder.use Rack::Head
  setup_logging    builder
  setup_sessions   builder
  setup_protection builder
end
setup_logging(builder) click to toggle source
# File lib/sinatra/base.rb, line 1696
def setup_logging(builder)
  if logging?
    setup_common_logger(builder)
    setup_custom_logger(builder)
  elsif logging == false
    setup_null_logger(builder)
  end
end
setup_middleware(builder) click to toggle source
# File lib/sinatra/base.rb, line 1692
def setup_middleware(builder)
  middleware.each { |c,a,b| builder.use(c, *a, &b) }
end
setup_null_logger(builder) click to toggle source
# File lib/sinatra/base.rb, line 1705
def setup_null_logger(builder)
  builder.use Rack::NullLogger
end
setup_protection(builder) click to toggle source
# File lib/sinatra/base.rb, line 1721
def setup_protection(builder)
  return unless protection?
  options = Hash === protection ? protection.dup : {}
  options = {
    img_src:  "'self' data:",
    font_src: "'self'"
  }.merge options

  protect_session = options.fetch(:session) { sessions? }
  options[:without_session] = !protect_session

  options[:reaction] ||= :drop_session

  builder.use Rack::Protection, options
end
setup_sessions(builder) click to toggle source
# File lib/sinatra/base.rb, line 1737
def setup_sessions(builder)
  return unless sessions?
  options = {}
  options[:secret] = session_secret if session_secret?
  options.merge! sessions.to_hash if sessions.respond_to? :to_hash
  builder.use session_store, options
end
setup_traps() click to toggle source
# File lib/sinatra/base.rb, line 1581
def setup_traps
  if traps?
    at_exit { quit! }

    [:INT, :TERM].each do |signal|
      old_handler = trap(signal) do
        quit!
        old_handler.call if old_handler.respond_to?(:call)
      end
    end

    set :traps, false
  end
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, line 1558
def start_server(handler, server_settings, handler_name)
  # Ensure we initialize middleware before startup, to match standard Rack
  # behavior, by ensuring an instance exists:
  prototype
  # Run the instance we created:
  handler.run(self, **server_settings) do |server|
    unless suppress_messages?
      $stderr.puts "== Sinatra (v#{Sinatra::VERSION}) has taken the stage on #{port} for #{environment} with backup from #{handler_name}"
    end

    setup_traps
    set :running_server, server
    set :handler_name,   handler_name
    server.threaded = settings.threaded if server.respond_to? :threaded=

    yield server if block_given?
  end
end
stop!()
Alias for: quit!
suppress_messages?() click to toggle source
# File lib/sinatra/base.rb, line 1577
def suppress_messages?
  handler_name =~ /cgi/i || quiet
end
synchronize() { || ... } click to toggle source
# File lib/sinatra/base.rb, line 1763
def synchronize(&block)
  if lock?
    @@mutex.synchronize(&block)
  else
    yield
  end
end
template(name, &block) click to toggle source

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

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

Use the specified Rack middleware

# File lib/sinatra/base.rb, line 1468
def use(middleware, *args, &block)
  @prototype = nil
  @middleware << [middleware, args, block]
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, line 1611
def user_agent(pattern)
  condition do
    if request.user_agent.to_s =~ pattern
      @params[:agent] = $~[1..-1]
      true
    else
      false
    end
  end
end
Also aliased as: agent
warn(message) click to toggle source

used for deprecation warnings

Calls superclass method
# File lib/sinatra/base.rb, line 1772
def warn(message)
  super message + "\n\tfrom #{cleaned_caller.first.join(':')}"
end

Public Instance Methods

call(env) click to toggle source

Rack call interface.

# File lib/sinatra/base.rb, line 926
def call(env)
  dup.call!(env)
end
forward() click to toggle source

Forward the request to the downstream app – middleware only.

# File lib/sinatra/base.rb, line 982
def forward
  fail "downstream app not set" unless @app.respond_to? :call
  status, headers, body = @app.call env
  @response.status = status
  @response.body = body
  @response.headers.merge! headers
  nil
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, line 969
def halt(*response)
  response = response.first if response.length == 1
  throw :halt, response
end
options() click to toggle source
# File lib/sinatra/base.rb, line 961
def options
  warn "Sinatra::Base#options is deprecated and will be removed, " \
    "use #settings instead."
  settings
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, line 977
def pass(&block)
  throw :pass, block
end
settings() click to toggle source

Access settings defined with ::set.

# File lib/sinatra/base.rb, line 957
def settings
  self.class.settings
end

Private Instance Methods

dispatch!() click to toggle source

Dispatch a request with error handling.

# File lib/sinatra/base.rb, line 1114
def dispatch!
  # Avoid passing frozen string in force_encoding
  @params.merge!(@request.params).each do |key, val|
    next unless val.respond_to?(:force_encoding)
    val = val.dup if val.frozen?
    @params[key] = force_encoding(val)
  end

  invoke do
    static! if settings.static? && (request.get? || request.head?)
    filter! :before do
      @pinned_response = !@response['Content-Type'].nil?
    end
    route!
  end
rescue ::Exception => boom
  invoke { handle_exception!(boom) }
ensure
  begin
    filter! :after unless env['sinatra.static_file']
  rescue ::Exception => boom
    invoke { handle_exception!(boom) } unless @env['sinatra.error']
  end
end
dump_errors!(boom) click to toggle source
# File lib/sinatra/base.rb, line 1197
def dump_errors!(boom)
  msg = ["#{Time.now.strftime("%Y-%m-%d %H:%M:%S")} - #{boom.class} - #{boom.message}:", *boom.backtrace].join("\n\t")
  @env['rack.errors'].puts(msg)
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, line 1182
def error_block!(key, *block_params)
  base = settings
  while base.respond_to?(:errors)
    next base = base.superclass unless args_array = base.errors[key]
    args_array.reverse_each do |args|
      first = args == args_array.first
      args += [block_params]
      resp = process_route(*args)
      return resp unless resp.nil? && !first
    end
  end
  return false unless key.respond_to? :superclass and key.superclass < Exception
  error_block!(key.superclass, *block_params)
end
filter!(type, base = settings) { |result| ... } 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, line 995
def filter!(type, base = settings)
  filter! type, base.superclass if base.superclass.respond_to?(:filters)
  base.filters[type].each do |args|
    result = process_route(*args)
    yield result if block_given?
  end
end
force_encoding(*args) click to toggle source
# File lib/sinatra/base.rb, line 1798
def force_encoding(*args) settings.force_encoding(*args) end
handle_exception!(boom) click to toggle source

Error handling during requests.

# File lib/sinatra/base.rb, line 1140
def handle_exception!(boom)
  if error_params = @env['sinatra.error.params']
    @params = @params.merge(error_params)
  end
  @env['sinatra.error'] = boom

  if boom.respond_to? :http_status
    status(boom.http_status)
  elsif settings.use_code? and boom.respond_to? :code and boom.code.between? 400, 599
    status(boom.code)
  else
    status(500)
  end

  status(500) unless status.between? 400, 599

  if server_error?
    dump_errors! boom if settings.dump_errors?
    raise boom if settings.show_exceptions? and settings.show_exceptions != :after_handler
  elsif not_found?
    headers['X-Cascade'] = 'pass' if settings.x_cascade?
  end

  if res = error_block!(boom.class, boom) || error_block!(status, boom)
    return res
  end

  if not_found? || bad_request?
    if boom.message && boom.message != boom.class.name
      body boom.message
    else
      content_type 'text/html'
      body '<h1>' + (not_found? ? 'Not Found' : 'Bad Request') + '</h1>'
    end
  end

  return unless server_error?
  raise boom if settings.raise_errors? or settings.show_exceptions?
  error_block! Exception, boom
end
invoke() { || ... } click to toggle source

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

# File lib/sinatra/base.rb, line 1098
def invoke
  res = catch(:halt) { yield }

  res = [res] if Integer === res or String === res
  if Array === res and Integer === res.first
    res = res.dup
    status(res.shift)
    body(res.pop)
    headers(*res)
  elsif res.respond_to? :each
    body res
  end
  nil # avoid double setting the same response tuple twice
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, line 1038
def process_route(pattern, conditions, block = nil, values = [])
  route = @request.path_info
  route = '/' if route.empty? and not settings.empty_path_info?
  route = route[0..-2] if !settings.strict_paths? && route != '/' && route.end_with?('/')
  return unless params = pattern.params(route)

  params.delete("ignore") # TODO: better params handling, maybe turn it into "smart" object or detect changes
  force_encoding(params)
  @params = @params.merge(params) if params.any?

  regexp_exists = pattern.is_a?(Mustermann::Regular) || (pattern.respond_to?(:patterns) && pattern.patterns.any? {|subpattern| subpattern.is_a?(Mustermann::Regular)} )
  if regexp_exists
    captures           = pattern.match(route).captures.map { |c| URI_INSTANCE.unescape(c) if c }
    values            += captures
    @params[:captures] = force_encoding(captures) unless captures.nil? || captures.empty?
  else
    values += params.values.flatten
  end

  catch(:pass) do
    conditions.each { |c| throw :pass if c.bind(self).call == false }
    block ? block[self, values] : yield(self, values)
  end
rescue
  @env['sinatra.error.params'] = @params
  raise
ensure
  params ||= {}
  params.each { |k, _| @params.delete(k) } unless @env['sinatra.error.params']
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, line 1004
def route!(base = settings, pass_block = nil)
  if routes = base.routes[@request.request_method]
    routes.each do |pattern, conditions, block|
      @response.delete_header('Content-Type') unless @pinned_response

      returned_pass_block = process_route(pattern, conditions) do |*args|
        env['sinatra.route'] = "#{@request.request_method} #{pattern}"
        route_eval { block[*args] }
      end

      # don't wipe out pass_block in superclass
      pass_block = returned_pass_block if returned_pass_block
    end
  end

  # Run routes defined in superclass.
  if base.superclass.respond_to?(:routes)
    return route!(base.superclass, pass_block)
  end

  route_eval(&pass_block) if pass_block
  route_missing
end
route_eval() { || ... } click to toggle source

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

# File lib/sinatra/base.rb, line 1029
def route_eval
  throw :halt, yield
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, line 1074
def route_missing
  if @app
    forward
  else
    raise NotFound, "#{request.request_method} #{request.path_info}"
  end
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, line 1084
def static!(options = {})
  return if (public_dir = settings.public_folder).nil?
  path = "#{public_dir}#{URI_INSTANCE.unescape(request.path_info)}"
  return unless valid_path?(path)

  path = File.expand_path(path)
  return unless File.file?(path)

  env['sinatra.static_file'] = path
  cache_control(*settings.static_cache_control) if settings.static_cache_control?
  send_file path, options.merge(:disposition => nil)
end