Update Vendored Rack to 1.2.0
Also update tests for itextomml 1.3.25.
This commit is contained in:
parent
4f8759cdf3
commit
6491d70326
107 changed files with 1463 additions and 2008 deletions
15
vendor/plugins/rack/lib/rack.rb
vendored
15
vendor/plugins/rack/lib/rack.rb
vendored
|
@ -1,4 +1,4 @@
|
|||
# Copyright (C) 2007, 2008, 2009 Christian Neukirchen <purl.org/net/chneukirchen>
|
||||
# Copyright (C) 2007, 2008, 2009, 2010 Christian Neukirchen <purl.org/net/chneukirchen>
|
||||
#
|
||||
# Rack is freely distributable under the terms of an MIT-style license.
|
||||
# See COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
@ -20,7 +20,7 @@ module Rack
|
|||
|
||||
# Return the Rack release as a dotted string.
|
||||
def self.release
|
||||
"1.1"
|
||||
"1.2"
|
||||
end
|
||||
|
||||
autoload :Builder, "rack/builder"
|
||||
|
@ -78,15 +78,4 @@ module Rack
|
|||
autoload :Pool, "rack/session/pool"
|
||||
autoload :Memcache, "rack/session/memcache"
|
||||
end
|
||||
|
||||
# *Adapters* connect Rack with third party web frameworks.
|
||||
#
|
||||
# Rack includes an adapter for Camping, see README for other
|
||||
# frameworks supporting Rack in their code bases.
|
||||
#
|
||||
# Refer to the submodules for framework-specific calling details.
|
||||
|
||||
module Adapter
|
||||
autoload :Camping, "rack/adapter/camping"
|
||||
end
|
||||
end
|
||||
|
|
22
vendor/plugins/rack/lib/rack/adapter/camping.rb
vendored
22
vendor/plugins/rack/lib/rack/adapter/camping.rb
vendored
|
@ -1,22 +0,0 @@
|
|||
module Rack
|
||||
module Adapter
|
||||
class Camping
|
||||
def initialize(app)
|
||||
@app = app
|
||||
end
|
||||
|
||||
def call(env)
|
||||
env["PATH_INFO"] ||= ""
|
||||
env["SCRIPT_NAME"] ||= ""
|
||||
controller = @app.run(env['rack.input'], env)
|
||||
h = controller.headers
|
||||
h.each_pair do |k,v|
|
||||
if v.kind_of? URI
|
||||
h[k] = v.to_s
|
||||
end
|
||||
end
|
||||
[controller.status, controller.headers, [controller.body.to_s]]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -35,7 +35,7 @@ module Rack
|
|||
super k.to_s, v.to_s
|
||||
end
|
||||
|
||||
UNQUOTED = ['qop', 'nc', 'stale']
|
||||
UNQUOTED = ['nc', 'stale']
|
||||
|
||||
def to_s
|
||||
inject([]) do |parts, (k, v)|
|
||||
|
|
480
vendor/plugins/rack/lib/rack/auth/openid.rb
vendored
480
vendor/plugins/rack/lib/rack/auth/openid.rb
vendored
|
@ -1,480 +0,0 @@
|
|||
# AUTHOR: blink <blinketje@gmail.com>; blink#ruby-lang@irc.freenode.net
|
||||
|
||||
gem 'ruby-openid', '~> 2' if defined? Gem
|
||||
require 'rack/request'
|
||||
require 'rack/utils'
|
||||
require 'rack/auth/abstract/handler'
|
||||
require 'uri'
|
||||
require 'openid' #gem
|
||||
require 'openid/extension' #gem
|
||||
require 'openid/store/memory' #gem
|
||||
|
||||
module Rack
|
||||
class Request
|
||||
def openid_request
|
||||
@env['rack.auth.openid.request']
|
||||
end
|
||||
|
||||
def openid_response
|
||||
@env['rack.auth.openid.response']
|
||||
end
|
||||
end
|
||||
|
||||
module Auth
|
||||
|
||||
# Rack::Auth::OpenID provides a simple method for setting up an OpenID
|
||||
# Consumer. It requires the ruby-openid library from janrain to operate,
|
||||
# as well as a rack method of session management.
|
||||
#
|
||||
# The ruby-openid home page is at http://openidenabled.com/ruby-openid/.
|
||||
#
|
||||
# The OpenID specifications can be found at
|
||||
# http://openid.net/specs/openid-authentication-1_1.html
|
||||
# and
|
||||
# http://openid.net/specs/openid-authentication-2_0.html. Documentation
|
||||
# for published OpenID extensions and related topics can be found at
|
||||
# http://openid.net/developers/specs/.
|
||||
#
|
||||
# It is recommended to read through the OpenID spec, as well as
|
||||
# ruby-openid's documentation, to understand what exactly goes on. However
|
||||
# a setup as simple as the presented examples is enough to provide
|
||||
# Consumer functionality.
|
||||
#
|
||||
# This library strongly intends to utilize the OpenID 2.0 features of the
|
||||
# ruby-openid library, which provides OpenID 1.0 compatiblity.
|
||||
#
|
||||
# NOTE: Due to the amount of data that this library stores in the
|
||||
# session, Rack::Session::Cookie may fault.
|
||||
|
||||
class OpenID
|
||||
|
||||
class NoSession < RuntimeError; end
|
||||
class BadExtension < RuntimeError; end
|
||||
# Required for ruby-openid
|
||||
ValidStatus = [:success, :setup_needed, :cancel, :failure]
|
||||
|
||||
# = Arguments
|
||||
#
|
||||
# The first argument is the realm, identifying the site they are trusting
|
||||
# with their identity. This is required, also treated as the trust_root
|
||||
# in OpenID 1.x exchanges.
|
||||
#
|
||||
# The optional second argument is a hash of options.
|
||||
#
|
||||
# == Options
|
||||
#
|
||||
# <tt>:return_to</tt> defines the url to return to after the client
|
||||
# authenticates with the openid service provider. This url should point
|
||||
# to where Rack::Auth::OpenID is mounted. If <tt>:return_to</tt> is not
|
||||
# provided, return_to will be the current url which allows flexibility
|
||||
# with caveats.
|
||||
#
|
||||
# <tt>:session_key</tt> defines the key to the session hash in the env.
|
||||
# It defaults to 'rack.session'.
|
||||
#
|
||||
# <tt>:openid_param</tt> defines at what key in the request parameters to
|
||||
# find the identifier to resolve. As per the 2.0 spec, the default is
|
||||
# 'openid_identifier'.
|
||||
#
|
||||
# <tt>:store</tt> defined what OpenID Store to use for persistant
|
||||
# information. By default a Store::Memory will be used.
|
||||
#
|
||||
# <tt>:immediate</tt> as true will make initial requests to be of an
|
||||
# immediate type. This is false by default. See OpenID specification
|
||||
# documentation.
|
||||
#
|
||||
# <tt>:extensions</tt> should be a hash of openid extension
|
||||
# implementations. The key should be the extension main module, the value
|
||||
# should be an array of arguments for extension::Request.new.
|
||||
# The hash is iterated over and passed to #add_extension for processing.
|
||||
# Please see #add_extension for further documentation.
|
||||
#
|
||||
# == Examples
|
||||
#
|
||||
# simple_oid = OpenID.new('http://mysite.com/')
|
||||
#
|
||||
# return_oid = OpenID.new('http://mysite.com/', {
|
||||
# :return_to => 'http://mysite.com/openid'
|
||||
# })
|
||||
#
|
||||
# complex_oid = OpenID.new('http://mysite.com/',
|
||||
# :immediate => true,
|
||||
# :extensions => {
|
||||
# ::OpenID::SReg => [['email'],['nickname']]
|
||||
# }
|
||||
# )
|
||||
#
|
||||
# = Advanced
|
||||
#
|
||||
# Most of the functionality of this library is encapsulated such that
|
||||
# expansion and overriding functions isn't difficult nor tricky.
|
||||
# Alternately, to avoid opening up singleton objects or subclassing, a
|
||||
# wrapper rack middleware can be composed to act upon Auth::OpenID's
|
||||
# responses. See #check and #finish for locations of pertinent data.
|
||||
#
|
||||
# == Responses
|
||||
#
|
||||
# To change the responses that Auth::OpenID returns, override the methods
|
||||
# #redirect, #bad_request, #unauthorized, #access_denied, and
|
||||
# #foreign_server_failure.
|
||||
#
|
||||
# Additionally #confirm_post_params is used when the URI would exceed
|
||||
# length limits on a GET request when doing the initial verification
|
||||
# request.
|
||||
#
|
||||
# == Processing
|
||||
#
|
||||
# To change methods of processing completed transactions, override the
|
||||
# methods #success, #setup_needed, #cancel, and #failure. Please ensure
|
||||
# the returned object is a rack compatible response.
|
||||
#
|
||||
# The first argument is an OpenID::Response, the second is a
|
||||
# Rack::Request of the current request, the last is the hash used in
|
||||
# ruby-openid handling, which can be found manually at
|
||||
# env['rack.session'][:openid].
|
||||
#
|
||||
# This is useful if you wanted to expand the processing done, such as
|
||||
# setting up user accounts.
|
||||
#
|
||||
# oid_app = Rack::Auth::OpenID.new realm, :return_to => return_to
|
||||
# def oid_app.success oid, request, session
|
||||
# user = Models::User[oid.identity_url]
|
||||
# user ||= Models::User.create_from_openid oid
|
||||
# request['rack.session'][:user] = user.id
|
||||
# redirect MyApp.site_home
|
||||
# end
|
||||
#
|
||||
# site_map['/openid'] = oid_app
|
||||
# map = Rack::URLMap.new site_map
|
||||
# ...
|
||||
|
||||
def initialize(realm, options={})
|
||||
realm = URI(realm)
|
||||
raise ArgumentError, "Invalid realm: #{realm}" \
|
||||
unless realm.absolute? \
|
||||
and realm.fragment.nil? \
|
||||
and realm.scheme =~ /^https?$/ \
|
||||
and realm.host =~ /^(\*\.)?#{URI::REGEXP::PATTERN::URIC_NO_SLASH}+/
|
||||
realm.path = '/' if realm.path.empty?
|
||||
@realm = realm.to_s
|
||||
|
||||
if ruri = options[:return_to]
|
||||
ruri = URI(ruri)
|
||||
raise ArgumentError, "Invalid return_to: #{ruri}" \
|
||||
unless ruri.absolute? \
|
||||
and ruri.scheme =~ /^https?$/ \
|
||||
and ruri.fragment.nil?
|
||||
raise ArgumentError, "return_to #{ruri} not within realm #{realm}" \
|
||||
unless self.within_realm?(ruri)
|
||||
@return_to = ruri.to_s
|
||||
end
|
||||
|
||||
@session_key = options[:session_key] || 'rack.session'
|
||||
@openid_param = options[:openid_param] || 'openid_identifier'
|
||||
@store = options[:store] || ::OpenID::Store::Memory.new
|
||||
@immediate = !!options[:immediate]
|
||||
|
||||
@extensions = {}
|
||||
if extensions = options.delete(:extensions)
|
||||
extensions.each do |ext, args|
|
||||
add_extension ext, *args
|
||||
end
|
||||
end
|
||||
|
||||
# Undocumented, semi-experimental
|
||||
@anonymous = !!options[:anonymous]
|
||||
end
|
||||
|
||||
attr_reader :realm, :return_to, :session_key, :openid_param, :store,
|
||||
:immediate, :extensions
|
||||
|
||||
# Sets up and uses session data at <tt>:openid</tt> within the session.
|
||||
# Errors in this setup will raise a NoSession exception.
|
||||
#
|
||||
# If the parameter 'openid.mode' is set, which implies a followup from
|
||||
# the openid server, processing is passed to #finish and the result is
|
||||
# returned. However, if there is no appropriate openid information in the
|
||||
# session, a 400 error is returned.
|
||||
#
|
||||
# If the parameter specified by <tt>options[:openid_param]</tt> is
|
||||
# present, processing is passed to #check and the result is returned.
|
||||
#
|
||||
# If neither of these conditions are met, #unauthorized is called.
|
||||
|
||||
def call(env)
|
||||
env['rack.auth.openid'] = self
|
||||
env_session = env[@session_key]
|
||||
unless env_session and env_session.is_a?(Hash)
|
||||
raise NoSession, 'No compatible session'
|
||||
end
|
||||
# let us work in our own namespace...
|
||||
session = (env_session[:openid] ||= {})
|
||||
unless session and session.is_a?(Hash)
|
||||
raise NoSession, 'Incompatible openid session'
|
||||
end
|
||||
|
||||
request = Rack::Request.new(env)
|
||||
consumer = ::OpenID::Consumer.new(session, @store)
|
||||
|
||||
if mode = request.GET['openid.mode']
|
||||
if session.key?(:openid_param)
|
||||
finish(consumer, session, request)
|
||||
else
|
||||
bad_request
|
||||
end
|
||||
elsif request.GET[@openid_param]
|
||||
check(consumer, session, request)
|
||||
else
|
||||
unauthorized
|
||||
end
|
||||
end
|
||||
|
||||
# As the first part of OpenID consumer action, #check retrieves the data
|
||||
# required for completion.
|
||||
#
|
||||
# If all parameters fit within the max length of a URI, a 303 redirect
|
||||
# will be returned. Otherwise #confirm_post_params will be called.
|
||||
#
|
||||
# Any messages from OpenID's request are logged to env['rack.errors']
|
||||
#
|
||||
# <tt>env['rack.auth.openid.request']</tt> is the openid checkid request
|
||||
# instance.
|
||||
#
|
||||
# <tt>session[:openid_param]</tt> is set to the openid identifier
|
||||
# provided by the user.
|
||||
#
|
||||
# <tt>session[:return_to]</tt> is set to the return_to uri given to the
|
||||
# identity provider.
|
||||
|
||||
def check(consumer, session, req)
|
||||
oid = consumer.begin(req.GET[@openid_param], @anonymous)
|
||||
req.env['rack.auth.openid.request'] = oid
|
||||
req.env['rack.errors'].puts(oid.message)
|
||||
p oid if $DEBUG
|
||||
|
||||
## Extension support
|
||||
extensions.each do |ext,args|
|
||||
oid.add_extension(ext::Request.new(*args))
|
||||
end
|
||||
|
||||
session[:openid_param] = req.GET[openid_param]
|
||||
return_to_uri = return_to ? return_to : req.url
|
||||
session[:return_to] = return_to_uri
|
||||
immediate = session.key?(:setup_needed) ? false : immediate
|
||||
|
||||
if oid.send_redirect?(realm, return_to_uri, immediate)
|
||||
uri = oid.redirect_url(realm, return_to_uri, immediate)
|
||||
redirect(uri)
|
||||
else
|
||||
confirm_post_params(oid, realm, return_to_uri, immediate)
|
||||
end
|
||||
rescue ::OpenID::DiscoveryFailure => e
|
||||
# thrown from inside OpenID::Consumer#begin by yadis stuff
|
||||
req.env['rack.errors'].puts([e.message, *e.backtrace]*"\n")
|
||||
return foreign_server_failure
|
||||
end
|
||||
|
||||
# This is the final portion of authentication.
|
||||
# If successful, a redirect to the realm is be returned.
|
||||
# Data gathered from extensions are stored in session[:openid] with the
|
||||
# extension's namespace uri as the key.
|
||||
#
|
||||
# Any messages from OpenID's response are logged to env['rack.errors']
|
||||
#
|
||||
# <tt>env['rack.auth.openid.response']</tt> will contain the openid
|
||||
# response.
|
||||
|
||||
def finish(consumer, session, req)
|
||||
oid = consumer.complete(req.GET, req.url)
|
||||
req.env['rack.auth.openid.response'] = oid
|
||||
req.env['rack.errors'].puts(oid.message)
|
||||
p oid if $DEBUG
|
||||
|
||||
raise unless ValidStatus.include?(oid.status)
|
||||
__send__(oid.status, oid, req, session)
|
||||
end
|
||||
|
||||
# The first argument should be the main extension module.
|
||||
# The extension module should contain the constants:
|
||||
# * class Request, should have OpenID::Extension as an ancestor
|
||||
# * class Response, should have OpenID::Extension as an ancestor
|
||||
# * string NS_URI, which defining the namespace of the extension
|
||||
#
|
||||
# All trailing arguments will be passed to extension::Request.new in
|
||||
# #check.
|
||||
# The openid response will be passed to
|
||||
# extension::Response#from_success_response, #get_extension_args will be
|
||||
# called on the result to attain the gathered data.
|
||||
#
|
||||
# This method returns the key at which the response data will be found in
|
||||
# the session, which is the namespace uri by default.
|
||||
|
||||
def add_extension(ext, *args)
|
||||
raise BadExtension unless valid_extension?(ext)
|
||||
extensions[ext] = args
|
||||
return ext::NS_URI
|
||||
end
|
||||
|
||||
# Checks the validitity, in the context of usage, of a submitted
|
||||
# extension.
|
||||
|
||||
def valid_extension?(ext)
|
||||
if not %w[NS_URI Request Response].all?{|c| ext.const_defined?(c) }
|
||||
raise ArgumentError, 'Extension is missing constants.'
|
||||
elsif not ext::Response.respond_to?(:from_success_response)
|
||||
raise ArgumentError, 'Response is missing required method.'
|
||||
end
|
||||
return true
|
||||
rescue
|
||||
return false
|
||||
end
|
||||
|
||||
# Checks the provided uri to ensure it'd be considered within the realm.
|
||||
# is currently not compatible with wildcard realms.
|
||||
|
||||
def within_realm? uri
|
||||
uri = URI.parse(uri.to_s)
|
||||
realm = URI.parse(self.realm)
|
||||
return false unless uri.absolute?
|
||||
return false unless uri.path[0, realm.path.size] == realm.path
|
||||
return false unless uri.host == realm.host or realm.host[/^\*\./]
|
||||
# for wildcard support, is awkward with URI limitations
|
||||
realm_match = Regexp.escape(realm.host).
|
||||
sub(/^\*\./,"^#{URI::REGEXP::PATTERN::URIC_NO_SLASH}+.")+'$'
|
||||
return false unless uri.host.match(realm_match)
|
||||
return true
|
||||
end
|
||||
alias_method :include?, :within_realm?
|
||||
|
||||
protected
|
||||
|
||||
### These methods define some of the boilerplate responses.
|
||||
|
||||
# Returns an html form page for posting to an Identity Provider if the
|
||||
# GET request would exceed the upper URI length limit.
|
||||
|
||||
def confirm_post_params(oid, realm, return_to, immediate)
|
||||
Rack::Response.new.finish do |r|
|
||||
r.write '<html><head><title>Confirm...</title></head><body>'
|
||||
r.write oid.form_markup(realm, return_to, immediate)
|
||||
r.write '</body></html>'
|
||||
end
|
||||
end
|
||||
|
||||
# Returns a 303 redirect with the destination of that provided by the
|
||||
# argument.
|
||||
|
||||
def redirect(uri)
|
||||
[ 303, {'Content-Length'=>'0', 'Content-Type'=>'text/plain',
|
||||
'Location' => uri},
|
||||
[] ]
|
||||
end
|
||||
|
||||
# Returns an empty 400 response.
|
||||
|
||||
def bad_request
|
||||
[ 400, {'Content-Type'=>'text/plain', 'Content-Length'=>'0'},
|
||||
[''] ]
|
||||
end
|
||||
|
||||
# Returns a basic unauthorized 401 response.
|
||||
|
||||
def unauthorized
|
||||
[ 401, {'Content-Type' => 'text/plain', 'Content-Length' => '13'},
|
||||
['Unauthorized.'] ]
|
||||
end
|
||||
|
||||
# Returns a basic access denied 403 response.
|
||||
|
||||
def access_denied
|
||||
[ 403, {'Content-Type' => 'text/plain', 'Content-Length' => '14'},
|
||||
['Access denied.'] ]
|
||||
end
|
||||
|
||||
# Returns a 503 response to be used if communication with the remote
|
||||
# OpenID server fails.
|
||||
|
||||
def foreign_server_failure
|
||||
[ 503, {'Content-Type'=>'text/plain', 'Content-Length' => '23'},
|
||||
['Foreign server failure.'] ]
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
### These methods are called after a transaction is completed, depending
|
||||
# on its outcome. These should all return a rack compatible response.
|
||||
# You'd want to override these to provide additional functionality.
|
||||
|
||||
# Called to complete processing on a successful transaction.
|
||||
# Within the openid session, :openid_identity and :openid_identifier are
|
||||
# set to the user friendly and the standard representation of the
|
||||
# validated identity. All other data in the openid session is cleared.
|
||||
|
||||
def success(oid, request, session)
|
||||
session.clear
|
||||
session[:openid_identity] = oid.display_identifier
|
||||
session[:openid_identifier] = oid.identity_url
|
||||
extensions.keys.each do |ext|
|
||||
label = ext.name[/[^:]+$/].downcase
|
||||
response = ext::Response.from_success_response(oid)
|
||||
session[label] = response.data
|
||||
end
|
||||
redirect(realm)
|
||||
end
|
||||
|
||||
# Called if the Identity Provider indicates further setup by the user is
|
||||
# required.
|
||||
# The identifier is retrived from the openid session at :openid_param.
|
||||
# And :setup_needed is set to true to prevent looping.
|
||||
|
||||
def setup_needed(oid, request, session)
|
||||
identifier = session[:openid_param]
|
||||
session[:setup_needed] = true
|
||||
redirect req.script_name + '?' + openid_param + '=' + identifier
|
||||
end
|
||||
|
||||
# Called if the user indicates they wish to cancel identification.
|
||||
# Data within openid session is cleared.
|
||||
|
||||
def cancel(oid, request, session)
|
||||
session.clear
|
||||
access_denied
|
||||
end
|
||||
|
||||
# Called if the Identity Provider indicates the user is unable to confirm
|
||||
# their identity. Data within the openid session is left alone, in case
|
||||
# of swarm auth attacks.
|
||||
|
||||
def failure(oid, request, session)
|
||||
unauthorized
|
||||
end
|
||||
end
|
||||
|
||||
# A class developed out of the request to use OpenID as an authentication
|
||||
# middleware. The request will be sent to the OpenID instance unless the
|
||||
# block evaluates to true. For example in rackup, you can use it as such:
|
||||
#
|
||||
# use Rack::Session::Pool
|
||||
# use Rack::Auth::OpenIDAuth, realm, openid_options do |env|
|
||||
# env['rack.session'][:authkey] == a_string
|
||||
# end
|
||||
# run RackApp
|
||||
#
|
||||
# Or simply:
|
||||
#
|
||||
# app = Rack::Auth::OpenIDAuth.new app, realm, openid_options, &auth
|
||||
|
||||
class OpenIDAuth < Rack::Auth::AbstractHandler
|
||||
attr_reader :oid
|
||||
def initialize(app, realm, options={}, &auth)
|
||||
@oid = OpenID.new(realm, options)
|
||||
super(app, &auth)
|
||||
end
|
||||
|
||||
def call(env)
|
||||
to = auth.call(env) ? @app : @oid
|
||||
to.call env
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -13,7 +13,7 @@ module Rack
|
|||
status, headers, body = @app.call(env)
|
||||
headers = HeaderHash.new(headers)
|
||||
|
||||
if !STATUS_WITH_NO_ENTITY_BODY.include?(status) &&
|
||||
if !STATUS_WITH_NO_ENTITY_BODY.include?(status.to_i) &&
|
||||
!headers['Content-Length'] &&
|
||||
!headers['Transfer-Encoding'] &&
|
||||
(body.respond_to?(:to_ary) || body.respond_to?(:to_str))
|
||||
|
|
21
vendor/plugins/rack/lib/rack/etag.rb
vendored
21
vendor/plugins/rack/lib/rack/etag.rb
vendored
|
@ -11,13 +11,22 @@ module Rack
|
|||
status, headers, body = @app.call(env)
|
||||
|
||||
if !headers.has_key?('ETag')
|
||||
parts = []
|
||||
body.each { |part| parts << part.to_s }
|
||||
headers['ETag'] = %("#{Digest::MD5.hexdigest(parts.join(""))}")
|
||||
[status, headers, parts]
|
||||
else
|
||||
[status, headers, body]
|
||||
digest, body = digest_body(body)
|
||||
headers['ETag'] = %("#{digest}")
|
||||
end
|
||||
|
||||
[status, headers, body]
|
||||
end
|
||||
|
||||
private
|
||||
def digest_body(body)
|
||||
digest = Digest::MD5.new
|
||||
parts = []
|
||||
body.each do |part|
|
||||
digest << part
|
||||
parts << part
|
||||
end
|
||||
[digest.hexdigest, parts]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
4
vendor/plugins/rack/lib/rack/file.rb
vendored
4
vendor/plugins/rack/lib/rack/file.rb
vendored
|
@ -3,8 +3,10 @@ require 'rack/utils'
|
|||
require 'rack/mime'
|
||||
|
||||
module Rack
|
||||
# Rack::File serves files below the +root+ given, according to the
|
||||
# Rack::File serves files below the +root+ directory given, according to the
|
||||
# path info of the Rack request.
|
||||
# e.g. when Rack::File.new("/etc") is used, you can access 'passwd' file
|
||||
# as http://localhost:9292/passwd
|
||||
#
|
||||
# Handlers can detect if bodies are a Rack::File, and use mechanisms
|
||||
# like sendfile on the +path+.
|
||||
|
|
18
vendor/plugins/rack/lib/rack/handler/cgi.rb
vendored
18
vendor/plugins/rack/lib/rack/handler/cgi.rb
vendored
|
@ -1,9 +1,11 @@
|
|||
require 'rack/content_length'
|
||||
require 'rack/rewindable_input'
|
||||
|
||||
module Rack
|
||||
module Handler
|
||||
class CGI
|
||||
def self.run(app, options=nil)
|
||||
$stdin.binmode
|
||||
serve app
|
||||
end
|
||||
|
||||
|
@ -15,8 +17,8 @@ module Rack
|
|||
|
||||
env["SCRIPT_NAME"] = "" if env["SCRIPT_NAME"] == "/"
|
||||
|
||||
env.update({"rack.version" => [1,1],
|
||||
"rack.input" => $stdin,
|
||||
env.update({"rack.version" => Rack::VERSION,
|
||||
"rack.input" => Rack::RewindableInput.new($stdin),
|
||||
"rack.errors" => $stderr,
|
||||
|
||||
"rack.multithread" => false,
|
||||
|
@ -40,20 +42,20 @@ module Rack
|
|||
end
|
||||
|
||||
def self.send_headers(status, headers)
|
||||
STDOUT.print "Status: #{status}\r\n"
|
||||
$stdout.print "Status: #{status}\r\n"
|
||||
headers.each { |k, vs|
|
||||
vs.split("\n").each { |v|
|
||||
STDOUT.print "#{k}: #{v}\r\n"
|
||||
$stdout.print "#{k}: #{v}\r\n"
|
||||
}
|
||||
}
|
||||
STDOUT.print "\r\n"
|
||||
STDOUT.flush
|
||||
$stdout.print "\r\n"
|
||||
$stdout.flush
|
||||
end
|
||||
|
||||
def self.send_body(body)
|
||||
body.each { |part|
|
||||
STDOUT.print part
|
||||
STDOUT.flush
|
||||
$stdout.print part
|
||||
$stdout.flush
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -36,7 +36,7 @@ module Rack
|
|||
|
||||
rack_input = RewindableInput.new(request.in)
|
||||
|
||||
env.update({"rack.version" => [1,1],
|
||||
env.update({"rack.version" => Rack::VERSION,
|
||||
"rack.input" => rack_input,
|
||||
"rack.errors" => request.err,
|
||||
|
||||
|
|
2
vendor/plugins/rack/lib/rack/handler/lsws.rb
vendored
2
vendor/plugins/rack/lib/rack/handler/lsws.rb
vendored
|
@ -20,7 +20,7 @@ module Rack
|
|||
rack_input = RewindableInput.new($stdin.read.to_s)
|
||||
|
||||
env.update(
|
||||
"rack.version" => [1,1],
|
||||
"rack.version" => Rack::VERSION,
|
||||
"rack.input" => rack_input,
|
||||
"rack.errors" => $stderr,
|
||||
"rack.multithread" => false,
|
||||
|
|
|
@ -52,7 +52,7 @@ module Rack
|
|||
rack_input = request.body || StringIO.new('')
|
||||
rack_input.set_encoding(Encoding::BINARY) if rack_input.respond_to?(:set_encoding)
|
||||
|
||||
env.update({"rack.version" => [1,1],
|
||||
env.update({"rack.version" => Rack::VERSION,
|
||||
"rack.input" => rack_input,
|
||||
"rack.errors" => $stderr,
|
||||
|
||||
|
|
5
vendor/plugins/rack/lib/rack/handler/scgi.rb
vendored
5
vendor/plugins/rack/lib/rack/handler/scgi.rb
vendored
|
@ -17,9 +17,6 @@ module Rack
|
|||
|
||||
def initialize(settings = {})
|
||||
@app = Rack::Chunked.new(Rack::ContentLength.new(settings[:app]))
|
||||
@log = Object.new
|
||||
def @log.info(*args); end
|
||||
def @log.error(*args); end
|
||||
super(settings)
|
||||
end
|
||||
|
||||
|
@ -36,7 +33,7 @@ module Rack
|
|||
rack_input = StringIO.new(input_body)
|
||||
rack_input.set_encoding(Encoding::BINARY) if rack_input.respond_to?(:set_encoding)
|
||||
|
||||
env.update({"rack.version" => [1,1],
|
||||
env.update({"rack.version" => Rack::VERSION,
|
||||
"rack.input" => rack_input,
|
||||
"rack.errors" => $stderr,
|
||||
"rack.multithread" => true,
|
||||
|
|
17
vendor/plugins/rack/lib/rack/handler/webrick.rb
vendored
17
vendor/plugins/rack/lib/rack/handler/webrick.rb
vendored
|
@ -7,12 +7,15 @@ module Rack
|
|||
class WEBrick < ::WEBrick::HTTPServlet::AbstractServlet
|
||||
def self.run(app, options={})
|
||||
options[:BindAddress] = options.delete(:Host) if options[:Host]
|
||||
server = ::WEBrick::HTTPServer.new(options)
|
||||
server.mount "/", Rack::Handler::WEBrick, app
|
||||
trap(:INT) { server.shutdown }
|
||||
trap(:TERM) { server.shutdown }
|
||||
yield server if block_given?
|
||||
server.start
|
||||
@server = ::WEBrick::HTTPServer.new(options)
|
||||
@server.mount "/", Rack::Handler::WEBrick, app
|
||||
yield @server if block_given?
|
||||
@server.start
|
||||
end
|
||||
|
||||
def self.shutdown
|
||||
@server.shutdown
|
||||
@server = nil
|
||||
end
|
||||
|
||||
def initialize(server, app)
|
||||
|
@ -27,7 +30,7 @@ module Rack
|
|||
rack_input = StringIO.new(req.body.to_s)
|
||||
rack_input.set_encoding(Encoding::BINARY) if rack_input.respond_to?(:set_encoding)
|
||||
|
||||
env.update({"rack.version" => [1,1],
|
||||
env.update({"rack.version" => Rack::VERSION,
|
||||
"rack.input" => rack_input,
|
||||
"rack.errors" => $stderr,
|
||||
|
||||
|
|
66
vendor/plugins/rack/lib/rack/lint.rb
vendored
66
vendor/plugins/rack/lib/rack/lint.rb
vendored
|
@ -7,6 +7,7 @@ module Rack
|
|||
class Lint
|
||||
def initialize(app)
|
||||
@app = app
|
||||
@content_length = nil
|
||||
end
|
||||
|
||||
# :stopdoc:
|
||||
|
@ -51,15 +52,16 @@ module Rack
|
|||
check_headers headers
|
||||
## and the *body*.
|
||||
check_content_type status, headers
|
||||
check_content_length status, headers, env
|
||||
check_content_length status, headers
|
||||
@head_request = env["REQUEST_METHOD"] == "HEAD"
|
||||
[status, headers, self]
|
||||
end
|
||||
|
||||
## == The Environment
|
||||
def check_env(env)
|
||||
## The environment must be an true instance of Hash (no
|
||||
## subclassing allowed) that includes CGI-like headers.
|
||||
## The application is free to modify the environment.
|
||||
## The environment must be an instance of Hash that includes
|
||||
## CGI-like headers. The application is free to modify the
|
||||
## environment.
|
||||
assert("env #{env.inspect} is not a Hash, but #{env.class}") {
|
||||
env.kind_of? Hash
|
||||
}
|
||||
|
@ -288,10 +290,6 @@ module Rack
|
|||
@input = input
|
||||
end
|
||||
|
||||
def size
|
||||
@input.size
|
||||
end
|
||||
|
||||
## * +gets+ must be called without arguments and return a string,
|
||||
## or +nil+ on EOF.
|
||||
def gets(*args)
|
||||
|
@ -481,7 +479,7 @@ module Rack
|
|||
end
|
||||
|
||||
## === The Content-Length
|
||||
def check_content_length(status, headers, env)
|
||||
def check_content_length(status, headers)
|
||||
headers.each { |key, value|
|
||||
if key.downcase == 'content-length'
|
||||
## There must not be a <tt>Content-Length</tt> header when the
|
||||
|
@ -489,49 +487,43 @@ module Rack
|
|||
assert("Content-Length header found in #{status} response, not allowed") {
|
||||
not Rack::Utils::STATUS_WITH_NO_ENTITY_BODY.include? status.to_i
|
||||
}
|
||||
|
||||
bytes = 0
|
||||
string_body = true
|
||||
|
||||
if @body.respond_to?(:to_ary)
|
||||
@body.each { |part|
|
||||
unless part.kind_of?(String)
|
||||
string_body = false
|
||||
break
|
||||
end
|
||||
|
||||
bytes += Rack::Utils.bytesize(part)
|
||||
}
|
||||
|
||||
if env["REQUEST_METHOD"] == "HEAD"
|
||||
assert("Response body was given for HEAD request, but should be empty") {
|
||||
bytes == 0
|
||||
}
|
||||
else
|
||||
if string_body
|
||||
assert("Content-Length header was #{value}, but should be #{bytes}") {
|
||||
value == bytes.to_s
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return
|
||||
@content_length = value
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
def verify_content_length(bytes)
|
||||
if @head_request
|
||||
assert("Response body was given for HEAD request, but should be empty") {
|
||||
bytes == 0
|
||||
}
|
||||
elsif @content_length
|
||||
assert("Content-Length header was #{@content_length}, but should be #{bytes}") {
|
||||
@content_length == bytes.to_s
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
## === The Body
|
||||
def each
|
||||
@closed = false
|
||||
bytes = 0
|
||||
|
||||
## The Body must respond to +each+
|
||||
assert("Response body must respond to each") do
|
||||
@body.respond_to?(:each)
|
||||
end
|
||||
|
||||
@body.each { |part|
|
||||
## and must only yield String values.
|
||||
assert("Body yielded non-string value #{part.inspect}") {
|
||||
part.kind_of? String
|
||||
}
|
||||
bytes += Rack::Utils.bytesize(part)
|
||||
yield part
|
||||
}
|
||||
verify_content_length(bytes)
|
||||
|
||||
##
|
||||
## The Body itself should not be an instance of String, as this will
|
||||
## break in Ruby 1.9.
|
||||
|
|
2
vendor/plugins/rack/lib/rack/mime.rb
vendored
2
vendor/plugins/rack/lib/rack/mime.rb
vendored
|
@ -87,6 +87,7 @@ module Rack
|
|||
".gif" => "image/gif",
|
||||
".gz" => "application/x-gzip",
|
||||
".h" => "text/x-c",
|
||||
".htc" => "text/x-component",
|
||||
".hh" => "text/x-c",
|
||||
".htm" => "text/html",
|
||||
".html" => "text/html",
|
||||
|
@ -186,6 +187,7 @@ module Rack
|
|||
".vrml" => "model/vrml",
|
||||
".war" => "application/java-archive",
|
||||
".wav" => "audio/x-wav",
|
||||
".webm" => "video/webm",
|
||||
".wma" => "audio/x-ms-wma",
|
||||
".wmv" => "video/x-ms-wmv",
|
||||
".wmx" => "video/x-ms-wmx",
|
||||
|
|
3
vendor/plugins/rack/lib/rack/mock.rb
vendored
3
vendor/plugins/rack/lib/rack/mock.rb
vendored
|
@ -1,5 +1,6 @@
|
|||
require 'uri'
|
||||
require 'stringio'
|
||||
require 'rack'
|
||||
require 'rack/lint'
|
||||
require 'rack/utils'
|
||||
require 'rack/response'
|
||||
|
@ -40,7 +41,7 @@ module Rack
|
|||
end
|
||||
|
||||
DEFAULT_ENV = {
|
||||
"rack.version" => [1,1],
|
||||
"rack.version" => Rack::VERSION,
|
||||
"rack.input" => StringIO.new,
|
||||
"rack.errors" => StringIO.new,
|
||||
"rack.multithread" => true,
|
||||
|
|
4
vendor/plugins/rack/lib/rack/recursive.rb
vendored
4
vendor/plugins/rack/lib/rack/recursive.rb
vendored
|
@ -35,6 +35,10 @@ module Rack
|
|||
end
|
||||
|
||||
def call(env)
|
||||
dup._call(env)
|
||||
end
|
||||
|
||||
def _call(env)
|
||||
@script_name = env["SCRIPT_NAME"]
|
||||
@app.call(env.merge('rack.recursive.include' => method(:include)))
|
||||
rescue ForwardRequest => req
|
||||
|
|
14
vendor/plugins/rack/lib/rack/request.rb
vendored
14
vendor/plugins/rack/lib/rack/request.rb
vendored
|
@ -80,11 +80,13 @@ module Rack
|
|||
def script_name=(s); @env["SCRIPT_NAME"] = s.to_s end
|
||||
def path_info=(s); @env["PATH_INFO"] = s.to_s end
|
||||
|
||||
def get?; request_method == "GET" end
|
||||
def post?; request_method == "POST" end
|
||||
def put?; request_method == "PUT" end
|
||||
def delete?; request_method == "DELETE" end
|
||||
def head?; request_method == "HEAD" end
|
||||
def delete?; request_method == "DELETE" end
|
||||
def get?; request_method == "GET" end
|
||||
def head?; request_method == "HEAD" end
|
||||
def options?; request_method == "OPTIONS" end
|
||||
def post?; request_method == "POST" end
|
||||
def put?; request_method == "PUT" end
|
||||
def trace?; request_method == "TRACE" end
|
||||
|
||||
# The set of form-data media-types. Requests that do not indicate
|
||||
# one of the media types presents in this list will not be eligible
|
||||
|
@ -253,7 +255,7 @@ module Rack
|
|||
|
||||
def ip
|
||||
if addr = @env['HTTP_X_FORWARDED_FOR']
|
||||
addr.split(',').last.strip
|
||||
(addr.split(',').grep(/\d\./).first || @env['REMOTE_ADDR']).to_s.strip
|
||||
else
|
||||
@env['REMOTE_ADDR']
|
||||
end
|
||||
|
|
1
vendor/plugins/rack/lib/rack/response.rb
vendored
1
vendor/plugins/rack/lib/rack/response.rb
vendored
|
@ -1,5 +1,6 @@
|
|||
require 'rack/request'
|
||||
require 'rack/utils'
|
||||
require 'time'
|
||||
|
||||
module Rack
|
||||
# Rack::Response provides a convenient interface to create a Rack
|
||||
|
|
35
vendor/plugins/rack/lib/rack/rewindable_input.rb
vendored
35
vendor/plugins/rack/lib/rack/rewindable_input.rb
vendored
|
@ -1,4 +1,6 @@
|
|||
# -*- encoding: binary -*-
|
||||
require 'tempfile'
|
||||
require 'rack/utils'
|
||||
|
||||
module Rack
|
||||
# Class which can make any IO object rewindable, including non-rewindable ones. It does
|
||||
|
@ -16,27 +18,27 @@ module Rack
|
|||
@rewindable_io = nil
|
||||
@unlinked = false
|
||||
end
|
||||
|
||||
|
||||
def gets
|
||||
make_rewindable unless @rewindable_io
|
||||
@rewindable_io.gets
|
||||
end
|
||||
|
||||
|
||||
def read(*args)
|
||||
make_rewindable unless @rewindable_io
|
||||
@rewindable_io.read(*args)
|
||||
end
|
||||
|
||||
|
||||
def each(&block)
|
||||
make_rewindable unless @rewindable_io
|
||||
@rewindable_io.each(&block)
|
||||
end
|
||||
|
||||
|
||||
def rewind
|
||||
make_rewindable unless @rewindable_io
|
||||
@rewindable_io.rewind
|
||||
end
|
||||
|
||||
|
||||
# Closes this RewindableInput object without closing the originally
|
||||
# wrapped IO oject. Cleans up any temporary resources that this RewindableInput
|
||||
# has created.
|
||||
|
@ -52,9 +54,9 @@ module Rack
|
|||
@rewindable_io = nil
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
private
|
||||
|
||||
|
||||
# Ruby's Tempfile class has a bug. Subclass it and fix it.
|
||||
class Tempfile < ::Tempfile
|
||||
def _close
|
||||
|
@ -74,17 +76,18 @@ module Rack
|
|||
@rewindable_io.chmod(0000)
|
||||
@rewindable_io.set_encoding(Encoding::BINARY) if @rewindable_io.respond_to?(:set_encoding)
|
||||
@rewindable_io.binmode
|
||||
if filesystem_has_posix_semantics? && !tempfile_unlink_contains_bug?
|
||||
if filesystem_has_posix_semantics?
|
||||
@rewindable_io.unlink
|
||||
raise 'Unlink failed. IO closed.' if @rewindable_io.closed?
|
||||
@unlinked = true
|
||||
end
|
||||
|
||||
|
||||
buffer = ""
|
||||
while @io.read(1024 * 4, buffer)
|
||||
entire_buffer_written_out = false
|
||||
while !entire_buffer_written_out
|
||||
written = @rewindable_io.write(buffer)
|
||||
entire_buffer_written_out = written == buffer.size
|
||||
entire_buffer_written_out = written == Rack::Utils.bytesize(buffer)
|
||||
if !entire_buffer_written_out
|
||||
buffer.slice!(0 .. written - 1)
|
||||
end
|
||||
|
@ -92,19 +95,9 @@ module Rack
|
|||
end
|
||||
@rewindable_io.rewind
|
||||
end
|
||||
|
||||
|
||||
def filesystem_has_posix_semantics?
|
||||
RUBY_PLATFORM !~ /(mswin|mingw|cygwin|java)/
|
||||
end
|
||||
|
||||
def tempfile_unlink_contains_bug?
|
||||
# The tempfile library as included in Ruby 1.9.1-p152 and later
|
||||
# contains a bug: unlinking an open Tempfile object also closes
|
||||
# it, which breaks our expected POSIX semantics. This problem
|
||||
# has been fixed in Ruby 1.9.2, but the Ruby team chose not to
|
||||
# include the bug fix in later versions of the 1.9.1 series.
|
||||
ruby_engine = defined?(RUBY_ENGINE) ? RUBY_ENGINE : "ruby"
|
||||
ruby_engine == "ruby" && RUBY_VERSION == "1.9.1" && RUBY_PATCHLEVEL >= 152
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
14
vendor/plugins/rack/lib/rack/sendfile.rb
vendored
14
vendor/plugins/rack/lib/rack/sendfile.rb
vendored
|
@ -2,7 +2,9 @@ require 'rack/file'
|
|||
|
||||
module Rack
|
||||
class File #:nodoc:
|
||||
alias :to_path :path
|
||||
unless instance_methods(false).include?('to_path')
|
||||
alias :to_path :path
|
||||
end
|
||||
end
|
||||
|
||||
# = Sendfile
|
||||
|
@ -11,7 +13,7 @@ module Rack
|
|||
# served from a file and replaces it with a server specific X-Sendfile
|
||||
# header. The web server is then responsible for writing the file contents
|
||||
# to the client. This can dramatically reduce the amount of work required
|
||||
# by the Ruby backend and takes advantage of the web servers optimized file
|
||||
# by the Ruby backend and takes advantage of the web server's optimized file
|
||||
# delivery code.
|
||||
#
|
||||
# In order to take advantage of this middleware, the response body must
|
||||
|
@ -31,19 +33,19 @@ module Rack
|
|||
# a private "/files/" area, enable X-Accel-Redirect, and pass the special
|
||||
# X-Sendfile-Type and X-Accel-Mapping headers to the backend:
|
||||
#
|
||||
# location /files/ {
|
||||
# location ~ /files/(.*) {
|
||||
# internal;
|
||||
# alias /var/www/;
|
||||
# alias /var/www/$1;
|
||||
# }
|
||||
#
|
||||
# location / {
|
||||
# proxy_redirect false;
|
||||
# proxy_redirect off;
|
||||
#
|
||||
# proxy_set_header Host $host;
|
||||
# proxy_set_header X-Real-IP $remote_addr;
|
||||
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
#
|
||||
# proxy_set_header X-Sendfile-Type X-Accel-Redirect
|
||||
# proxy_set_header X-Sendfile-Type X-Accel-Redirect;
|
||||
# proxy_set_header X-Accel-Mapping /files/=/var/www/;
|
||||
#
|
||||
# proxy_pass http://127.0.0.1:8080/;
|
||||
|
|
83
vendor/plugins/rack/lib/rack/server.rb
vendored
83
vendor/plugins/rack/lib/rack/server.rb
vendored
|
@ -57,7 +57,7 @@ module Rack
|
|||
}
|
||||
|
||||
opts.on("-P", "--pid FILE", "file to store PID (default: rack.pid)") { |f|
|
||||
options[:pid] = ::File.expand_path(f)
|
||||
options[:pid] = f
|
||||
}
|
||||
|
||||
opts.separator ""
|
||||
|
@ -74,17 +74,66 @@ module Rack
|
|||
end
|
||||
end
|
||||
opt_parser.parse! args
|
||||
options[:rack_file] = args.last if args.last
|
||||
options[:config] = args.last if args.last
|
||||
options
|
||||
end
|
||||
end
|
||||
|
||||
def self.start
|
||||
new.start
|
||||
# Start a new rack server (like running rackup). This will parse ARGV and
|
||||
# provide standard ARGV rackup options, defaulting to load 'config.ru'.
|
||||
#
|
||||
# Providing an options hash will prevent ARGV parsing and will not include
|
||||
# any default options.
|
||||
#
|
||||
# This method can be used to very easily launch a CGI application, for
|
||||
# example:
|
||||
#
|
||||
# Rack::Server.start(
|
||||
# :app => lambda do |e|
|
||||
# [200, {'Content-Type' => 'text/html'}, ['hello world']]
|
||||
# end,
|
||||
# :server => 'cgi'
|
||||
# )
|
||||
#
|
||||
# Further options available here are documented on Rack::Server#initialize
|
||||
def self.start(options = nil)
|
||||
new(options).start
|
||||
end
|
||||
|
||||
attr_accessor :options
|
||||
attr_writer :options
|
||||
|
||||
# Options may include:
|
||||
# * :app
|
||||
# a rack application to run (overrides :config)
|
||||
# * :config
|
||||
# a rackup configuration file path to load (.ru)
|
||||
# * :environment
|
||||
# this selects the middleware that will be wrapped around
|
||||
# your application. Default options available are:
|
||||
# - development: CommonLogger, ShowExceptions, and Lint
|
||||
# - deployment: CommonLogger
|
||||
# - none: no extra middleware
|
||||
# note: when the server is a cgi server, CommonLogger is not included.
|
||||
# * :server
|
||||
# choose a specific Rack::Handler, e.g. cgi, fcgi, webrick
|
||||
# * :daemonize
|
||||
# if true, the server will daemonize itself (fork, detach, etc)
|
||||
# * :pid
|
||||
# path to write a pid file after daemonize
|
||||
# * :Host
|
||||
# the host address to bind to (used by supporting Rack::Handler)
|
||||
# * :Port
|
||||
# the port to bind to (used by supporting Rack::Handler)
|
||||
# * :AccessLog
|
||||
# webrick acess log options (or supporting Rack::Handler)
|
||||
# * :debug
|
||||
# turn on debug output ($DEBUG = true)
|
||||
# * :warn
|
||||
# turn on warnings ($-w = true)
|
||||
# * :include
|
||||
# add given paths to $LOAD_PATH
|
||||
# * :require
|
||||
# require the given libraries
|
||||
def initialize(options = nil)
|
||||
@options = options
|
||||
end
|
||||
|
@ -100,17 +149,17 @@ module Rack
|
|||
:Port => 9292,
|
||||
:Host => "0.0.0.0",
|
||||
:AccessLog => [],
|
||||
:rack_file => ::File.expand_path("config.ru")
|
||||
:config => "config.ru"
|
||||
}
|
||||
end
|
||||
|
||||
def app
|
||||
@app ||= begin
|
||||
if !::File.exist? options[:rack_file]
|
||||
abort "configuration #{options[:rack_file]} not found"
|
||||
if !::File.exist? options[:config]
|
||||
abort "configuration #{options[:config]} not found"
|
||||
end
|
||||
|
||||
app, options = Rack::Builder.parse_file(self.options[:rack_file], opt_parser)
|
||||
app, options = Rack::Builder.parse_file(self.options[:config], opt_parser)
|
||||
self.options.merge! options
|
||||
app
|
||||
end
|
||||
|
@ -119,7 +168,7 @@ module Rack
|
|||
def self.middleware
|
||||
@middleware ||= begin
|
||||
m = Hash.new {|h,k| h[k] = []}
|
||||
m["deployment"].concat [lambda {|server| server.server =~ /CGI/ ? nil : [Rack::CommonLogger, $stderr] }]
|
||||
m["deployment"].concat [lambda {|server| server.server.name =~ /CGI/ ? nil : [Rack::CommonLogger, $stderr] }]
|
||||
m["development"].concat m["deployment"] + [[Rack::ShowExceptions], [Rack::Lint]]
|
||||
m
|
||||
end
|
||||
|
@ -143,7 +192,7 @@ module Rack
|
|||
end
|
||||
|
||||
if includes = options[:include]
|
||||
$LOAD_PATH.unshift *includes
|
||||
$LOAD_PATH.unshift(*includes)
|
||||
end
|
||||
|
||||
if library = options[:require]
|
||||
|
@ -152,11 +201,20 @@ module Rack
|
|||
|
||||
daemonize_app if options[:daemonize]
|
||||
write_pid if options[:pid]
|
||||
|
||||
trap(:INT) do
|
||||
if server.respond_to?(:shutdown)
|
||||
server.shutdown
|
||||
else
|
||||
exit
|
||||
end
|
||||
end
|
||||
|
||||
server.run wrapped_app, options
|
||||
end
|
||||
|
||||
def server
|
||||
@_server ||= Rack::Handler.get(options[:server]) || Rack::Handler.default
|
||||
@_server ||= Rack::Handler.get(options[:server]) || Rack::Handler.default(options)
|
||||
end
|
||||
|
||||
private
|
||||
|
@ -168,6 +226,7 @@ module Rack
|
|||
args.clear if ENV.include?("REQUEST_METHOD")
|
||||
|
||||
options.merge! opt_parser.parse! args
|
||||
ENV["RACK_ENV"] = options[:environment]
|
||||
options
|
||||
end
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ module Rack
|
|||
@mutex = Mutex.new
|
||||
mserv = @default_options[:memcache_server]
|
||||
mopts = @default_options.
|
||||
reject{|k,v| MemCache::DEFAULT_OPTIONS.include? k }
|
||||
reject{|k,v| !MemCache::DEFAULT_OPTIONS.include? k }
|
||||
@pool = MemCache.new mserv, mopts
|
||||
unless @pool.active? and @pool.servers.any?{|c| c.alive? }
|
||||
raise 'No memcache servers'
|
||||
|
|
13
vendor/plugins/rack/lib/rack/urlmap.rb
vendored
13
vendor/plugins/rack/lib/rack/urlmap.rb
vendored
|
@ -35,21 +35,20 @@ module Rack
|
|||
end
|
||||
|
||||
def call(env)
|
||||
path = env["PATH_INFO"].to_s
|
||||
path = env["PATH_INFO"]
|
||||
script_name = env['SCRIPT_NAME']
|
||||
hHost, sName, sPort = env.values_at('HTTP_HOST','SERVER_NAME','SERVER_PORT')
|
||||
@mapping.each { |host, location, match, app|
|
||||
next unless (hHost == host || sName == host \
|
||||
|| (host.nil? && (hHost == sName || hHost == sName+':'+sPort)))
|
||||
next unless path =~ match && rest = $1
|
||||
next unless path.to_s =~ match && rest = $1
|
||||
next unless rest.empty? || rest[0] == ?/
|
||||
|
||||
return app.call(
|
||||
env.merge(
|
||||
'SCRIPT_NAME' => (script_name + location),
|
||||
'PATH_INFO' => rest))
|
||||
env.merge!('SCRIPT_NAME' => (script_name + location), 'PATH_INFO' => rest)
|
||||
return app.call(env)
|
||||
}
|
||||
[404, {"Content-Type" => "text/plain", "X-Cascade" => "pass"}, ["Not Found: #{path}"]]
|
||||
ensure
|
||||
env.merge! 'PATH_INFO' => path, 'SCRIPT_NAME' => script_name
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
101
vendor/plugins/rack/lib/rack/utils.rb
vendored
101
vendor/plugins/rack/lib/rack/utils.rb
vendored
|
@ -1,5 +1,6 @@
|
|||
# -*- encoding: binary -*-
|
||||
|
||||
require 'fileutils'
|
||||
require 'set'
|
||||
require 'tempfile'
|
||||
|
||||
|
@ -38,9 +39,6 @@ module Rack
|
|||
|
||||
(qs || '').split(d ? /[#{d}] */n : DEFAULT_SEP).each do |p|
|
||||
k, v = p.split('=', 2).map { |x| unescape(x) }
|
||||
if v =~ /^("|')(.*)\1$/
|
||||
v = $2.gsub('\\'+$1, $1)
|
||||
end
|
||||
if cur = params[k]
|
||||
if cur.class == Array
|
||||
params[k] << v
|
||||
|
@ -69,9 +67,6 @@ module Rack
|
|||
module_function :parse_nested_query
|
||||
|
||||
def normalize_params(params, name, v = nil)
|
||||
if v and v =~ /^("|')(.*)\1$/
|
||||
v = $2.gsub('\\'+$1, $1)
|
||||
end
|
||||
name =~ %r(\A[\[\]]*([^\[\]]+)\]*)
|
||||
k = $1 || ''
|
||||
after = $' || ''
|
||||
|
@ -133,13 +128,18 @@ module Rack
|
|||
end
|
||||
module_function :build_nested_query
|
||||
|
||||
ESCAPE_HTML = {
|
||||
"&" => "&",
|
||||
"<" => "<",
|
||||
">" => ">",
|
||||
"'" => "'",
|
||||
'"' => """,
|
||||
}
|
||||
ESCAPE_HTML_PATTERN = Regexp.union(ESCAPE_HTML.keys)
|
||||
|
||||
# Escape ampersands, brackets and quotes to their HTML/XML entities.
|
||||
def escape_html(string)
|
||||
string.to_s.gsub("&", "&").
|
||||
gsub("<", "<").
|
||||
gsub(">", ">").
|
||||
gsub("'", "'").
|
||||
gsub('"', """)
|
||||
string.to_s.gsub(ESCAPE_HTML_PATTERN){|c| ESCAPE_HTML[c] }
|
||||
end
|
||||
module_function :escape_html
|
||||
|
||||
|
@ -180,8 +180,8 @@ module Rack
|
|||
path = "; path=" + value[:path] if value[:path]
|
||||
# According to RFC 2109, we need dashes here.
|
||||
# N.B.: cgi.rb uses spaces...
|
||||
expires = "; expires=" + value[:expires].clone.gmtime.
|
||||
strftime("%a, %d-%b-%Y %H:%M:%S GMT") if value[:expires]
|
||||
expires = "; expires=" +
|
||||
rfc2822(value[:expires].clone.gmtime) if value[:expires]
|
||||
secure = "; secure" if value[:secure]
|
||||
httponly = "; HttpOnly" if value[:httponly]
|
||||
value = value[:value]
|
||||
|
@ -192,12 +192,12 @@ module Rack
|
|||
"#{domain}#{path}#{expires}#{secure}#{httponly}"
|
||||
|
||||
case header["Set-Cookie"]
|
||||
when Array
|
||||
header["Set-Cookie"] << cookie
|
||||
when String
|
||||
header["Set-Cookie"] = [header["Set-Cookie"], cookie]
|
||||
when nil
|
||||
when nil, ''
|
||||
header["Set-Cookie"] = cookie
|
||||
when String
|
||||
header["Set-Cookie"] = [header["Set-Cookie"], cookie].join("\n")
|
||||
when Array
|
||||
header["Set-Cookie"] = (header["Set-Cookie"] + [cookie]).join("\n")
|
||||
end
|
||||
|
||||
nil
|
||||
|
@ -205,14 +205,25 @@ module Rack
|
|||
module_function :set_cookie_header!
|
||||
|
||||
def delete_cookie_header!(header, key, value = {})
|
||||
unless Array === header["Set-Cookie"]
|
||||
header["Set-Cookie"] = [header["Set-Cookie"]].compact
|
||||
case header["Set-Cookie"]
|
||||
when nil, ''
|
||||
cookies = []
|
||||
when String
|
||||
cookies = header["Set-Cookie"].split("\n")
|
||||
when Array
|
||||
cookies = header["Set-Cookie"]
|
||||
end
|
||||
|
||||
header["Set-Cookie"].reject! { |cookie|
|
||||
cookie =~ /\A#{escape(key)}=/
|
||||
cookies.reject! { |cookie|
|
||||
if value[:domain]
|
||||
cookie =~ /\A#{escape(key)}=.*domain=#{value[:domain]}/
|
||||
else
|
||||
cookie =~ /\A#{escape(key)}=/
|
||||
end
|
||||
}
|
||||
|
||||
header["Set-Cookie"] = cookies.join("\n")
|
||||
|
||||
set_cookie_header!(header, key,
|
||||
{:value => '', :path => nil, :domain => nil,
|
||||
:expires => Time.at(0) }.merge(value))
|
||||
|
@ -234,6 +245,22 @@ module Rack
|
|||
end
|
||||
module_function :bytesize
|
||||
|
||||
# Modified version of stdlib time.rb Time#rfc2822 to use '%d-%b-%Y' instead
|
||||
# of '% %b %Y'.
|
||||
# It assumes that the time is in GMT to comply to the RFC 2109.
|
||||
#
|
||||
# NOTE: I'm not sure the RFC says it requires GMT, but is ambigous enough
|
||||
# that I'm certain someone implemented only that option.
|
||||
# Do not use %a and %b from Time.strptime, it would use localized names for
|
||||
# weekday and month.
|
||||
#
|
||||
def rfc2822(time)
|
||||
wday = Time::RFC2822_DAY_NAME[time.wday]
|
||||
mon = Time::RFC2822_MONTH_NAME[time.mon - 1]
|
||||
time.strftime("#{wday}, %d-#{mon}-%Y %T GMT")
|
||||
end
|
||||
module_function :rfc2822
|
||||
|
||||
# Context allows the use of a compatible middleware at different points
|
||||
# in a request handling stack. A compatible middleware must define
|
||||
# #context which should take the arguments env and app. The first of which
|
||||
|
@ -291,7 +318,8 @@ module Rack
|
|||
end
|
||||
|
||||
def [](k)
|
||||
super(@names[k] ||= @names[k.downcase])
|
||||
super(@names[k]) if @names[k]
|
||||
super(@names[k.downcase])
|
||||
end
|
||||
|
||||
def []=(k, v)
|
||||
|
@ -478,11 +506,31 @@ module Rack
|
|||
head = buf.slice!(0, i+2) # First \r\n
|
||||
buf.slice!(0, 2) # Second \r\n
|
||||
|
||||
filename = head[/Content-Disposition:.* filename=(?:"((?:\\.|[^\"])*)"|([^;\s]*))/ni, 1]
|
||||
token = /[^\s()<>,;:\\"\/\[\]?=]+/
|
||||
condisp = /Content-Disposition:\s*#{token}\s*/i
|
||||
dispparm = /;\s*(#{token})=("(?:\\"|[^"])*"|#{token})*/
|
||||
|
||||
rfc2183 = /^#{condisp}(#{dispparm})+$/i
|
||||
broken_quoted = /^#{condisp}.*;\sfilename="(.*?)"(?:\s*$|\s*;\s*#{token}=)/i
|
||||
broken_unquoted = /^#{condisp}.*;\sfilename=(#{token})/i
|
||||
|
||||
if head =~ rfc2183
|
||||
filename = Hash[head.scan(dispparm)]['filename']
|
||||
filename = $1 if filename and filename =~ /^"(.*)"$/
|
||||
elsif head =~ broken_quoted
|
||||
filename = $1
|
||||
elsif head =~ broken_unquoted
|
||||
filename = $1
|
||||
end
|
||||
|
||||
if filename && filename !~ /\\[^\\"]/
|
||||
filename = Utils.unescape(filename).gsub(/\\(.)/, '\1')
|
||||
end
|
||||
|
||||
content_type = head[/Content-Type: (.*)#{EOL}/ni, 1]
|
||||
name = head[/Content-Disposition:.*\s+name="?([^\";]*)"?/ni, 1] || head[/Content-ID:\s*([^#{EOL}]*)/ni, 1]
|
||||
|
||||
if content_type || filename
|
||||
if filename
|
||||
body = Tempfile.new("RackMultipart")
|
||||
body.binmode if body.respond_to?(:binmode)
|
||||
end
|
||||
|
@ -519,8 +567,7 @@ module Rack
|
|||
# This handles the full Windows paths given by Internet Explorer
|
||||
# (and perhaps other broken user agents) without affecting
|
||||
# those which give the lone filename.
|
||||
filename =~ /^(?:.*[:\\\/])?(.*)/m
|
||||
filename = $1
|
||||
filename = filename.split(/[\/\\]/).last
|
||||
|
||||
data = {:filename => filename, :type => content_type,
|
||||
:name => name, :tempfile => body, :head => head}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue