Vendor Rack 1.1
Also clean up some View stuff.
This commit is contained in:
parent
77014652a3
commit
a705709f9a
74 changed files with 3080 additions and 608 deletions
|
@ -18,7 +18,7 @@
|
|||
onchange="proposeAddress();" />   
|
||||
<label for="address">Address:</label> <input type="text" class="disableAutoComplete" id="address" name="address" value="<%= @web.address %>"
|
||||
onchange="cleanAddress();" />
|
||||
<small><em>(Letters and digits only)</em></small>
|
||||
<em>(Letters and digits only)</em>
|
||||
</div>
|
||||
|
||||
<h2 style="margin-bottom: 3px">Specialize</h2>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<input type="text" name="author" id="authorName" value="<%= @author %>"
|
||||
onclick="this.value == 'AnonymousCoward' ? this.value = '' : true" />
|
||||
<%- if @page -%>
|
||||
| <%= link_to 'Cancel', :web => @web.address, :action => 'file'%> <small>(unlocks page)</small>
|
||||
| <%= link_to 'Cancel', :web => @web.address, :action => 'file'%> <em>(unlocks page)</em>
|
||||
<%- end -%>
|
||||
|
||||
</p>
|
||||
|
|
|
@ -4,8 +4,6 @@
|
|||
@hide_navigation = true
|
||||
-%>
|
||||
|
||||
<%= "<p style='color:red'>Please correct the error that caused this error in rendering:<br/><small>#{params["msg"]}</small></p>" if params["msg"] %>
|
||||
|
||||
<div id="MarkupHelp">
|
||||
<%= render(:file => "#{@web.markup}_help") -%>
|
||||
<%= render(:file => 'wiki_words_help') unless @web.brackets_only? -%>
|
||||
|
|
|
@ -61,13 +61,6 @@ margin:0.2em 0 0.2em 0;
|
|||
padding:0;
|
||||
}
|
||||
|
||||
h1#pageName small {
|
||||
color:#444;
|
||||
font-size:35%;
|
||||
line-height:1em;
|
||||
padding:0;
|
||||
}
|
||||
|
||||
#svg_logo {
|
||||
float:left;
|
||||
margin:.5em .25em 0 -.625em;
|
||||
|
|
3
vendor/plugins/rack/KNOWN-ISSUES
vendored
3
vendor/plugins/rack/KNOWN-ISSUES
vendored
|
@ -16,3 +16,6 @@
|
|||
end
|
||||
|
||||
Of course, use this only when your app runs at "/".
|
||||
|
||||
Since lighttpd 1.4.23, you also can use the "fix-root-scriptname" flag
|
||||
in fastcgi.server.
|
||||
|
|
83
vendor/plugins/rack/README
vendored
83
vendor/plugins/rack/README
vendored
|
@ -11,21 +11,13 @@ which all Rack applications should conform to.
|
|||
|
||||
== Specification changes in this release
|
||||
|
||||
With Rack 1.0, the Rack specification (found in SPEC) changed in the
|
||||
following backward-incompatible ways. This was done to properly
|
||||
support Ruby 1.9 and to deprecate some problematic techniques:
|
||||
With Rack 1.1, the Rack specification (found in SPEC) changed in the
|
||||
following backward-incompatible ways.
|
||||
|
||||
* Rack::VERSION has been pushed to [1,0].
|
||||
* Header values must be Strings now, split on "\n".
|
||||
* rack.input must be rewindable and support reading into a buffer,
|
||||
wrap with Rack::RewindableInput if it isn't.
|
||||
* Content-Length can be missing, in this case chunked transfer
|
||||
encoding is used.
|
||||
* Bodies can now additionally respond to #to_path with a filename to
|
||||
be served.
|
||||
* String bodies are deprecated and will not work with Ruby 1.9, use an
|
||||
Array with a single String instead.
|
||||
* rack.session is now specified.
|
||||
* Rack::VERSION has been pushed to [1,1].
|
||||
* rack.logger is now specified.
|
||||
* The SPEC now allows subclasses of the required types.
|
||||
* rack.input has to be opened in binary mode.
|
||||
|
||||
== Supported web servers
|
||||
|
||||
|
@ -43,8 +35,11 @@ The included *handlers* connect all kinds of web servers to Rack:
|
|||
These web servers include Rack handlers in their distributions:
|
||||
* Ebb
|
||||
* Fuzed
|
||||
* Glassfish v3
|
||||
* Phusion Passenger (which is mod_rack for Apache and for nginx)
|
||||
* Rainbows!
|
||||
* Unicorn
|
||||
* Zbatery
|
||||
|
||||
Any valid Rack app will run the same on all these handlers, without
|
||||
changing anything.
|
||||
|
@ -70,6 +65,7 @@ These frameworks include Rack adapters in their distributions:
|
|||
* Vintage
|
||||
* Waves
|
||||
* Wee
|
||||
* ... and many others.
|
||||
|
||||
Current links to these projects can be found at
|
||||
http://wiki.ramaze.net/Home#other-frameworks
|
||||
|
@ -130,13 +126,13 @@ Either with the embedded WEBrick starter:
|
|||
|
||||
Or with rackup:
|
||||
|
||||
bin/rackup -Ilib example/lobster.ru
|
||||
bin/rackup -Ilib example/lobster.ru
|
||||
|
||||
By default, the lobster is found at http://localhost:9292.
|
||||
|
||||
== Installing with RubyGems
|
||||
|
||||
A Gem of Rack is available. You can install it with:
|
||||
A Gem of Rack is available at gemcutter.org. You can install it with:
|
||||
|
||||
gem install rack
|
||||
|
||||
|
@ -165,7 +161,6 @@ To run the test suite completely, you need:
|
|||
* fcgi
|
||||
* memcache-client
|
||||
* mongrel
|
||||
* ruby-openid
|
||||
* thin
|
||||
|
||||
The full set of tests test FCGI access with lighttpd (on port
|
||||
|
@ -283,16 +278,49 @@ run on port 11211) and memcache-client installed.
|
|||
* Make sure WEBrick respects the :Host option
|
||||
* Many Ruby 1.9 fixes.
|
||||
|
||||
* December ??th, 2009: Ninth public release 1.1.0.
|
||||
* Moved Auth::OpenID to rack-contrib.
|
||||
* SPEC change that relaxes Lint slightly to allow subclasses of the
|
||||
required types
|
||||
* SPEC change to document rack.input binary mode in greator detail
|
||||
* SPEC define optional rack.logger specification
|
||||
* File servers support X-Cascade header
|
||||
* Imported Config middleware
|
||||
* Imported ETag middleware
|
||||
* Imported Runtime middleware
|
||||
* Imported Sendfile middleware
|
||||
* New Logger and NullLogger middlewares
|
||||
* Added mime type for .ogv and .manifest.
|
||||
* Don't squeeze PATH_INFO slashes
|
||||
* Use Content-Type to determine POST params parsing
|
||||
* Update Rack::Utils::HTTP_STATUS_CODES hash
|
||||
* Add status code lookup utility
|
||||
* Response should call #to_i on the status
|
||||
* Add Request#user_agent
|
||||
* Request#host knows about forwared host
|
||||
* Return an empty string for Request#host if HTTP_HOST and
|
||||
SERVER_NAME are both missing
|
||||
* Allow MockRequest to accept hash params
|
||||
* Optimizations to HeaderHash
|
||||
* Refactored rackup into Rack::Server
|
||||
* Added Utils.build_nested_query to complement Utils.parse_nested_query
|
||||
* Added Utils::Multipart.build_multipart to complement
|
||||
Utils::Multipart.parse_multipart
|
||||
* Extracted set and delete cookie helpers into Utils so they can be
|
||||
used outside Response
|
||||
* Extract parse_query and parse_multipart in Request so subclasses
|
||||
can change their behavior
|
||||
* Enforce binary encoding in RewindableInput
|
||||
* Set correct external_encoding for handlers that don't use RewindableInput
|
||||
|
||||
== Contact
|
||||
|
||||
Please mail bugs, suggestions and patches to
|
||||
<mailto:rack-devel@googlegroups.com>.
|
||||
Please post bugs, suggestions and patches to
|
||||
the bug tracker at <http://rack.lighthouseapp.com/>.
|
||||
|
||||
Mailing list archives are available at
|
||||
<http://groups.google.com/group/rack-devel>.
|
||||
|
||||
There is a bug tracker at <http://rack.lighthouseapp.com/>.
|
||||
|
||||
Git repository (send Git patches to the mailing list):
|
||||
* http://github.com/rack/rack
|
||||
* http://git.vuxu.org/cgi-bin/gitweb.cgi?p=rack.git
|
||||
|
@ -318,8 +346,14 @@ would like to thank:
|
|||
* Luc Heinrich for the Cookie sessions, the static file handler and bugfixes.
|
||||
* Armin Ronacher, for the logo and racktools.
|
||||
* Aredridel, Ben Alpert, Dan Kubb, Daniel Roethlisberger, Matt Todd,
|
||||
Tom Robinson, Phil Hagelberg, and S. Brent Faulkner for bug fixing
|
||||
and other improvements.
|
||||
Tom Robinson, Phil Hagelberg, S. Brent Faulkner, Bosko Milekic,
|
||||
Daniel Rodríguez Troitiño, Genki Takiuchi, Geoffrey Grosenbach,
|
||||
Julien Sanchez, Kamal Fariz Mahyuddin, Masayoshi Takahashi, Patrick
|
||||
Aljordm, Mig, and Kazuhiro Nishiyama for bug fixing and other
|
||||
improvements.
|
||||
* Eric Wong, Hongli Lai, Jeremy Kemper for their continuous support
|
||||
and API improvements.
|
||||
* Yehuda Katz and Carl Lerche for refactoring rackup.
|
||||
* Brian Candler, for Rack::ContentType.
|
||||
* Graham Batty, for improved handler loading.
|
||||
* Stephen Bannasch, for bug reports and documentation.
|
||||
|
@ -349,7 +383,7 @@ all copies or substantial portions of the Software.
|
|||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
@ -358,6 +392,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
Rack:: <http://rack.rubyforge.org/>
|
||||
Rack's Rubyforge project:: <http://rubyforge.org/projects/rack>
|
||||
Official Rack repositories:: <http://github.com/rack>
|
||||
Rack Lighthouse Bug Tracking:: <http://rack.lighthouseapp.com/>
|
||||
rack-devel mailing list:: <http://groups.google.com/group/rack-devel>
|
||||
|
||||
Christian Neukirchen:: <http://chneukirchen.org/>
|
||||
|
|
76
vendor/plugins/rack/Rakefile
vendored
76
vendor/plugins/rack/Rakefile
vendored
|
@ -6,9 +6,8 @@ require 'rake/testtask'
|
|||
desc "Run all the tests"
|
||||
task :default => [:test]
|
||||
|
||||
|
||||
desc "Make an archive as .tar.gz"
|
||||
task :dist => [:chmod, :changelog, :rdoc, "SPEC", "rack.gemspec"] do
|
||||
task :dist => [:chmod, :changelog, :rdoc, "SPEC"] do
|
||||
FileUtils.touch("RDOX")
|
||||
sh "git archive --format=tar --prefix=#{release}/ HEAD^{tree} >#{release}.tar"
|
||||
sh "pax -waf #{release}.tar -s ':^:#{release}/:' RDOX SPEC ChangeLog doc rack.gemspec"
|
||||
|
@ -28,21 +27,11 @@ task :officialrelease_really => [:fulltest, "RDOX", "SPEC", :dist, :gem] do
|
|||
sh "sha1sum #{release}.tar.gz #{release}.gem"
|
||||
end
|
||||
|
||||
|
||||
def version
|
||||
abort "You need to pass VERSION=... to build packages." unless ENV["VERSION"]
|
||||
ENV["VERSION"]
|
||||
end
|
||||
|
||||
def release
|
||||
"rack-#{version}"
|
||||
require File.dirname(__FILE__) + "/lib/rack"
|
||||
"rack-#{Rack.release}"
|
||||
end
|
||||
|
||||
def manifest
|
||||
`git ls-files`.split("\n")
|
||||
end
|
||||
|
||||
|
||||
desc "Make binaries executable"
|
||||
task :chmod do
|
||||
Dir["bin/*"].each { |binary| File.chmod(0775, binary) }
|
||||
|
@ -86,7 +75,7 @@ end
|
|||
|
||||
desc "Run all the fast tests"
|
||||
task :test do
|
||||
sh "specrb -Ilib:test -w #{ENV['TEST'] || '-a'} #{ENV['TESTOPTS'] || '-t "^(?!Rack::Handler|Rack::Adapter|Rack::Session::Memcache|Rack::Auth::OpenID)"'}"
|
||||
sh "specrb -Ilib:test -w #{ENV['TEST'] || '-a'} #{ENV['TESTOPTS'] || '-t "^(?!Rack::Handler|Rack::Adapter|Rack::Session::Memcache|rackup)"'}"
|
||||
end
|
||||
|
||||
desc "Run all the tests"
|
||||
|
@ -94,63 +83,14 @@ task :fulltest => [:chmod] do
|
|||
sh "specrb -Ilib:test -w #{ENV['TEST'] || '-a'} #{ENV['TESTOPTS']}"
|
||||
end
|
||||
|
||||
begin
|
||||
require 'rubygems'
|
||||
rescue LoadError
|
||||
# Too bad.
|
||||
else
|
||||
task "rack.gemspec" do
|
||||
spec = Gem::Specification.new do |s|
|
||||
s.name = "rack"
|
||||
s.version = version
|
||||
s.platform = Gem::Platform::RUBY
|
||||
s.summary = "a modular Ruby webserver interface"
|
||||
|
||||
s.description = <<-EOF
|
||||
Rack provides minimal, modular and adaptable interface for developing
|
||||
web applications in Ruby. By wrapping HTTP requests and responses in
|
||||
the simplest way possible, it unifies and distills the API for web
|
||||
servers, web frameworks, and software in between (the so-called
|
||||
middleware) into a single method call.
|
||||
|
||||
Also see http://rack.rubyforge.org.
|
||||
EOF
|
||||
|
||||
s.files = manifest + %w(SPEC RDOX rack.gemspec)
|
||||
s.bindir = 'bin'
|
||||
s.executables << 'rackup'
|
||||
s.require_path = 'lib'
|
||||
s.has_rdoc = true
|
||||
s.extra_rdoc_files = ['README', 'SPEC', 'RDOX', 'KNOWN-ISSUES']
|
||||
s.test_files = Dir['test/{test,spec}_*.rb']
|
||||
|
||||
s.author = 'Christian Neukirchen'
|
||||
s.email = 'chneukirchen@gmail.com'
|
||||
s.homepage = 'http://rack.rubyforge.org'
|
||||
s.rubyforge_project = 'rack'
|
||||
|
||||
s.add_development_dependency 'test-spec'
|
||||
|
||||
s.add_development_dependency 'camping'
|
||||
s.add_development_dependency 'fcgi'
|
||||
s.add_development_dependency 'memcache-client'
|
||||
s.add_development_dependency 'mongrel'
|
||||
s.add_development_dependency 'ruby-openid', '~> 2.0.0'
|
||||
s.add_development_dependency 'thin'
|
||||
end
|
||||
|
||||
File.open("rack.gemspec", "w") { |f| f << spec.to_ruby }
|
||||
end
|
||||
|
||||
task :gem => ["rack.gemspec", "SPEC"] do
|
||||
FileUtils.touch("RDOX")
|
||||
sh "gem build rack.gemspec"
|
||||
end
|
||||
task :gem => ["SPEC"] do
|
||||
FileUtils.touch("RDOX")
|
||||
sh "gem build rack.gemspec"
|
||||
end
|
||||
|
||||
desc "Generate RDoc documentation"
|
||||
task :rdoc do
|
||||
sh(*%w{rdoc --line-numbers --main README
|
||||
sh(*%w{rdoc --line-numbers --main README
|
||||
--title 'Rack\ Documentation' --charset utf-8 -U -o doc} +
|
||||
%w{README KNOWN-ISSUES SPEC RDOX} +
|
||||
Dir["lib/**/*.rb"])
|
||||
|
|
178
vendor/plugins/rack/bin/rackup
vendored
178
vendor/plugins/rack/bin/rackup
vendored
|
@ -1,176 +1,2 @@
|
|||
#!/usr/bin/env ruby
|
||||
# -*- ruby -*-
|
||||
|
||||
$LOAD_PATH.unshift File.expand_path("#{__FILE__}/../../lib")
|
||||
autoload :Rack, 'rack'
|
||||
|
||||
require 'optparse'
|
||||
|
||||
automatic = false
|
||||
server = nil
|
||||
env = "development"
|
||||
daemonize = false
|
||||
pid = nil
|
||||
options = {:Port => 9292, :Host => "0.0.0.0", :AccessLog => []}
|
||||
|
||||
# Don't evaluate CGI ISINDEX parameters.
|
||||
# http://hoohoo.ncsa.uiuc.edu/cgi/cl.html
|
||||
ARGV.clear if ENV.include?("REQUEST_METHOD")
|
||||
|
||||
opts = OptionParser.new("", 24, ' ') { |opts|
|
||||
opts.banner = "Usage: rackup [ruby options] [rack options] [rackup config]"
|
||||
|
||||
opts.separator ""
|
||||
opts.separator "Ruby options:"
|
||||
|
||||
lineno = 1
|
||||
opts.on("-e", "--eval LINE", "evaluate a LINE of code") { |line|
|
||||
eval line, TOPLEVEL_BINDING, "-e", lineno
|
||||
lineno += 1
|
||||
}
|
||||
|
||||
opts.on("-d", "--debug", "set debugging flags (set $DEBUG to true)") {
|
||||
$DEBUG = true
|
||||
}
|
||||
opts.on("-w", "--warn", "turn warnings on for your script") {
|
||||
$-w = true
|
||||
}
|
||||
|
||||
opts.on("-I", "--include PATH",
|
||||
"specify $LOAD_PATH (may be used more than once)") { |path|
|
||||
$LOAD_PATH.unshift(*path.split(":"))
|
||||
}
|
||||
|
||||
opts.on("-r", "--require LIBRARY",
|
||||
"require the library, before executing your script") { |library|
|
||||
require library
|
||||
}
|
||||
|
||||
opts.separator ""
|
||||
opts.separator "Rack options:"
|
||||
opts.on("-s", "--server SERVER", "serve using SERVER (webrick/mongrel)") { |s|
|
||||
server = s
|
||||
}
|
||||
|
||||
opts.on("-o", "--host HOST", "listen on HOST (default: 0.0.0.0)") { |host|
|
||||
options[:Host] = host
|
||||
}
|
||||
|
||||
opts.on("-p", "--port PORT", "use PORT (default: 9292)") { |port|
|
||||
options[:Port] = port
|
||||
}
|
||||
|
||||
opts.on("-E", "--env ENVIRONMENT", "use ENVIRONMENT for defaults (default: development)") { |e|
|
||||
env = e
|
||||
}
|
||||
|
||||
opts.on("-D", "--daemonize", "run daemonized in the background") { |d|
|
||||
daemonize = d ? true : false
|
||||
}
|
||||
|
||||
opts.on("-P", "--pid FILE", "file to store PID (default: rack.pid)") { |f|
|
||||
pid = File.expand_path(f)
|
||||
}
|
||||
|
||||
opts.separator ""
|
||||
opts.separator "Common options:"
|
||||
|
||||
opts.on_tail("-h", "--help", "Show this message") do
|
||||
puts opts
|
||||
exit
|
||||
end
|
||||
|
||||
opts.on_tail("--version", "Show version") do
|
||||
puts "Rack #{Rack.version}"
|
||||
exit
|
||||
end
|
||||
|
||||
opts.parse! ARGV
|
||||
}
|
||||
|
||||
require 'pp' if $DEBUG
|
||||
|
||||
config = ARGV[0] || "config.ru"
|
||||
if !File.exist? config
|
||||
abort "configuration #{config} not found"
|
||||
end
|
||||
|
||||
if config =~ /\.ru$/
|
||||
cfgfile = File.read(config)
|
||||
if cfgfile[/^#\\(.*)/]
|
||||
opts.parse! $1.split(/\s+/)
|
||||
end
|
||||
inner_app = eval "Rack::Builder.new {( " + cfgfile + "\n )}.to_app",
|
||||
nil, config
|
||||
else
|
||||
require config
|
||||
inner_app = Object.const_get(File.basename(config, '.rb').capitalize)
|
||||
end
|
||||
|
||||
unless server = Rack::Handler.get(server)
|
||||
# Guess.
|
||||
if ENV.include?("PHP_FCGI_CHILDREN")
|
||||
server = Rack::Handler::FastCGI
|
||||
|
||||
# We already speak FastCGI
|
||||
options.delete :File
|
||||
options.delete :Port
|
||||
elsif ENV.include?("REQUEST_METHOD")
|
||||
server = Rack::Handler::CGI
|
||||
else
|
||||
begin
|
||||
server = Rack::Handler::Mongrel
|
||||
rescue LoadError => e
|
||||
server = Rack::Handler::WEBrick
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
p server if $DEBUG
|
||||
|
||||
case env
|
||||
when "development"
|
||||
app = Rack::Builder.new {
|
||||
use Rack::CommonLogger, $stderr unless server.name =~ /CGI/
|
||||
use Rack::ShowExceptions
|
||||
use Rack::Lint
|
||||
run inner_app
|
||||
}.to_app
|
||||
|
||||
when "deployment"
|
||||
app = Rack::Builder.new {
|
||||
use Rack::CommonLogger, $stderr unless server.name =~ /CGI/
|
||||
run inner_app
|
||||
}.to_app
|
||||
|
||||
when "none"
|
||||
app = inner_app
|
||||
|
||||
end
|
||||
|
||||
if $DEBUG
|
||||
pp app
|
||||
pp inner_app
|
||||
end
|
||||
|
||||
if daemonize
|
||||
if RUBY_VERSION < "1.9"
|
||||
exit if fork
|
||||
Process.setsid
|
||||
exit if fork
|
||||
Dir.chdir "/"
|
||||
File.umask 0000
|
||||
STDIN.reopen "/dev/null"
|
||||
STDOUT.reopen "/dev/null", "a"
|
||||
STDERR.reopen "/dev/null", "a"
|
||||
else
|
||||
Process.daemon
|
||||
end
|
||||
|
||||
if pid
|
||||
File.open(pid, 'w'){ |f| f.write("#{Process.pid}") }
|
||||
at_exit { File.delete(pid) if File.exist?(pid) }
|
||||
end
|
||||
end
|
||||
|
||||
server.run app, options
|
||||
require "rack"
|
||||
Rack::Server.start
|
||||
|
|
16
vendor/plugins/rack/lib/rack.rb
vendored
16
vendor/plugins/rack/lib/rack.rb
vendored
|
@ -3,10 +3,6 @@
|
|||
# Rack is freely distributable under the terms of an MIT-style license.
|
||||
# See COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
path = File.expand_path(File.dirname(__FILE__))
|
||||
$:.unshift(path) unless $:.include?(path)
|
||||
|
||||
|
||||
# The Rack main module, serving as a namespace for all core Rack
|
||||
# modules and classes.
|
||||
#
|
||||
|
@ -15,7 +11,7 @@ $:.unshift(path) unless $:.include?(path)
|
|||
|
||||
module Rack
|
||||
# The Rack protocol version number implemented.
|
||||
VERSION = [1,0]
|
||||
VERSION = [1,1]
|
||||
|
||||
# Return the Rack protocol version as a dotted string.
|
||||
def self.version
|
||||
|
@ -24,7 +20,7 @@ module Rack
|
|||
|
||||
# Return the Rack release as a dotted string.
|
||||
def self.release
|
||||
"1.0"
|
||||
"1.1"
|
||||
end
|
||||
|
||||
autoload :Builder, "rack/builder"
|
||||
|
@ -32,8 +28,10 @@ module Rack
|
|||
autoload :Chunked, "rack/chunked"
|
||||
autoload :CommonLogger, "rack/commonlogger"
|
||||
autoload :ConditionalGet, "rack/conditionalget"
|
||||
autoload :Config, "rack/config"
|
||||
autoload :ContentLength, "rack/content_length"
|
||||
autoload :ContentType, "rack/content_type"
|
||||
autoload :ETag, "rack/etag"
|
||||
autoload :File, "rack/file"
|
||||
autoload :Deflater, "rack/deflater"
|
||||
autoload :Directory, "rack/directory"
|
||||
|
@ -42,10 +40,15 @@ module Rack
|
|||
autoload :Head, "rack/head"
|
||||
autoload :Lint, "rack/lint"
|
||||
autoload :Lock, "rack/lock"
|
||||
autoload :Logger, "rack/logger"
|
||||
autoload :MethodOverride, "rack/methodoverride"
|
||||
autoload :Mime, "rack/mime"
|
||||
autoload :NullLogger, "rack/nulllogger"
|
||||
autoload :Recursive, "rack/recursive"
|
||||
autoload :Reloader, "rack/reloader"
|
||||
autoload :Runtime, "rack/runtime"
|
||||
autoload :Sendfile, "rack/sendfile"
|
||||
autoload :Server, "rack/server"
|
||||
autoload :ShowExceptions, "rack/showexceptions"
|
||||
autoload :ShowStatus, "rack/showstatus"
|
||||
autoload :Static, "rack/static"
|
||||
|
@ -62,7 +65,6 @@ module Rack
|
|||
autoload :Basic, "rack/auth/basic"
|
||||
autoload :AbstractRequest, "rack/auth/abstract/request"
|
||||
autoload :AbstractHandler, "rack/auth/abstract/handler"
|
||||
autoload :OpenID, "rack/auth/openid"
|
||||
module Digest
|
||||
autoload :MD5, "rack/auth/digest/md5"
|
||||
autoload :Nonce, "rack/auth/digest/nonce"
|
||||
|
|
17
vendor/plugins/rack/lib/rack/builder.rb
vendored
17
vendor/plugins/rack/lib/rack/builder.rb
vendored
|
@ -24,6 +24,23 @@ module Rack
|
|||
# You can use +map+ to construct a Rack::URLMap in a convenient way.
|
||||
|
||||
class Builder
|
||||
def self.parse_file(config, opts = Server::Options.new)
|
||||
options = {}
|
||||
if config =~ /\.ru$/
|
||||
cfgfile = ::File.read(config)
|
||||
if cfgfile[/^#\\(.*)/] && opts
|
||||
options = opts.parse! $1.split(/\s+/)
|
||||
end
|
||||
cfgfile.sub!(/^__END__\n.*/, '')
|
||||
app = eval "Rack::Builder.new {( " + cfgfile + "\n )}.to_app",
|
||||
TOPLEVEL_BINDING, config
|
||||
else
|
||||
require config
|
||||
app = Object.const_get(::File.basename(config, '.rb').capitalize)
|
||||
end
|
||||
return app, options
|
||||
end
|
||||
|
||||
def initialize(&block)
|
||||
@ins = []
|
||||
instance_eval(&block) if block_given?
|
||||
|
|
29
vendor/plugins/rack/lib/rack/cascade.rb
vendored
29
vendor/plugins/rack/lib/rack/cascade.rb
vendored
|
@ -4,31 +4,36 @@ module Rack
|
|||
# status codes).
|
||||
|
||||
class Cascade
|
||||
NotFound = [404, {}, []]
|
||||
|
||||
attr_reader :apps
|
||||
|
||||
def initialize(apps, catch=404)
|
||||
@apps = apps
|
||||
@catch = [*catch]
|
||||
@apps = []; @has_app = {}
|
||||
apps.each { |app| add app }
|
||||
|
||||
@catch = {}
|
||||
[*catch].each { |status| @catch[status] = true }
|
||||
end
|
||||
|
||||
def call(env)
|
||||
status = headers = body = nil
|
||||
raise ArgumentError, "empty cascade" if @apps.empty?
|
||||
@apps.each { |app|
|
||||
begin
|
||||
status, headers, body = app.call(env)
|
||||
break unless @catch.include?(status.to_i)
|
||||
end
|
||||
}
|
||||
[status, headers, body]
|
||||
result = NotFound
|
||||
|
||||
@apps.each do |app|
|
||||
result = app.call(env)
|
||||
break unless @catch.include?(result[0].to_i)
|
||||
end
|
||||
|
||||
result
|
||||
end
|
||||
|
||||
def add app
|
||||
@has_app[app] = true
|
||||
@apps << app
|
||||
end
|
||||
|
||||
def include? app
|
||||
@apps.include? app
|
||||
@has_app.include? app
|
||||
end
|
||||
|
||||
alias_method :<<, :add
|
||||
|
|
4
vendor/plugins/rack/lib/rack/chunked.rb
vendored
4
vendor/plugins/rack/lib/rack/chunked.rb
vendored
|
@ -19,7 +19,7 @@ module Rack
|
|||
STATUS_WITH_NO_ENTITY_BODY.include?(status) ||
|
||||
headers['Content-Length'] ||
|
||||
headers['Transfer-Encoding']
|
||||
[status, headers.to_hash, body]
|
||||
[status, headers, body]
|
||||
else
|
||||
dup.chunk(status, headers, body)
|
||||
end
|
||||
|
@ -29,7 +29,7 @@ module Rack
|
|||
@body = body
|
||||
headers.delete('Content-Length')
|
||||
headers['Transfer-Encoding'] = 'chunked'
|
||||
[status, headers.to_hash, self]
|
||||
[status, headers, self]
|
||||
end
|
||||
|
||||
def each
|
||||
|
|
74
vendor/plugins/rack/lib/rack/commonlogger.rb
vendored
74
vendor/plugins/rack/lib/rack/commonlogger.rb
vendored
|
@ -2,60 +2,48 @@ module Rack
|
|||
# Rack::CommonLogger forwards every request to an +app+ given, and
|
||||
# logs a line in the Apache common log format to the +logger+, or
|
||||
# rack.errors by default.
|
||||
|
||||
class CommonLogger
|
||||
# Common Log Format: http://httpd.apache.org/docs/1.3/logs.html#common
|
||||
# lilith.local - - [07/Aug/2006 23:58:02] "GET / HTTP/1.1" 500 -
|
||||
# %{%s - %s [%s] "%s %s%s %s" %d %s\n} %
|
||||
FORMAT = %{%s - %s [%s] "%s %s%s %s" %d %s %0.4f\n}
|
||||
|
||||
def initialize(app, logger=nil)
|
||||
@app = app
|
||||
@logger = logger
|
||||
end
|
||||
|
||||
def call(env)
|
||||
dup._call(env)
|
||||
began_at = Time.now
|
||||
status, header, body = @app.call(env)
|
||||
header = Utils::HeaderHash.new(header)
|
||||
log(env, status, header, began_at)
|
||||
[status, header, body]
|
||||
end
|
||||
|
||||
def _call(env)
|
||||
@env = env
|
||||
@logger ||= self
|
||||
@time = Time.now
|
||||
@status, @header, @body = @app.call(env)
|
||||
[@status, @header, self]
|
||||
private
|
||||
|
||||
def log(env, status, header, began_at)
|
||||
now = Time.now
|
||||
length = extract_content_length(header)
|
||||
|
||||
logger = @logger || env['rack.errors']
|
||||
logger.write FORMAT % [
|
||||
env['HTTP_X_FORWARDED_FOR'] || env["REMOTE_ADDR"] || "-",
|
||||
env["REMOTE_USER"] || "-",
|
||||
now.strftime("%d/%b/%Y %H:%M:%S"),
|
||||
env["REQUEST_METHOD"],
|
||||
env["PATH_INFO"],
|
||||
env["QUERY_STRING"].empty? ? "" : "?"+env["QUERY_STRING"],
|
||||
env["HTTP_VERSION"],
|
||||
status.to_s[0..3],
|
||||
length,
|
||||
now - began_at ]
|
||||
end
|
||||
|
||||
def close
|
||||
@body.close if @body.respond_to? :close
|
||||
end
|
||||
|
||||
# By default, log to rack.errors.
|
||||
def <<(str)
|
||||
@env["rack.errors"].write(str)
|
||||
@env["rack.errors"].flush
|
||||
end
|
||||
|
||||
def each
|
||||
length = 0
|
||||
@body.each { |part|
|
||||
length += part.size
|
||||
yield part
|
||||
}
|
||||
|
||||
@now = Time.now
|
||||
|
||||
# Common Log Format: http://httpd.apache.org/docs/1.3/logs.html#common
|
||||
# lilith.local - - [07/Aug/2006 23:58:02] "GET / HTTP/1.1" 500 -
|
||||
# %{%s - %s [%s] "%s %s%s %s" %d %s\n} %
|
||||
@logger << %{%s - %s [%s] "%s %s%s %s" %d %s %0.4f\n} %
|
||||
[
|
||||
@env['HTTP_X_FORWARDED_FOR'] || @env["REMOTE_ADDR"] || "-",
|
||||
@env["REMOTE_USER"] || "-",
|
||||
@now.strftime("%d/%b/%Y %H:%M:%S"),
|
||||
@env["REQUEST_METHOD"],
|
||||
@env["PATH_INFO"],
|
||||
@env["QUERY_STRING"].empty? ? "" : "?"+@env["QUERY_STRING"],
|
||||
@env["HTTP_VERSION"],
|
||||
@status.to_s[0..3],
|
||||
(length.zero? ? "-" : length.to_s),
|
||||
@now - @time
|
||||
]
|
||||
def extract_content_length(headers)
|
||||
value = headers['Content-Length'] or return '-'
|
||||
value.to_s == '0' ? '-' : value
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
15
vendor/plugins/rack/lib/rack/config.rb
vendored
Normal file
15
vendor/plugins/rack/lib/rack/config.rb
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
module Rack
|
||||
# Rack::Config modifies the environment using the block given during
|
||||
# initialization.
|
||||
class Config
|
||||
def initialize(app, &block)
|
||||
@app = app
|
||||
@block = block
|
||||
end
|
||||
|
||||
def call(env)
|
||||
@block.call(env)
|
||||
@app.call(env)
|
||||
end
|
||||
end
|
||||
end
|
2
vendor/plugins/rack/lib/rack/content_type.rb
vendored
2
vendor/plugins/rack/lib/rack/content_type.rb
vendored
|
@ -17,7 +17,7 @@ module Rack
|
|||
status, headers, body = @app.call(env)
|
||||
headers = Utils::HeaderHash.new(headers)
|
||||
headers['Content-Type'] ||= @content_type
|
||||
[status, headers.to_hash, body]
|
||||
[status, headers, body]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
8
vendor/plugins/rack/lib/rack/directory.rb
vendored
8
vendor/plugins/rack/lib/rack/directory.rb
vendored
|
@ -71,7 +71,9 @@ table { width:100%%; }
|
|||
|
||||
body = "Forbidden\n"
|
||||
size = Rack::Utils.bytesize(body)
|
||||
return [403, {"Content-Type" => "text/plain","Content-Length" => size.to_s}, [body]]
|
||||
return [403, {"Content-Type" => "text/plain",
|
||||
"Content-Length" => size.to_s,
|
||||
"X-Cascade" => "pass"}, [body]]
|
||||
end
|
||||
|
||||
def list_directory
|
||||
|
@ -123,7 +125,9 @@ table { width:100%%; }
|
|||
def entity_not_found
|
||||
body = "Entity not found: #{@path_info}\n"
|
||||
size = Rack::Utils.bytesize(body)
|
||||
return [404, {"Content-Type" => "text/plain", "Content-Length" => size.to_s}, [body]]
|
||||
return [404, {"Content-Type" => "text/plain",
|
||||
"Content-Length" => size.to_s,
|
||||
"X-Cascade" => "pass"}, [body]]
|
||||
end
|
||||
|
||||
def each
|
||||
|
|
23
vendor/plugins/rack/lib/rack/etag.rb
vendored
Normal file
23
vendor/plugins/rack/lib/rack/etag.rb
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
require 'digest/md5'
|
||||
|
||||
module Rack
|
||||
# Automatically sets the ETag header on all String bodies
|
||||
class ETag
|
||||
def initialize(app)
|
||||
@app = app
|
||||
end
|
||||
|
||||
def call(env)
|
||||
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]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
6
vendor/plugins/rack/lib/rack/file.rb
vendored
6
vendor/plugins/rack/lib/rack/file.rb
vendored
|
@ -45,7 +45,8 @@ module Rack
|
|||
def forbidden
|
||||
body = "Forbidden\n"
|
||||
[403, {"Content-Type" => "text/plain",
|
||||
"Content-Length" => body.size.to_s},
|
||||
"Content-Length" => body.size.to_s,
|
||||
"X-Cascade" => "pass"},
|
||||
[body]]
|
||||
end
|
||||
|
||||
|
@ -73,7 +74,8 @@ module Rack
|
|||
def not_found
|
||||
body = "File not found: #{@path_info}\n"
|
||||
[404, {"Content-Type" => "text/plain",
|
||||
"Content-Length" => body.size.to_s},
|
||||
"Content-Length" => body.size.to_s,
|
||||
"X-Cascade" => "pass"},
|
||||
[body]]
|
||||
end
|
||||
|
||||
|
|
19
vendor/plugins/rack/lib/rack/handler.rb
vendored
19
vendor/plugins/rack/lib/rack/handler.rb
vendored
|
@ -22,6 +22,25 @@ module Rack
|
|||
end
|
||||
end
|
||||
|
||||
def self.default(options = {})
|
||||
# Guess.
|
||||
if ENV.include?("PHP_FCGI_CHILDREN")
|
||||
# We already speak FastCGI
|
||||
options.delete :File
|
||||
options.delete :Port
|
||||
|
||||
Rack::Handler::FastCGI
|
||||
elsif ENV.include?("REQUEST_METHOD")
|
||||
Rack::Handler::CGI
|
||||
else
|
||||
begin
|
||||
Rack::Handler::Mongrel
|
||||
rescue LoadError => e
|
||||
Rack::Handler::WEBrick
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Transforms server-name constants to their canonical form as filenames,
|
||||
# then tries to require them but silences the LoadError if not found
|
||||
#
|
||||
|
|
2
vendor/plugins/rack/lib/rack/handler/cgi.rb
vendored
2
vendor/plugins/rack/lib/rack/handler/cgi.rb
vendored
|
@ -15,7 +15,7 @@ module Rack
|
|||
|
||||
env["SCRIPT_NAME"] = "" if env["SCRIPT_NAME"] == "/"
|
||||
|
||||
env.update({"rack.version" => [1,0],
|
||||
env.update({"rack.version" => [1,1],
|
||||
"rack.input" => $stdin,
|
||||
"rack.errors" => $stderr,
|
||||
|
||||
|
|
|
@ -33,10 +33,10 @@ module Rack
|
|||
env.delete "HTTP_CONTENT_LENGTH"
|
||||
|
||||
env["SCRIPT_NAME"] = "" if env["SCRIPT_NAME"] == "/"
|
||||
|
||||
|
||||
rack_input = RewindableInput.new(request.in)
|
||||
|
||||
env.update({"rack.version" => [1,0],
|
||||
env.update({"rack.version" => [1,1],
|
||||
"rack.input" => rack_input,
|
||||
"rack.errors" => request.err,
|
||||
|
||||
|
@ -50,7 +50,6 @@ module Rack
|
|||
env["QUERY_STRING"] ||= ""
|
||||
env["HTTP_VERSION"] ||= env["SERVER_PROTOCOL"]
|
||||
env["REQUEST_PATH"] ||= "/"
|
||||
env.delete "PATH_INFO" if env["PATH_INFO"] == ""
|
||||
env.delete "CONTENT_TYPE" if env["CONTENT_TYPE"] == ""
|
||||
env.delete "CONTENT_LENGTH" if env["CONTENT_LENGTH"] == ""
|
||||
|
||||
|
|
5
vendor/plugins/rack/lib/rack/handler/lsws.rb
vendored
5
vendor/plugins/rack/lib/rack/handler/lsws.rb
vendored
|
@ -1,5 +1,6 @@
|
|||
require 'lsapi'
|
||||
require 'rack/content_length'
|
||||
require 'rack/rewindable_input'
|
||||
|
||||
module Rack
|
||||
module Handler
|
||||
|
@ -19,7 +20,7 @@ module Rack
|
|||
rack_input = RewindableInput.new($stdin.read.to_s)
|
||||
|
||||
env.update(
|
||||
"rack.version" => [1,0],
|
||||
"rack.version" => [1,1],
|
||||
"rack.input" => rack_input,
|
||||
"rack.errors" => $stderr,
|
||||
"rack.multithread" => false,
|
||||
|
@ -38,6 +39,8 @@ module Rack
|
|||
ensure
|
||||
body.close if body.respond_to? :close
|
||||
end
|
||||
ensure
|
||||
rack_input.close
|
||||
end
|
||||
def self.send_headers(status, headers)
|
||||
print "Status: #{status}\r\n"
|
||||
|
|
13
vendor/plugins/rack/lib/rack/handler/mongrel.rb
vendored
13
vendor/plugins/rack/lib/rack/handler/mongrel.rb
vendored
|
@ -7,10 +7,14 @@ module Rack
|
|||
module Handler
|
||||
class Mongrel < ::Mongrel::HttpHandler
|
||||
def self.run(app, options={})
|
||||
server = ::Mongrel::HttpServer.new(options[:Host] || '0.0.0.0',
|
||||
options[:Port] || 8080)
|
||||
server = ::Mongrel::HttpServer.new(
|
||||
options[:Host] || '0.0.0.0',
|
||||
options[:Port] || 8080,
|
||||
options[:num_processors] || 950,
|
||||
options[:throttle] || 0,
|
||||
options[:timeout] || 60)
|
||||
# Acts like Rack::URLMap, utilizing Mongrel's own path finding methods.
|
||||
# Use is similar to #run, replacing the app argument with a hash of
|
||||
# Use is similar to #run, replacing the app argument with a hash of
|
||||
# { path=>app, ... } or an instance of Rack::URLMap.
|
||||
if options[:map]
|
||||
if app.is_a? Hash
|
||||
|
@ -48,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,0],
|
||||
env.update({"rack.version" => [1,1],
|
||||
"rack.input" => rack_input,
|
||||
"rack.errors" => $stderr,
|
||||
|
||||
|
@ -59,7 +63,6 @@ module Rack
|
|||
"rack.url_scheme" => "http",
|
||||
})
|
||||
env["QUERY_STRING"] ||= ""
|
||||
env.delete "PATH_INFO" if env["PATH_INFO"] == ""
|
||||
|
||||
status, headers, body = @app.call(env)
|
||||
|
||||
|
|
8
vendor/plugins/rack/lib/rack/handler/scgi.rb
vendored
8
vendor/plugins/rack/lib/rack/handler/scgi.rb
vendored
|
@ -7,14 +7,14 @@ module Rack
|
|||
module Handler
|
||||
class SCGI < ::SCGI::Processor
|
||||
attr_accessor :app
|
||||
|
||||
|
||||
def self.run(app, options=nil)
|
||||
new(options.merge(:app=>app,
|
||||
:host=>options[:Host],
|
||||
:port=>options[:Port],
|
||||
:socket=>options[:Socket])).listen
|
||||
end
|
||||
|
||||
|
||||
def initialize(settings = {})
|
||||
@app = Rack::Chunked.new(Rack::ContentLength.new(settings[:app]))
|
||||
@log = Object.new
|
||||
|
@ -22,7 +22,7 @@ module Rack
|
|||
def @log.error(*args); end
|
||||
super(settings)
|
||||
end
|
||||
|
||||
|
||||
def process_request(request, input_body, socket)
|
||||
env = {}.replace(request)
|
||||
env.delete "HTTP_CONTENT_TYPE"
|
||||
|
@ -36,7 +36,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,0],
|
||||
env.update({"rack.version" => [1,1],
|
||||
"rack.input" => rack_input,
|
||||
"rack.errors" => $stderr,
|
||||
"rack.multithread" => true,
|
||||
|
|
|
@ -27,7 +27,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,0],
|
||||
env.update({"rack.version" => [1,1],
|
||||
"rack.input" => rack_input,
|
||||
"rack.errors" => $stderr,
|
||||
|
||||
|
@ -41,9 +41,7 @@ module Rack
|
|||
env["HTTP_VERSION"] ||= env["SERVER_PROTOCOL"]
|
||||
env["QUERY_STRING"] ||= ""
|
||||
env["REQUEST_PATH"] ||= "/"
|
||||
if env["PATH_INFO"] == ""
|
||||
env.delete "PATH_INFO"
|
||||
else
|
||||
unless env["PATH_INFO"] == ""
|
||||
path, n = req.request_uri.path, env["SCRIPT_NAME"].length
|
||||
env["PATH_INFO"] = path[n, path.length-n]
|
||||
end
|
||||
|
|
59
vendor/plugins/rack/lib/rack/lint.rb
vendored
59
vendor/plugins/rack/lib/rack/lint.rb
vendored
|
@ -61,7 +61,7 @@ module Rack
|
|||
## subclassing allowed) 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.instance_of? Hash
|
||||
env.kind_of? Hash
|
||||
}
|
||||
|
||||
##
|
||||
|
@ -111,7 +111,7 @@ module Rack
|
|||
## In addition to this, the Rack environment must include these
|
||||
## Rack-specific variables:
|
||||
|
||||
## <tt>rack.version</tt>:: The Array [1,0], representing this version of Rack.
|
||||
## <tt>rack.version</tt>:: The Array [1,1], representing this version of Rack.
|
||||
## <tt>rack.url_scheme</tt>:: +http+ or +https+, depending on the request URL.
|
||||
## <tt>rack.input</tt>:: See below, the input stream.
|
||||
## <tt>rack.errors</tt>:: See below, the error stream.
|
||||
|
@ -148,6 +148,35 @@ module Rack
|
|||
}
|
||||
end
|
||||
|
||||
## <tt>rack.logger</tt>:: A common object interface for logging messages.
|
||||
## The object must implement:
|
||||
if logger = env['rack.logger']
|
||||
## info(message, &block)
|
||||
assert("logger #{logger.inspect} must respond to info") {
|
||||
logger.respond_to?(:info)
|
||||
}
|
||||
|
||||
## debug(message, &block)
|
||||
assert("logger #{logger.inspect} must respond to debug") {
|
||||
logger.respond_to?(:debug)
|
||||
}
|
||||
|
||||
## warn(message, &block)
|
||||
assert("logger #{logger.inspect} must respond to warn") {
|
||||
logger.respond_to?(:warn)
|
||||
}
|
||||
|
||||
## error(message, &block)
|
||||
assert("logger #{logger.inspect} must respond to error") {
|
||||
logger.respond_to?(:error)
|
||||
}
|
||||
|
||||
## fatal(message, &block)
|
||||
assert("logger #{logger.inspect} must respond to fatal") {
|
||||
logger.respond_to?(:fatal)
|
||||
}
|
||||
end
|
||||
|
||||
## The server or the application can store their own data in the
|
||||
## environment, too. The keys must contain at least one dot,
|
||||
## and should be prefixed uniquely. The prefix <tt>rack.</tt>
|
||||
|
@ -175,7 +204,7 @@ module Rack
|
|||
env.each { |key, value|
|
||||
next if key.include? "." # Skip extensions
|
||||
assert("env variable #{key} has non-string value #{value.inspect}") {
|
||||
value.instance_of? String
|
||||
value.kind_of? String
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -184,7 +213,7 @@ module Rack
|
|||
|
||||
## * <tt>rack.version</tt> must be an array of Integers.
|
||||
assert("rack.version must be an Array, was #{env["rack.version"].class}") {
|
||||
env["rack.version"].instance_of? Array
|
||||
env["rack.version"].kind_of? Array
|
||||
}
|
||||
## * <tt>rack.url_scheme</tt> must either be +http+ or +https+.
|
||||
assert("rack.url_scheme unknown: #{env["rack.url_scheme"].inspect}") {
|
||||
|
@ -243,7 +272,7 @@ module Rack
|
|||
assert("rack.input #{input} is not opened in binary mode") {
|
||||
input.binmode?
|
||||
} if input.respond_to?(:binmode?)
|
||||
|
||||
|
||||
## The input stream must respond to +gets+, +each+, +read+ and +rewind+.
|
||||
[:gets, :each, :read, :rewind].each { |method|
|
||||
assert("rack.input #{input} does not respond to ##{method}") {
|
||||
|
@ -269,7 +298,7 @@ module Rack
|
|||
assert("rack.input#gets called with arguments") { args.size == 0 }
|
||||
v = @input.gets
|
||||
assert("rack.input#gets didn't return a String") {
|
||||
v.nil? or v.instance_of? String
|
||||
v.nil? or v.kind_of? String
|
||||
}
|
||||
v
|
||||
end
|
||||
|
@ -300,18 +329,18 @@ module Rack
|
|||
args[1].kind_of?(String)
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
v = @input.read(*args)
|
||||
|
||||
|
||||
assert("rack.input#read didn't return nil or a String") {
|
||||
v.nil? or v.instance_of? String
|
||||
v.nil? or v.kind_of? String
|
||||
}
|
||||
if args[0].nil?
|
||||
assert("rack.input#read(nil) returned nil on EOF") {
|
||||
!v.nil?
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
v
|
||||
end
|
||||
|
||||
|
@ -320,12 +349,12 @@ module Rack
|
|||
assert("rack.input#each called with arguments") { args.size == 0 }
|
||||
@input.each { |line|
|
||||
assert("rack.input#each didn't yield a String") {
|
||||
line.instance_of? String
|
||||
line.kind_of? String
|
||||
}
|
||||
yield line
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
## * +rewind+ must be called without arguments. It rewinds the input
|
||||
## stream back to the beginning. It must not raise Errno::ESPIPE:
|
||||
## that is, it may not be a pipe or a socket. Therefore, handler
|
||||
|
@ -373,7 +402,7 @@ module Rack
|
|||
|
||||
## * +write+ must be called with a single argument that is a String.
|
||||
def write(str)
|
||||
assert("rack.errors#write not called with a String") { str.instance_of? String }
|
||||
assert("rack.errors#write not called with a String") { str.kind_of? String }
|
||||
@error.write str
|
||||
end
|
||||
|
||||
|
@ -407,7 +436,7 @@ module Rack
|
|||
header.each { |key, value|
|
||||
## The header keys must be Strings.
|
||||
assert("header key must be a string, was #{key.class}") {
|
||||
key.instance_of? String
|
||||
key.kind_of? String
|
||||
}
|
||||
## The header must not contain a +Status+ key,
|
||||
assert("header must not contain Status") { key.downcase != "status" }
|
||||
|
@ -499,7 +528,7 @@ module Rack
|
|||
@body.each { |part|
|
||||
## and must only yield String values.
|
||||
assert("Body yielded non-string value #{part.inspect}") {
|
||||
part.instance_of? String
|
||||
part.kind_of? String
|
||||
}
|
||||
yield part
|
||||
}
|
||||
|
|
20
vendor/plugins/rack/lib/rack/logger.rb
vendored
Normal file
20
vendor/plugins/rack/lib/rack/logger.rb
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
require 'logger'
|
||||
|
||||
module Rack
|
||||
# Sets up rack.logger to write to rack.errors stream
|
||||
class Logger
|
||||
def initialize(app, level = ::Logger::INFO)
|
||||
@app, @level = app, level
|
||||
end
|
||||
|
||||
def call(env)
|
||||
logger = ::Logger.new(env['rack.errors'])
|
||||
logger.level = @level
|
||||
|
||||
env['rack.logger'] = logger
|
||||
@app.call(env)
|
||||
ensure
|
||||
logger.close
|
||||
end
|
||||
end
|
||||
end
|
4
vendor/plugins/rack/lib/rack/mime.rb
vendored
4
vendor/plugins/rack/lib/rack/mime.rb
vendored
|
@ -14,7 +14,7 @@ module Rack
|
|||
# Rack::Mime::MIME_TYPES.fetch('.foo', 'application/octet-stream')
|
||||
|
||||
def mime_type(ext, fallback='application/octet-stream')
|
||||
MIME_TYPES.fetch(ext, fallback)
|
||||
MIME_TYPES.fetch(ext.to_s.downcase, fallback)
|
||||
end
|
||||
module_function :mime_type
|
||||
|
||||
|
@ -105,6 +105,7 @@ module Rack
|
|||
".m3u" => "audio/x-mpegurl",
|
||||
".m4v" => "video/mp4",
|
||||
".man" => "text/troff",
|
||||
".manifest"=> "text/cache-manifest",
|
||||
".mathml" => "application/mathml+xml",
|
||||
".mbox" => "application/mbox",
|
||||
".mdoc" => "text/troff",
|
||||
|
@ -126,6 +127,7 @@ module Rack
|
|||
".ods" => "application/vnd.oasis.opendocument.spreadsheet",
|
||||
".odt" => "application/vnd.oasis.opendocument.text",
|
||||
".ogg" => "application/ogg",
|
||||
".ogv" => "video/ogg",
|
||||
".p" => "text/x-pascal",
|
||||
".pas" => "text/x-pascal",
|
||||
".pbm" => "image/x-portable-bitmap",
|
||||
|
|
34
vendor/plugins/rack/lib/rack/mock.rb
vendored
34
vendor/plugins/rack/lib/rack/mock.rb
vendored
|
@ -40,7 +40,7 @@ module Rack
|
|||
end
|
||||
|
||||
DEFAULT_ENV = {
|
||||
"rack.version" => [1,0],
|
||||
"rack.version" => [1,1],
|
||||
"rack.input" => StringIO.new,
|
||||
"rack.errors" => StringIO.new,
|
||||
"rack.multithread" => true,
|
||||
|
@ -73,14 +73,17 @@ module Rack
|
|||
# Return the Rack environment used for a request to +uri+.
|
||||
def self.env_for(uri="", opts={})
|
||||
uri = URI(uri)
|
||||
uri.path = "/#{uri.path}" unless uri.path[0] == ?/
|
||||
|
||||
env = DEFAULT_ENV.dup
|
||||
|
||||
env["REQUEST_METHOD"] = opts[:method] || "GET"
|
||||
env["REQUEST_METHOD"] = opts[:method] ? opts[:method].to_s.upcase : "GET"
|
||||
env["SERVER_NAME"] = uri.host || "example.org"
|
||||
env["SERVER_PORT"] = uri.port ? uri.port.to_s : "80"
|
||||
env["QUERY_STRING"] = uri.query.to_s
|
||||
env["PATH_INFO"] = (!uri.path || uri.path.empty?) ? "/" : uri.path
|
||||
env["rack.url_scheme"] = uri.scheme || "http"
|
||||
env["HTTPS"] = env["rack.url_scheme"] == "https" ? "on" : "off"
|
||||
|
||||
env["SCRIPT_NAME"] = opts[:script_name] || ""
|
||||
|
||||
|
@ -90,7 +93,30 @@ module Rack
|
|||
env["rack.errors"] = StringIO.new
|
||||
end
|
||||
|
||||
opts[:input] ||= ""
|
||||
if params = opts[:params]
|
||||
if env["REQUEST_METHOD"] == "GET"
|
||||
params = Utils.parse_nested_query(params) if params.is_a?(String)
|
||||
params.update(Utils.parse_nested_query(env["QUERY_STRING"]))
|
||||
env["QUERY_STRING"] = Utils.build_nested_query(params)
|
||||
elsif !opts.has_key?(:input)
|
||||
opts["CONTENT_TYPE"] = "application/x-www-form-urlencoded"
|
||||
if params.is_a?(Hash)
|
||||
if data = Utils::Multipart.build_multipart(params)
|
||||
opts[:input] = data
|
||||
opts["CONTENT_LENGTH"] ||= data.length.to_s
|
||||
opts["CONTENT_TYPE"] = "multipart/form-data; boundary=#{Utils::Multipart::MULTIPART_BOUNDARY}"
|
||||
else
|
||||
opts[:input] = Utils.build_nested_query(params)
|
||||
end
|
||||
else
|
||||
opts[:input] = params
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
empty_str = ""
|
||||
empty_str.force_encoding("ASCII-8BIT") if empty_str.respond_to? :force_encoding
|
||||
opts[:input] ||= empty_str
|
||||
if String === opts[:input]
|
||||
rack_input = StringIO.new(opts[:input])
|
||||
else
|
||||
|
@ -128,7 +154,7 @@ module Rack
|
|||
@body = ""
|
||||
body.each { |part| @body << part }
|
||||
|
||||
@errors = errors.string
|
||||
@errors = errors.string if errors.respond_to?(:string)
|
||||
end
|
||||
|
||||
# Status
|
||||
|
|
18
vendor/plugins/rack/lib/rack/nulllogger.rb
vendored
Normal file
18
vendor/plugins/rack/lib/rack/nulllogger.rb
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
module Rack
|
||||
class NullLogger
|
||||
def initialize(app)
|
||||
@app = app
|
||||
end
|
||||
|
||||
def call(env)
|
||||
env['rack.logger'] = self
|
||||
@app.call(env)
|
||||
end
|
||||
|
||||
def info(progname = nil, &block); end
|
||||
def debug(progname = nil, &block); end
|
||||
def warn(progname = nil, &block); end
|
||||
def error(progname = nil, &block); end
|
||||
def fatal(progname = nil, &block); end
|
||||
end
|
||||
end
|
5
vendor/plugins/rack/lib/rack/reloader.rb
vendored
5
vendor/plugins/rack/lib/rack/reloader.rb
vendored
|
@ -1,5 +1,6 @@
|
|||
# Copyright (c) 2009 Michael Fellinger m.fellinger@gmail.com
|
||||
# All files in this distribution are subject to the terms of the Ruby license.
|
||||
# Rack::Reloader is subject to the terms of an MIT-style license.
|
||||
# See COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
require 'pathname'
|
||||
|
||||
|
@ -92,6 +93,8 @@ module Rack
|
|||
found, stat = safe_stat(path)
|
||||
return ::File.expand_path(found), stat if found
|
||||
end
|
||||
|
||||
return false, false
|
||||
end
|
||||
|
||||
def safe_stat(file)
|
||||
|
|
55
vendor/plugins/rack/lib/rack/request.rb
vendored
55
vendor/plugins/rack/lib/rack/request.rb
vendored
|
@ -32,6 +32,7 @@ module Rack
|
|||
def content_type; @env['CONTENT_TYPE'] end
|
||||
def session; @env['rack.session'] ||= {} end
|
||||
def session_options; @env['rack.session.options'] ||= {} end
|
||||
def logger; @env['rack.logger'] end
|
||||
|
||||
# The media type (type/subtype) portion of the CONTENT_TYPE header
|
||||
# without any media type parameters. e.g., when CONTENT_TYPE is
|
||||
|
@ -63,9 +64,17 @@ module Rack
|
|||
media_type_params['charset']
|
||||
end
|
||||
|
||||
def host_with_port
|
||||
if forwarded = @env["HTTP_X_FORWARDED_HOST"]
|
||||
forwarded.split(/,\s?/).last
|
||||
else
|
||||
@env['HTTP_HOST'] || "#{@env['SERVER_NAME'] || @env['SERVER_ADDR']}:#{@env['SERVER_PORT']}"
|
||||
end
|
||||
end
|
||||
|
||||
def host
|
||||
# Remove port number.
|
||||
(@env["HTTP_HOST"] || @env["SERVER_NAME"]).to_s.gsub(/:\d+\z/, '')
|
||||
host_with_port.to_s.gsub(/:\d+\z/, '')
|
||||
end
|
||||
|
||||
def script_name=(s); @env["SCRIPT_NAME"] = s.to_s end
|
||||
|
@ -81,7 +90,6 @@ module Rack
|
|||
# one of the media types presents in this list will not be eligible
|
||||
# for form-data / param parsing.
|
||||
FORM_DATA_MEDIA_TYPES = [
|
||||
nil,
|
||||
'application/x-www-form-urlencoded',
|
||||
'multipart/form-data'
|
||||
]
|
||||
|
@ -92,15 +100,20 @@ module Rack
|
|||
PARSEABLE_DATA_MEDIA_TYPES = [
|
||||
'multipart/related',
|
||||
'multipart/mixed'
|
||||
]
|
||||
]
|
||||
|
||||
# Determine whether the request body contains form-data by checking
|
||||
# the request media_type against registered form-data media-types:
|
||||
# "application/x-www-form-urlencoded" and "multipart/form-data". The
|
||||
# the request Content-Type for one of the media-types:
|
||||
# "application/x-www-form-urlencoded" or "multipart/form-data". The
|
||||
# list of form-data media types can be modified through the
|
||||
# +FORM_DATA_MEDIA_TYPES+ array.
|
||||
#
|
||||
# A request body is also assumed to contain form-data when no
|
||||
# Content-Type header is provided and the request_method is POST.
|
||||
def form_data?
|
||||
FORM_DATA_MEDIA_TYPES.include?(media_type)
|
||||
type = media_type
|
||||
meth = env["rack.methodoverride.original_method"] || env['REQUEST_METHOD']
|
||||
(meth == 'POST' && type.nil?) || FORM_DATA_MEDIA_TYPES.include?(type)
|
||||
end
|
||||
|
||||
# Determine whether the request body contains data by checking
|
||||
|
@ -115,8 +128,7 @@ module Rack
|
|||
@env["rack.request.query_hash"]
|
||||
else
|
||||
@env["rack.request.query_string"] = query_string
|
||||
@env["rack.request.query_hash"] =
|
||||
Utils.parse_nested_query(query_string)
|
||||
@env["rack.request.query_hash"] = parse_query(query_string)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -125,19 +137,20 @@ module Rack
|
|||
# This method support both application/x-www-form-urlencoded and
|
||||
# multipart/form-data.
|
||||
def POST
|
||||
if @env["rack.request.form_input"].eql? @env["rack.input"]
|
||||
if @env["rack.input"].nil?
|
||||
raise "Missing rack.input"
|
||||
elsif @env["rack.request.form_input"].eql? @env["rack.input"]
|
||||
@env["rack.request.form_hash"]
|
||||
elsif form_data? || parseable_data?
|
||||
@env["rack.request.form_input"] = @env["rack.input"]
|
||||
unless @env["rack.request.form_hash"] =
|
||||
Utils::Multipart.parse_multipart(env)
|
||||
unless @env["rack.request.form_hash"] = parse_multipart(env)
|
||||
form_vars = @env["rack.input"].read
|
||||
|
||||
# Fix for Safari Ajax postings that always append \0
|
||||
form_vars.sub!(/\0\z/, '')
|
||||
|
||||
@env["rack.request.form_vars"] = form_vars
|
||||
@env["rack.request.form_hash"] = Utils.parse_nested_query(form_vars)
|
||||
@env["rack.request.form_hash"] = parse_query(form_vars)
|
||||
|
||||
@env["rack.input"].rewind
|
||||
end
|
||||
|
@ -149,7 +162,7 @@ module Rack
|
|||
|
||||
# The union of GET and POST data.
|
||||
def params
|
||||
self.put? ? self.GET : self.GET.update(self.POST)
|
||||
self.GET.update(self.POST)
|
||||
rescue EOFError => e
|
||||
self.GET
|
||||
end
|
||||
|
@ -175,6 +188,9 @@ module Rack
|
|||
end
|
||||
alias referrer referer
|
||||
|
||||
def user_agent
|
||||
@env['HTTP_USER_AGENT']
|
||||
end
|
||||
|
||||
def cookies
|
||||
return {} unless @env["HTTP_COOKIE"]
|
||||
|
@ -214,11 +230,11 @@ module Rack
|
|||
|
||||
url
|
||||
end
|
||||
|
||||
|
||||
def path
|
||||
script_name + path_info
|
||||
end
|
||||
|
||||
|
||||
def fullpath
|
||||
query_string.empty? ? path : "#{path}?#{query_string}"
|
||||
end
|
||||
|
@ -242,5 +258,14 @@ module Rack
|
|||
@env['REMOTE_ADDR']
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
def parse_query(qs)
|
||||
Utils.parse_nested_query(qs)
|
||||
end
|
||||
|
||||
def parse_multipart(env)
|
||||
Utils::Multipart.parse_multipart(env)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
44
vendor/plugins/rack/lib/rack/response.rb
vendored
44
vendor/plugins/rack/lib/rack/response.rb
vendored
|
@ -19,7 +19,7 @@ module Rack
|
|||
attr_accessor :length
|
||||
|
||||
def initialize(body=[], status=200, header={}, &block)
|
||||
@status = status
|
||||
@status = status.to_i
|
||||
@header = Utils::HeaderHash.new({"Content-Type" => "text/html"}.
|
||||
merge(header))
|
||||
|
||||
|
@ -54,45 +54,11 @@ module Rack
|
|||
end
|
||||
|
||||
def set_cookie(key, value)
|
||||
case value
|
||||
when Hash
|
||||
domain = "; domain=" + value[:domain] if value[:domain]
|
||||
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]
|
||||
secure = "; secure" if value[:secure]
|
||||
httponly = "; HttpOnly" if value[:httponly]
|
||||
value = value[:value]
|
||||
end
|
||||
value = [value] unless Array === value
|
||||
cookie = Utils.escape(key) + "=" +
|
||||
value.map { |v| Utils.escape v }.join("&") +
|
||||
"#{domain}#{path}#{expires}#{secure}#{httponly}"
|
||||
|
||||
case self["Set-Cookie"]
|
||||
when Array
|
||||
self["Set-Cookie"] << cookie
|
||||
when String
|
||||
self["Set-Cookie"] = [self["Set-Cookie"], cookie]
|
||||
when nil
|
||||
self["Set-Cookie"] = cookie
|
||||
end
|
||||
Utils.set_cookie_header!(header, key, value)
|
||||
end
|
||||
|
||||
def delete_cookie(key, value={})
|
||||
unless Array === self["Set-Cookie"]
|
||||
self["Set-Cookie"] = [self["Set-Cookie"]].compact
|
||||
end
|
||||
|
||||
self["Set-Cookie"].reject! { |cookie|
|
||||
cookie =~ /\A#{Utils.escape(key)}=/
|
||||
}
|
||||
|
||||
set_cookie(key,
|
||||
{:value => '', :path => nil, :domain => nil,
|
||||
:expires => Time.at(0) }.merge(value))
|
||||
Utils.delete_cookie_header!(header, key, value)
|
||||
end
|
||||
|
||||
def redirect(target, status=302)
|
||||
|
@ -105,9 +71,9 @@ module Rack
|
|||
|
||||
if [204, 304].include?(status.to_i)
|
||||
header.delete "Content-Type"
|
||||
[status.to_i, header.to_hash, []]
|
||||
[status.to_i, header, []]
|
||||
else
|
||||
[status.to_i, header.to_hash, self]
|
||||
[status.to_i, header, self]
|
||||
end
|
||||
end
|
||||
alias to_a finish # For *response
|
||||
|
|
20
vendor/plugins/rack/lib/rack/rewindable_input.rb
vendored
20
vendor/plugins/rack/lib/rack/rewindable_input.rb
vendored
|
@ -16,27 +16,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 +52,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
|
||||
|
@ -72,11 +72,13 @@ module Rack
|
|||
# access it because we have the file handle open.
|
||||
@rewindable_io = Tempfile.new('RackRewindableInput')
|
||||
@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?
|
||||
@rewindable_io.unlink
|
||||
@unlinked = true
|
||||
end
|
||||
|
||||
|
||||
buffer = ""
|
||||
while @io.read(1024 * 4, buffer)
|
||||
entire_buffer_written_out = false
|
||||
|
@ -90,7 +92,7 @@ module Rack
|
|||
end
|
||||
@rewindable_io.rewind
|
||||
end
|
||||
|
||||
|
||||
def filesystem_has_posix_semantics?
|
||||
RUBY_PLATFORM !~ /(mswin|mingw|cygwin|java)/
|
||||
end
|
||||
|
|
27
vendor/plugins/rack/lib/rack/runtime.rb
vendored
Normal file
27
vendor/plugins/rack/lib/rack/runtime.rb
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
module Rack
|
||||
# Sets an "X-Runtime" response header, indicating the response
|
||||
# time of the request, in seconds
|
||||
#
|
||||
# You can put it right before the application to see the processing
|
||||
# time, or before all the other middlewares to include time for them,
|
||||
# too.
|
||||
class Runtime
|
||||
def initialize(app, name = nil)
|
||||
@app = app
|
||||
@header_name = "X-Runtime"
|
||||
@header_name << "-#{name}" if name
|
||||
end
|
||||
|
||||
def call(env)
|
||||
start_time = Time.now
|
||||
status, headers, body = @app.call(env)
|
||||
request_time = Time.now - start_time
|
||||
|
||||
if !headers.has_key?(@header_name)
|
||||
headers[@header_name] = "%0.6f" % request_time
|
||||
end
|
||||
|
||||
[status, headers, body]
|
||||
end
|
||||
end
|
||||
end
|
142
vendor/plugins/rack/lib/rack/sendfile.rb
vendored
Normal file
142
vendor/plugins/rack/lib/rack/sendfile.rb
vendored
Normal file
|
@ -0,0 +1,142 @@
|
|||
require 'rack/file'
|
||||
|
||||
module Rack
|
||||
class File #:nodoc:
|
||||
alias :to_path :path
|
||||
end
|
||||
|
||||
# = Sendfile
|
||||
#
|
||||
# The Sendfile middleware intercepts responses whose body is being
|
||||
# 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
|
||||
# delivery code.
|
||||
#
|
||||
# In order to take advantage of this middleware, the response body must
|
||||
# respond to +to_path+ and the request must include an X-Sendfile-Type
|
||||
# header. Rack::File and other components implement +to_path+ so there's
|
||||
# rarely anything you need to do in your application. The X-Sendfile-Type
|
||||
# header is typically set in your web servers configuration. The following
|
||||
# sections attempt to document
|
||||
#
|
||||
# === Nginx
|
||||
#
|
||||
# Nginx supports the X-Accel-Redirect header. This is similar to X-Sendfile
|
||||
# but requires parts of the filesystem to be mapped into a private URL
|
||||
# hierarachy.
|
||||
#
|
||||
# The following example shows the Nginx configuration required to create
|
||||
# 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/ {
|
||||
# internal;
|
||||
# alias /var/www/;
|
||||
# }
|
||||
#
|
||||
# location / {
|
||||
# proxy_redirect false;
|
||||
#
|
||||
# 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-Accel-Mapping /files/=/var/www/;
|
||||
#
|
||||
# proxy_pass http://127.0.0.1:8080/;
|
||||
# }
|
||||
#
|
||||
# Note that the X-Sendfile-Type header must be set exactly as shown above. The
|
||||
# X-Accel-Mapping header should specify the name of the private URL pattern,
|
||||
# followed by an equals sign (=), followed by the location on the file system
|
||||
# that it maps to. The middleware performs a simple substitution on the
|
||||
# resulting path.
|
||||
#
|
||||
# See Also: http://wiki.codemongers.com/NginxXSendfile
|
||||
#
|
||||
# === lighttpd
|
||||
#
|
||||
# Lighttpd has supported some variation of the X-Sendfile header for some
|
||||
# time, although only recent version support X-Sendfile in a reverse proxy
|
||||
# configuration.
|
||||
#
|
||||
# $HTTP["host"] == "example.com" {
|
||||
# proxy-core.protocol = "http"
|
||||
# proxy-core.balancer = "round-robin"
|
||||
# proxy-core.backends = (
|
||||
# "127.0.0.1:8000",
|
||||
# "127.0.0.1:8001",
|
||||
# ...
|
||||
# )
|
||||
#
|
||||
# proxy-core.allow-x-sendfile = "enable"
|
||||
# proxy-core.rewrite-request = (
|
||||
# "X-Sendfile-Type" => (".*" => "X-Sendfile")
|
||||
# )
|
||||
# }
|
||||
#
|
||||
# See Also: http://redmine.lighttpd.net/wiki/lighttpd/Docs:ModProxyCore
|
||||
#
|
||||
# === Apache
|
||||
#
|
||||
# X-Sendfile is supported under Apache 2.x using a separate module:
|
||||
#
|
||||
# http://tn123.ath.cx/mod_xsendfile/
|
||||
#
|
||||
# Once the module is compiled and installed, you can enable it using
|
||||
# XSendFile config directive:
|
||||
#
|
||||
# RequestHeader Set X-Sendfile-Type X-Sendfile
|
||||
# ProxyPassReverse / http://localhost:8001/
|
||||
# XSendFile on
|
||||
|
||||
class Sendfile
|
||||
F = ::File
|
||||
|
||||
def initialize(app, variation=nil)
|
||||
@app = app
|
||||
@variation = variation
|
||||
end
|
||||
|
||||
def call(env)
|
||||
status, headers, body = @app.call(env)
|
||||
if body.respond_to?(:to_path)
|
||||
case type = variation(env)
|
||||
when 'X-Accel-Redirect'
|
||||
path = F.expand_path(body.to_path)
|
||||
if url = map_accel_path(env, path)
|
||||
headers[type] = url
|
||||
body = []
|
||||
else
|
||||
env['rack.errors'] << "X-Accel-Mapping header missing"
|
||||
end
|
||||
when 'X-Sendfile', 'X-Lighttpd-Send-File'
|
||||
path = F.expand_path(body.to_path)
|
||||
headers[type] = path
|
||||
body = []
|
||||
when '', nil
|
||||
else
|
||||
env['rack.errors'] << "Unknown x-sendfile variation: '#{variation}'.\n"
|
||||
end
|
||||
end
|
||||
[status, headers, body]
|
||||
end
|
||||
|
||||
private
|
||||
def variation(env)
|
||||
@variation ||
|
||||
env['sendfile.type'] ||
|
||||
env['HTTP_X_SENDFILE_TYPE']
|
||||
end
|
||||
|
||||
def map_accel_path(env, file)
|
||||
if mapping = env['HTTP_X_ACCEL_MAPPING']
|
||||
internal, external = mapping.split('=', 2).map{ |p| p.strip }
|
||||
file.sub(/^#{internal}/i, external)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
212
vendor/plugins/rack/lib/rack/server.rb
vendored
Normal file
212
vendor/plugins/rack/lib/rack/server.rb
vendored
Normal file
|
@ -0,0 +1,212 @@
|
|||
require 'optparse'
|
||||
|
||||
module Rack
|
||||
class Server
|
||||
class Options
|
||||
def parse!(args)
|
||||
options = {}
|
||||
opt_parser = OptionParser.new("", 24, ' ') do |opts|
|
||||
opts.banner = "Usage: rackup [ruby options] [rack options] [rackup config]"
|
||||
|
||||
opts.separator ""
|
||||
opts.separator "Ruby options:"
|
||||
|
||||
lineno = 1
|
||||
opts.on("-e", "--eval LINE", "evaluate a LINE of code") { |line|
|
||||
eval line, TOPLEVEL_BINDING, "-e", lineno
|
||||
lineno += 1
|
||||
}
|
||||
|
||||
opts.on("-d", "--debug", "set debugging flags (set $DEBUG to true)") {
|
||||
options[:debug] = true
|
||||
}
|
||||
opts.on("-w", "--warn", "turn warnings on for your script") {
|
||||
options[:warn] = true
|
||||
}
|
||||
|
||||
opts.on("-I", "--include PATH",
|
||||
"specify $LOAD_PATH (may be used more than once)") { |path|
|
||||
options[:include] = path.split(":")
|
||||
}
|
||||
|
||||
opts.on("-r", "--require LIBRARY",
|
||||
"require the library, before executing your script") { |library|
|
||||
options[:require] = library
|
||||
}
|
||||
|
||||
opts.separator ""
|
||||
opts.separator "Rack options:"
|
||||
opts.on("-s", "--server SERVER", "serve using SERVER (webrick/mongrel)") { |s|
|
||||
options[:server] = s
|
||||
}
|
||||
|
||||
opts.on("-o", "--host HOST", "listen on HOST (default: 0.0.0.0)") { |host|
|
||||
options[:Host] = host
|
||||
}
|
||||
|
||||
opts.on("-p", "--port PORT", "use PORT (default: 9292)") { |port|
|
||||
options[:Port] = port
|
||||
}
|
||||
|
||||
opts.on("-E", "--env ENVIRONMENT", "use ENVIRONMENT for defaults (default: development)") { |e|
|
||||
options[:environment] = e
|
||||
}
|
||||
|
||||
opts.on("-D", "--daemonize", "run daemonized in the background") { |d|
|
||||
options[:daemonize] = d ? true : false
|
||||
}
|
||||
|
||||
opts.on("-P", "--pid FILE", "file to store PID (default: rack.pid)") { |f|
|
||||
options[:pid] = ::File.expand_path(f)
|
||||
}
|
||||
|
||||
opts.separator ""
|
||||
opts.separator "Common options:"
|
||||
|
||||
opts.on_tail("-h", "--help", "Show this message") do
|
||||
puts opts
|
||||
exit
|
||||
end
|
||||
|
||||
opts.on_tail("--version", "Show version") do
|
||||
puts "Rack #{Rack.version}"
|
||||
exit
|
||||
end
|
||||
end
|
||||
opt_parser.parse! args
|
||||
options[:rack_file] = args.last if args.last
|
||||
options
|
||||
end
|
||||
end
|
||||
|
||||
def self.start
|
||||
new.start
|
||||
end
|
||||
|
||||
attr_accessor :options
|
||||
|
||||
def initialize(options = nil)
|
||||
@options = options
|
||||
end
|
||||
|
||||
def options
|
||||
@options ||= parse_options(ARGV)
|
||||
end
|
||||
|
||||
def default_options
|
||||
{
|
||||
:environment => "development",
|
||||
:pid => nil,
|
||||
:Port => 9292,
|
||||
:Host => "0.0.0.0",
|
||||
:AccessLog => [],
|
||||
:rack_file => ::File.expand_path("config.ru")
|
||||
}
|
||||
end
|
||||
|
||||
def app
|
||||
@app ||= begin
|
||||
if !::File.exist? options[:rack_file]
|
||||
abort "configuration #{options[:rack_file]} not found"
|
||||
end
|
||||
|
||||
app, options = Rack::Builder.parse_file(self.options[:rack_file], opt_parser)
|
||||
self.options.merge! options
|
||||
app
|
||||
end
|
||||
end
|
||||
|
||||
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["development"].concat m["deployment"] + [[Rack::ShowExceptions], [Rack::Lint]]
|
||||
m
|
||||
end
|
||||
end
|
||||
|
||||
def middleware
|
||||
self.class.middleware
|
||||
end
|
||||
|
||||
def start
|
||||
if options[:debug]
|
||||
$DEBUG = true
|
||||
require 'pp'
|
||||
p options[:server]
|
||||
pp wrapped_app
|
||||
pp app
|
||||
end
|
||||
|
||||
if options[:warn]
|
||||
$-w = true
|
||||
end
|
||||
|
||||
if includes = options[:include]
|
||||
$LOAD_PATH.unshift *includes
|
||||
end
|
||||
|
||||
if library = options[:require]
|
||||
require library
|
||||
end
|
||||
|
||||
daemonize_app if options[:daemonize]
|
||||
write_pid if options[:pid]
|
||||
server.run wrapped_app, options
|
||||
end
|
||||
|
||||
def server
|
||||
@_server ||= Rack::Handler.get(options[:server]) || Rack::Handler.default
|
||||
end
|
||||
|
||||
private
|
||||
def parse_options(args)
|
||||
options = default_options
|
||||
|
||||
# Don't evaluate CGI ISINDEX parameters.
|
||||
# http://hoohoo.ncsa.uiuc.edu/cgi/cl.html
|
||||
args.clear if ENV.include?("REQUEST_METHOD")
|
||||
|
||||
options.merge! opt_parser.parse! args
|
||||
options
|
||||
end
|
||||
|
||||
def opt_parser
|
||||
Options.new
|
||||
end
|
||||
|
||||
def build_app(app)
|
||||
middleware[options[:environment]].reverse_each do |middleware|
|
||||
middleware = middleware.call(self) if middleware.respond_to?(:call)
|
||||
next unless middleware
|
||||
klass = middleware.shift
|
||||
app = klass.new(app, *middleware)
|
||||
end
|
||||
app
|
||||
end
|
||||
|
||||
def wrapped_app
|
||||
@wrapped_app ||= build_app app
|
||||
end
|
||||
|
||||
def daemonize_app
|
||||
if RUBY_VERSION < "1.9"
|
||||
exit if fork
|
||||
Process.setsid
|
||||
exit if fork
|
||||
Dir.chdir "/"
|
||||
::File.umask 0000
|
||||
STDIN.reopen "/dev/null"
|
||||
STDOUT.reopen "/dev/null", "a"
|
||||
STDERR.reopen "/dev/null", "a"
|
||||
else
|
||||
Process.daemon
|
||||
end
|
||||
end
|
||||
|
||||
def write_pid
|
||||
::File.open(options[:pid], 'w'){ |f| f.write("#{Process.pid}") }
|
||||
at_exit { ::File.delete(options[:pid]) if ::File.exist?(options[:pid]) }
|
||||
end
|
||||
end
|
||||
end
|
|
@ -107,18 +107,16 @@ module Rack
|
|||
|
||||
if not session_id = set_session(env, session_id, session, options)
|
||||
env["rack.errors"].puts("Warning! #{self.class.name} failed to save session. Content dropped.")
|
||||
[status, headers, body]
|
||||
elsif options[:defer] and not options[:renew]
|
||||
env["rack.errors"].puts("Defering cookie for #{session_id}") if $VERBOSE
|
||||
[status, headers, body]
|
||||
else
|
||||
cookie = Hash.new
|
||||
cookie[:value] = session_id
|
||||
cookie[:expires] = Time.now + options[:expire_after] unless options[:expire_after].nil?
|
||||
response = Rack::Response.new(body, status, headers)
|
||||
response.set_cookie(@key, cookie.merge(options))
|
||||
response.to_a
|
||||
Utils.set_cookie_header!(headers, @key, cookie.merge(options))
|
||||
end
|
||||
|
||||
[status, headers, body]
|
||||
end
|
||||
|
||||
# All thread safety and session retrival proceedures should occur here.
|
||||
|
|
|
@ -70,16 +70,15 @@ module Rack
|
|||
|
||||
if session_data.size > (4096 - @key.size)
|
||||
env["rack.errors"].puts("Warning! Rack::Session::Cookie data size exceeds 4K. Content dropped.")
|
||||
[status, headers, body]
|
||||
else
|
||||
options = env["rack.session.options"]
|
||||
cookie = Hash.new
|
||||
cookie[:value] = session_data
|
||||
cookie[:expires] = Time.now + options[:expire_after] unless options[:expire_after].nil?
|
||||
response = Rack::Response.new(body, status, headers)
|
||||
response.set_cookie(@key, cookie.merge(options))
|
||||
response.to_a
|
||||
Utils.set_cookie_header!(headers, @key, cookie.merge(options))
|
||||
end
|
||||
|
||||
[status, headers, body]
|
||||
end
|
||||
|
||||
def generate_hmac(data)
|
||||
|
|
96
vendor/plugins/rack/lib/rack/session/memcache.rb
vendored
96
vendor/plugins/rack/lib/rack/session/memcache.rb
vendored
|
@ -29,9 +29,13 @@ module Rack
|
|||
super
|
||||
|
||||
@mutex = Mutex.new
|
||||
@pool = MemCache.
|
||||
new @default_options[:memcache_server], @default_options
|
||||
raise 'No memcache servers' unless @pool.servers.any?{|s|s.alive?}
|
||||
mserv = @default_options[:memcache_server]
|
||||
mopts = @default_options.
|
||||
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'
|
||||
end
|
||||
end
|
||||
|
||||
def generate_sid
|
||||
|
@ -41,24 +45,23 @@ module Rack
|
|||
end
|
||||
end
|
||||
|
||||
def get_session(env, sid)
|
||||
session = @pool.get(sid) if sid
|
||||
def get_session(env, session_id)
|
||||
@mutex.lock if env['rack.multithread']
|
||||
unless sid and session
|
||||
env['rack.errors'].puts("Session '#{sid.inspect}' not found, initializing...") if $VERBOSE and not sid.nil?
|
||||
session = {}
|
||||
sid = generate_sid
|
||||
ret = @pool.add sid, session
|
||||
raise "Session collision on '#{sid.inspect}'" unless /^STORED/ =~ ret
|
||||
unless session_id and session = @pool.get(session_id)
|
||||
session_id, session = generate_sid, {}
|
||||
unless /^STORED/ =~ @pool.add(session_id, session)
|
||||
raise "Session collision on '#{session_id.inspect}'"
|
||||
end
|
||||
end
|
||||
session.instance_variable_set('@old', {}.merge(session))
|
||||
return [sid, session]
|
||||
rescue MemCache::MemCacheError, Errno::ECONNREFUSED # MemCache server cannot be contacted
|
||||
warn "#{self} is unable to find server."
|
||||
session.instance_variable_set '@old', @pool.get(session_id, true)
|
||||
return [session_id, session]
|
||||
rescue MemCache::MemCacheError, Errno::ECONNREFUSED
|
||||
# MemCache server cannot be contacted
|
||||
warn "#{self} is unable to find memcached server."
|
||||
warn $!.inspect
|
||||
return [ nil, {} ]
|
||||
ensure
|
||||
@mutex.unlock if env['rack.multithread']
|
||||
@mutex.unlock if @mutex.locked?
|
||||
end
|
||||
|
||||
def set_session(env, session_id, new_session, options)
|
||||
|
@ -66,43 +69,50 @@ module Rack
|
|||
expiry = expiry.nil? ? 0 : expiry + 1
|
||||
|
||||
@mutex.lock if env['rack.multithread']
|
||||
session = @pool.get(session_id) || {}
|
||||
if options[:renew] or options[:drop]
|
||||
@pool.delete session_id
|
||||
return false if options[:drop]
|
||||
session_id = generate_sid
|
||||
@pool.add session_id, 0 # so we don't worry about cache miss on #set
|
||||
@pool.add session_id, {} # so we don't worry about cache miss on #set
|
||||
end
|
||||
old_session = new_session.instance_variable_get('@old') || {}
|
||||
session = merge_sessions session_id, old_session, new_session, session
|
||||
|
||||
session = @pool.get(session_id) || {}
|
||||
old_session = new_session.instance_variable_get '@old'
|
||||
old_session = old_session ? Marshal.load(old_session) : {}
|
||||
|
||||
unless Hash === old_session and Hash === new_session
|
||||
env['rack.errors'].
|
||||
puts 'Bad old_session or new_session sessions provided.'
|
||||
else # merge sessions
|
||||
# alterations are either update or delete, making as few changes as
|
||||
# possible to prevent possible issues.
|
||||
|
||||
# removed keys
|
||||
delete = old_session.keys - new_session.keys
|
||||
if $VERBOSE and not delete.empty?
|
||||
env['rack.errors'].
|
||||
puts "//@#{session_id}: delete #{delete*','}"
|
||||
end
|
||||
delete.each{|k| session.delete k }
|
||||
|
||||
# added or altered keys
|
||||
update = new_session.keys.
|
||||
select{|k| new_session[k] != old_session[k] }
|
||||
if $VERBOSE and not update.empty?
|
||||
env['rack.errors'].puts "//@#{session_id}: update #{update*','}"
|
||||
end
|
||||
update.each{|k| session[k] = new_session[k] }
|
||||
end
|
||||
|
||||
@pool.set session_id, session, expiry
|
||||
return session_id
|
||||
rescue MemCache::MemCacheError, Errno::ECONNREFUSED # MemCache server cannot be contacted
|
||||
warn "#{self} is unable to find server."
|
||||
rescue MemCache::MemCacheError, Errno::ECONNREFUSED
|
||||
# MemCache server cannot be contacted
|
||||
warn "#{self} is unable to find memcached server."
|
||||
warn $!.inspect
|
||||
return false
|
||||
ensure
|
||||
@mutex.unlock if env['rack.multithread']
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def merge_sessions sid, old, new, cur=nil
|
||||
cur ||= {}
|
||||
unless Hash === old and Hash === new
|
||||
warn 'Bad old or new sessions provided.'
|
||||
return cur
|
||||
end
|
||||
|
||||
delete = old.keys - new.keys
|
||||
warn "//@#{sid}: delete #{delete*','}" if $VERBOSE and not delete.empty?
|
||||
delete.each{|k| cur.delete k }
|
||||
|
||||
update = new.keys.select{|k| new[k] != old[k] }
|
||||
warn "//@#{sid}: update #{update*','}" if $VERBOSE and not update.empty?
|
||||
update.each{|k| cur[k] = new[k] }
|
||||
|
||||
cur
|
||||
@mutex.unlock if @mutex.locked?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
2
vendor/plugins/rack/lib/rack/session/pool.rb
vendored
2
vendor/plugins/rack/lib/rack/session/pool.rb
vendored
|
@ -13,7 +13,7 @@ module Rack
|
|||
# In the context of a multithreaded environment, sessions being
|
||||
# committed to the pool is done in a merging manner.
|
||||
#
|
||||
# The :drop option is available in rack.session.options if you with to
|
||||
# The :drop option is available in rack.session.options if you wish to
|
||||
# explicitly remove the session from the session cache.
|
||||
#
|
||||
# Example:
|
||||
|
|
17
vendor/plugins/rack/lib/rack/urlmap.rb
vendored
17
vendor/plugins/rack/lib/rack/urlmap.rb
vendored
|
@ -28,27 +28,28 @@ module Rack
|
|||
raise ArgumentError, "paths need to start with /"
|
||||
end
|
||||
location = location.chomp('/')
|
||||
match = Regexp.new("^#{Regexp.quote(location).gsub('/', '/+')}(.*)", nil, 'n')
|
||||
|
||||
[host, location, app]
|
||||
}.sort_by { |(h, l, a)| [h ? -h.size : (-1.0 / 0.0), -l.size] } # Longest path first
|
||||
[host, location, match, app]
|
||||
}.sort_by { |(h, l, m, a)| [h ? -h.size : (-1.0 / 0.0), -l.size] } # Longest path first
|
||||
end
|
||||
|
||||
def call(env)
|
||||
path = env["PATH_INFO"].to_s.squeeze("/")
|
||||
path = env["PATH_INFO"].to_s
|
||||
script_name = env['SCRIPT_NAME']
|
||||
hHost, sName, sPort = env.values_at('HTTP_HOST','SERVER_NAME','SERVER_PORT')
|
||||
@mapping.each { |host, location, app|
|
||||
@mapping.each { |host, location, match, app|
|
||||
next unless (hHost == host || sName == host \
|
||||
|| (host.nil? && (hHost == sName || hHost == sName+':'+sPort)))
|
||||
next unless location == path[0, location.size]
|
||||
next unless path[location.size] == nil || path[location.size] == ?/
|
||||
next unless path =~ match && rest = $1
|
||||
next unless rest.empty? || rest[0] == ?/
|
||||
|
||||
return app.call(
|
||||
env.merge(
|
||||
'SCRIPT_NAME' => (script_name + location),
|
||||
'PATH_INFO' => path[location.size..-1]))
|
||||
'PATH_INFO' => rest))
|
||||
}
|
||||
[404, {"Content-Type" => "text/plain"}, ["Not Found: #{path}"]]
|
||||
[404, {"Content-Type" => "text/plain", "X-Cascade" => "pass"}, ["Not Found: #{path}"]]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
241
vendor/plugins/rack/lib/rack/utils.rb
vendored
241
vendor/plugins/rack/lib/rack/utils.rb
vendored
|
@ -27,7 +27,7 @@ module Rack
|
|||
module_function :unescape
|
||||
|
||||
DEFAULT_SEP = /[&;] */n
|
||||
|
||||
|
||||
# Stolen from Mongrel, with some small modifications:
|
||||
# Parses a query string by breaking it up at the '&'
|
||||
# and ';' characters. You can also use this to parse
|
||||
|
@ -38,7 +38,9 @@ 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
|
||||
|
@ -67,6 +69,9 @@ 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 = $' || ''
|
||||
|
@ -109,6 +114,25 @@ module Rack
|
|||
end
|
||||
module_function :build_query
|
||||
|
||||
def build_nested_query(value, prefix = nil)
|
||||
case value
|
||||
when Array
|
||||
value.map { |v|
|
||||
build_nested_query(v, "#{prefix}[]")
|
||||
}.join("&")
|
||||
when Hash
|
||||
value.map { |k, v|
|
||||
build_nested_query(v, prefix ? "#{prefix}[#{escape(k)}]" : escape(k))
|
||||
}.join("&")
|
||||
when String
|
||||
raise ArgumentError, "value must be a Hash" if prefix.nil?
|
||||
"#{prefix}=#{escape(value)}"
|
||||
else
|
||||
prefix
|
||||
end
|
||||
end
|
||||
module_function :build_nested_query
|
||||
|
||||
# Escape ampersands, brackets and quotes to their HTML/XML entities.
|
||||
def escape_html(string)
|
||||
string.to_s.gsub("&", "&").
|
||||
|
@ -149,6 +173,54 @@ module Rack
|
|||
end
|
||||
module_function :select_best_encoding
|
||||
|
||||
def set_cookie_header!(header, key, value)
|
||||
case value
|
||||
when Hash
|
||||
domain = "; domain=" + value[:domain] if value[:domain]
|
||||
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]
|
||||
secure = "; secure" if value[:secure]
|
||||
httponly = "; HttpOnly" if value[:httponly]
|
||||
value = value[:value]
|
||||
end
|
||||
value = [value] unless Array === value
|
||||
cookie = escape(key) + "=" +
|
||||
value.map { |v| escape v }.join("&") +
|
||||
"#{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
|
||||
header["Set-Cookie"] = cookie
|
||||
end
|
||||
|
||||
nil
|
||||
end
|
||||
module_function :set_cookie_header!
|
||||
|
||||
def delete_cookie_header!(header, key, value = {})
|
||||
unless Array === header["Set-Cookie"]
|
||||
header["Set-Cookie"] = [header["Set-Cookie"]].compact
|
||||
end
|
||||
|
||||
header["Set-Cookie"].reject! { |cookie|
|
||||
cookie =~ /\A#{escape(key)}=/
|
||||
}
|
||||
|
||||
set_cookie_header!(header, key,
|
||||
{:value => '', :path => nil, :domain => nil,
|
||||
:expires => Time.at(0) }.merge(value))
|
||||
|
||||
nil
|
||||
end
|
||||
module_function :delete_cookie_header!
|
||||
|
||||
# Return the bytesize of String; uses String#length under Ruby 1.8 and
|
||||
# String#bytesize under 1.9.
|
||||
if ''.respond_to?(:bytesize)
|
||||
|
@ -191,11 +263,22 @@ module Rack
|
|||
# A case-insensitive Hash that preserves the original case of a
|
||||
# header when set.
|
||||
class HeaderHash < Hash
|
||||
def self.new(hash={})
|
||||
HeaderHash === hash ? hash : super(hash)
|
||||
end
|
||||
|
||||
def initialize(hash={})
|
||||
super()
|
||||
@names = {}
|
||||
hash.each { |k, v| self[k] = v }
|
||||
end
|
||||
|
||||
def each
|
||||
super do |k, v|
|
||||
yield(k, v.respond_to?(:to_ary) ? v.to_ary.join("\n") : v)
|
||||
end
|
||||
end
|
||||
|
||||
def to_hash
|
||||
inject({}) do |hash, (k,v)|
|
||||
if v.respond_to? :to_ary
|
||||
|
@ -208,21 +291,24 @@ module Rack
|
|||
end
|
||||
|
||||
def [](k)
|
||||
super @names[k.downcase]
|
||||
super(@names[k] ||= @names[k.downcase])
|
||||
end
|
||||
|
||||
def []=(k, v)
|
||||
delete k
|
||||
@names[k.downcase] = k
|
||||
@names[k] = @names[k.downcase] = k
|
||||
super k, v
|
||||
end
|
||||
|
||||
def delete(k)
|
||||
super @names.delete(k.downcase)
|
||||
canonical = k.downcase
|
||||
result = super @names.delete(canonical)
|
||||
@names.delete_if { |name,| name.downcase == canonical }
|
||||
result
|
||||
end
|
||||
|
||||
def include?(k)
|
||||
@names.has_key? k.downcase
|
||||
@names.include?(k) || @names.include?(k.downcase)
|
||||
end
|
||||
|
||||
alias_method :has_key?, :include?
|
||||
|
@ -238,13 +324,23 @@ module Rack
|
|||
hash = dup
|
||||
hash.merge! other
|
||||
end
|
||||
|
||||
def replace(other)
|
||||
clear
|
||||
other.each { |k, v| self[k] = v }
|
||||
self
|
||||
end
|
||||
end
|
||||
|
||||
# Every standard HTTP code mapped to the appropriate message.
|
||||
# Stolen from Mongrel.
|
||||
# Generated with:
|
||||
# curl -s http://www.iana.org/assignments/http-status-codes | \
|
||||
# ruby -ane 'm = /^(\d{3}) +(\S[^\[(]+)/.match($_) and
|
||||
# puts " #{m[1]} => \x27#{m[2].strip}x27,"'
|
||||
HTTP_STATUS_CODES = {
|
||||
100 => 'Continue',
|
||||
101 => 'Switching Protocols',
|
||||
102 => 'Processing',
|
||||
200 => 'OK',
|
||||
201 => 'Created',
|
||||
202 => 'Accepted',
|
||||
|
@ -252,12 +348,15 @@ module Rack
|
|||
204 => 'No Content',
|
||||
205 => 'Reset Content',
|
||||
206 => 'Partial Content',
|
||||
207 => 'Multi-Status',
|
||||
226 => 'IM Used',
|
||||
300 => 'Multiple Choices',
|
||||
301 => 'Moved Permanently',
|
||||
302 => 'Found',
|
||||
303 => 'See Other',
|
||||
304 => 'Not Modified',
|
||||
305 => 'Use Proxy',
|
||||
306 => 'Reserved',
|
||||
307 => 'Temporary Redirect',
|
||||
400 => 'Bad Request',
|
||||
401 => 'Unauthorized',
|
||||
|
@ -273,27 +372,76 @@ module Rack
|
|||
411 => 'Length Required',
|
||||
412 => 'Precondition Failed',
|
||||
413 => 'Request Entity Too Large',
|
||||
414 => 'Request-URI Too Large',
|
||||
414 => 'Request-URI Too Long',
|
||||
415 => 'Unsupported Media Type',
|
||||
416 => 'Requested Range Not Satisfiable',
|
||||
417 => 'Expectation Failed',
|
||||
422 => 'Unprocessable Entity',
|
||||
423 => 'Locked',
|
||||
424 => 'Failed Dependency',
|
||||
426 => 'Upgrade Required',
|
||||
500 => 'Internal Server Error',
|
||||
501 => 'Not Implemented',
|
||||
502 => 'Bad Gateway',
|
||||
503 => 'Service Unavailable',
|
||||
504 => 'Gateway Timeout',
|
||||
505 => 'HTTP Version Not Supported'
|
||||
505 => 'HTTP Version Not Supported',
|
||||
506 => 'Variant Also Negotiates',
|
||||
507 => 'Insufficient Storage',
|
||||
510 => 'Not Extended',
|
||||
}
|
||||
|
||||
# Responses with HTTP status codes that should not have an entity body
|
||||
STATUS_WITH_NO_ENTITY_BODY = Set.new((100..199).to_a << 204 << 304)
|
||||
|
||||
SYMBOL_TO_STATUS_CODE = HTTP_STATUS_CODES.inject({}) { |hash, (code, message)|
|
||||
hash[message.downcase.gsub(/\s|-/, '_').to_sym] = code
|
||||
hash
|
||||
}
|
||||
|
||||
def status_code(status)
|
||||
if status.is_a?(Symbol)
|
||||
SYMBOL_TO_STATUS_CODE[status] || 500
|
||||
else
|
||||
status.to_i
|
||||
end
|
||||
end
|
||||
module_function :status_code
|
||||
|
||||
# A multipart form data parser, adapted from IOWA.
|
||||
#
|
||||
# Usually, Rack::Request#POST takes care of calling this.
|
||||
|
||||
module Multipart
|
||||
class UploadedFile
|
||||
# The filename, *not* including the path, of the "uploaded" file
|
||||
attr_reader :original_filename
|
||||
|
||||
# The content type of the "uploaded" file
|
||||
attr_accessor :content_type
|
||||
|
||||
def initialize(path, content_type = "text/plain", binary = false)
|
||||
raise "#{path} file does not exist" unless ::File.exist?(path)
|
||||
@content_type = content_type
|
||||
@original_filename = ::File.basename(path)
|
||||
@tempfile = Tempfile.new(@original_filename)
|
||||
@tempfile.set_encoding(Encoding::BINARY) if @tempfile.respond_to?(:set_encoding)
|
||||
@tempfile.binmode if binary
|
||||
FileUtils.copy_file(path, @tempfile.path)
|
||||
end
|
||||
|
||||
def path
|
||||
@tempfile.path
|
||||
end
|
||||
alias_method :local_path, :path
|
||||
|
||||
def method_missing(method_name, *args, &block) #:nodoc:
|
||||
@tempfile.__send__(method_name, *args, &block)
|
||||
end
|
||||
end
|
||||
|
||||
EOL = "\r\n"
|
||||
MULTIPART_BOUNDARY = "AaB03x"
|
||||
|
||||
def self.parse_multipart(env)
|
||||
unless env['CONTENT_TYPE'] =~
|
||||
|
@ -378,7 +526,7 @@ module Rack
|
|||
:name => name, :tempfile => body, :head => head}
|
||||
elsif !filename && content_type
|
||||
body.rewind
|
||||
|
||||
|
||||
# Generic multipart cases, not coming from a form
|
||||
data = {:type => content_type,
|
||||
:name => name, :tempfile => body, :head => head}
|
||||
|
@ -388,7 +536,8 @@ module Rack
|
|||
|
||||
Utils.normalize_params(params, name, data) unless data.nil?
|
||||
|
||||
break if buf.empty? || content_length == -1
|
||||
# break if we're at the end of a buffer, but not if it is the end of a field
|
||||
break if (buf.empty? && $1 != EOL) || content_length == -1
|
||||
}
|
||||
|
||||
input.rewind
|
||||
|
@ -396,6 +545,76 @@ module Rack
|
|||
params
|
||||
end
|
||||
end
|
||||
|
||||
def self.build_multipart(params, first = true)
|
||||
if first
|
||||
unless params.is_a?(Hash)
|
||||
raise ArgumentError, "value must be a Hash"
|
||||
end
|
||||
|
||||
multipart = false
|
||||
query = lambda { |value|
|
||||
case value
|
||||
when Array
|
||||
value.each(&query)
|
||||
when Hash
|
||||
value.values.each(&query)
|
||||
when UploadedFile
|
||||
multipart = true
|
||||
end
|
||||
}
|
||||
params.values.each(&query)
|
||||
return nil unless multipart
|
||||
end
|
||||
|
||||
flattened_params = Hash.new
|
||||
|
||||
params.each do |key, value|
|
||||
k = first ? key.to_s : "[#{key}]"
|
||||
|
||||
case value
|
||||
when Array
|
||||
value.map { |v|
|
||||
build_multipart(v, false).each { |subkey, subvalue|
|
||||
flattened_params["#{k}[]#{subkey}"] = subvalue
|
||||
}
|
||||
}
|
||||
when Hash
|
||||
build_multipart(value, false).each { |subkey, subvalue|
|
||||
flattened_params[k + subkey] = subvalue
|
||||
}
|
||||
else
|
||||
flattened_params[k] = value
|
||||
end
|
||||
end
|
||||
|
||||
if first
|
||||
flattened_params.map { |name, file|
|
||||
if file.respond_to?(:original_filename)
|
||||
::File.open(file.path, "rb") do |f|
|
||||
f.set_encoding(Encoding::BINARY) if f.respond_to?(:set_encoding)
|
||||
<<-EOF
|
||||
--#{MULTIPART_BOUNDARY}\r
|
||||
Content-Disposition: form-data; name="#{name}"; filename="#{Utils.escape(file.original_filename)}"\r
|
||||
Content-Type: #{file.content_type}\r
|
||||
Content-Length: #{::File.stat(file.path).size}\r
|
||||
\r
|
||||
#{f.read}\r
|
||||
EOF
|
||||
end
|
||||
else
|
||||
<<-EOF
|
||||
--#{MULTIPART_BOUNDARY}\r
|
||||
Content-Disposition: form-data; name="#{name}"\r
|
||||
\r
|
||||
#{file}\r
|
||||
EOF
|
||||
end
|
||||
}.join + "--#{MULTIPART_BOUNDARY}--\r"
|
||||
else
|
||||
flattened_params
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
38
vendor/plugins/rack/rack.gemspec
vendored
Normal file
38
vendor/plugins/rack/rack.gemspec
vendored
Normal file
|
@ -0,0 +1,38 @@
|
|||
Gem::Specification.new do |s|
|
||||
s.name = "rack"
|
||||
s.version = "1.1.0"
|
||||
s.platform = Gem::Platform::RUBY
|
||||
s.summary = "a modular Ruby webserver interface"
|
||||
|
||||
s.description = <<-EOF
|
||||
Rack provides minimal, modular and adaptable interface for developing
|
||||
web applications in Ruby. By wrapping HTTP requests and responses in
|
||||
the simplest way possible, it unifies and distills the API for web
|
||||
servers, web frameworks, and software in between (the so-called
|
||||
middleware) into a single method call.
|
||||
|
||||
Also see http://rack.rubyforge.org.
|
||||
EOF
|
||||
|
||||
s.files = Dir['{bin/*,contrib/*,example/*,lib/**/*}'] +
|
||||
%w(COPYING KNOWN-ISSUES rack.gemspec RDOX README SPEC)
|
||||
s.bindir = 'bin'
|
||||
s.executables << 'rackup'
|
||||
s.require_path = 'lib'
|
||||
s.has_rdoc = true
|
||||
s.extra_rdoc_files = ['README', 'SPEC', 'KNOWN-ISSUES']
|
||||
s.test_files = Dir['test/{test,spec}_*.rb']
|
||||
|
||||
s.author = 'Christian Neukirchen'
|
||||
s.email = 'chneukirchen@gmail.com'
|
||||
s.homepage = 'http://rack.rubyforge.org'
|
||||
s.rubyforge_project = 'rack'
|
||||
|
||||
s.add_development_dependency 'test-spec'
|
||||
|
||||
s.add_development_dependency 'camping'
|
||||
s.add_development_dependency 'fcgi'
|
||||
s.add_development_dependency 'memcache-client'
|
||||
s.add_development_dependency 'mongrel'
|
||||
s.add_development_dependency 'thin'
|
||||
end
|
3
vendor/plugins/rack/test/cgi/test.ru
vendored
3
vendor/plugins/rack/test/cgi/test.ru
vendored
|
@ -1,5 +1,4 @@
|
|||
#!/usr/bin/env ../../bin/rackup
|
||||
#\ -E deployment -I ../../lib
|
||||
#!/usr/bin/env ruby -I ../../lib ../../bin/rackup -E deployment -I ../../lib
|
||||
# -*- ruby -*-
|
||||
|
||||
require '../testrequest'
|
||||
|
|
259
vendor/plugins/rack/test/multipart/bad_robots
vendored
Normal file
259
vendor/plugins/rack/test/multipart/bad_robots
vendored
Normal file
|
@ -0,0 +1,259 @@
|
|||
--1yy3laWhgX31qpiHinh67wJXqKalukEUTvqTzmon
|
||||
Content-Disposition: form-data; name="bbbbbbbbbbbbbbb"
|
||||
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaa
|
||||
|
||||
--1yy3laWhgX31qpiHinh67wJXqKalukEUTvqTzmon
|
||||
Content-Disposition: form-data; name="ccccccc"
|
||||
|
||||
ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd
|
||||
--1yy3laWhgX31qpiHinh67wJXqKalukEUTvqTzmon
|
||||
Content-Disposition: form-data; name="file.name"
|
||||
|
||||
INPUTMSG.gz
|
||||
--1yy3laWhgX31qpiHinh67wJXqKalukEUTvqTzmon
|
||||
Content-Disposition: form-data; name="file.content_type"
|
||||
|
||||
application/octet-stream
|
||||
--1yy3laWhgX31qpiHinh67wJXqKalukEUTvqTzmon
|
||||
Content-Disposition: form-data; name="file.path"
|
||||
|
||||
/var/tmp/uploads/4/0001728414
|
||||
--1yy3laWhgX31qpiHinh67wJXqKalukEUTvqTzmon
|
||||
Content-Disposition: form-data; name="file.md5"
|
||||
|
||||
aa73198feb4b4c1c3186f5e7466cbbcc
|
||||
--1yy3laWhgX31qpiHinh67wJXqKalukEUTvqTzmon
|
||||
Content-Disposition: form-data; name="file.size"
|
||||
|
||||
13212
|
||||
--1yy3laWhgX31qpiHinh67wJXqKalukEUTvqTzmon
|
||||
Content-Disposition: form-data; name="size"
|
||||
|
||||
80892
|
||||
--1yy3laWhgX31qpiHinh67wJXqKalukEUTvqTzmon
|
||||
Content-Disposition: form-data; name="mail_server_id"
|
||||
|
||||
<1111111111.22222222.3333333333333.JavaMail.app@ffff-aaaa.dddd>
|
||||
|
||||
--1yy3laWhgX31qpiHinh67wJXqKalukEUTvqTzmon
|
||||
Content-Disposition: form-data; name="addresses"
|
||||
|
||||
{"campsy_programmer@pinkedum.com":{"domain":"pinkedum.com","name":"Campsy Programmer","type":["env_sender"],"mailbox":"campsy_programmer"},"tex@rapidcity.com":{"domain":"rapidcity.com","name":"Big Tex","type":["env_recipients","to"],"mailbox":"tex"},"group-digests@linkedin.com":{"domain":"linkedin.com","name":"Group Members","type":["from"],"mailbox":"group-digests"}}
|
||||
--1yy3laWhgX31qpiHinh67wJXqKalukEUTvqTzmon
|
||||
Content-Disposition: form-data; name="received_on"
|
||||
|
||||
2009-11-15T14:21:11Z
|
||||
--1yy3laWhgX31qpiHinh67wJXqKalukEUTvqTzmon
|
||||
Content-Disposition: form-data; name="id"
|
||||
|
||||
dbfd9804d26d11deab24e3037639bf77
|
||||
--1yy3laWhgX31qpiHinh67wJXqKalukEUTvqTzmon
|
||||
Content-Disposition: form-data; name="ip_address"
|
||||
|
||||
127.0.0.1
|
||||
--1yy3laWhgX31qpiHinh67wJXqKalukEUTvqTzmon--
|
814
vendor/plugins/rack/test/multipart/fail_16384_nofile
vendored
Normal file
814
vendor/plugins/rack/test/multipart/fail_16384_nofile
vendored
Normal file
|
@ -0,0 +1,814 @@
|
|||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="_method"
|
||||
|
||||
put
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="authenticity_token"
|
||||
|
||||
XCUgSyYsZ+iHQunq/yCSKFzjeVmsXV/WcphHQ0J+05I=
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[SESE]"
|
||||
|
||||
BooBar
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[BBBBBBBBB]"
|
||||
|
||||
18
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[CCCCCCCCCCCCCCCCCCC]"
|
||||
|
||||
0
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[STARTFOO]"
|
||||
|
||||
2009-11-04
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[ENDFOO]"
|
||||
|
||||
2009-12-01
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[DDDDDDDD]"
|
||||
|
||||
0
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[DDDDDDDD]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[EEEEEEEEEE]"
|
||||
|
||||
10000
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[FFFFFFFFF]"
|
||||
|
||||
boskoizcool
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[GGGGGGGGGGG]"
|
||||
|
||||
0
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[GGGGGGGGGGG]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[YYYYYYYYYYYYYYY]"
|
||||
|
||||
5.00
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[ZZZZZZZZZZZZZ]"
|
||||
|
||||
mille
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[XXXXXXXXXXXXXXXXXXXXX]"
|
||||
|
||||
0
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][1][9]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][1][10]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][1][11]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][1][12]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][1][13]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][1][14]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][1][15]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][1][16]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][1][17]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][1][18]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][1][19]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][1][20]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][1][21]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][1][22]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][1][23]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][1][0]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][1][1]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][1][2]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][1][3]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][1][4]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][1][5]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][1][6]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][1][7]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][1][8]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][2][9]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][2][10]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][2][11]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][2][12]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][2][13]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][2][14]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][2][15]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][2][16]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][2][17]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][2][18]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][2][19]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][2][20]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][2][21]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][2][22]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][2][23]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][2][0]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][2][1]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][2][2]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][2][3]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][2][4]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][2][5]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][2][6]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][2][7]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][2][8]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][3][9]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][3][10]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][3][11]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][3][12]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][3][13]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][3][14]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][3][15]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][3][16]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][3][17]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][3][18]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][3][19]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][3][20]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][3][21]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][3][22]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][3][23]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][3][0]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][3][1]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][3][2]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][3][3]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][3][4]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][3][5]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][3][6]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][3][7]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][3][8]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][4][9]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][4][10]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][4][11]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][4][12]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][4][13]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][4][14]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][4][15]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][4][16]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][4][17]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][4][18]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][4][19]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][4][20]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][4][21]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][4][22]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][4][23]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][4][0]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][4][1]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][4][2]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][4][3]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][4][4]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][4][5]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][4][6]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][4][7]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][4][8]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][5][9]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][5][10]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][5][11]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][5][12]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][5][13]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][5][14]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][5][15]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][5][16]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][5][17]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][5][18]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][5][19]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][5][20]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][5][21]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][5][22]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][5][23]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][5][0]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][5][1]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][5][2]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][5][3]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][5][4]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][5][5]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][5][6]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][5][7]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][5][8]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][6][9]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][6][10]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][6][11]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][6][12]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][6][13]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][6][14]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][6][15]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][6][16]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][6][17]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][6][18]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][6][19]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][6][20]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][6][21]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][6][22]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][6][23]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][6][0]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][6][1]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][6][2]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][6][3]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][6][4]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][6][5]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][6][6]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][6][7]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][6][8]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][0][9]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][0][10]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][0][11]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][0][12]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][0][13]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][0][14]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][0][15]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][0][16]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][0][17]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][0][18]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][0][19]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][0][20]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][0][21]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][0][22]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][0][23]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][0][0]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][0][1]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][0][2]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][0][3]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][0][4]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][0][5]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][0][6]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][0][7]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[VVVVVVVVVVVVVVVVVVVVVVV][0][8]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[WWWWWWWWWWWWWWWWWWWWWWWWW][678][ZEZE]"
|
||||
|
||||
PLAPLAPLAINCINCINC
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[WWWWWWWWWWWWWWWWWWWWWWWWW][678][123412341234e]"
|
||||
|
||||
SITE
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[WWWWWWWWWWWWWWWWWWWWWWWWW][678][12345678901]"
|
||||
|
||||
56
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[TARTARTAR_type]"
|
||||
|
||||
none
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[TARTARTAR_wizard][has_hashashas_has]"
|
||||
|
||||
0
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[TARTARTAR_wizard][frefrefre_fre_freee]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[TARTARTAR_wizard][frefrefre_fre_frefre]"
|
||||
|
||||
forever
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[TARTARTAR_wizard][self_block]"
|
||||
|
||||
0
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[TARTARTAR_wizard][GGG_RULES][][COUCOUN]"
|
||||
|
||||
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[TARTARTAR_wizard][GGG_RULES][][REGREG]"
|
||||
|
||||
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[TARTARTAR_wizard][GGG_RULES][][c1c1]"
|
||||
|
||||
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA_TARTARTAR_wizard_rule"
|
||||
|
||||
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[TARTARTAR_rule]"
|
||||
|
||||
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[selection_selection]"
|
||||
|
||||
R
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[PLAPLAPLA_MEMMEMMEMM_ATTRATTRER][new][-1][selection_selection]"
|
||||
|
||||
1
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[PLAPLAPLA_MEMMEMMEMM_ATTRATTRER][new][-1][ba_unit_id]"
|
||||
|
||||
1015
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[PLAPLAPLA_MEMMEMMEMM_ATTRATTRER][new][-2][selection_selection]"
|
||||
|
||||
2
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[PLAPLAPLA_MEMMEMMEMM_ATTRATTRER][new][-2][ba_unit_id]"
|
||||
|
||||
1017
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo
|
||||
Content-Disposition: form-data; name="AAAAAAAAAAAAAAAAAAA[tile_name]"
|
||||
|
||||
|
||||
------WebKitFormBoundaryWsY0GnpbI5U7ztzo--
|
||||
|
1
vendor/plugins/rack/test/multipart/file1.txt
vendored
Normal file
1
vendor/plugins/rack/test/multipart/file1.txt
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
contents
|
1
vendor/plugins/rack/test/rackup/.gitignore
vendored
Normal file
1
vendor/plugins/rack/test/rackup/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
log_output
|
31
vendor/plugins/rack/test/rackup/config.ru
vendored
Normal file
31
vendor/plugins/rack/test/rackup/config.ru
vendored
Normal file
|
@ -0,0 +1,31 @@
|
|||
require "#{File.dirname(__FILE__)}/../testrequest"
|
||||
|
||||
$stderr = File.open("#{File.dirname(__FILE__)}/log_output", "w")
|
||||
|
||||
class EnvMiddleware
|
||||
def initialize(app)
|
||||
@app = app
|
||||
end
|
||||
|
||||
def call(env)
|
||||
# provides a way to test that lint is present
|
||||
if env["PATH_INFO"] == "/broken_lint"
|
||||
return [200, {}, ["Broken Lint"]]
|
||||
# provides a way to kill the process without knowing the pid
|
||||
elsif env["PATH_INFO"] == "/die"
|
||||
exit!
|
||||
end
|
||||
|
||||
env["test.$DEBUG"] = $DEBUG
|
||||
env["test.$EVAL"] = BUKKIT if defined?(BUKKIT)
|
||||
env["test.$VERBOSE"] = $VERBOSE
|
||||
env["test.$LOAD_PATH"] = $LOAD_PATH
|
||||
env["test.stderr"] = File.expand_path($stderr.path)
|
||||
env["test.Ping"] = defined?(Ping)
|
||||
env["test.pid"] = Process.pid
|
||||
@app.call(env)
|
||||
end
|
||||
end
|
||||
|
||||
use EnvMiddleware
|
||||
run TestRequest.new
|
|
@ -28,15 +28,13 @@ context "Rack::Cascade" do
|
|||
Rack::MockRequest.new(cascade).get("/cgi/../bla").should.be.not_found
|
||||
end
|
||||
|
||||
specify "should fail if empty" do
|
||||
lambda { Rack::MockRequest.new(Rack::Cascade.new([])).get("/") }.
|
||||
should.raise(ArgumentError)
|
||||
specify "should return 404 if empty" do
|
||||
Rack::MockRequest.new(Rack::Cascade.new([])).get('/').should.be.not_found
|
||||
end
|
||||
|
||||
specify "should append new app" do
|
||||
cascade = Rack::Cascade.new([], [404, 403])
|
||||
lambda { Rack::MockRequest.new(cascade).get('/cgi/test') }.
|
||||
should.raise(ArgumentError)
|
||||
Rack::MockRequest.new(cascade).get('/').should.be.not_found
|
||||
cascade << app2
|
||||
Rack::MockRequest.new(cascade).get('/cgi/test').should.be.not_found
|
||||
Rack::MockRequest.new(cascade).get('/cgi/../bla').should.be.not_found
|
||||
|
|
6
vendor/plugins/rack/test/spec_rack_cgi.rb
vendored
6
vendor/plugins/rack/test/spec_rack_cgi.rb
vendored
|
@ -3,7 +3,7 @@ require 'testrequest'
|
|||
|
||||
context "Rack::Handler::CGI" do
|
||||
include TestRequest::Helpers
|
||||
|
||||
|
||||
setup do
|
||||
@host = '0.0.0.0'
|
||||
@port = 9203
|
||||
|
@ -36,7 +36,7 @@ context "Rack::Handler::CGI" do
|
|||
|
||||
specify "should have rack headers" do
|
||||
GET("/test")
|
||||
response["rack.version"].should.equal [1,0]
|
||||
response["rack.version"].should.equal [1,1]
|
||||
response["rack.multithread"].should.be false
|
||||
response["rack.multiprocess"].should.be true
|
||||
response["rack.run_once"].should.be true
|
||||
|
@ -47,7 +47,7 @@ context "Rack::Handler::CGI" do
|
|||
response["REQUEST_METHOD"].should.equal "GET"
|
||||
response["SCRIPT_NAME"].should.equal "/test"
|
||||
response["REQUEST_PATH"].should.equal "/"
|
||||
response["PATH_INFO"].should.be.nil
|
||||
response["PATH_INFO"].should.equal ""
|
||||
response["QUERY_STRING"].should.equal ""
|
||||
response["test.postdata"].should.equal ""
|
||||
|
||||
|
|
|
@ -7,26 +7,55 @@ require 'rack/mock'
|
|||
|
||||
context "Rack::CommonLogger" do
|
||||
app = lambda { |env|
|
||||
[200,
|
||||
{"Content-Type" => "text/html", "Content-Length" => length.to_s},
|
||||
[obj]]}
|
||||
app_without_length = lambda { |env|
|
||||
[200,
|
||||
{"Content-Type" => "text/html"},
|
||||
["foo"]]}
|
||||
[]]}
|
||||
app_with_zero_length = lambda { |env|
|
||||
[200,
|
||||
{"Content-Type" => "text/html", "Content-Length" => "0"},
|
||||
[]]}
|
||||
|
||||
specify "should log to rack.errors by default" do
|
||||
log = StringIO.new
|
||||
res = Rack::MockRequest.new(Rack::CommonLogger.new(app)).get("/")
|
||||
|
||||
res.errors.should.not.be.empty
|
||||
res.errors.should =~ /GET /
|
||||
res.errors.should =~ / 200 / # status
|
||||
res.errors.should =~ / 3 / # length
|
||||
res.errors.should =~ /"GET \/ " 200 #{length} /
|
||||
end
|
||||
|
||||
specify "should log to anything with <<" do
|
||||
log = ""
|
||||
specify "should log to anything with +write+" do
|
||||
log = StringIO.new
|
||||
res = Rack::MockRequest.new(Rack::CommonLogger.new(app, log)).get("/")
|
||||
|
||||
log.should =~ /GET /
|
||||
log.should =~ / 200 / # status
|
||||
log.should =~ / 3 / # length
|
||||
log.string.should =~ /"GET \/ " 200 #{length} /
|
||||
end
|
||||
|
||||
specify "should log - content length if header is missing" do
|
||||
res = Rack::MockRequest.new(Rack::CommonLogger.new(app_without_length)).get("/")
|
||||
|
||||
res.errors.should.not.be.empty
|
||||
res.errors.should =~ /"GET \/ " 200 - /
|
||||
end
|
||||
|
||||
specify "should log - content length if header is zero" do
|
||||
res = Rack::MockRequest.new(Rack::CommonLogger.new(app_with_zero_length)).get("/")
|
||||
|
||||
res.errors.should.not.be.empty
|
||||
res.errors.should =~ /"GET \/ " 200 - /
|
||||
end
|
||||
|
||||
def length
|
||||
self.class.length
|
||||
end
|
||||
|
||||
def self.length
|
||||
123
|
||||
end
|
||||
|
||||
def self.obj
|
||||
"hello world"
|
||||
end
|
||||
end
|
||||
|
|
24
vendor/plugins/rack/test/spec_rack_config.rb
vendored
Normal file
24
vendor/plugins/rack/test/spec_rack_config.rb
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
require 'test/spec'
|
||||
require 'rack/mock'
|
||||
require 'rack/builder'
|
||||
require 'rack/content_length'
|
||||
require 'rack/config'
|
||||
|
||||
context "Rack::Config" do
|
||||
|
||||
specify "should accept a block that modifies the environment" do
|
||||
app = Rack::Builder.new do
|
||||
use Rack::Lint
|
||||
use Rack::ContentLength
|
||||
use Rack::Config do |env|
|
||||
env['greeting'] = 'hello'
|
||||
end
|
||||
run lambda { |env|
|
||||
[200, {'Content-Type' => 'text/plain'}, [env['greeting'] || '']]
|
||||
}
|
||||
end
|
||||
response = Rack::MockRequest.new(app).get('/')
|
||||
response.body.should.equal('hello')
|
||||
end
|
||||
|
||||
end
|
|
@ -6,7 +6,7 @@ require 'rack/lint'
|
|||
require 'rack/mock'
|
||||
|
||||
context "Rack::Directory" do
|
||||
DOCROOT = File.expand_path(File.dirname(__FILE__))
|
||||
DOCROOT = File.expand_path(File.dirname(__FILE__)) unless defined? DOCROOT
|
||||
FILE_CATCH = proc{|env| [200, {'Content-Type'=>'text/plain', "Content-Length" => "7"}, ['passed!']] }
|
||||
app = Rack::Directory.new DOCROOT, FILE_CATCH
|
||||
|
||||
|
|
17
vendor/plugins/rack/test/spec_rack_etag.rb
vendored
Normal file
17
vendor/plugins/rack/test/spec_rack_etag.rb
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
require 'test/spec'
|
||||
require 'rack/mock'
|
||||
require 'rack/etag'
|
||||
|
||||
context "Rack::ETag" do
|
||||
specify "sets ETag if none is set" do
|
||||
app = lambda { |env| [200, {'Content-Type' => 'text/plain'}, ["Hello, World!"]] }
|
||||
response = Rack::ETag.new(app).call({})
|
||||
response[1]['ETag'].should.equal "\"65a8e27d8879283831b664bd8b7f0ad4\""
|
||||
end
|
||||
|
||||
specify "does not change ETag if it is already set" do
|
||||
app = lambda { |env| [200, {'Content-Type' => 'text/plain', 'ETag' => '"abc"'}, ["Hello, World!"]] }
|
||||
response = Rack::ETag.new(app).call({})
|
||||
response[1]['ETag'].should.equal "\"abc\""
|
||||
end
|
||||
end
|
|
@ -36,7 +36,7 @@ context "Rack::Handler::FastCGI" do
|
|||
|
||||
specify "should have rack headers" do
|
||||
GET("/test.fcgi")
|
||||
response["rack.version"].should.equal [1,0]
|
||||
response["rack.version"].should.equal [1,1]
|
||||
response["rack.multithread"].should.be false
|
||||
response["rack.multiprocess"].should.be true
|
||||
response["rack.run_once"].should.be false
|
||||
|
@ -47,7 +47,7 @@ context "Rack::Handler::FastCGI" do
|
|||
response["REQUEST_METHOD"].should.equal "GET"
|
||||
response["SCRIPT_NAME"].should.equal "/test.fcgi"
|
||||
response["REQUEST_PATH"].should.equal "/"
|
||||
response["PATH_INFO"].should.be.nil
|
||||
response["PATH_INFO"].should.equal ""
|
||||
response["QUERY_STRING"].should.equal ""
|
||||
response["test.postdata"].should.equal ""
|
||||
|
||||
|
|
2
vendor/plugins/rack/test/spec_rack_file.rb
vendored
2
vendor/plugins/rack/test/spec_rack_file.rb
vendored
|
@ -6,7 +6,7 @@ require 'rack/lint'
|
|||
require 'rack/mock'
|
||||
|
||||
context "Rack::File" do
|
||||
DOCROOT = File.expand_path(File.dirname(__FILE__))
|
||||
DOCROOT = File.expand_path(File.dirname(__FILE__)) unless defined? DOCROOT
|
||||
|
||||
specify "serves files" do
|
||||
res = Rack::MockRequest.new(Rack::Lint.new(Rack::File.new(DOCROOT))).
|
||||
|
|
45
vendor/plugins/rack/test/spec_rack_lint.rb
vendored
45
vendor/plugins/rack/test/spec_rack_lint.rb
vendored
|
@ -71,6 +71,11 @@ context "Rack::Lint" do
|
|||
}.should.raise(Rack::Lint::LintError).
|
||||
message.should.equal("session [] must respond to store and []=")
|
||||
|
||||
lambda {
|
||||
Rack::Lint.new(nil).call(env("rack.logger" => []))
|
||||
}.should.raise(Rack::Lint::LintError).
|
||||
message.should.equal("logger [] must respond to info")
|
||||
|
||||
lambda {
|
||||
Rack::Lint.new(nil).call(env("REQUEST_METHOD" => "FUCKUP?"))
|
||||
}.should.raise(Rack::Lint::LintError).
|
||||
|
@ -110,7 +115,7 @@ context "Rack::Lint" do
|
|||
Rack::Lint.new(nil).call(env("rack.input" => ""))
|
||||
}.should.raise(Rack::Lint::LintError).
|
||||
message.should.match(/does not respond to #gets/)
|
||||
|
||||
|
||||
lambda {
|
||||
input = Object.new
|
||||
def input.binmode?
|
||||
|
@ -119,7 +124,7 @@ context "Rack::Lint" do
|
|||
Rack::Lint.new(nil).call(env("rack.input" => input))
|
||||
}.should.raise(Rack::Lint::LintError).
|
||||
message.should.match(/is not opened in binary mode/)
|
||||
|
||||
|
||||
lambda {
|
||||
input = Object.new
|
||||
def input.external_encoding
|
||||
|
@ -347,25 +352,25 @@ context "Rack::Lint" do
|
|||
yield 23
|
||||
yield 42
|
||||
end
|
||||
|
||||
|
||||
def rewind
|
||||
raise Errno::ESPIPE, "Errno::ESPIPE"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
eof_weirdio = Object.new
|
||||
class << eof_weirdio
|
||||
def gets
|
||||
nil
|
||||
end
|
||||
|
||||
|
||||
def read(*args)
|
||||
nil
|
||||
end
|
||||
|
||||
|
||||
def each
|
||||
end
|
||||
|
||||
|
||||
def rewind
|
||||
end
|
||||
end
|
||||
|
@ -452,48 +457,50 @@ context "Rack::Lint" do
|
|||
}.should.raise(Rack::Lint::LintError).
|
||||
message.should.match(/body was given for HEAD/)
|
||||
end
|
||||
|
||||
|
||||
specify "passes valid read calls" do
|
||||
hello_str = "hello world"
|
||||
hello_str.force_encoding("ASCII-8BIT") if hello_str.respond_to? :force_encoding
|
||||
lambda {
|
||||
Rack::Lint.new(lambda { |env|
|
||||
env["rack.input"].read
|
||||
[201, {"Content-type" => "text/plain", "Content-length" => "0"}, []]
|
||||
}).call(env({"rack.input" => StringIO.new("hello world")}))
|
||||
}).call(env({"rack.input" => StringIO.new(hello_str)}))
|
||||
}.should.not.raise(Rack::Lint::LintError)
|
||||
|
||||
|
||||
lambda {
|
||||
Rack::Lint.new(lambda { |env|
|
||||
env["rack.input"].read(0)
|
||||
[201, {"Content-type" => "text/plain", "Content-length" => "0"}, []]
|
||||
}).call(env({"rack.input" => StringIO.new("hello world")}))
|
||||
}).call(env({"rack.input" => StringIO.new(hello_str)}))
|
||||
}.should.not.raise(Rack::Lint::LintError)
|
||||
|
||||
|
||||
lambda {
|
||||
Rack::Lint.new(lambda { |env|
|
||||
env["rack.input"].read(1)
|
||||
[201, {"Content-type" => "text/plain", "Content-length" => "0"}, []]
|
||||
}).call(env({"rack.input" => StringIO.new("hello world")}))
|
||||
}).call(env({"rack.input" => StringIO.new(hello_str)}))
|
||||
}.should.not.raise(Rack::Lint::LintError)
|
||||
|
||||
|
||||
lambda {
|
||||
Rack::Lint.new(lambda { |env|
|
||||
env["rack.input"].read(nil)
|
||||
[201, {"Content-type" => "text/plain", "Content-length" => "0"}, []]
|
||||
}).call(env({"rack.input" => StringIO.new("hello world")}))
|
||||
}).call(env({"rack.input" => StringIO.new(hello_str)}))
|
||||
}.should.not.raise(Rack::Lint::LintError)
|
||||
|
||||
|
||||
lambda {
|
||||
Rack::Lint.new(lambda { |env|
|
||||
env["rack.input"].read(nil, '')
|
||||
[201, {"Content-type" => "text/plain", "Content-length" => "0"}, []]
|
||||
}).call(env({"rack.input" => StringIO.new("hello world")}))
|
||||
}).call(env({"rack.input" => StringIO.new(hello_str)}))
|
||||
}.should.not.raise(Rack::Lint::LintError)
|
||||
|
||||
|
||||
lambda {
|
||||
Rack::Lint.new(lambda { |env|
|
||||
env["rack.input"].read(1, '')
|
||||
[201, {"Content-type" => "text/plain", "Content-length" => "0"}, []]
|
||||
}).call(env({"rack.input" => StringIO.new("hello world")}))
|
||||
}).call(env({"rack.input" => StringIO.new(hello_str)}))
|
||||
}.should.not.raise(Rack::Lint::LintError)
|
||||
end
|
||||
end
|
||||
|
|
21
vendor/plugins/rack/test/spec_rack_logger.rb
vendored
Normal file
21
vendor/plugins/rack/test/spec_rack_logger.rb
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
require 'rack/logger'
|
||||
require 'rack/lint'
|
||||
require 'stringio'
|
||||
|
||||
context "Rack::Logger" do
|
||||
specify "logs to rack.errors" do
|
||||
app = lambda { |env|
|
||||
log = env['rack.logger']
|
||||
log.debug("Created logger")
|
||||
log.info("Program started")
|
||||
log.warn("Nothing to do!")
|
||||
|
||||
[200, {'Content-Type' => 'text/plain'}, ["Hello, World!"]]
|
||||
}
|
||||
|
||||
errors = StringIO.new
|
||||
Rack::Logger.new(app).call({'rack.errors' => errors})
|
||||
errors.string.should.match "INFO -- : Program started"
|
||||
errors.string.should.match "WARN -- : Nothing to do"
|
||||
end
|
||||
end
|
88
vendor/plugins/rack/test/spec_rack_mock.rb
vendored
88
vendor/plugins/rack/test/spec_rack_mock.rb
vendored
|
@ -93,6 +93,92 @@ context "Rack::MockRequest" do
|
|||
env["rack.url_scheme"].should.equal "https"
|
||||
end
|
||||
|
||||
specify "should set SSL port and HTTP flag on when using https" do
|
||||
res = Rack::MockRequest.new(app).
|
||||
get("https://example.org/foo")
|
||||
res.should.be.kind_of Rack::MockResponse
|
||||
|
||||
env = YAML.load(res.body)
|
||||
env["REQUEST_METHOD"].should.equal "GET"
|
||||
env["SERVER_NAME"].should.equal "example.org"
|
||||
env["SERVER_PORT"].should.equal "443"
|
||||
env["QUERY_STRING"].should.equal ""
|
||||
env["PATH_INFO"].should.equal "/foo"
|
||||
env["rack.url_scheme"].should.equal "https"
|
||||
env["HTTPS"].should.equal "on"
|
||||
end
|
||||
|
||||
specify "should prepend slash to uri path" do
|
||||
res = Rack::MockRequest.new(app).
|
||||
get("foo")
|
||||
res.should.be.kind_of Rack::MockResponse
|
||||
|
||||
env = YAML.load(res.body)
|
||||
env["REQUEST_METHOD"].should.equal "GET"
|
||||
env["SERVER_NAME"].should.equal "example.org"
|
||||
env["SERVER_PORT"].should.equal "80"
|
||||
env["QUERY_STRING"].should.equal ""
|
||||
env["PATH_INFO"].should.equal "/foo"
|
||||
env["rack.url_scheme"].should.equal "http"
|
||||
end
|
||||
|
||||
specify "should properly convert method name to an uppercase string" do
|
||||
res = Rack::MockRequest.new(app).request(:get)
|
||||
env = YAML.load(res.body)
|
||||
env["REQUEST_METHOD"].should.equal "GET"
|
||||
end
|
||||
|
||||
specify "should accept params and build query string for GET requests" do
|
||||
res = Rack::MockRequest.new(app).get("/foo?baz=2", :params => {:foo => {:bar => "1"}})
|
||||
env = YAML.load(res.body)
|
||||
env["REQUEST_METHOD"].should.equal "GET"
|
||||
env["QUERY_STRING"].should.match "baz=2"
|
||||
env["QUERY_STRING"].should.match "foo[bar]=1"
|
||||
env["PATH_INFO"].should.equal "/foo"
|
||||
env["mock.postdata"].should.equal ""
|
||||
end
|
||||
|
||||
specify "should accept raw input in params for GET requests" do
|
||||
res = Rack::MockRequest.new(app).get("/foo?baz=2", :params => "foo[bar]=1")
|
||||
env = YAML.load(res.body)
|
||||
env["REQUEST_METHOD"].should.equal "GET"
|
||||
env["QUERY_STRING"].should.match "baz=2"
|
||||
env["QUERY_STRING"].should.match "foo[bar]=1"
|
||||
env["PATH_INFO"].should.equal "/foo"
|
||||
env["mock.postdata"].should.equal ""
|
||||
end
|
||||
|
||||
specify "should accept params and build url encoded params for POST requests" do
|
||||
res = Rack::MockRequest.new(app).post("/foo", :params => {:foo => {:bar => "1"}})
|
||||
env = YAML.load(res.body)
|
||||
env["REQUEST_METHOD"].should.equal "POST"
|
||||
env["QUERY_STRING"].should.equal ""
|
||||
env["PATH_INFO"].should.equal "/foo"
|
||||
env["CONTENT_TYPE"].should.equal "application/x-www-form-urlencoded"
|
||||
env["mock.postdata"].should.equal "foo[bar]=1"
|
||||
end
|
||||
|
||||
specify "should accept raw input in params for POST requests" do
|
||||
res = Rack::MockRequest.new(app).post("/foo", :params => "foo[bar]=1")
|
||||
env = YAML.load(res.body)
|
||||
env["REQUEST_METHOD"].should.equal "POST"
|
||||
env["QUERY_STRING"].should.equal ""
|
||||
env["PATH_INFO"].should.equal "/foo"
|
||||
env["CONTENT_TYPE"].should.equal "application/x-www-form-urlencoded"
|
||||
env["mock.postdata"].should.equal "foo[bar]=1"
|
||||
end
|
||||
|
||||
specify "should accept params and build multipart encoded params for POST requests" do
|
||||
files = Rack::Utils::Multipart::UploadedFile.new(File.join(File.dirname(__FILE__), "multipart", "file1.txt"))
|
||||
res = Rack::MockRequest.new(app).post("/foo", :params => { "submit-name" => "Larry", "files" => files })
|
||||
env = YAML.load(res.body)
|
||||
env["REQUEST_METHOD"].should.equal "POST"
|
||||
env["QUERY_STRING"].should.equal ""
|
||||
env["PATH_INFO"].should.equal "/foo"
|
||||
env["CONTENT_TYPE"].should.equal "multipart/form-data; boundary=AaB03x"
|
||||
env["mock.postdata"].length.should.equal 206
|
||||
end
|
||||
|
||||
specify "should behave valid according to the Rack spec" do
|
||||
lambda {
|
||||
res = Rack::MockRequest.new(app).
|
||||
|
@ -130,7 +216,7 @@ context "Rack::MockResponse" do
|
|||
res.original_headers["Content-Type"].should.equal "text/yaml"
|
||||
res["Content-Type"].should.equal "text/yaml"
|
||||
res.content_type.should.equal "text/yaml"
|
||||
res.content_length.should.be 401 # needs change often.
|
||||
res.content_length.should.be 414 # needs change often.
|
||||
res.location.should.be.nil
|
||||
end
|
||||
|
||||
|
|
|
@ -6,14 +6,14 @@ require 'rack/urlmap'
|
|||
require 'rack/lint'
|
||||
require 'testrequest'
|
||||
require 'timeout'
|
||||
|
||||
|
||||
Thread.abort_on_exception = true
|
||||
$tcp_defer_accept_opts = nil
|
||||
$tcp_cork_opts = nil
|
||||
|
||||
context "Rack::Handler::Mongrel" do
|
||||
include TestRequest::Helpers
|
||||
|
||||
|
||||
setup do
|
||||
server = Mongrel::HttpServer.new(@host='0.0.0.0', @port=9201)
|
||||
server.register('/test',
|
||||
|
@ -41,7 +41,7 @@ context "Rack::Handler::Mongrel" do
|
|||
|
||||
specify "should have rack headers" do
|
||||
GET("/test")
|
||||
response["rack.version"].should.equal [1,0]
|
||||
response["rack.version"].should.equal [1,1]
|
||||
response["rack.multithread"].should.be true
|
||||
response["rack.multiprocess"].should.be false
|
||||
response["rack.run_once"].should.be false
|
||||
|
@ -52,7 +52,7 @@ context "Rack::Handler::Mongrel" do
|
|||
response["REQUEST_METHOD"].should.equal "GET"
|
||||
response["SCRIPT_NAME"].should.equal "/test"
|
||||
response["REQUEST_PATH"].should.equal "/test"
|
||||
response["PATH_INFO"].should.be.nil
|
||||
response["PATH_INFO"].should.be.equal ""
|
||||
response["QUERY_STRING"].should.equal ""
|
||||
response["test.postdata"].should.equal ""
|
||||
|
||||
|
|
13
vendor/plugins/rack/test/spec_rack_nulllogger.rb
vendored
Normal file
13
vendor/plugins/rack/test/spec_rack_nulllogger.rb
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
require 'rack/nulllogger'
|
||||
require 'rack/lint'
|
||||
require 'rack/mock'
|
||||
|
||||
context "Rack::NullLogger" do
|
||||
specify "acks as a nop logger" do
|
||||
app = lambda { |env|
|
||||
env['rack.logger'].warn "b00m"
|
||||
[200, {'Content-Type' => 'text/plain'}, ["Hello, World!"]]
|
||||
}
|
||||
Rack::NullLogger.new(app).call({})
|
||||
end
|
||||
end
|
53
vendor/plugins/rack/test/spec_rack_request.rb
vendored
53
vendor/plugins/rack/test/spec_rack_request.rb
vendored
|
@ -35,9 +35,18 @@ context "Rack::Request" do
|
|||
req.host.should.equal "www2.example.org"
|
||||
|
||||
req = Rack::Request.new \
|
||||
Rack::MockRequest.env_for("/", "SERVER_NAME" => "example.org:9292")
|
||||
Rack::MockRequest.env_for("/", "SERVER_NAME" => "example.org", "SERVER_PORT" => "9292")
|
||||
req.host.should.equal "example.org"
|
||||
|
||||
req = Rack::Request.new \
|
||||
Rack::MockRequest.env_for("/", "HTTP_HOST" => "localhost:81", "HTTP_X_FORWARDED_HOST" => "example.org:9292")
|
||||
req.host.should.equal "example.org"
|
||||
|
||||
env = Rack::MockRequest.env_for("/", "SERVER_ADDR" => "192.168.1.1", "SERVER_PORT" => "9292")
|
||||
env.delete("SERVER_NAME")
|
||||
req = Rack::Request.new(env)
|
||||
req.host.should.equal "192.168.1.1"
|
||||
|
||||
env = Rack::MockRequest.env_for("/")
|
||||
env.delete("SERVER_NAME")
|
||||
req = Rack::Request.new(env)
|
||||
|
@ -52,9 +61,16 @@ context "Rack::Request" do
|
|||
req.params.should.equal "foo" => "bar", "quux" => "bla"
|
||||
end
|
||||
|
||||
specify "can parse POST data" do
|
||||
specify "raises if rack.input is missing" do
|
||||
req = Rack::Request.new({})
|
||||
lambda { req.POST }.should.raise(RuntimeError)
|
||||
end
|
||||
|
||||
specify "can parse POST data when method is POST and no Content-Type given" do
|
||||
req = Rack::Request.new \
|
||||
Rack::MockRequest.env_for("/?foo=quux", :input => "foo=bar&quux=bla")
|
||||
Rack::MockRequest.env_for("/?foo=quux",
|
||||
"REQUEST_METHOD" => 'POST',
|
||||
:input => "foo=bar&quux=bla")
|
||||
req.content_type.should.be.nil
|
||||
req.media_type.should.be.nil
|
||||
req.query_string.should.equal "foo=quux"
|
||||
|
@ -63,7 +79,7 @@ context "Rack::Request" do
|
|||
req.params.should.equal "foo" => "bar", "quux" => "bla"
|
||||
end
|
||||
|
||||
specify "can parse POST data with explicit content type" do
|
||||
specify "can parse POST data with explicit content type regardless of method" do
|
||||
req = Rack::Request.new \
|
||||
Rack::MockRequest.env_for("/",
|
||||
"CONTENT_TYPE" => 'application/x-www-form-urlencoded;foo=bar',
|
||||
|
@ -78,6 +94,7 @@ context "Rack::Request" do
|
|||
specify "does not parse POST data when media type is not form-data" do
|
||||
req = Rack::Request.new \
|
||||
Rack::MockRequest.env_for("/?foo=quux",
|
||||
"REQUEST_METHOD" => 'POST',
|
||||
"CONTENT_TYPE" => 'text/plain;charset=utf-8',
|
||||
:input => "foo=bar&quux=bla")
|
||||
req.content_type.should.equal 'text/plain;charset=utf-8'
|
||||
|
@ -88,6 +105,16 @@ context "Rack::Request" do
|
|||
req.body.read.should.equal "foo=bar&quux=bla"
|
||||
end
|
||||
|
||||
specify "can parse POST data on PUT when media type is form-data" do
|
||||
req = Rack::Request.new \
|
||||
Rack::MockRequest.env_for("/?foo=quux",
|
||||
"REQUEST_METHOD" => 'PUT',
|
||||
"CONTENT_TYPE" => 'application/x-www-form-urlencoded',
|
||||
:input => "foo=bar&quux=bla")
|
||||
req.POST.should.equal "foo" => "bar", "quux" => "bla"
|
||||
req.body.read.should.equal "foo=bar&quux=bla"
|
||||
end
|
||||
|
||||
specify "rewinds input after parsing POST data" do
|
||||
input = StringIO.new("foo=bar&quux=bla")
|
||||
req = Rack::Request.new \
|
||||
|
@ -100,7 +127,8 @@ context "Rack::Request" do
|
|||
|
||||
specify "cleans up Safari's ajax POST body" do
|
||||
req = Rack::Request.new \
|
||||
Rack::MockRequest.env_for("/", :input => "foo=bar&quux=bla\0")
|
||||
Rack::MockRequest.env_for("/",
|
||||
'REQUEST_METHOD' => 'POST', :input => "foo=bar&quux=bla\0")
|
||||
req.POST.should.equal "foo" => "bar", "quux" => "bla"
|
||||
end
|
||||
|
||||
|
@ -147,9 +175,21 @@ context "Rack::Request" do
|
|||
req.referer.should.equal "/"
|
||||
end
|
||||
|
||||
specify "user agent should be extracted correct" do
|
||||
req = Rack::Request.new \
|
||||
Rack::MockRequest.env_for("/", "HTTP_USER_AGENT" => "Mozilla/4.0 (compatible)")
|
||||
req.user_agent.should.equal "Mozilla/4.0 (compatible)"
|
||||
|
||||
req = Rack::Request.new \
|
||||
Rack::MockRequest.env_for("/")
|
||||
req.user_agent.should.equal nil
|
||||
end
|
||||
|
||||
specify "can cache, but invalidates the cache" do
|
||||
req = Rack::Request.new \
|
||||
Rack::MockRequest.env_for("/?foo=quux", :input => "foo=bar&quux=bla")
|
||||
Rack::MockRequest.env_for("/?foo=quux",
|
||||
"CONTENT_TYPE" => "application/x-www-form-urlencoded",
|
||||
:input => "foo=bar&quux=bla")
|
||||
req.GET.should.equal "foo" => "quux"
|
||||
req.GET.should.equal "foo" => "quux"
|
||||
req.env["QUERY_STRING"] = "bla=foo"
|
||||
|
@ -424,6 +464,7 @@ Content-Transfer-Encoding: base64\r
|
|||
/9j/4AAQSkZJRgABAQAAAQABAAD//gA+Q1JFQVRPUjogZ2QtanBlZyB2MS4wICh1c2luZyBJSkcg\r
|
||||
--AaB03x--\r
|
||||
EOF
|
||||
input.force_encoding("ASCII-8BIT") if input.respond_to? :force_encoding
|
||||
res = Rack::MockRequest.new(Rack::Lint.new(app)).get "/",
|
||||
"CONTENT_TYPE" => "multipart/form-data, boundary=AaB03x",
|
||||
"CONTENT_LENGTH" => input.size.to_s, "rack.input" => StringIO.new(input)
|
||||
|
|
|
@ -118,6 +118,9 @@ context "Rack::Response" do
|
|||
|
||||
r = Rack::Response.new([], 500)
|
||||
r.status.should.equal 500
|
||||
|
||||
r = Rack::Response.new([], "200 OK")
|
||||
r.status.should.equal 200
|
||||
end
|
||||
|
||||
specify "has a constructor that can take a block" do
|
||||
|
|
35
vendor/plugins/rack/test/spec_rack_runtime.rb
vendored
Normal file
35
vendor/plugins/rack/test/spec_rack_runtime.rb
vendored
Normal file
|
@ -0,0 +1,35 @@
|
|||
require 'test/spec'
|
||||
require 'rack/mock'
|
||||
require 'rack/runtime'
|
||||
|
||||
context "Rack::Runtime" do
|
||||
specify "sets X-Runtime is none is set" do
|
||||
app = lambda { |env| [200, {'Content-Type' => 'text/plain'}, "Hello, World!"] }
|
||||
response = Rack::Runtime.new(app).call({})
|
||||
response[1]['X-Runtime'].should =~ /[\d\.]+/
|
||||
end
|
||||
|
||||
specify "does not set the X-Runtime if it is already set" do
|
||||
app = lambda { |env| [200, {'Content-Type' => 'text/plain', "X-Runtime" => "foobar"}, "Hello, World!"] }
|
||||
response = Rack::Runtime.new(app).call({})
|
||||
response[1]['X-Runtime'].should == "foobar"
|
||||
end
|
||||
|
||||
specify "should allow a suffix to be set" do
|
||||
app = lambda { |env| [200, {'Content-Type' => 'text/plain'}, "Hello, World!"] }
|
||||
response = Rack::Runtime.new(app, "Test").call({})
|
||||
response[1]['X-Runtime-Test'].should =~ /[\d\.]+/
|
||||
end
|
||||
|
||||
specify "should allow multiple timers to be set" do
|
||||
app = lambda { |env| [200, {'Content-Type' => 'text/plain'}, "Hello, World!"] }
|
||||
runtime1 = Rack::Runtime.new(app, "App")
|
||||
runtime2 = Rack::Runtime.new(runtime1, "All")
|
||||
response = runtime2.call({})
|
||||
|
||||
response[1]['X-Runtime-App'].should =~ /[\d\.]+/
|
||||
response[1]['X-Runtime-All'].should =~ /[\d\.]+/
|
||||
|
||||
Float(response[1]['X-Runtime-All']).should > Float(response[1]['X-Runtime-App'])
|
||||
end
|
||||
end
|
86
vendor/plugins/rack/test/spec_rack_sendfile.rb
vendored
Normal file
86
vendor/plugins/rack/test/spec_rack_sendfile.rb
vendored
Normal file
|
@ -0,0 +1,86 @@
|
|||
require 'test/spec'
|
||||
require 'rack/mock'
|
||||
require 'rack/sendfile'
|
||||
|
||||
context "Rack::File" do
|
||||
specify "should respond to #to_path" do
|
||||
Rack::File.new(Dir.pwd).should.respond_to :to_path
|
||||
end
|
||||
end
|
||||
|
||||
context "Rack::Sendfile" do
|
||||
def sendfile_body
|
||||
res = ['Hello World']
|
||||
def res.to_path ; "/tmp/hello.txt" ; end
|
||||
res
|
||||
end
|
||||
|
||||
def simple_app(body=sendfile_body)
|
||||
lambda { |env| [200, {'Content-Type' => 'text/plain'}, body] }
|
||||
end
|
||||
|
||||
def sendfile_app(body=sendfile_body)
|
||||
Rack::Sendfile.new(simple_app(body))
|
||||
end
|
||||
|
||||
setup do
|
||||
@request = Rack::MockRequest.new(sendfile_app)
|
||||
end
|
||||
|
||||
def request(headers={})
|
||||
yield @request.get('/', headers)
|
||||
end
|
||||
|
||||
specify "does nothing when no X-Sendfile-Type header present" do
|
||||
request do |response|
|
||||
response.should.be.ok
|
||||
response.body.should.equal 'Hello World'
|
||||
response.headers.should.not.include 'X-Sendfile'
|
||||
end
|
||||
end
|
||||
|
||||
specify "sets X-Sendfile response header and discards body" do
|
||||
request 'HTTP_X_SENDFILE_TYPE' => 'X-Sendfile' do |response|
|
||||
response.should.be.ok
|
||||
response.body.should.be.empty
|
||||
response.headers['X-Sendfile'].should.equal '/tmp/hello.txt'
|
||||
end
|
||||
end
|
||||
|
||||
specify "sets X-Lighttpd-Send-File response header and discards body" do
|
||||
request 'HTTP_X_SENDFILE_TYPE' => 'X-Lighttpd-Send-File' do |response|
|
||||
response.should.be.ok
|
||||
response.body.should.be.empty
|
||||
response.headers['X-Lighttpd-Send-File'].should.equal '/tmp/hello.txt'
|
||||
end
|
||||
end
|
||||
|
||||
specify "sets X-Accel-Redirect response header and discards body" do
|
||||
headers = {
|
||||
'HTTP_X_SENDFILE_TYPE' => 'X-Accel-Redirect',
|
||||
'HTTP_X_ACCEL_MAPPING' => '/tmp/=/foo/bar/'
|
||||
}
|
||||
request headers do |response|
|
||||
response.should.be.ok
|
||||
response.body.should.be.empty
|
||||
response.headers['X-Accel-Redirect'].should.equal '/foo/bar/hello.txt'
|
||||
end
|
||||
end
|
||||
|
||||
specify 'writes to rack.error when no X-Accel-Mapping is specified' do
|
||||
request 'HTTP_X_SENDFILE_TYPE' => 'X-Accel-Redirect' do |response|
|
||||
response.should.be.ok
|
||||
response.body.should.equal 'Hello World'
|
||||
response.headers.should.not.include 'X-Accel-Redirect'
|
||||
response.errors.should.include 'X-Accel-Mapping'
|
||||
end
|
||||
end
|
||||
|
||||
specify 'does nothing when body does not respond to #to_path' do
|
||||
@request = Rack::MockRequest.new(sendfile_app(['Not a file...']))
|
||||
request 'HTTP_X_SENDFILE_TYPE' => 'X-Sendfile' do |response|
|
||||
response.body.should.equal 'Not a file...'
|
||||
response.headers.should.not.include 'X-Sendfile'
|
||||
end
|
||||
end
|
||||
end
|
|
@ -8,7 +8,7 @@ begin
|
|||
|
||||
context "Rack::Session::Memcache" do
|
||||
session_key = Rack::Session::Memcache::DEFAULT_OPTIONS[:key]
|
||||
session_match = /#{session_key}=[0-9a-fA-F]+;/
|
||||
session_match = /#{session_key}=([0-9a-fA-F]+);/
|
||||
incrementor = lambda do |env|
|
||||
env["rack.session"]["counter"] ||= 0
|
||||
env["rack.session"]["counter"] += 1
|
||||
|
@ -27,14 +27,20 @@ begin
|
|||
incrementor.call(env)
|
||||
end
|
||||
|
||||
specify "MemCache can connect to existing server" do
|
||||
test_pool = MemCache.new :namespace => 'test:rack:session'
|
||||
specify "faults on no connection" do
|
||||
if RUBY_VERSION < "1.9"
|
||||
lambda do
|
||||
Rack::Session::Memcache.new incrementor, :memcache_server => 'nosuchserver'
|
||||
end.should.raise
|
||||
else
|
||||
lambda do
|
||||
Rack::Session::Memcache.new incrementor, :memcache_server => 'nosuchserver'
|
||||
end.should.raise ArgumentError
|
||||
end
|
||||
end
|
||||
|
||||
specify "faults on no connection" do
|
||||
lambda do
|
||||
Rack::Session::Memcache.new(incrementor, :memcache_server => '')
|
||||
end.should.raise
|
||||
specify "connect to existing server" do
|
||||
test_pool = MemCache.new incrementor, :namespace => 'test:rack:session'
|
||||
end
|
||||
|
||||
specify "creates a new cookie" do
|
||||
|
@ -151,6 +157,31 @@ begin
|
|||
res3.body.should.equal '{"counter"=>4}'
|
||||
end
|
||||
|
||||
specify "deep hashes are correctly updated" do
|
||||
store = nil
|
||||
hash_check = proc do |env|
|
||||
session = env['rack.session']
|
||||
unless session.include? 'test'
|
||||
session.update :a => :b, :c => { :d => :e },
|
||||
:f => { :g => { :h => :i} }, 'test' => true
|
||||
else
|
||||
session[:f][:g][:h] = :j
|
||||
end
|
||||
[200, {}, session.inspect]
|
||||
end
|
||||
pool = Rack::Session::Memcache.new(hash_check)
|
||||
req = Rack::MockRequest.new(pool)
|
||||
|
||||
res0 = req.get("/")
|
||||
session_id = (cookie = res0["Set-Cookie"])[session_match, 1]
|
||||
ses0 = pool.pool.get(session_id, true)
|
||||
|
||||
res1 = req.get("/", "HTTP_COOKIE" => cookie)
|
||||
ses1 = pool.pool.get(session_id, true)
|
||||
|
||||
ses1.should.not.equal ses0
|
||||
end
|
||||
|
||||
# anyone know how to do this better?
|
||||
specify "multithread: should cleanly merge sessions" do
|
||||
next unless $DEBUG
|
||||
|
@ -161,7 +192,7 @@ begin
|
|||
res = req.get('/')
|
||||
res.body.should.equal '{"counter"=>1}'
|
||||
cookie = res["Set-Cookie"]
|
||||
sess_id = cookie[/#{pool.key}=([^,;]+)/,1]
|
||||
session_id = cookie[session_match, 1]
|
||||
|
||||
delta_incrementor = lambda do |env|
|
||||
# emulate disconjoinment of threading
|
||||
|
@ -178,12 +209,12 @@ begin
|
|||
run.get('/', "HTTP_COOKIE" => cookie, 'rack.multithread' => true)
|
||||
end
|
||||
end.reverse.map{|t| t.run.join.value }
|
||||
r.each do |res|
|
||||
res['Set-Cookie'].should.equal cookie
|
||||
res.body.should.include '"counter"=>2'
|
||||
r.each do |request|
|
||||
request['Set-Cookie'].should.equal cookie
|
||||
request.body.should.include '"counter"=>2'
|
||||
end
|
||||
|
||||
session = pool.pool.get(sess_id)
|
||||
session = pool.pool.get(session_id)
|
||||
session.size.should.be tnum+1 # counter
|
||||
session['counter'].should.be 2 # meeeh
|
||||
|
||||
|
@ -202,12 +233,12 @@ begin
|
|||
run.get('/', "HTTP_COOKIE" => cookie, 'rack.multithread' => true)
|
||||
end
|
||||
end.reverse.map{|t| t.run.join.value }
|
||||
r.each do |res|
|
||||
res['Set-Cookie'].should.equal cookie
|
||||
res.body.should.include '"counter"=>3'
|
||||
r.each do |request|
|
||||
request['Set-Cookie'].should.equal cookie
|
||||
request.body.should.include '"counter"=>3'
|
||||
end
|
||||
|
||||
session = pool.pool.get(sess_id)
|
||||
session = pool.pool.get(session_id)
|
||||
session.size.should.be tnum+1
|
||||
session['counter'].should.be 3
|
||||
|
||||
|
@ -224,17 +255,19 @@ begin
|
|||
run.get('/', "HTTP_COOKIE" => cookie, 'rack.multithread' => true)
|
||||
end
|
||||
end.reverse.map{|t| t.run.join.value }
|
||||
r.each do |res|
|
||||
res['Set-Cookie'].should.equal cookie
|
||||
res.body.should.include '"foo"=>"bar"'
|
||||
r.each do |request|
|
||||
request['Set-Cookie'].should.equal cookie
|
||||
request.body.should.include '"foo"=>"bar"'
|
||||
end
|
||||
|
||||
session = pool.pool.get(sess_id)
|
||||
session = pool.pool.get(session_id)
|
||||
session.size.should.be r.size+1
|
||||
session['counter'].should.be.nil?
|
||||
session['foo'].should.equal 'bar'
|
||||
end
|
||||
end
|
||||
rescue RuntimeError
|
||||
$stderr.puts "Skipping Rack::Session::Memcache tests. Start memcached and try again."
|
||||
rescue LoadError
|
||||
$stderr.puts "Skipping Rack::Session::Memcache tests (Memcache is required). `gem install memcache-client` and try again."
|
||||
end
|
||||
|
|
30
vendor/plugins/rack/test/spec_rack_urlmap.rb
vendored
30
vendor/plugins/rack/test/spec_rack_urlmap.rb
vendored
|
@ -44,6 +44,12 @@ context "Rack::URLMap" do
|
|||
res["X-ScriptName"].should.equal "/foo/bar"
|
||||
res["X-PathInfo"].should.equal "/"
|
||||
|
||||
res = Rack::MockRequest.new(map).get("/foo///bar//quux")
|
||||
res.status.should.equal 200
|
||||
res.should.be.ok
|
||||
res["X-ScriptName"].should.equal "/foo/bar"
|
||||
res["X-PathInfo"].should.equal "//quux"
|
||||
|
||||
res = Rack::MockRequest.new(map).get("/foo/quux", "SCRIPT_NAME" => "/bleh")
|
||||
res.should.be.ok
|
||||
res["X-ScriptName"].should.equal "/bleh/foo"
|
||||
|
@ -182,4 +188,28 @@ context "Rack::URLMap" do
|
|||
res["X-PathInfo"].should.equal "/"
|
||||
res["X-ScriptName"].should.equal ""
|
||||
end
|
||||
|
||||
specify "should not squeeze slashes" do
|
||||
map = Rack::URLMap.new("/" => lambda { |env|
|
||||
[200,
|
||||
{ "Content-Type" => "text/plain",
|
||||
"X-Position" => "root",
|
||||
"X-PathInfo" => env["PATH_INFO"],
|
||||
"X-ScriptName" => env["SCRIPT_NAME"]
|
||||
}, [""]]},
|
||||
"/foo" => lambda { |env|
|
||||
[200,
|
||||
{ "Content-Type" => "text/plain",
|
||||
"X-Position" => "foo",
|
||||
"X-PathInfo" => env["PATH_INFO"],
|
||||
"X-ScriptName" => env["SCRIPT_NAME"]
|
||||
}, [""]]}
|
||||
)
|
||||
|
||||
res = Rack::MockRequest.new(map).get("/http://example.org/bar")
|
||||
res.should.be.ok
|
||||
res["X-Position"].should.equal "root"
|
||||
res["X-PathInfo"].should.equal "/http://example.org/bar"
|
||||
res["X-ScriptName"].should.equal ""
|
||||
end
|
||||
end
|
||||
|
|
177
vendor/plugins/rack/test/spec_rack_utils.rb
vendored
177
vendor/plugins/rack/test/spec_rack_utils.rb
vendored
|
@ -30,7 +30,10 @@ context "Rack::Utils" do
|
|||
end
|
||||
|
||||
specify "should parse query strings correctly" do
|
||||
Rack::Utils.parse_query("foo=bar").should.equal "foo" => "bar"
|
||||
Rack::Utils.parse_query("foo=bar").
|
||||
should.equal "foo" => "bar"
|
||||
Rack::Utils.parse_query("foo=\"bar\"").
|
||||
should.equal "foo" => "bar"
|
||||
Rack::Utils.parse_query("foo=bar&foo=quux").
|
||||
should.equal "foo" => ["bar", "quux"]
|
||||
Rack::Utils.parse_query("foo=1&bar=2").
|
||||
|
@ -47,6 +50,8 @@ context "Rack::Utils" do
|
|||
should.equal "foo" => ""
|
||||
Rack::Utils.parse_nested_query("foo=bar").
|
||||
should.equal "foo" => "bar"
|
||||
Rack::Utils.parse_nested_query("foo=\"bar\"").
|
||||
should.equal "foo" => "bar"
|
||||
|
||||
Rack::Utils.parse_nested_query("foo=bar&foo=quux").
|
||||
should.equal "foo" => "quux"
|
||||
|
@ -126,6 +131,53 @@ context "Rack::Utils" do
|
|||
should.equal "my+weird+field=q1%212%22%27w%245%267%2Fz8%29%3F"
|
||||
end
|
||||
|
||||
specify "should build nested query strings correctly" do
|
||||
Rack::Utils.build_nested_query("foo" => nil).should.equal "foo"
|
||||
Rack::Utils.build_nested_query("foo" => "").should.equal "foo="
|
||||
Rack::Utils.build_nested_query("foo" => "bar").should.equal "foo=bar"
|
||||
|
||||
Rack::Utils.build_nested_query("foo" => "1", "bar" => "2").
|
||||
should.equal "foo=1&bar=2"
|
||||
Rack::Utils.build_nested_query("my weird field" => "q1!2\"'w$5&7/z8)?").
|
||||
should.equal "my+weird+field=q1%212%22%27w%245%267%2Fz8%29%3F"
|
||||
|
||||
Rack::Utils.build_nested_query("foo" => [nil]).
|
||||
should.equal "foo[]"
|
||||
Rack::Utils.build_nested_query("foo" => [""]).
|
||||
should.equal "foo[]="
|
||||
Rack::Utils.build_nested_query("foo" => ["bar"]).
|
||||
should.equal "foo[]=bar"
|
||||
|
||||
# The ordering of the output query string is unpredictable with 1.8's
|
||||
# unordered hash. Test that build_nested_query performs the inverse
|
||||
# function of parse_nested_query.
|
||||
[{"foo" => nil, "bar" => ""},
|
||||
{"foo" => "bar", "baz" => ""},
|
||||
{"foo" => ["1", "2"]},
|
||||
{"foo" => "bar", "baz" => ["1", "2", "3"]},
|
||||
{"foo" => ["bar"], "baz" => ["1", "2", "3"]},
|
||||
{"foo" => ["1", "2"]},
|
||||
{"foo" => "bar", "baz" => ["1", "2", "3"]},
|
||||
{"x" => {"y" => {"z" => "1"}}},
|
||||
{"x" => {"y" => {"z" => ["1"]}}},
|
||||
{"x" => {"y" => {"z" => ["1", "2"]}}},
|
||||
{"x" => {"y" => [{"z" => "1"}]}},
|
||||
{"x" => {"y" => [{"z" => ["1"]}]}},
|
||||
{"x" => {"y" => [{"z" => "1", "w" => "2"}]}},
|
||||
{"x" => {"y" => [{"v" => {"w" => "1"}}]}},
|
||||
{"x" => {"y" => [{"z" => "1", "v" => {"w" => "2"}}]}},
|
||||
{"x" => {"y" => [{"z" => "1"}, {"z" => "2"}]}},
|
||||
{"x" => {"y" => [{"z" => "1", "w" => "a"}, {"z" => "2", "w" => "3"}]}}
|
||||
].each { |params|
|
||||
qs = Rack::Utils.build_nested_query(params)
|
||||
Rack::Utils.parse_nested_query(qs).should.equal params
|
||||
}
|
||||
|
||||
lambda { Rack::Utils.build_nested_query("foo=bar") }.
|
||||
should.raise(ArgumentError).
|
||||
message.should.equal "value must be a Hash"
|
||||
end
|
||||
|
||||
specify "should figure out which encodings are acceptable" do
|
||||
helper = lambda do |a, b|
|
||||
request = Rack::Request.new(Rack::MockRequest.env_for("", "HTTP_ACCEPT_ENCODING" => a))
|
||||
|
@ -152,6 +204,18 @@ context "Rack::Utils" do
|
|||
specify "should return the bytesize of String" do
|
||||
Rack::Utils.bytesize("FOO\xE2\x82\xAC").should.equal 6
|
||||
end
|
||||
|
||||
specify "should return status code for integer" do
|
||||
Rack::Utils.status_code(200).should.equal 200
|
||||
end
|
||||
|
||||
specify "should return status code for string" do
|
||||
Rack::Utils.status_code("200").should.equal 200
|
||||
end
|
||||
|
||||
specify "should return status code for symbol" do
|
||||
Rack::Utils.status_code(:ok).should.equal 200
|
||||
end
|
||||
end
|
||||
|
||||
context "Rack::Utils::HeaderHash" do
|
||||
|
@ -190,30 +254,53 @@ context "Rack::Utils::HeaderHash" do
|
|||
h = Rack::Utils::HeaderHash.new("foo" => ["bar", "baz"])
|
||||
h.to_hash.should.equal({ "foo" => "bar\nbaz" })
|
||||
end
|
||||
|
||||
|
||||
specify "should replace hashes correctly" do
|
||||
h = Rack::Utils::HeaderHash.new("Foo-Bar" => "baz")
|
||||
j = {"foo" => "bar"}
|
||||
h.replace(j)
|
||||
h["foo"].should.equal "bar"
|
||||
end
|
||||
|
||||
specify "should be able to delete the given key case-sensitively" do
|
||||
h = Rack::Utils::HeaderHash.new("foo" => "bar")
|
||||
h.delete("foo")
|
||||
h["foo"].should.be.nil
|
||||
h["FOO"].should.be.nil
|
||||
end
|
||||
|
||||
|
||||
specify "should be able to delete the given key case-insensitively" do
|
||||
h = Rack::Utils::HeaderHash.new("foo" => "bar")
|
||||
h.delete("FOO")
|
||||
h["foo"].should.be.nil
|
||||
h["FOO"].should.be.nil
|
||||
end
|
||||
|
||||
|
||||
specify "should return the deleted value when #delete is called on an existing key" do
|
||||
h = Rack::Utils::HeaderHash.new("foo" => "bar")
|
||||
h.delete("Foo").should.equal("bar")
|
||||
end
|
||||
|
||||
|
||||
specify "should return nil when #delete is called on a non-existant key" do
|
||||
h = Rack::Utils::HeaderHash.new("foo" => "bar")
|
||||
h.delete("Hello").should.be.nil
|
||||
end
|
||||
|
||||
specify "should avoid unnecessary object creation if possible" do
|
||||
a = Rack::Utils::HeaderHash.new("foo" => "bar")
|
||||
b = Rack::Utils::HeaderHash.new(a)
|
||||
b.object_id.should.equal(a.object_id)
|
||||
b.should.equal(a)
|
||||
end
|
||||
|
||||
specify "should convert Array values to Strings when responding to #each" do
|
||||
h = Rack::Utils::HeaderHash.new("foo" => ["bar", "baz"])
|
||||
h.each do |k,v|
|
||||
k.should.equal("foo")
|
||||
v.should.equal("bar\nbaz")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context "Rack::Utils::Context" do
|
||||
|
@ -372,9 +459,83 @@ context "Rack::Utils::Multipart" do
|
|||
input.read.length.should.equal 197
|
||||
end
|
||||
|
||||
specify "builds multipart body" do
|
||||
files = Rack::Utils::Multipart::UploadedFile.new(multipart_file("file1.txt"))
|
||||
data = Rack::Utils::Multipart.build_multipart("submit-name" => "Larry", "files" => files)
|
||||
|
||||
options = {
|
||||
"CONTENT_TYPE" => "multipart/form-data; boundary=AaB03x",
|
||||
"CONTENT_LENGTH" => data.length.to_s,
|
||||
:input => StringIO.new(data)
|
||||
}
|
||||
env = Rack::MockRequest.env_for("/", options)
|
||||
params = Rack::Utils::Multipart.parse_multipart(env)
|
||||
params["submit-name"].should.equal "Larry"
|
||||
params["files"][:filename].should.equal "file1.txt"
|
||||
params["files"][:tempfile].read.should.equal "contents"
|
||||
end
|
||||
|
||||
specify "builds nested multipart body" do
|
||||
files = Rack::Utils::Multipart::UploadedFile.new(multipart_file("file1.txt"))
|
||||
data = Rack::Utils::Multipart.build_multipart("people" => [{"submit-name" => "Larry", "files" => files}])
|
||||
|
||||
options = {
|
||||
"CONTENT_TYPE" => "multipart/form-data; boundary=AaB03x",
|
||||
"CONTENT_LENGTH" => data.length.to_s,
|
||||
:input => StringIO.new(data)
|
||||
}
|
||||
env = Rack::MockRequest.env_for("/", options)
|
||||
params = Rack::Utils::Multipart.parse_multipart(env)
|
||||
params["people"][0]["submit-name"].should.equal "Larry"
|
||||
params["people"][0]["files"][:filename].should.equal "file1.txt"
|
||||
params["people"][0]["files"][:tempfile].read.should.equal "contents"
|
||||
end
|
||||
|
||||
specify "can parse fields that end at the end of the buffer" do
|
||||
input = File.read(multipart_file("bad_robots"))
|
||||
|
||||
req = Rack::Request.new Rack::MockRequest.env_for("/",
|
||||
"CONTENT_TYPE" => "multipart/form-data, boundary=1yy3laWhgX31qpiHinh67wJXqKalukEUTvqTzmon",
|
||||
"CONTENT_LENGTH" => input.size,
|
||||
:input => input)
|
||||
|
||||
req.POST['file.path'].should.equal "/var/tmp/uploads/4/0001728414"
|
||||
req.POST['addresses'].should.not.equal nil
|
||||
end
|
||||
|
||||
specify "builds complete params with the chunk size of 16384 slicing exactly on boundary" do
|
||||
data = File.open(multipart_file("fail_16384_nofile")) { |f| f.read }.gsub(/\n/, "\r\n")
|
||||
options = {
|
||||
"CONTENT_TYPE" => "multipart/form-data; boundary=----WebKitFormBoundaryWsY0GnpbI5U7ztzo",
|
||||
"CONTENT_LENGTH" => data.length.to_s,
|
||||
:input => StringIO.new(data)
|
||||
}
|
||||
env = Rack::MockRequest.env_for("/", options)
|
||||
params = Rack::Utils::Multipart.parse_multipart(env)
|
||||
|
||||
params.should.not.equal nil
|
||||
params.keys.should.include "AAAAAAAAAAAAAAAAAAA"
|
||||
params["AAAAAAAAAAAAAAAAAAA"].keys.should.include "PLAPLAPLA_MEMMEMMEMM_ATTRATTRER"
|
||||
params["AAAAAAAAAAAAAAAAAAA"]["PLAPLAPLA_MEMMEMMEMM_ATTRATTRER"].keys.should.include "new"
|
||||
params["AAAAAAAAAAAAAAAAAAA"]["PLAPLAPLA_MEMMEMMEMM_ATTRATTRER"]["new"].keys.should.include "-2"
|
||||
params["AAAAAAAAAAAAAAAAAAA"]["PLAPLAPLA_MEMMEMMEMM_ATTRATTRER"]["new"]["-2"].keys.should.include "ba_unit_id"
|
||||
params["AAAAAAAAAAAAAAAAAAA"]["PLAPLAPLA_MEMMEMMEMM_ATTRATTRER"]["new"]["-2"]["ba_unit_id"].should.equal "1017"
|
||||
end
|
||||
|
||||
specify "should return nil if no UploadedFiles were used" do
|
||||
data = Rack::Utils::Multipart.build_multipart("people" => [{"submit-name" => "Larry", "files" => "contents"}])
|
||||
data.should.equal nil
|
||||
end
|
||||
|
||||
specify "should raise ArgumentError if params is not a Hash" do
|
||||
lambda { Rack::Utils::Multipart.build_multipart("foo=bar") }.
|
||||
should.raise(ArgumentError).
|
||||
message.should.equal "value must be a Hash"
|
||||
end
|
||||
|
||||
private
|
||||
def multipart_fixture(name)
|
||||
file = File.join(File.dirname(__FILE__), "multipart", name.to_s)
|
||||
file = multipart_file(name)
|
||||
data = File.open(file, 'rb') { |io| io.read }
|
||||
|
||||
type = "multipart/form-data; boundary=AaB03x"
|
||||
|
@ -384,4 +545,8 @@ context "Rack::Utils::Multipart" do
|
|||
"CONTENT_LENGTH" => length.to_s,
|
||||
:input => StringIO.new(data) }
|
||||
end
|
||||
|
||||
def multipart_file(name)
|
||||
File.join(File.dirname(__FILE__), "multipart", name.to_s)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -9,7 +9,7 @@ Thread.abort_on_exception = true
|
|||
|
||||
context "Rack::Handler::WEBrick" do
|
||||
include TestRequest::Helpers
|
||||
|
||||
|
||||
setup do
|
||||
@server = WEBrick::HTTPServer.new(:Host => @host='0.0.0.0',
|
||||
:Port => @port=9202,
|
||||
|
@ -39,7 +39,7 @@ context "Rack::Handler::WEBrick" do
|
|||
|
||||
specify "should have rack headers" do
|
||||
GET("/test")
|
||||
response["rack.version"].should.equal [1,0]
|
||||
response["rack.version"].should.equal [1,1]
|
||||
response["rack.multithread"].should.be true
|
||||
response["rack.multiprocess"].should.be false
|
||||
response["rack.run_once"].should.be false
|
||||
|
@ -50,7 +50,7 @@ context "Rack::Handler::WEBrick" do
|
|||
response["REQUEST_METHOD"].should.equal "GET"
|
||||
response["SCRIPT_NAME"].should.equal "/test"
|
||||
response["REQUEST_PATH"].should.equal "/"
|
||||
response["PATH_INFO"].should.be.nil
|
||||
response["PATH_INFO"].should.be.equal ""
|
||||
response["QUERY_STRING"].should.equal ""
|
||||
response["test.postdata"].should.equal ""
|
||||
|
||||
|
@ -60,7 +60,7 @@ context "Rack::Handler::WEBrick" do
|
|||
response["REQUEST_PATH"].should.equal "/"
|
||||
response["PATH_INFO"].should.equal "/foo"
|
||||
response["QUERY_STRING"].should.equal "quux=1"
|
||||
|
||||
|
||||
GET("/test/foo%25encoding?quux=1")
|
||||
response["REQUEST_METHOD"].should.equal "GET"
|
||||
response["SCRIPT_NAME"].should.equal "/test"
|
||||
|
|
154
vendor/plugins/rack/test/spec_rackup.rb
vendored
Normal file
154
vendor/plugins/rack/test/spec_rackup.rb
vendored
Normal file
|
@ -0,0 +1,154 @@
|
|||
require 'test/spec'
|
||||
require 'testrequest'
|
||||
require 'rack/server'
|
||||
require 'open3'
|
||||
|
||||
begin
|
||||
require "mongrel"
|
||||
|
||||
context "rackup" do
|
||||
include TestRequest::Helpers
|
||||
|
||||
def run_rackup(*args)
|
||||
options = args.last.is_a?(Hash) ? args.pop : {}
|
||||
flags = args.first
|
||||
@host = options[:host] || "0.0.0.0"
|
||||
@port = options[:port] || 9292
|
||||
|
||||
Dir.chdir("#{root}/test/rackup") do
|
||||
@in, @rackup, @err = Open3.popen3("#{Gem.ruby} -S #{rackup} #{flags}")
|
||||
end
|
||||
|
||||
return if options[:port] == false
|
||||
|
||||
# Wait until the server is available
|
||||
begin
|
||||
GET("/")
|
||||
rescue
|
||||
sleep 0.05
|
||||
retry
|
||||
end
|
||||
end
|
||||
|
||||
def output
|
||||
@rackup.read
|
||||
end
|
||||
|
||||
after do
|
||||
# This doesn't actually return a response, so we rescue
|
||||
GET "/die" rescue nil
|
||||
|
||||
Dir["#{root}/**/*.pid"].each do |file|
|
||||
File.delete(file)
|
||||
end
|
||||
|
||||
File.delete("#{root}/log_output") if File.exist?("#{root}/log_output")
|
||||
end
|
||||
|
||||
specify "rackup" do
|
||||
run_rackup
|
||||
response["PATH_INFO"].should.equal '/'
|
||||
response["test.$DEBUG"].should.be false
|
||||
response["test.$EVAL"].should.be nil
|
||||
response["test.$VERBOSE"].should.be false
|
||||
response["test.Ping"].should.be nil
|
||||
response["SERVER_SOFTWARE"].should.not =~ /webrick/
|
||||
end
|
||||
|
||||
specify "rackup --help" do
|
||||
run_rackup "--help", :port => false
|
||||
output.should.match /--port/
|
||||
end
|
||||
|
||||
specify "rackup --port" do
|
||||
run_rackup "--port 9000", :port => 9000
|
||||
response["SERVER_PORT"].should.equal "9000"
|
||||
end
|
||||
|
||||
specify "rackup --debug" do
|
||||
run_rackup "--debug"
|
||||
response["test.$DEBUG"].should.be true
|
||||
end
|
||||
|
||||
specify "rackup --eval" do
|
||||
run_rackup %{--eval "BUKKIT = 'BUKKIT'"}
|
||||
response["test.$EVAL"].should.equal "BUKKIT"
|
||||
end
|
||||
|
||||
specify "rackup --warn" do
|
||||
run_rackup %{--warn}
|
||||
response["test.$VERBOSE"].should.be true
|
||||
end
|
||||
|
||||
specify "rackup --include" do
|
||||
run_rackup %{--include /foo/bar}
|
||||
response["test.$LOAD_PATH"].should.include "/foo/bar"
|
||||
end
|
||||
|
||||
specify "rackup --require" do
|
||||
run_rackup %{--require ping}
|
||||
response["test.Ping"].should.equal "constant"
|
||||
end
|
||||
|
||||
specify "rackup --server" do
|
||||
run_rackup %{--server webrick}
|
||||
response["SERVER_SOFTWARE"].should =~ /webrick/i
|
||||
end
|
||||
|
||||
specify "rackup --host" do
|
||||
run_rackup %{--host 127.0.0.1}, :host => "127.0.0.1"
|
||||
response["REMOTE_ADDR"].should.equal "127.0.0.1"
|
||||
end
|
||||
|
||||
specify "rackup --daemonize --pid" do
|
||||
run_rackup %{--daemonize --pid testing.pid}
|
||||
status.should.be 200
|
||||
@rackup.should.be.eof?
|
||||
Dir["#{root}/**/testing.pid"].should.not.be.empty?
|
||||
end
|
||||
|
||||
specify "rackup --pid" do
|
||||
run_rackup %{--pid testing.pid}
|
||||
status.should.be 200
|
||||
Dir["#{root}/**/testing.pid"].should.not.be.empty?
|
||||
end
|
||||
|
||||
specify "rackup --version" do
|
||||
run_rackup %{--version}, :port => false
|
||||
output.should =~ /1.0/
|
||||
end
|
||||
|
||||
specify "rackup --env development includes lint" do
|
||||
run_rackup
|
||||
GET("/broken_lint")
|
||||
status.should.be 500
|
||||
end
|
||||
|
||||
specify "rackup --env deployment does not include lint" do
|
||||
run_rackup %{--env deployment}
|
||||
GET("/broken_lint")
|
||||
status.should.be 200
|
||||
end
|
||||
|
||||
specify "rackup --env none does not include lint" do
|
||||
run_rackup %{--env none}
|
||||
GET("/broken_lint")
|
||||
status.should.be 200
|
||||
end
|
||||
|
||||
specify "rackup --env deployment does log" do
|
||||
run_rackup %{--env deployment}
|
||||
log = File.read(response["test.stderr"])
|
||||
log.should.be.empty?
|
||||
end
|
||||
|
||||
specify "rackup --env none does not log" do
|
||||
run_rackup %{--env none}
|
||||
GET("/")
|
||||
log = File.read(response["test.stderr"])
|
||||
log.should.be.empty?
|
||||
end
|
||||
end
|
||||
rescue LoadError
|
||||
$stderr.puts "Skipping rackup --server tests (mongrel is required). `gem install thin` and try again."
|
||||
end
|
17
vendor/plugins/rack/test/testrequest.rb
vendored
17
vendor/plugins/rack/test/testrequest.rb
vendored
|
@ -13,6 +13,17 @@ class TestRequest
|
|||
module Helpers
|
||||
attr_reader :status, :response
|
||||
|
||||
ROOT = File.expand_path(File.dirname(__FILE__) + "/..")
|
||||
ENV["RUBYOPT"] = "-I#{ROOT}/lib -rubygems"
|
||||
|
||||
def root
|
||||
ROOT
|
||||
end
|
||||
|
||||
def rackup
|
||||
"#{ROOT}/bin/rackup"
|
||||
end
|
||||
|
||||
def GET(path, header={})
|
||||
Net::HTTP.start(@host, @port) { |http|
|
||||
user = header.delete(:user)
|
||||
|
@ -22,7 +33,11 @@ class TestRequest
|
|||
get.basic_auth user, passwd if user && passwd
|
||||
http.request(get) { |response|
|
||||
@status = response.code.to_i
|
||||
@response = YAML.load(response.body)
|
||||
begin
|
||||
@response = YAML.load(response.body)
|
||||
rescue ArgumentError
|
||||
@response = nil
|
||||
end
|
||||
}
|
||||
}
|
||||
end
|
||||
|
|
|
@ -32,7 +32,7 @@ rescue LoadError
|
|||
end
|
||||
|
||||
begin
|
||||
gem 'rack', '~> 1.1.0'
|
||||
gem 'rack', '~> 1.1.1'
|
||||
require 'rack'
|
||||
rescue Gem::LoadError
|
||||
$:.unshift "#{File.dirname(__FILE__)}/../../../plugins/rack/lib"
|
||||
|
|
Loading…
Reference in a new issue