class Sinatra::Helpers::Stream::Base

Base class for all Sinatra applications and middleware.

Constants

URI

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

build(builder, *args, &bk) click to toggle source

Creates a Rack::Builder instance with all the middleware set up and an instance of this class as end point.

# File lib/sinatra/base.rb, line 1409
def build(builder, *args, &bk)
  setup_default_middleware builder
  setup_middleware builder
  builder.run new!(*args, &bk)
  builder
end
call(env) click to toggle source
# File lib/sinatra/base.rb, line 1416
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 1523
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 1529
def caller_locations
  cleaned_caller 2
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 1355
def configure(*envs, &block)
  yield self if envs.empty? || envs.include?(environment.to_sym)
end
delete(path, opts={}, &bk) click to toggle source
# File lib/sinatra/base.rb, line 1257
def delete(path, opts={}, &bk)  route 'DELETE',  path, opts, &bk end
development?() click to toggle source
# File lib/sinatra/base.rb, line 1349
def development?; environment == :development 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 1247
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 1258
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 1333
def helpers(*extensions, &block)
  class_eval(&block)   if block_given?
  include(*extensions) if extensions.any?
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 1403
def new(*args, &bk)
  build(Rack::Builder.new, *args, &bk).to_app
end
new(app=nil) { |self| ... } click to toggle source
Calls superclass method Sinatra::Helpers::Stream::Templates.new
# File lib/sinatra/base.rb, line 771
def initialize(app=nil)
  super()
  @app = app
  @template_cache = Tilt::Cache.new
  yield self if block_given?
end
Also aliased as: new!
new!(app=nil)

Create a new instance without middleware in front of it.

Alias for: new
options(path, opts={}, &bk) click to toggle source
# File lib/sinatra/base.rb, line 1259
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 1260
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 1256
def post(path, opts={}, &bk)    route 'POST',    path, opts, &bk end
production?() click to toggle source
# File lib/sinatra/base.rb, line 1350
def production?;  environment == :production  end
prototype() click to toggle source

The prototype instance used to process requests.

# File lib/sinatra/base.rb, line 1393
def prototype
  @prototype ||= new
end
put(path, opts={}, &bk) click to toggle source
# File lib/sinatra/base.rb, line 1255
def put(path, opts={}, &bk)     route 'PUT',     path, opts, &bk end
quit!(server, handler_name) click to toggle source
# File lib/sinatra/base.rb, line 1365
def quit!(server, handler_name)
  # Use Thin's hard #stop! if available, otherwise just #stop.
  server.respond_to?(:stop!) ? server.stop! : server.stop
  $stderr.puts "\n== Sinatra has ended his set (crowd applauds)" unless handler_name =~/cgi/
end
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 1340
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
run!(options={}) { |server| ... } click to toggle source

Run the Sinatra app as a self-hosted server using Thin, 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 1374
def run!(options={})
  set options
  handler      = detect_rack_handler
  handler_name = handler.name.gsub(/.*::/, '')
  handler.run self, :Host => bind, :Port => port do |server|
    unless handler_name =~ /cgi/
      $stderr.puts "== Sinatra/#{Sinatra::VERSION} has taken the stage " +
      "on #{port} for #{environment} with backup from #{handler_name}"
    end
    [:INT, :TERM].each { |sig| trap(sig) { quit!(server, handler_name) } }
    server.threaded = settings.threaded if server.respond_to? :threaded=
    set :running, true
    yield server if block_given?
  end
rescue Errno::EADDRINUSE
  $stderr.puts "== Someone is already performing on port #{port}!"
end
settings() click to toggle source

Access settings defined with ::set.

# File lib/sinatra/base.rb, line 809
def self.settings
  self
end
test?() click to toggle source
# File lib/sinatra/base.rb, line 1351
def test?;        environment == :test        end
use(middleware, *args, &block) click to toggle source

Use the specified Rack middleware

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

Private Class Methods

add_filter(type, path = nil, options = {}, &block) click to toggle source

add a filter

