class Sinatra::Base

Base class for all Sinatra applications and middleware.

def self.force_encoding(data, encoding = default_encoding)

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

def self.force_encoding(data, *) data end

def self.force_encoding(data, *) data end

def self.settings

Access settings defined with Base.set.
def self.settings
  self
end

def add_filter(type, path = nil, options = {}, &block)

add a filter
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

def after(path = nil, options = {}, &block)

response.
context as route handlers and may access/modify the request and
Define an after filter; runs after all requests within the same
def after(path = nil, options = {}, &block)
  add_filter(:after, path, options, &block)
end

def before(path = nil, options = {}, &block)

response.
context as route handlers and may access/modify the request and
Define a before filter; runs before all requests within the same
def before(path = nil, options = {}, &block)
  add_filter(:before, path, options, &block)
end

def build(app)

the given +app+ as end point.
Creates a Rack::Builder instance with all the middleware set up and
def build(app)
  builder = Rack::Builder.new
  setup_default_middleware builder
  setup_middleware builder
  builder.run app
  builder
end

def call(env)

Rack call interface.
def call(env)
  dup.call!(env)
end

def call(env)

def call(env)
  synchronize { prototype.call(env) }
end

def call!(env) # :nodoc:

:nodoc:
def call!(env) # :nodoc:
  @env      = env
  @request  = Request.new(env)
  @response = Response.new
  @params   = indifferent_params(@request.params)
  template_cache.clear if settings.reload_templates
  force_encoding(@params)
  @response['Content-Type'] = nil
  invoke { dispatch! }
  invoke { error_block!(response.status) } unless @env['sinatra.error']
  unless @response['Content-Type']
    if Array === body and body[0].respond_to? :content_type
      content_type body[0].content_type
    else
      content_type :html
    end
  end
  @response.finish
end

def caller_files

line / method information; the resulting array contains filenames only.
Like Kernel#caller but excluding certain magic entries and without
def caller_files
  cleaned_caller(1).flatten
end

def caller_locations

first element being the file, and the second being the line.
Like caller_files, but containing Arrays rather than strings with the
def caller_locations
  cleaned_caller 2
end

def cleaned_caller(keep = 3)

Like Kernel#caller but excluding certain magic entries
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

def compile(path)

def compile(path)
  keys = []
  if path.respond_to? :to_str
    ignore = ""
    pattern = path.to_str.gsub(/[^\?\%\\\/\:\*\w]/) do |c|
      ignore << escaped(c).join if c.match(/[\.@]/)
      patt = encoded(c)
      patt.gsub(/%[\da-fA-F]{2}/) do |match|
        match.split(//).map {|char| char =~ /[A-Z]/ ? "[#{char}#{char.tr('A-Z', 'a-z')}]" : char}.join
      end
    end
    pattern.gsub!(/((:\w+)|\*)/) do |match|
      if match == "*"
        keys << 'splat'
        "(.*?)"
      else
        keys << $2[1..-1]
        ignore_pattern = safe_ignore(ignore)
        ignore_pattern
      end
    end
    [/\A#{pattern}\z/, 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

def compile!(verb, path, block, options = {})

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

def condition(name = "#{caller.first[/`.*'/]} condition", &block)

block returns false.
Add a route condition. The route is considered non-matching when the
def condition(name = "#{caller.first[/`.*'/]} condition", &block)
  @conditions << generate_method(name, &block)
end

def configure(*envs, &block)

Allows scoping of settings for certain environments.
Set configuration options for Sinatra and/or the app.
def configure(*envs, &block)
  yield self if envs.empty? || envs.include?(environment.to_sym)
end

def define_singleton(name, content = Proc.new)

Dynamically defines a method on settings.
def define_singleton(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

def delete(path, opts = {}, &bk) route 'DELETE', path, opts, &bk end

def delete(path, opts = {}, &bk)  route 'DELETE',  path, opts, &bk end

def detect_rack_handler

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

def development?; environment == :development end

def development?; environment == :development end

def disable(*opts)

Same as calling `set :option, false` for each of the given options.
def disable(*opts)
  opts.each { |key| set(key, false) }
end

def dispatch!

Dispatch a request with error handling.
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

def dump_errors!(boom)

def dump_errors!(boom)
  msg = ["#{boom.class} - #{boom.message}:", *boom.backtrace].join("\n\t")
  @env['rack.errors'].puts(msg)
end

def enable(*opts)

Same as calling `set :option, true` for each of the given options.
def enable(*opts)
  opts.each { |key| set(key, true) }
end

def encoded(char)

def encoded(char)
  enc = URI.escape(char)
  enc = "(?:#{escaped(char, enc).join('|')})" if enc == char
  enc = "(?:#{enc}|#{encoded('+')})" if char == " "
  enc
end

def error(*codes, &block)

handled.
class, or an HTTP status code to specify which errors should be
Define a custom error handler. Optionally takes either an Exception
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

def error_block!(key, *block_params)

Find an custom error block for the key(s) specified.
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

def escaped(char, enc = URI.escape(char))

def escaped(char, enc = URI.escape(char))
  [Regexp.escape(enc), URI.escape(char, /./)]
end

def extensions

Extension modules registered on this class and all superclasses.
def extensions
  if superclass.respond_to?(:extensions)
    (@extensions + superclass.extensions).uniq
  else
    @extensions
  end
end

def filter!(type, base = settings)

Run filters defined on the class and all superclasses.
def filter!(type, base = settings)
  filter! type, base.superclass if base.superclass.respond_to?(:filters)
  base.filters[type].each { |args| process_route(*args) }
end

def force_encoding(*args) settings.force_encoding(*args) end

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

* casting params to Encoding.default_external
* defaulting to UTF-8
Fixes encoding issues by
def force_encoding(*args) settings.force_encoding(*args) end

def forward

Forward the request to the downstream app -- middleware only.
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

def generate_method(method_name, &block)

def generate_method(method_name, &block)
  define_method(method_name, &block)
  method = instance_method method_name
  remove_method method_name
  method
end

def get(path, opts = {}, &block)

a `HEAD` handler.
Defining a `GET` handler also automatically defines
def get(path, opts = {}, &block)
  conditions = @conditions.dup
  route('GET', path, opts, &block)
  @conditions = conditions
  route('HEAD', path, opts, &block)
end

def halt(*response)

of the request, and returns the specified response.
Exit the current block, halts any further processing
def halt(*response)
  response = response.first if response.length == 1
  throw :halt, response
end

def handle_exception!(boom)

Error handling during requests.
def handle_exception!(boom)
  @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
  end
  if not_found?
    headers['X-Cascade'] = 'pass' if settings.x_cascade?
    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

def head(path, opts = {}, &bk) route 'HEAD', path, opts, &bk end

def head(path, opts = {}, &bk)    route 'HEAD',    path, opts, &bk end

def helpers(*extensions, &block)

in `extensions` available to the handlers and templates
Makes the methods defined in the block and in the Modules given
def helpers(*extensions, &block)
  class_eval(&block)   if block_given?
  include(*extensions) if extensions.any?
end

def host_name(pattern)

Condition for matching host name. Parameter might be String or Regexp.
def host_name(pattern)
  condition { pattern === request.host }
end

def indifferent_hash

Creates a Hash with indifferent access.
def indifferent_hash
  Hash.new {|hash,key| hash[key.to_s] if Symbol === key }
end

def indifferent_params(object)

Enable string or symbol key access to the nested params hash.
def indifferent_params(object)
  case object
  when Hash
    new_hash = indifferent_hash
    object.each { |key, value| new_hash[key] = indifferent_params(value) }
    new_hash
  when Array
    object.map { |item| indifferent_params(item) }
  else
    object
  end
end

def inherited(subclass)

def inherited(subclass)
  subclass.reset!
  subclass.set :app_file, caller_files.first unless subclass.app_file?
  super
end

def initialize(app = nil)

def initialize(app = nil)
  super()
  @app = app
  @template_cache = Tilt::Cache.new
  yield self if block_given?
end

def inline_templates=(file = nil)

when no file is specified.
Load embeded templates from the file; uses the caller's __FILE__
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('', encoding)
        templates[$1.to_sym] = [template, file, lines]
      elsif template
        template << line
      end
    end
  end
end

def invoke

Run the block with 'throw :halt' support and apply result to the response.
def invoke
  res = catch(:halt) { yield }
  res = [res] if Fixnum === res or String === res
  if Array === res and Fixnum === 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

def invoke_hook(name, *args)

def invoke_hook(name, *args)
  extensions.each { |e| e.send(name, *args) if e.respond_to?(name) }
end

def layout(name = :layout, &block)

Define the layout template. The block must return the template source.
def layout(name = :layout, &block)
  template name, &block
end

def middleware

Middleware used in this class and all superclasses.
def middleware
  if superclass.respond_to?(:middleware)
    superclass.middleware + @middleware
  else
    @middleware
  end
end

def mime_type(type, value = nil)

Lookup or register a mime type in Rack's mime registry.
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

def mime_types(type)

mime_types :js # => ['application/javascript', 'text/javascript']
mime_types :html # => ['text/html']
provides all mime types matching type, including deprecated types:
def mime_types(type)
  type = mime_type type
  type =~ /^application\/(xml|javascript)$/ ? [type, "text/#$1"] : [type]
end

def new(*args, &bk)

an instance of the class new was called on.
pipeline. The object is guaranteed to respond to #call but may not be
Create a new instance of the class fronted by its middleware
def new(*args, &bk)
  instance = new!(*args, &bk)
  Wrapper.new(build(instance).to_app, instance)
end

def not_found(&block)

Sugar for `error(404) { ... }`
def not_found(&block)
  error(404, &block)
  error(Sinatra::NotFound, &block)
end

def options

def options
  warn "Sinatra::Base#options is deprecated and will be removed, " \
    "use #settings instead."
  settings
end

def options(path, opts = {}, &bk) route 'OPTIONS', path, opts, &bk end

def options(path, opts = {}, &bk) route 'OPTIONS', path, opts, &bk end

def pass(&block)

return a 404 response.
If there are no more matching routes, Sinatra will
Pass control to the next matching route.
def pass(&block)
  throw :pass, block
end

def patch(path, opts = {}, &bk) route 'PATCH', path, opts, &bk end

def patch(path, opts = {}, &bk)   route 'PATCH',   path, opts, &bk end

def post(path, opts = {}, &bk) route 'POST', path, opts, &bk end

def post(path, opts = {}, &bk)    route 'POST',    path, opts, &bk end

def process_route(pattern, keys, conditions, block = nil, values = [])

Returns pass block.

Revert params afterwards.
with keys and call the given block.
If the current request matches pattern and conditions, fill params
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(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

def production?; environment == :production end

def production?;  environment == :production  end

def prototype

The prototype instance used to process requests.
def prototype
  @prototype ||= new
end

def provides(*types)

Condition for matching mimetypes. Accepts file extensions.
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

def public=(value)

def public=(value)
  warn ":public is no longer used to avoid overloading Module#public, use :public_dir instead"
  set(:public_folder, value)
end

def public_dir

def public_dir
  public_folder
end

def public_dir=(value)

def public_dir=(value)
  self.public_folder = value
end

def put(path, opts = {}, &bk) route 'PUT', path, opts, &bk end

def put(path, opts = {}, &bk)     route 'PUT',     path, opts, &bk end

def quit!(server, handler_name)

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/i
end

def register(*extensions, &block)

extension will be created and registered on the fly.
Register an extension. Alternatively take a block from which an
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

def reset!

current class (not routes/filters/... defined by its superclass).
Removes all routes, filters, middleware and extension hooks from the
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

def route(verb, path, options = {}, &block)

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

def route!(base = settings, pass_block = nil)

Run routes defined on the class and all superclasses.
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

def route_eval

Run a route block and throw :halt with the result.
def route_eval
  throw :halt, yield
end

def route_missing

custom route miss logic.
a NotFound exception. Subclasses can override this method to perform
as middleware (@app is non-nil); when no downstream app is set, raise
implementation is to forward the request downstream when running
No matching route was found or all routes passed. The default
def route_missing
  if @app
    forward
  else
    raise NotFound
  end
end

def run!(options = {})

with the constructed handler once we have taken the stage.
Thin, Puma, Mongrel, or WEBrick (in that order). If given a block, will call
Run the Sinatra app as a self-hosted server using
def run!(options = {})
  set options
  handler         = detect_rack_handler
  handler_name    = handler.name.gsub(/.*::/, '')
  server_settings = settings.respond_to?(:server_settings) ? settings.server_settings : {}
  handler.run self, server_settings.merge(:Port => port, :Host => bind) do |server|
    unless handler_name =~ /cgi/i
      $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

def safe_ignore(ignore)

def safe_ignore(ignore)
  unsafe_ignore = []
  ignore = ignore.gsub(/%[\da-fA-F]{2}/) do |hex|
    unsafe_ignore << hex[1..2]
    ''
  end
  unsafe_patterns = unsafe_ignore.map do |unsafe|
    chars = unsafe.split(//).map do |char|
      if char =~ /[A-Z]/
        char <<= char.tr('A-Z', 'a-z')
      end
      char
    end
    "|(?:%[^#{chars[0]}].|%[#{chars[0]}][^#{chars[1]}])"
  end
  if unsafe_patterns.length > 0
    "((?:[^#{ignore}/?#%]#{unsafe_patterns.join()})+)"
  else
    "([^#{ignore}/?#]+)"
  end
end

def set(option, value = (not_set = true), ignore_setter = false, &block)

the proc will be called every time the option is accessed.
Sets an option to the given value. If the value is a proc,
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("#{option}=", setter) if setter
  define_singleton(option, getter) if getter
  define_singleton("#{option}?", "!!#{option}") unless method_defined? "#{option}?"
  self
end

def settings

Access settings defined with Base.set.
def settings
  self.class.settings
end

def setup_common_logger(builder)

def setup_common_logger(builder)
  builder.use Sinatra::CommonLogger
end

def setup_custom_logger(builder)

def setup_custom_logger(builder)
  if logging.respond_to? :to_int
    builder.use Rack::Logger, logging
  else
    builder.use Rack::Logger
  end
end

def setup_default_middleware(builder)

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

def setup_logging(builder)

def setup_logging(builder)
  if logging?
    setup_common_logger(builder)
    setup_custom_logger(builder)
  elsif logging == false
    setup_null_logger(builder)
  end
end

def setup_middleware(builder)

def setup_middleware(builder)
  middleware.each { |c,a,b| builder.use(c, *a, &b) }
end

def setup_null_logger(builder)

def setup_null_logger(builder)
  builder.use Rack::NullLogger
end

def setup_protection(builder)

def setup_protection(builder)
  return unless protection?
  options = Hash === protection ? protection.dup : {}
  protect_session  = options.fetch(:session) { sessions? }
  options[:except] = Array options[:except]
  options[:except] += [:session_hijacking, :remote_token] unless protect_session
  options[:reaction] ||= :drop_session
  builder.use Rack::Protection, options
end

def setup_sessions(builder)

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

def static!

a matching file is found, returns nil otherwise.
Attempt to serve static files from public directory. Throws :halt when
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

def synchronize(&block)

def synchronize(&block)
  if lock?
    @@mutex.synchronize(&block)
  else
    yield
  end
end

def template(name, &block)

Define a named template. The block must return the template source.
def template(name, &block)
  filename, line = caller_locations.first
  templates[name] = [block, filename, line.to_i]
end

def test?; environment == :test end

def test?;        environment == :test        end

def use(middleware, *args, &block)

Use the specified Rack middleware
def use(middleware, *args, &block)
  @prototype = nil
  @middleware << [middleware, args, block]
end

def user_agent(pattern)

Will set params[:agent].
Condition for matching user agent. Parameter should be Regexp.
def user_agent(pattern)
  condition do
    if request.user_agent.to_s =~ pattern
      @params[:agent] = $~[1..-1]
      true
    else
      false
    end
  end
end

def warn(message)

used for deprecation warnings
def warn(message)
  super message + "\n\tfrom #{cleaned_caller.first.join(':')}"
end