# File lib/sinatra/base.rb, line 1185
def add_filter(type, path = nil, options = {}, &block)
  path, options = //, path if path.respond_to?(:each_pair)
  filters[type] << compile!(type, path || //, block, options)
end
after(path = nil, 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 1180
def after(path = nil, options = {}, &block)
  add_filter(:after, path, options, &block)
end
agent(pattern)
Alias for: user_agent
before(path = nil, 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 1173
def before(path = nil, options = {}, &block)
  add_filter(:before, path, options, &block)
end
cleaned_caller(keep = 3) click to toggle source

Like Kernel#caller but excluding certain magic entries

# File lib/sinatra/base.rb, line 1540
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) click to toggle source
# File lib/sinatra/base.rb, line 1296
def compile(path)
  keys = []
  if path.respond_to? :to_str
    pattern = path.to_str.gsub(/[^\?\%\\/\:\*\w]/) { |c| encoded(c) }
    pattern.gsub!(/((:\w+)|\*)/) do |match|
      if match == "*"
        keys << 'splat'
        "(.*?)"
      else
        keys << $2[1..-1]
        "([^/?#]+)"
      end
    end
    [/^#{pattern}$/, keys]
  elsif path.respond_to?(:keys) && path.respond_to?(:match)
    [path, path.keys]
  elsif path.respond_to?(:names) && path.respond_to?(:match)
    [path, path.names]
  elsif path.respond_to? :match
    [path, keys]
  else
    raise TypeError, path
  end
end
compile!(verb, path, block, options = {}) click to toggle source
# File lib/sinatra/base.rb, line 1284
def compile!(verb, path, block, options = {})
  options.each_pair { |option, args| send(option, *args) }
  method_name             = "#{verb} #{path}"
  unbound_method          = generate_method(method_name, &block)
  pattern, keys           = compile path
  conditions, @conditions = @conditions, []

  [ pattern, keys, conditions, block.arity != 0 ?
      proc { |a,p| unbound_method.bind(a).call(*p) } :
      proc { |a,p| unbound_method.bind(a).call } ]
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 1192
def condition(name = "#{caller.first[/`.*'/]} condition", &block)
  @conditions << generate_method(name, &block)
end
define_singleton_method(name, content = Proc.new) click to toggle source

Dynamically defines a method on settings.

# File lib/sinatra/base.rb, line 1203
def define_singleton_method(name, content = Proc.new)
  # replace with call to singleton_class once we're 1.9 only
  (class << self; self; end).class_eval do
    undef_method(name) if method_defined? name
    String === content ? class_eval("def #{name}() #{content}; end") : define_method(name, &content)
  end
end
detect_rack_handler() click to toggle source
# File lib/sinatra/base.rb, line 1477
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
disable(*opts) click to toggle source

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

# File lib/sinatra/base.rb, line 1091
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 1086
def enable(*opts)
  opts.each { |key| set(key, true) }
end
encoded(char) click to toggle source
# File lib/sinatra/base.rb, line 1323
def encoded(char)
  enc = URI.escape(char)
  enc = "(?:#{Regexp.escape enc}|#{URI.escape char, /./})" if enc == char
  enc = "(?:#{enc}|#{encoded('+')})" if char == " "
  enc
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 1098
def error(*codes, &block)
  args  = compile! "ERROR", //, block
  codes = codes.map { |c| Array(c) }.flatten
  codes << Exception if codes.empty?
  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 1031
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
# File lib/sinatra/base.rb, line 1555
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 1277
def generate_method(method_name, &block)
  define_method(method_name, &block)
  method = instance_method method_name
  remove_method method_name
  method
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 1212
def host_name(pattern)
  condition { pattern === request.host }
end
inherited(subclass) click to toggle source
Calls superclass method
# File lib/sinatra/base.rb, line 1488
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 embeded templates from the file; uses the caller's __FILE__ when no file is specified.

# File lib/sinatra/base.rb, line 1123
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+)/
      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('', 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 1273
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 1117
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 1040
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 1155
def mime_type(type, value=nil)
  return type if type.nil? || 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 1165
def mime_types(type)
  type = mime_type type
  type =~ /^application\/(xml|javascript)$/ ? [type, "text/#$1"] : [type]
end
not_found(&block) click to toggle source

Sugar for `error(404) { … }`

# File lib/sinatra/base.rb, line 1106
def not_found(&block)
  error 404, &block
end
provides(*types) click to toggle source

Condition for matching mimetypes. Accepts file extensions.

# File lib/sinatra/base.rb, line 1231
def provides(*types)
  types.map! { |t| mime_types(t) }
  types.flatten!
  condition do
    if type = request.preferred_type(types)
      content_type(type)
      true
    else
      false
    end
  end
end
public=(value) click to toggle source
# File lib/sinatra/base.rb, line 1196
def public=(value)
  warn ":public is no longer used to avoid overloading Module#public, use :public_folder instead"
  set(:public_folder, value)
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 1014
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 1263
def route(verb, path, options={}, &block)
  # Because of self.options.host
  host_name(options.delete(:host)) if options.key?(:host)
  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
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 1050
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, Fixnum, 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_method("#{option}=", setter) if setter
  define_singleton_method(option, getter) if getter
  define_singleton_method("#{option}?", "!!#{option}") unless method_defined? "#{option}?"
  self
end
setup_common_logger(builder) click to toggle source
# File lib/sinatra/base.rb, line 1448
def setup_common_logger(builder)
  builder.use Sinatra::CommonLogger
end
setup_custom_logger(builder) click to toggle source
# File lib/sinatra/base.rb, line 1452
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 1421
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 1435
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 1431
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 1444
def setup_null_logger(builder)
  builder.use Rack::NullLogger
end
setup_protection(builder) click to toggle source
# File lib/sinatra/base.rb, line 1460
def setup_protection(builder)
  return unless protection?
  options = Hash === protection ? protection.dup : {}
  options[:except] = Array options[:except]
  options[:except] += [:session_hijacking, :remote_token] unless sessions?
  options[:reaction] ||= :drop_session
  builder.use Rack::Protection, options
end
setup_sessions(builder) click to toggle source
# File lib/sinatra/base.rb, line 1469
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 Rack::Session::Cookie, options
end
synchronize() { || ... } click to toggle source
# File lib/sinatra/base.rb, line 1495
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 1111
def template(name, &block)
  filename, line = caller_locations.first
  templates[name] = [block, filename, line.to_i]
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 1218
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 1535
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 779
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 839
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 826
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 818
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 834
def pass(&block)
  throw :pass, block
end
settings() click to toggle source

Access settings defined with ::set.

# File lib/sinatra/base.rb, line 814
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 959
def dispatch!
  invoke do
    static! if settings.static? && (request.get? || request.head?)
    filter! :before
    route!
  end
rescue ::Exception => boom
  invoke { handle_exception!(boom) }
ensure
  filter! :after unless env['sinatra.static_file']
end
dump_errors!(boom) click to toggle source
# File lib/sinatra/base.rb, line 1004
def dump_errors!(boom)
  msg = ["#{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 993
def error_block!(key, *block_params)
  base = settings
  while base.respond_to?(:errors)
    next base = base.superclass unless args = base.errors[key]
    args += [block_params]
    return process_route(*args)
  end
  return false unless key.respond_to? :superclass and key.superclass < Exception
  error_block!(key.superclass, *block_params)
end
filter!(type, base = settings) click to toggle source

Run filters defined on the class and all superclasses.

# File lib/sinatra/base.rb, line 850
def filter!(type, base = settings)
  filter! type, base.superclass if base.superclass.respond_to?(:filters)
  base.filters[type].each { |args| process_route(*args) }
end
force_encoding(*args) click to toggle source

Fixes encoding issues by

  • defaulting to UTF-8

  • casting params to Encoding.default_external

The latter might not be necessary if Rack handles it one day. Keep an eye on Rack's LH #100.

# File lib/sinatra/base.rb, line 1553
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 972
def handle_exception!(boom)
  @env['sinatra.error'] = boom
  status boom.respond_to?(:code) ? Integer(boom.code) : 500

  if server_error?
    dump_errors! boom if settings.dump_errors?
    raise boom if settings.show_exceptions? and settings.show_exceptions != :after_handler
  end

  if not_found?
    headers['X-Cascade'] = 'pass'
    body '<h1>Not Found</h1>'
  end

  res = error_block!(boom.class, boom) || error_block!(status, boom)
  return res if res or not server_error?
  raise boom if settings.raise_errors? or settings.show_exceptions?
  error_block! Exception, boom
end
indifferent_hash() click to toggle source

Creates a Hash with indifferent access.

# File lib/sinatra/base.rb, line 940
def indifferent_hash
  Hash.new {|hash,key| hash[key.to_s] if Symbol === key }
end
indifferent_params(params) click to toggle source

Enable string or symbol key access to the nested params hash.

# File lib/sinatra/base.rb, line 931
def indifferent_params(params)
  params = indifferent_hash.merge(params)
  params.each do |key, value|
    next unless value.is_a?(Hash)
    params[key] = indifferent_params(value)
  end
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 945
def invoke
  res = catch(:halt) { yield }
  res = [res] if Fixnum === res or String === res
  if Array === res and Fixnum === res.first
    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, keys, 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 884
def process_route(pattern, keys, conditions, block = nil, values = [])
  route = @request.path_info
  route = '/' if route.empty? and not settings.empty_path_info?
  return unless match = pattern.match(route)
  values += match.captures.to_a.map { |v| force_encoding URI.decode_www_form_component(v) if v }

  if values.any?
    original, @params = params, params.merge('splat' => [], 'captures' => values)
    keys.zip(values) { |k,v| Array === @params[k] ? @params[k] << v : @params[k] = v if v }
  end

  catch(:pass) do
    conditions.each { |c| throw :pass if c.bind(self).call == false }
    block ? block[self, values] : yield(self, values)
  end
ensure
  @params = original if original
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 856
def route!(base = settings, pass_block=nil)
  if routes = base.routes[@request.request_method]
    routes.each do |pattern, keys, conditions, block|
      pass_block = process_route(pattern, keys, conditions) do |*args|
        route_eval { block[*args] }
      end
    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 875
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 908
def route_missing
  if @app
    forward
  else
    raise NotFound
  end
end
static!() 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 918
def static!
  return if (public_dir = settings.public_folder).nil?
  public_dir = File.expand_path(public_dir)

  path = File.expand_path(public_dir + unescape(request.path_info))
  return unless path.start_with?(public_dir) and File.file?(path)

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