Updates
SVG-Edit -> 2.5final Vendored Rack -> 1.2.1
This commit is contained in:
parent
6338a3bcb2
commit
0d8f680d4f
82 changed files with 138 additions and 70 deletions
25
vendor/plugins/rack/test/cgi/lighttpd.conf
vendored
Executable file
25
vendor/plugins/rack/test/cgi/lighttpd.conf
vendored
Executable file
|
@ -0,0 +1,25 @@
|
|||
server.modules = ("mod_fastcgi", "mod_cgi")
|
||||
server.document-root = "."
|
||||
server.errorlog = var.CWD + "/lighttpd.errors"
|
||||
server.port = 9203
|
||||
|
||||
server.event-handler = "select"
|
||||
|
||||
cgi.assign = ("/test" => "",
|
||||
# ".ru" => ""
|
||||
)
|
||||
|
||||
fastcgi.server = (
|
||||
"test.fcgi" => ("localhost" =>
|
||||
("min-procs" => 1,
|
||||
"socket" => "/tmp/rack-test-fcgi",
|
||||
"bin-path" => "test.fcgi")),
|
||||
"test.ru" => ("localhost" =>
|
||||
("min-procs" => 1,
|
||||
"socket" => "/tmp/rack-test-ru-fcgi",
|
||||
"bin-path" => CWD + "/rackup_stub.rb test.ru")),
|
||||
"sample_rackup.ru" => ("localhost" =>
|
||||
("min-procs" => 1,
|
||||
"socket" => "/tmp/rack-test-rackup-fcgi",
|
||||
"bin-path" => CWD + "/rackup_stub.rb sample_rackup.ru")),
|
||||
)
|
6
vendor/plugins/rack/test/cgi/rackup_stub.rb
vendored
Executable file
6
vendor/plugins/rack/test/cgi/rackup_stub.rb
vendored
Executable file
|
@ -0,0 +1,6 @@
|
|||
#!/usr/bin/env ruby
|
||||
# -*- ruby -*-
|
||||
|
||||
$:.unshift '../../lib'
|
||||
require 'rack'
|
||||
Rack::Server.start
|
5
vendor/plugins/rack/test/cgi/sample_rackup.ru
vendored
Executable file
5
vendor/plugins/rack/test/cgi/sample_rackup.ru
vendored
Executable file
|
@ -0,0 +1,5 @@
|
|||
# -*- ruby -*-
|
||||
|
||||
require '../testrequest'
|
||||
|
||||
run TestRequest.new
|
9
vendor/plugins/rack/test/cgi/test
vendored
Executable file
9
vendor/plugins/rack/test/cgi/test
vendored
Executable file
|
@ -0,0 +1,9 @@
|
|||
#!/usr/bin/env ruby
|
||||
# -*- ruby -*-
|
||||
|
||||
$: << File.join(File.dirname(__FILE__), "..", "..", "lib")
|
||||
|
||||
require 'rack'
|
||||
require '../testrequest'
|
||||
|
||||
Rack::Handler::CGI.run(Rack::Lint.new(TestRequest.new))
|
8
vendor/plugins/rack/test/cgi/test.fcgi
vendored
Executable file
8
vendor/plugins/rack/test/cgi/test.fcgi
vendored
Executable file
|
@ -0,0 +1,8 @@
|
|||
#!/usr/bin/env ruby
|
||||
# -*- ruby -*-
|
||||
|
||||
$:.unshift '../../lib'
|
||||
require 'rack'
|
||||
require '../testrequest'
|
||||
|
||||
Rack::Handler::FastCGI.run(Rack::Lint.new(TestRequest.new))
|
5
vendor/plugins/rack/test/cgi/test.ru
vendored
Executable file
5
vendor/plugins/rack/test/cgi/test.ru
vendored
Executable file
|
@ -0,0 +1,5 @@
|
|||
#!../../bin/rackup
|
||||
# -*- ruby -*-
|
||||
|
||||
require '../testrequest'
|
||||
run TestRequest.new
|
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--
|
BIN
vendor/plugins/rack/test/multipart/binary
vendored
Normal file
BIN
vendor/plugins/rack/test/multipart/binary
vendored
Normal file
Binary file not shown.
10
vendor/plugins/rack/test/multipart/empty
vendored
Normal file
10
vendor/plugins/rack/test/multipart/empty
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
--AaB03x
|
||||
Content-Disposition: form-data; name="submit-name"
|
||||
|
||||
Larry
|
||||
--AaB03x
|
||||
Content-Disposition: form-data; name="files"; filename="file1.txt"
|
||||
Content-Type: text/plain
|
||||
|
||||
|
||||
--AaB03x--
|
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
|
7
vendor/plugins/rack/test/multipart/filename_and_modification_param
vendored
Normal file
7
vendor/plugins/rack/test/multipart/filename_and_modification_param
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
--AaB03x
|
||||
Content-Type: image/jpeg
|
||||
Content-Disposition: attachment; name="files"; filename=genome.jpeg; modification-date="Wed, 12 Feb 1997 16:29:51 -0500";
|
||||
Content-Description: a complete map of the human genome
|
||||
|
||||
contents
|
||||
--AaB03x--
|
6
vendor/plugins/rack/test/multipart/filename_with_escaped_quotes
vendored
Normal file
6
vendor/plugins/rack/test/multipart/filename_with_escaped_quotes
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
--AaB03x
|
||||
Content-Disposition: form-data; name="files"; filename="escape \"quotes"
|
||||
Content-Type: application/octet-stream
|
||||
|
||||
contents
|
||||
--AaB03x--
|
7
vendor/plugins/rack/test/multipart/filename_with_escaped_quotes_and_modification_param
vendored
Normal file
7
vendor/plugins/rack/test/multipart/filename_with_escaped_quotes_and_modification_param
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
--AaB03x
|
||||
Content-Type: image/jpeg
|
||||
Content-Disposition: attachment; name="files"; filename=""human" genome.jpeg"; modification-date="Wed, 12 Feb 1997 16:29:51 -0500";
|
||||
Content-Description: a complete map of the human genome
|
||||
|
||||
contents
|
||||
--AaB03x--
|
6
vendor/plugins/rack/test/multipart/filename_with_percent_escaped_quotes
vendored
Normal file
6
vendor/plugins/rack/test/multipart/filename_with_percent_escaped_quotes
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
--AaB03x
|
||||
Content-Disposition: form-data; name="files"; filename="escape %22quotes"
|
||||
Content-Type: application/octet-stream
|
||||
|
||||
contents
|
||||
--AaB03x--
|
6
vendor/plugins/rack/test/multipart/filename_with_unescaped_quotes
vendored
Normal file
6
vendor/plugins/rack/test/multipart/filename_with_unescaped_quotes
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
--AaB03x
|
||||
Content-Disposition: form-data; name="files"; filename="escape "quotes"
|
||||
Content-Type: application/octet-stream
|
||||
|
||||
contents
|
||||
--AaB03x--
|
6
vendor/plugins/rack/test/multipart/ie
vendored
Normal file
6
vendor/plugins/rack/test/multipart/ie
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
--AaB03x
|
||||
Content-Disposition: form-data; name="files"; filename="C:\Documents and Settings\Administrator\Desktop\file1.txt"
|
||||
Content-Type: text/plain
|
||||
|
||||
contents
|
||||
--AaB03x--
|
10
vendor/plugins/rack/test/multipart/nested
vendored
Normal file
10
vendor/plugins/rack/test/multipart/nested
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
--AaB03x
|
||||
Content-Disposition: form-data; name="foo[submit-name]"
|
||||
|
||||
Larry
|
||||
--AaB03x
|
||||
Content-Disposition: form-data; name="foo[files]"; filename="file1.txt"
|
||||
Content-Type: text/plain
|
||||
|
||||
contents
|
||||
--AaB03x--
|
9
vendor/plugins/rack/test/multipart/none
vendored
Normal file
9
vendor/plugins/rack/test/multipart/none
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
--AaB03x
|
||||
Content-Disposition: form-data; name="submit-name"
|
||||
|
||||
Larry
|
||||
--AaB03x
|
||||
Content-Disposition: form-data; name="files"; filename=""
|
||||
|
||||
|
||||
--AaB03x--
|
6
vendor/plugins/rack/test/multipart/semicolon
vendored
Normal file
6
vendor/plugins/rack/test/multipart/semicolon
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
--AaB03x
|
||||
Content-Disposition: form-data; name="files"; filename="fi;le1.txt"
|
||||
Content-Type: text/plain
|
||||
|
||||
contents
|
||||
--AaB03x--
|
10
vendor/plugins/rack/test/multipart/text
vendored
Normal file
10
vendor/plugins/rack/test/multipart/text
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
--AaB03x
|
||||
Content-Disposition: form-data; name="submit-name"
|
||||
|
||||
Larry
|
||||
--AaB03x
|
||||
Content-Disposition: form-data; name="files"; filename="file1.txt"
|
||||
Content-Type: text/plain
|
||||
|
||||
contents
|
||||
--AaB03x--
|
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
|
70
vendor/plugins/rack/test/spec_auth_basic.rb
vendored
Normal file
70
vendor/plugins/rack/test/spec_auth_basic.rb
vendored
Normal file
|
@ -0,0 +1,70 @@
|
|||
require 'rack/auth/basic'
|
||||
require 'rack/mock'
|
||||
|
||||
describe Rack::Auth::Basic do
|
||||
def realm
|
||||
'WallysWorld'
|
||||
end
|
||||
|
||||
def unprotected_app
|
||||
lambda { |env| [ 200, {'Content-Type' => 'text/plain'}, ["Hi #{env['REMOTE_USER']}"] ] }
|
||||
end
|
||||
|
||||
def protected_app
|
||||
app = Rack::Auth::Basic.new(unprotected_app) { |username, password| 'Boss' == username }
|
||||
app.realm = realm
|
||||
app
|
||||
end
|
||||
|
||||
before do
|
||||
@request = Rack::MockRequest.new(protected_app)
|
||||
end
|
||||
|
||||
def request_with_basic_auth(username, password, &block)
|
||||
request 'HTTP_AUTHORIZATION' => 'Basic ' + ["#{username}:#{password}"].pack("m*"), &block
|
||||
end
|
||||
|
||||
def request(headers = {})
|
||||
yield @request.get('/', headers)
|
||||
end
|
||||
|
||||
def assert_basic_auth_challenge(response)
|
||||
response.should.be.a.client_error
|
||||
response.status.should.equal 401
|
||||
response.should.include 'WWW-Authenticate'
|
||||
response.headers['WWW-Authenticate'].should =~ /Basic realm="#{Regexp.escape(realm)}"/
|
||||
response.body.should.be.empty
|
||||
end
|
||||
|
||||
should 'challenge correctly when no credentials are specified' do
|
||||
request do |response|
|
||||
assert_basic_auth_challenge response
|
||||
end
|
||||
end
|
||||
|
||||
should 'rechallenge if incorrect credentials are specified' do
|
||||
request_with_basic_auth 'joe', 'password' do |response|
|
||||
assert_basic_auth_challenge response
|
||||
end
|
||||
end
|
||||
|
||||
should 'return application output if correct credentials are specified' do
|
||||
request_with_basic_auth 'Boss', 'password' do |response|
|
||||
response.status.should.equal 200
|
||||
response.body.to_s.should.equal 'Hi Boss'
|
||||
end
|
||||
end
|
||||
|
||||
should 'return 400 Bad Request if different auth scheme used' do
|
||||
request 'HTTP_AUTHORIZATION' => 'Digest params' do |response|
|
||||
response.should.be.a.client_error
|
||||
response.status.should.equal 400
|
||||
response.should.not.include 'WWW-Authenticate'
|
||||
end
|
||||
end
|
||||
|
||||
it 'takes realm as optional constructor arg' do
|
||||
app = Rack::Auth::Basic.new(unprotected_app, realm) { true }
|
||||
realm.should == app.realm
|
||||
end
|
||||
end
|
223
vendor/plugins/rack/test/spec_auth_digest.rb
vendored
Normal file
223
vendor/plugins/rack/test/spec_auth_digest.rb
vendored
Normal file
|
@ -0,0 +1,223 @@
|
|||
require 'rack/auth/digest/md5'
|
||||
require 'rack/mock'
|
||||
|
||||
describe Rack::Auth::Digest::MD5 do
|
||||
def realm
|
||||
'WallysWorld'
|
||||
end
|
||||
|
||||
def unprotected_app
|
||||
lambda do |env|
|
||||
[ 200, {'Content-Type' => 'text/plain'}, ["Hi #{env['REMOTE_USER']}"] ]
|
||||
end
|
||||
end
|
||||
|
||||
def protected_app
|
||||
app = Rack::Auth::Digest::MD5.new(unprotected_app) do |username|
|
||||
{ 'Alice' => 'correct-password' }[username]
|
||||
end
|
||||
app.realm = realm
|
||||
app.opaque = 'this-should-be-secret'
|
||||
app
|
||||
end
|
||||
|
||||
def protected_app_with_hashed_passwords
|
||||
app = Rack::Auth::Digest::MD5.new(unprotected_app) do |username|
|
||||
username == 'Alice' ? Digest::MD5.hexdigest("Alice:#{realm}:correct-password") : nil
|
||||
end
|
||||
app.realm = realm
|
||||
app.opaque = 'this-should-be-secret'
|
||||
app.passwords_hashed = true
|
||||
app
|
||||
end
|
||||
|
||||
def partially_protected_app
|
||||
Rack::URLMap.new({
|
||||
'/' => unprotected_app,
|
||||
'/protected' => protected_app
|
||||
})
|
||||
end
|
||||
|
||||
def protected_app_with_method_override
|
||||
Rack::MethodOverride.new(protected_app)
|
||||
end
|
||||
|
||||
before do
|
||||
@request = Rack::MockRequest.new(protected_app)
|
||||
end
|
||||
|
||||
def request(method, path, headers = {}, &block)
|
||||
response = @request.request(method, path, headers)
|
||||
block.call(response) if block
|
||||
return response
|
||||
end
|
||||
|
||||
class MockDigestRequest
|
||||
def initialize(params)
|
||||
@params = params
|
||||
end
|
||||
def method_missing(sym)
|
||||
if @params.has_key? k = sym.to_s
|
||||
return @params[k]
|
||||
end
|
||||
super
|
||||
end
|
||||
def method
|
||||
@params['method']
|
||||
end
|
||||
def response(password)
|
||||
Rack::Auth::Digest::MD5.new(nil).send :digest, self, password
|
||||
end
|
||||
end
|
||||
|
||||
def request_with_digest_auth(method, path, username, password, options = {}, &block)
|
||||
request_options = {}
|
||||
request_options[:input] = options.delete(:input) if options.include? :input
|
||||
|
||||
response = request(method, path, request_options)
|
||||
|
||||
return response unless response.status == 401
|
||||
|
||||
if wait = options.delete(:wait)
|
||||
sleep wait
|
||||
end
|
||||
|
||||
challenge = response['WWW-Authenticate'].split(' ', 2).last
|
||||
|
||||
params = Rack::Auth::Digest::Params.parse(challenge)
|
||||
|
||||
params['username'] = username
|
||||
params['nc'] = '00000001'
|
||||
params['cnonce'] = 'nonsensenonce'
|
||||
params['uri'] = path
|
||||
|
||||
params['method'] = method
|
||||
|
||||
params.update options
|
||||
|
||||
params['response'] = MockDigestRequest.new(params).response(password)
|
||||
|
||||
request(method, path, request_options.merge('HTTP_AUTHORIZATION' => "Digest #{params}"), &block)
|
||||
end
|
||||
|
||||
def assert_digest_auth_challenge(response)
|
||||
response.should.be.a.client_error
|
||||
response.status.should.equal 401
|
||||
response.should.include 'WWW-Authenticate'
|
||||
response.headers['WWW-Authenticate'].should =~ /^Digest /
|
||||
response.body.should.be.empty
|
||||
end
|
||||
|
||||
def assert_bad_request(response)
|
||||
response.should.be.a.client_error
|
||||
response.status.should.equal 400
|
||||
response.should.not.include 'WWW-Authenticate'
|
||||
end
|
||||
|
||||
should 'challenge when no credentials are specified' do
|
||||
request 'GET', '/' do |response|
|
||||
assert_digest_auth_challenge response
|
||||
end
|
||||
end
|
||||
|
||||
should 'return application output if correct credentials given' do
|
||||
request_with_digest_auth 'GET', '/', 'Alice', 'correct-password' do |response|
|
||||
response.status.should.equal 200
|
||||
response.body.to_s.should.equal 'Hi Alice'
|
||||
end
|
||||
end
|
||||
|
||||
should 'return application output if correct credentials given (hashed passwords)' do
|
||||
@request = Rack::MockRequest.new(protected_app_with_hashed_passwords)
|
||||
|
||||
request_with_digest_auth 'GET', '/', 'Alice', 'correct-password' do |response|
|
||||
response.status.should.equal 200
|
||||
response.body.to_s.should.equal 'Hi Alice'
|
||||
end
|
||||
end
|
||||
|
||||
should 'rechallenge if incorrect username given' do
|
||||
request_with_digest_auth 'GET', '/', 'Bob', 'correct-password' do |response|
|
||||
assert_digest_auth_challenge response
|
||||
end
|
||||
end
|
||||
|
||||
should 'rechallenge if incorrect password given' do
|
||||
request_with_digest_auth 'GET', '/', 'Alice', 'wrong-password' do |response|
|
||||
assert_digest_auth_challenge response
|
||||
end
|
||||
end
|
||||
|
||||
should 'rechallenge with stale parameter if nonce is stale' do
|
||||
begin
|
||||
Rack::Auth::Digest::Nonce.time_limit = 1
|
||||
|
||||
request_with_digest_auth 'GET', '/', 'Alice', 'correct-password', :wait => 2 do |response|
|
||||
assert_digest_auth_challenge response
|
||||
response.headers['WWW-Authenticate'].should =~ /\bstale=true\b/
|
||||
end
|
||||
ensure
|
||||
Rack::Auth::Digest::Nonce.time_limit = nil
|
||||
end
|
||||
end
|
||||
|
||||
should 'return 400 Bad Request if incorrect qop given' do
|
||||
request_with_digest_auth 'GET', '/', 'Alice', 'correct-password', 'qop' => 'auth-int' do |response|
|
||||
assert_bad_request response
|
||||
end
|
||||
end
|
||||
|
||||
should 'return 400 Bad Request if incorrect uri given' do
|
||||
request_with_digest_auth 'GET', '/', 'Alice', 'correct-password', 'uri' => '/foo' do |response|
|
||||
assert_bad_request response
|
||||
end
|
||||
end
|
||||
|
||||
should 'return 400 Bad Request if different auth scheme used' do
|
||||
request 'GET', '/', 'HTTP_AUTHORIZATION' => 'Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==' do |response|
|
||||
assert_bad_request response
|
||||
end
|
||||
end
|
||||
|
||||
should 'not require credentials for unprotected path' do
|
||||
@request = Rack::MockRequest.new(partially_protected_app)
|
||||
request 'GET', '/' do |response|
|
||||
response.should.be.ok
|
||||
end
|
||||
end
|
||||
|
||||
should 'challenge when no credentials are specified for protected path' do
|
||||
@request = Rack::MockRequest.new(partially_protected_app)
|
||||
request 'GET', '/protected' do |response|
|
||||
assert_digest_auth_challenge response
|
||||
end
|
||||
end
|
||||
|
||||
should 'return application output if correct credentials given for protected path' do
|
||||
@request = Rack::MockRequest.new(partially_protected_app)
|
||||
request_with_digest_auth 'GET', '/protected', 'Alice', 'correct-password' do |response|
|
||||
response.status.should.equal 200
|
||||
response.body.to_s.should.equal 'Hi Alice'
|
||||
end
|
||||
end
|
||||
|
||||
should 'return application output if correct credentials given for POST' do
|
||||
request_with_digest_auth 'POST', '/', 'Alice', 'correct-password' do |response|
|
||||
response.status.should.equal 200
|
||||
response.body.to_s.should.equal 'Hi Alice'
|
||||
end
|
||||
end
|
||||
|
||||
should 'return application output if correct credentials given for PUT (using method override of POST)' do
|
||||
@request = Rack::MockRequest.new(protected_app_with_method_override)
|
||||
request_with_digest_auth 'POST', '/', 'Alice', 'correct-password', :input => "_method=put" do |response|
|
||||
response.status.should.equal 200
|
||||
response.body.to_s.should.equal 'Hi Alice'
|
||||
end
|
||||
end
|
||||
|
||||
it 'takes realm as optional constructor arg' do
|
||||
app = Rack::Auth::Digest::MD5.new(unprotected_app, realm) { true }
|
||||
realm.should == app.realm
|
||||
end
|
||||
end
|
123
vendor/plugins/rack/test/spec_builder.rb
vendored
Normal file
123
vendor/plugins/rack/test/spec_builder.rb
vendored
Normal file
|
@ -0,0 +1,123 @@
|
|||
require 'rack/builder'
|
||||
require 'rack/mock'
|
||||
require 'rack/showexceptions'
|
||||
require 'rack/urlmap'
|
||||
|
||||
class NothingMiddleware
|
||||
def initialize(app)
|
||||
@app = app
|
||||
end
|
||||
def call(env)
|
||||
@@env = env
|
||||
response = @app.call(env)
|
||||
response
|
||||
end
|
||||
def self.env
|
||||
@@env
|
||||
end
|
||||
end
|
||||
|
||||
describe Rack::Builder do
|
||||
it "supports mapping" do
|
||||
app = Rack::Builder.new do
|
||||
map '/' do |outer_env|
|
||||
run lambda { |inner_env| [200, {}, ['root']] }
|
||||
end
|
||||
map '/sub' do
|
||||
run lambda { |inner_env| [200, {}, ['sub']] }
|
||||
end
|
||||
end.to_app
|
||||
Rack::MockRequest.new(app).get("/").body.to_s.should.equal 'root'
|
||||
Rack::MockRequest.new(app).get("/sub").body.to_s.should.equal 'sub'
|
||||
end
|
||||
|
||||
it "doesn't dupe env even when mapping" do
|
||||
app = Rack::Builder.new do
|
||||
use NothingMiddleware
|
||||
map '/' do |outer_env|
|
||||
run lambda { |inner_env|
|
||||
inner_env['new_key'] = 'new_value'
|
||||
[200, {}, ['root']]
|
||||
}
|
||||
end
|
||||
end.to_app
|
||||
Rack::MockRequest.new(app).get("/").body.to_s.should.equal 'root'
|
||||
NothingMiddleware.env['new_key'].should.equal 'new_value'
|
||||
end
|
||||
|
||||
it "chains apps by default" do
|
||||
app = Rack::Builder.new do
|
||||
use Rack::ShowExceptions
|
||||
run lambda { |env| raise "bzzzt" }
|
||||
end.to_app
|
||||
|
||||
Rack::MockRequest.new(app).get("/").should.be.server_error
|
||||
Rack::MockRequest.new(app).get("/").should.be.server_error
|
||||
Rack::MockRequest.new(app).get("/").should.be.server_error
|
||||
end
|
||||
|
||||
it "has implicit #to_app" do
|
||||
app = Rack::Builder.new do
|
||||
use Rack::ShowExceptions
|
||||
run lambda { |env| raise "bzzzt" }
|
||||
end
|
||||
|
||||
Rack::MockRequest.new(app).get("/").should.be.server_error
|
||||
Rack::MockRequest.new(app).get("/").should.be.server_error
|
||||
Rack::MockRequest.new(app).get("/").should.be.server_error
|
||||
end
|
||||
|
||||
it "supports blocks on use" do
|
||||
app = Rack::Builder.new do
|
||||
use Rack::ShowExceptions
|
||||
use Rack::Auth::Basic do |username, password|
|
||||
'secret' == password
|
||||
end
|
||||
|
||||
run lambda { |env| [200, {}, ['Hi Boss']] }
|
||||
end
|
||||
|
||||
response = Rack::MockRequest.new(app).get("/")
|
||||
response.should.be.client_error
|
||||
response.status.should.equal 401
|
||||
|
||||
# with auth...
|
||||
response = Rack::MockRequest.new(app).get("/",
|
||||
'HTTP_AUTHORIZATION' => 'Basic ' + ["joe:secret"].pack("m*"))
|
||||
response.status.should.equal 200
|
||||
response.body.to_s.should.equal 'Hi Boss'
|
||||
end
|
||||
|
||||
it "has explicit #to_app" do
|
||||
app = Rack::Builder.app do
|
||||
use Rack::ShowExceptions
|
||||
run lambda { |env| raise "bzzzt" }
|
||||
end
|
||||
|
||||
Rack::MockRequest.new(app).get("/").should.be.server_error
|
||||
Rack::MockRequest.new(app).get("/").should.be.server_error
|
||||
Rack::MockRequest.new(app).get("/").should.be.server_error
|
||||
end
|
||||
|
||||
should "initialize apps once" do
|
||||
app = Rack::Builder.new do
|
||||
class AppClass
|
||||
def initialize
|
||||
@called = 0
|
||||
end
|
||||
def call(env)
|
||||
raise "bzzzt" if @called > 0
|
||||
@called += 1
|
||||
[200, {'Content-Type' => 'text/plain'}, ['OK']]
|
||||
end
|
||||
end
|
||||
|
||||
use Rack::ShowExceptions
|
||||
run AppClass.new
|
||||
end
|
||||
|
||||
Rack::MockRequest.new(app).get("/").status.should.equal 200
|
||||
Rack::MockRequest.new(app).get("/").should.be.server_error
|
||||
end
|
||||
|
||||
end
|
45
vendor/plugins/rack/test/spec_cascade.rb
vendored
Normal file
45
vendor/plugins/rack/test/spec_cascade.rb
vendored
Normal file
|
@ -0,0 +1,45 @@
|
|||
require 'rack/cascade'
|
||||
require 'rack/file'
|
||||
require 'rack/urlmap'
|
||||
require 'rack/mock'
|
||||
|
||||
describe Rack::Cascade do
|
||||
docroot = File.expand_path(File.dirname(__FILE__))
|
||||
app1 = Rack::File.new(docroot)
|
||||
|
||||
app2 = Rack::URLMap.new("/crash" => lambda { |env| raise "boom" })
|
||||
|
||||
app3 = Rack::URLMap.new("/foo" => lambda { |env|
|
||||
[200, { "Content-Type" => "text/plain"}, [""]]})
|
||||
|
||||
should "dispatch onward on 404 by default" do
|
||||
cascade = Rack::Cascade.new([app1, app2, app3])
|
||||
Rack::MockRequest.new(cascade).get("/cgi/test").should.be.ok
|
||||
Rack::MockRequest.new(cascade).get("/foo").should.be.ok
|
||||
Rack::MockRequest.new(cascade).get("/toobad").should.be.not_found
|
||||
Rack::MockRequest.new(cascade).get("/cgi/../bla").should.be.forbidden
|
||||
end
|
||||
|
||||
should "dispatch onward on whatever is passed" do
|
||||
cascade = Rack::Cascade.new([app1, app2, app3], [404, 403])
|
||||
Rack::MockRequest.new(cascade).get("/cgi/../bla").should.be.not_found
|
||||
end
|
||||
|
||||
should "return 404 if empty" do
|
||||
Rack::MockRequest.new(Rack::Cascade.new([])).get('/').should.be.not_found
|
||||
end
|
||||
|
||||
should "append new app" do
|
||||
cascade = Rack::Cascade.new([], [404, 403])
|
||||
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
|
||||
cascade << app1
|
||||
Rack::MockRequest.new(cascade).get('/cgi/test').should.be.ok
|
||||
Rack::MockRequest.new(cascade).get('/cgi/../bla').should.be.forbidden
|
||||
Rack::MockRequest.new(cascade).get('/foo').should.be.not_found
|
||||
cascade << app3
|
||||
Rack::MockRequest.new(cascade).get('/foo').should.be.ok
|
||||
end
|
||||
end
|
100
vendor/plugins/rack/test/spec_cgi.rb
vendored
Normal file
100
vendor/plugins/rack/test/spec_cgi.rb
vendored
Normal file
|
@ -0,0 +1,100 @@
|
|||
begin
|
||||
require File.expand_path('../testrequest', __FILE__)
|
||||
require 'rack/handler/cgi'
|
||||
|
||||
describe Rack::Handler::CGI do
|
||||
extend TestRequest::Helpers
|
||||
|
||||
@host = '0.0.0.0'
|
||||
@port = 9203
|
||||
|
||||
if `which lighttpd` && !$?.success?
|
||||
raise "lighttpd not found"
|
||||
end
|
||||
|
||||
# Keep this first.
|
||||
$pid = fork {
|
||||
ENV['RACK_ENV'] = 'deployment'
|
||||
ENV['RUBYLIB'] = [
|
||||
File.expand_path('../../lib', __FILE__),
|
||||
ENV['RUBYLIB'],
|
||||
].compact.join(':')
|
||||
|
||||
Dir.chdir(File.expand_path("../cgi", __FILE__)) do
|
||||
exec "lighttpd -D -f lighttpd.conf"
|
||||
end
|
||||
}
|
||||
|
||||
should "respond" do
|
||||
sleep 1
|
||||
GET("/test")
|
||||
response.should.not.be.nil
|
||||
end
|
||||
|
||||
should "be a lighttpd" do
|
||||
GET("/test")
|
||||
status.should.equal 200
|
||||
response["SERVER_SOFTWARE"].should =~ /lighttpd/
|
||||
response["HTTP_VERSION"].should.equal "HTTP/1.1"
|
||||
response["SERVER_PROTOCOL"].should.equal "HTTP/1.1"
|
||||
response["SERVER_PORT"].should.equal @port.to_s
|
||||
response["SERVER_NAME"].should.equal @host
|
||||
end
|
||||
|
||||
should "have rack headers" do
|
||||
GET("/test")
|
||||
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
|
||||
end
|
||||
|
||||
should "have CGI headers on GET" do
|
||||
GET("/test")
|
||||
response["REQUEST_METHOD"].should.equal "GET"
|
||||
response["SCRIPT_NAME"].should.equal "/test"
|
||||
response["REQUEST_PATH"].should.equal "/"
|
||||
response["PATH_INFO"].should.be.nil
|
||||
response["QUERY_STRING"].should.equal ""
|
||||
response["test.postdata"].should.equal ""
|
||||
|
||||
GET("/test/foo?quux=1")
|
||||
response["REQUEST_METHOD"].should.equal "GET"
|
||||
response["SCRIPT_NAME"].should.equal "/test"
|
||||
response["REQUEST_PATH"].should.equal "/"
|
||||
response["PATH_INFO"].should.equal "/foo"
|
||||
response["QUERY_STRING"].should.equal "quux=1"
|
||||
end
|
||||
|
||||
should "have CGI headers on POST" do
|
||||
POST("/test", {"rack-form-data" => "23"}, {'X-test-header' => '42'})
|
||||
status.should.equal 200
|
||||
response["REQUEST_METHOD"].should.equal "POST"
|
||||
response["SCRIPT_NAME"].should.equal "/test"
|
||||
response["REQUEST_PATH"].should.equal "/"
|
||||
response["QUERY_STRING"].should.equal ""
|
||||
response["HTTP_X_TEST_HEADER"].should.equal "42"
|
||||
response["test.postdata"].should.equal "rack-form-data=23"
|
||||
end
|
||||
|
||||
should "support HTTP auth" do
|
||||
GET("/test", {:user => "ruth", :passwd => "secret"})
|
||||
response["HTTP_AUTHORIZATION"].should.equal "Basic cnV0aDpzZWNyZXQ="
|
||||
end
|
||||
|
||||
should "set status" do
|
||||
GET("/test?secret")
|
||||
status.should.equal 403
|
||||
response["rack.url_scheme"].should.equal "http"
|
||||
end
|
||||
|
||||
# Keep this last.
|
||||
should "shutdown" do
|
||||
Process.kill 15, $pid
|
||||
Process.wait($pid).should == $pid
|
||||
end
|
||||
end
|
||||
|
||||
rescue RuntimeError
|
||||
$stderr.puts "Skipping Rack::Session::FastCGI tests (lighttpd is required). Install lighttpd and try again."
|
||||
end
|
60
vendor/plugins/rack/test/spec_chunked.rb
vendored
Normal file
60
vendor/plugins/rack/test/spec_chunked.rb
vendored
Normal file
|
@ -0,0 +1,60 @@
|
|||
require 'rack/chunked'
|
||||
require 'rack/mock'
|
||||
|
||||
describe Rack::Chunked do
|
||||
before do
|
||||
@env = Rack::MockRequest.
|
||||
env_for('/', 'HTTP_VERSION' => '1.1', 'REQUEST_METHOD' => 'GET')
|
||||
end
|
||||
|
||||
should 'chunk responses with no Content-Length' do
|
||||
app = lambda { |env| [200, {}, ['Hello', ' ', 'World!']] }
|
||||
response = Rack::MockResponse.new(*Rack::Chunked.new(app).call(@env))
|
||||
response.headers.should.not.include 'Content-Length'
|
||||
response.headers['Transfer-Encoding'].should.equal 'chunked'
|
||||
response.body.should.equal "5\r\nHello\r\n1\r\n \r\n6\r\nWorld!\r\n0\r\n\r\n"
|
||||
end
|
||||
|
||||
should 'chunks empty bodies properly' do
|
||||
app = lambda { |env| [200, {}, []] }
|
||||
response = Rack::MockResponse.new(*Rack::Chunked.new(app).call(@env))
|
||||
response.headers.should.not.include 'Content-Length'
|
||||
response.headers['Transfer-Encoding'].should.equal 'chunked'
|
||||
response.body.should.equal "0\r\n\r\n"
|
||||
end
|
||||
|
||||
should 'not modify response when Content-Length header present' do
|
||||
app = lambda { |env| [200, {'Content-Length'=>'12'}, ['Hello', ' ', 'World!']] }
|
||||
status, headers, body = Rack::Chunked.new(app).call(@env)
|
||||
status.should.equal 200
|
||||
headers.should.not.include 'Transfer-Encoding'
|
||||
headers.should.include 'Content-Length'
|
||||
body.join.should.equal 'Hello World!'
|
||||
end
|
||||
|
||||
should 'not modify response when client is HTTP/1.0' do
|
||||
app = lambda { |env| [200, {}, ['Hello', ' ', 'World!']] }
|
||||
@env['HTTP_VERSION'] = 'HTTP/1.0'
|
||||
status, headers, body = Rack::Chunked.new(app).call(@env)
|
||||
status.should.equal 200
|
||||
headers.should.not.include 'Transfer-Encoding'
|
||||
body.join.should.equal 'Hello World!'
|
||||
end
|
||||
|
||||
should 'not modify response when Transfer-Encoding header already present' do
|
||||
app = lambda { |env| [200, {'Transfer-Encoding' => 'identity'}, ['Hello', ' ', 'World!']] }
|
||||
status, headers, body = Rack::Chunked.new(app).call(@env)
|
||||
status.should.equal 200
|
||||
headers['Transfer-Encoding'].should.equal 'identity'
|
||||
body.join.should.equal 'Hello World!'
|
||||
end
|
||||
|
||||
[100, 204, 304].each do |status_code|
|
||||
should "not modify response when status code is #{status_code}" do
|
||||
app = lambda { |env| [status_code, {}, []] }
|
||||
status, headers, body = Rack::Chunked.new(app).call(@env)
|
||||
status.should.equal status_code
|
||||
headers.should.not.include 'Transfer-Encoding'
|
||||
end
|
||||
end
|
||||
end
|
56
vendor/plugins/rack/test/spec_commonlogger.rb
vendored
Normal file
56
vendor/plugins/rack/test/spec_commonlogger.rb
vendored
Normal file
|
@ -0,0 +1,56 @@
|
|||
require 'rack/commonlogger'
|
||||
require 'rack/mock'
|
||||
|
||||
describe Rack::CommonLogger do
|
||||
obj = 'foobar'
|
||||
length = obj.size
|
||||
|
||||
app = lambda { |env|
|
||||
[200,
|
||||
{"Content-Type" => "text/html", "Content-Length" => length.to_s},
|
||||
[obj]]}
|
||||
app_without_length = lambda { |env|
|
||||
[200,
|
||||
{"Content-Type" => "text/html"},
|
||||
[]]}
|
||||
app_with_zero_length = lambda { |env|
|
||||
[200,
|
||||
{"Content-Type" => "text/html", "Content-Length" => "0"},
|
||||
[]]}
|
||||
|
||||
should "log to rack.errors by default" do
|
||||
res = Rack::MockRequest.new(Rack::CommonLogger.new(app)).get("/")
|
||||
|
||||
res.errors.should.not.be.empty
|
||||
res.errors.should =~ /"GET \/ " 200 #{length} /
|
||||
end
|
||||
|
||||
should "log to anything with +write+" do
|
||||
log = StringIO.new
|
||||
res = Rack::MockRequest.new(Rack::CommonLogger.new(app, log)).get("/")
|
||||
|
||||
log.string.should =~ /"GET \/ " 200 #{length} /
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
123
|
||||
end
|
||||
|
||||
def self.obj
|
||||
"hello world"
|
||||
end
|
||||
end
|
39
vendor/plugins/rack/test/spec_conditionalget.rb
vendored
Normal file
39
vendor/plugins/rack/test/spec_conditionalget.rb
vendored
Normal file
|
@ -0,0 +1,39 @@
|
|||
require 'time'
|
||||
require 'rack/conditionalget'
|
||||
require 'rack/mock'
|
||||
|
||||
describe Rack::ConditionalGet do
|
||||
should "set a 304 status and truncate body when If-Modified-Since hits" do
|
||||
timestamp = Time.now.httpdate
|
||||
app = Rack::ConditionalGet.new(lambda { |env|
|
||||
[200, {'Last-Modified'=>timestamp}, ['TEST']] })
|
||||
|
||||
response = Rack::MockRequest.new(app).
|
||||
get("/", 'HTTP_IF_MODIFIED_SINCE' => timestamp)
|
||||
|
||||
response.status.should.equal 304
|
||||
response.body.should.be.empty
|
||||
end
|
||||
|
||||
should "set a 304 status and truncate body when If-None-Match hits" do
|
||||
app = Rack::ConditionalGet.new(lambda { |env|
|
||||
[200, {'Etag'=>'1234'}, ['TEST']] })
|
||||
|
||||
response = Rack::MockRequest.new(app).
|
||||
get("/", 'HTTP_IF_NONE_MATCH' => '1234')
|
||||
|
||||
response.status.should.equal 304
|
||||
response.body.should.be.empty
|
||||
end
|
||||
|
||||
should "not affect non-GET/HEAD requests" do
|
||||
app = Rack::ConditionalGet.new(lambda { |env|
|
||||
[200, {'Etag'=>'1234'}, ['TEST']] })
|
||||
|
||||
response = Rack::MockRequest.new(app).
|
||||
post("/", 'HTTP_IF_NONE_MATCH' => '1234')
|
||||
|
||||
response.status.should.equal 200
|
||||
response.body.should.equal 'TEST'
|
||||
end
|
||||
end
|
23
vendor/plugins/rack/test/spec_config.rb
vendored
Normal file
23
vendor/plugins/rack/test/spec_config.rb
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
require 'rack/builder'
|
||||
require 'rack/config'
|
||||
require 'rack/content_length'
|
||||
require 'rack/lint'
|
||||
require 'rack/mock'
|
||||
|
||||
describe Rack::Config do
|
||||
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
|
42
vendor/plugins/rack/test/spec_content_length.rb
vendored
Normal file
42
vendor/plugins/rack/test/spec_content_length.rb
vendored
Normal file
|
@ -0,0 +1,42 @@
|
|||
require 'rack/content_length'
|
||||
|
||||
describe Rack::ContentLength do
|
||||
should "set Content-Length on String bodies if none is set" do
|
||||
app = lambda { |env| [200, {'Content-Type' => 'text/plain'}, "Hello, World!"] }
|
||||
response = Rack::ContentLength.new(app).call({})
|
||||
response[1]['Content-Length'].should.equal '13'
|
||||
end
|
||||
|
||||
should "set Content-Length on Array bodies if none is set" do
|
||||
app = lambda { |env| [200, {'Content-Type' => 'text/plain'}, ["Hello, World!"]] }
|
||||
response = Rack::ContentLength.new(app).call({})
|
||||
response[1]['Content-Length'].should.equal '13'
|
||||
end
|
||||
|
||||
should "not set Content-Length on variable length bodies" do
|
||||
body = lambda { "Hello World!" }
|
||||
def body.each ; yield call ; end
|
||||
|
||||
app = lambda { |env| [200, {'Content-Type' => 'text/plain'}, body] }
|
||||
response = Rack::ContentLength.new(app).call({})
|
||||
response[1]['Content-Length'].should.be.nil
|
||||
end
|
||||
|
||||
should "not change Content-Length if it is already set" do
|
||||
app = lambda { |env| [200, {'Content-Type' => 'text/plain', 'Content-Length' => '1'}, "Hello, World!"] }
|
||||
response = Rack::ContentLength.new(app).call({})
|
||||
response[1]['Content-Length'].should.equal '1'
|
||||
end
|
||||
|
||||
should "not set Content-Length on 304 responses" do
|
||||
app = lambda { |env| [304, {'Content-Type' => 'text/plain'}, []] }
|
||||
response = Rack::ContentLength.new(app).call({})
|
||||
response[1]['Content-Length'].should.equal nil
|
||||
end
|
||||
|
||||
should "not set Content-Length when Transfer-Encoding is chunked" do
|
||||
app = lambda { |env| [200, {'Transfer-Encoding' => 'chunked'}, []] }
|
||||
response = Rack::ContentLength.new(app).call({})
|
||||
response[1]['Content-Length'].should.equal nil
|
||||
end
|
||||
end
|
29
vendor/plugins/rack/test/spec_content_type.rb
vendored
Normal file
29
vendor/plugins/rack/test/spec_content_type.rb
vendored
Normal file
|
@ -0,0 +1,29 @@
|
|||
require 'rack/content_type'
|
||||
|
||||
describe Rack::ContentType do
|
||||
should "set Content-Type to default text/html if none is set" do
|
||||
app = lambda { |env| [200, {}, "Hello, World!"] }
|
||||
status, headers, body = Rack::ContentType.new(app).call({})
|
||||
headers['Content-Type'].should.equal 'text/html'
|
||||
end
|
||||
|
||||
should "set Content-Type to chosen default if none is set" do
|
||||
app = lambda { |env| [200, {}, "Hello, World!"] }
|
||||
status, headers, body =
|
||||
Rack::ContentType.new(app, 'application/octet-stream').call({})
|
||||
headers['Content-Type'].should.equal 'application/octet-stream'
|
||||
end
|
||||
|
||||
should "not change Content-Type if it is already set" do
|
||||
app = lambda { |env| [200, {'Content-Type' => 'foo/bar'}, "Hello, World!"] }
|
||||
status, headers, body = Rack::ContentType.new(app).call({})
|
||||
headers['Content-Type'].should.equal 'foo/bar'
|
||||
end
|
||||
|
||||
should "detect Content-Type case insensitive" do
|
||||
app = lambda { |env| [200, {'CONTENT-Type' => 'foo/bar'}, "Hello, World!"] }
|
||||
status, headers, body = Rack::ContentType.new(app).call({})
|
||||
headers.to_a.select { |k,v| k.downcase == "content-type" }.
|
||||
should.equal [["CONTENT-Type","foo/bar"]]
|
||||
end
|
||||
end
|
125
vendor/plugins/rack/test/spec_deflater.rb
vendored
Normal file
125
vendor/plugins/rack/test/spec_deflater.rb
vendored
Normal file
|
@ -0,0 +1,125 @@
|
|||
require 'stringio'
|
||||
require 'time' # for Time#httpdate
|
||||
require 'rack/deflater'
|
||||
require 'rack/mock'
|
||||
|
||||
describe Rack::Deflater do
|
||||
def build_response(status, body, accept_encoding, headers = {})
|
||||
body = [body] if body.respond_to? :to_str
|
||||
app = lambda { |env| [status, {}, body] }
|
||||
request = Rack::MockRequest.env_for("", headers.merge("HTTP_ACCEPT_ENCODING" => accept_encoding))
|
||||
response = Rack::Deflater.new(app).call(request)
|
||||
|
||||
return response
|
||||
end
|
||||
|
||||
should "be able to deflate bodies that respond to each" do
|
||||
body = Object.new
|
||||
class << body; def each; yield("foo"); yield("bar"); end; end
|
||||
|
||||
response = build_response(200, body, "deflate")
|
||||
|
||||
response[0].should.equal(200)
|
||||
response[1].should.equal({
|
||||
"Content-Encoding" => "deflate",
|
||||
"Vary" => "Accept-Encoding"
|
||||
})
|
||||
buf = ''
|
||||
response[2].each { |part| buf << part }
|
||||
buf.should.equal("K\313\317OJ,\002\000")
|
||||
end
|
||||
|
||||
# TODO: This is really just a special case of the above...
|
||||
should "be able to deflate String bodies" do
|
||||
response = build_response(200, "Hello world!", "deflate")
|
||||
|
||||
response[0].should.equal(200)
|
||||
response[1].should.equal({
|
||||
"Content-Encoding" => "deflate",
|
||||
"Vary" => "Accept-Encoding"
|
||||
})
|
||||
buf = ''
|
||||
response[2].each { |part| buf << part }
|
||||
buf.should.equal("\363H\315\311\311W(\317/\312IQ\004\000")
|
||||
end
|
||||
|
||||
should "be able to gzip bodies that respond to each" do
|
||||
body = Object.new
|
||||
class << body; def each; yield("foo"); yield("bar"); end; end
|
||||
|
||||
response = build_response(200, body, "gzip")
|
||||
|
||||
response[0].should.equal(200)
|
||||
response[1].should.equal({
|
||||
"Content-Encoding" => "gzip",
|
||||
"Vary" => "Accept-Encoding",
|
||||
})
|
||||
|
||||
buf = ''
|
||||
response[2].each { |part| buf << part }
|
||||
io = StringIO.new(buf)
|
||||
gz = Zlib::GzipReader.new(io)
|
||||
gz.read.should.equal("foobar")
|
||||
gz.close
|
||||
end
|
||||
|
||||
should "be able to fallback to no deflation" do
|
||||
response = build_response(200, "Hello world!", "superzip")
|
||||
|
||||
response[0].should.equal(200)
|
||||
response[1].should.equal({ "Vary" => "Accept-Encoding" })
|
||||
response[2].should.equal(["Hello world!"])
|
||||
end
|
||||
|
||||
should "be able to skip when there is no response entity body" do
|
||||
response = build_response(304, [], "gzip")
|
||||
|
||||
response[0].should.equal(304)
|
||||
response[1].should.equal({})
|
||||
response[2].should.equal([])
|
||||
end
|
||||
|
||||
should "handle the lack of an acceptable encoding" do
|
||||
response1 = build_response(200, "Hello world!", "identity;q=0", "PATH_INFO" => "/")
|
||||
response1[0].should.equal(406)
|
||||
response1[1].should.equal({"Content-Type" => "text/plain", "Content-Length" => "71"})
|
||||
response1[2].should.equal(["An acceptable encoding for the requested resource / could not be found."])
|
||||
|
||||
response2 = build_response(200, "Hello world!", "identity;q=0", "SCRIPT_NAME" => "/foo", "PATH_INFO" => "/bar")
|
||||
response2[0].should.equal(406)
|
||||
response2[1].should.equal({"Content-Type" => "text/plain", "Content-Length" => "78"})
|
||||
response2[2].should.equal(["An acceptable encoding for the requested resource /foo/bar could not be found."])
|
||||
end
|
||||
|
||||
should "handle gzip response with Last-Modified header" do
|
||||
last_modified = Time.now.httpdate
|
||||
|
||||
app = lambda { |env| [200, { "Last-Modified" => last_modified }, ["Hello World!"]] }
|
||||
request = Rack::MockRequest.env_for("", "HTTP_ACCEPT_ENCODING" => "gzip")
|
||||
response = Rack::Deflater.new(app).call(request)
|
||||
|
||||
response[0].should.equal(200)
|
||||
response[1].should.equal({
|
||||
"Content-Encoding" => "gzip",
|
||||
"Vary" => "Accept-Encoding",
|
||||
"Last-Modified" => last_modified
|
||||
})
|
||||
|
||||
buf = ''
|
||||
response[2].each { |part| buf << part }
|
||||
io = StringIO.new(buf)
|
||||
gz = Zlib::GzipReader.new(io)
|
||||
gz.read.should.equal("Hello World!")
|
||||
gz.close
|
||||
end
|
||||
|
||||
should "do nothing when no-transform Cache-Control directive present" do
|
||||
app = lambda { |env| [200, {'Cache-Control' => 'no-transform'}, ['Hello World!']] }
|
||||
request = Rack::MockRequest.env_for("", "HTTP_ACCEPT_ENCODING" => "gzip")
|
||||
response = Rack::Deflater.new(app).call(request)
|
||||
|
||||
response[0].should.equal(200)
|
||||
response[1].should.not.include "Content-Encoding"
|
||||
response[2].join.should.equal("Hello World!")
|
||||
end
|
||||
end
|
57
vendor/plugins/rack/test/spec_directory.rb
vendored
Normal file
57
vendor/plugins/rack/test/spec_directory.rb
vendored
Normal file
|
@ -0,0 +1,57 @@
|
|||
require 'rack/directory'
|
||||
require 'rack/mock'
|
||||
|
||||
describe Rack::Directory do
|
||||
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
|
||||
|
||||
should "serve directory indices" do
|
||||
res = Rack::MockRequest.new(Rack::Lint.new(app)).
|
||||
get("/cgi/")
|
||||
|
||||
res.should.be.ok
|
||||
res.should =~ /<html><head>/
|
||||
end
|
||||
|
||||
should "pass to app if file found" do
|
||||
res = Rack::MockRequest.new(Rack::Lint.new(app)).
|
||||
get("/cgi/test")
|
||||
|
||||
res.should.be.ok
|
||||
res.should =~ /passed!/
|
||||
end
|
||||
|
||||
should "serve uri with URL encoded filenames" do
|
||||
res = Rack::MockRequest.new(Rack::Lint.new(app)).
|
||||
get("/%63%67%69/") # "/cgi/test"
|
||||
|
||||
res.should.be.ok
|
||||
res.should =~ /<html><head>/
|
||||
|
||||
res = Rack::MockRequest.new(Rack::Lint.new(app)).
|
||||
get("/cgi/%74%65%73%74") # "/cgi/test"
|
||||
|
||||
res.should.be.ok
|
||||
res.should =~ /passed!/
|
||||
end
|
||||
|
||||
should "not allow directory traversal" do
|
||||
res = Rack::MockRequest.new(Rack::Lint.new(app)).
|
||||
get("/cgi/../test")
|
||||
|
||||
res.should.be.forbidden
|
||||
|
||||
res = Rack::MockRequest.new(Rack::Lint.new(app)).
|
||||
get("/cgi/%2E%2E/test")
|
||||
|
||||
res.should.be.forbidden
|
||||
end
|
||||
|
||||
should "404 if it can't find the file" do
|
||||
res = Rack::MockRequest.new(Rack::Lint.new(app)).
|
||||
get("/cgi/blubb")
|
||||
|
||||
res.should.be.not_found
|
||||
end
|
||||
end
|
15
vendor/plugins/rack/test/spec_etag.rb
vendored
Normal file
15
vendor/plugins/rack/test/spec_etag.rb
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
require 'rack/etag'
|
||||
|
||||
describe Rack::ETag do
|
||||
should "set 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
|
||||
|
||||
should "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
|
107
vendor/plugins/rack/test/spec_fastcgi.rb
vendored
Normal file
107
vendor/plugins/rack/test/spec_fastcgi.rb
vendored
Normal file
|
@ -0,0 +1,107 @@
|
|||
begin
|
||||
require File.expand_path('../testrequest', __FILE__)
|
||||
require 'rack/handler/fastcgi'
|
||||
|
||||
describe Rack::Handler::FastCGI do
|
||||
extend TestRequest::Helpers
|
||||
|
||||
@host = '0.0.0.0'
|
||||
@port = 9203
|
||||
|
||||
if `which lighttpd` && !$?.success?
|
||||
raise "lighttpd not found"
|
||||
end
|
||||
|
||||
# Keep this first.
|
||||
$pid = fork {
|
||||
ENV['RACK_ENV'] = 'deployment'
|
||||
ENV['RUBYLIB'] = [
|
||||
File.expand_path('../../lib', __FILE__),
|
||||
ENV['RUBYLIB'],
|
||||
].compact.join(':')
|
||||
|
||||
Dir.chdir(File.expand_path("../cgi", __FILE__)) do
|
||||
exec "lighttpd -D -f lighttpd.conf"
|
||||
end
|
||||
}
|
||||
|
||||
should "respond" do
|
||||
sleep 1
|
||||
GET("/test")
|
||||
response.should.not.be.nil
|
||||
end
|
||||
|
||||
should "respond via rackup server" do
|
||||
GET("/sample_rackup.ru")
|
||||
status.should.equal 200
|
||||
end
|
||||
|
||||
should "be a lighttpd" do
|
||||
GET("/test.fcgi")
|
||||
status.should.equal 200
|
||||
response["SERVER_SOFTWARE"].should =~ /lighttpd/
|
||||
response["HTTP_VERSION"].should.equal "HTTP/1.1"
|
||||
response["SERVER_PROTOCOL"].should.equal "HTTP/1.1"
|
||||
response["SERVER_PORT"].should.equal @port.to_s
|
||||
response["SERVER_NAME"].should.equal @host
|
||||
end
|
||||
|
||||
should "have rack headers" do
|
||||
GET("/test.fcgi")
|
||||
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
|
||||
end
|
||||
|
||||
should "have CGI headers on GET" do
|
||||
GET("/test.fcgi")
|
||||
response["REQUEST_METHOD"].should.equal "GET"
|
||||
response["SCRIPT_NAME"].should.equal "/test.fcgi"
|
||||
response["REQUEST_PATH"].should.equal "/"
|
||||
response["PATH_INFO"].should.equal ""
|
||||
response["QUERY_STRING"].should.equal ""
|
||||
response["test.postdata"].should.equal ""
|
||||
|
||||
GET("/test.fcgi/foo?quux=1")
|
||||
response["REQUEST_METHOD"].should.equal "GET"
|
||||
response["SCRIPT_NAME"].should.equal "/test.fcgi"
|
||||
response["REQUEST_PATH"].should.equal "/"
|
||||
response["PATH_INFO"].should.equal "/foo"
|
||||
response["QUERY_STRING"].should.equal "quux=1"
|
||||
end
|
||||
|
||||
should "have CGI headers on POST" do
|
||||
POST("/test.fcgi", {"rack-form-data" => "23"}, {'X-test-header' => '42'})
|
||||
status.should.equal 200
|
||||
response["REQUEST_METHOD"].should.equal "POST"
|
||||
response["SCRIPT_NAME"].should.equal "/test.fcgi"
|
||||
response["REQUEST_PATH"].should.equal "/"
|
||||
response["QUERY_STRING"].should.equal ""
|
||||
response["HTTP_X_TEST_HEADER"].should.equal "42"
|
||||
response["test.postdata"].should.equal "rack-form-data=23"
|
||||
end
|
||||
|
||||
should "support HTTP auth" do
|
||||
GET("/test.fcgi", {:user => "ruth", :passwd => "secret"})
|
||||
response["HTTP_AUTHORIZATION"].should.equal "Basic cnV0aDpzZWNyZXQ="
|
||||
end
|
||||
|
||||
should "set status" do
|
||||
GET("/test.fcgi?secret")
|
||||
status.should.equal 403
|
||||
response["rack.url_scheme"].should.equal "http"
|
||||
end
|
||||
|
||||
# Keep this last.
|
||||
should "shutdown" do
|
||||
Process.kill 15, $pid
|
||||
Process.wait($pid).should.equal $pid
|
||||
end
|
||||
end
|
||||
|
||||
rescue RuntimeError
|
||||
$stderr.puts "Skipping Rack::Session::FastCGI tests (lighttpd is required). Install lighttpd and try again."
|
||||
rescue LoadError
|
||||
$stderr.puts "Skipping Rack::Handler::FastCGI tests (FCGI is required). `gem install fcgi` and try again."
|
||||
end
|
71
vendor/plugins/rack/test/spec_file.rb
vendored
Normal file
71
vendor/plugins/rack/test/spec_file.rb
vendored
Normal file
|
@ -0,0 +1,71 @@
|
|||
require 'rack/file'
|
||||
require 'rack/mock'
|
||||
|
||||
describe Rack::File do
|
||||
DOCROOT = File.expand_path(File.dirname(__FILE__)) unless defined? DOCROOT
|
||||
|
||||
should "serve files" do
|
||||
res = Rack::MockRequest.new(Rack::Lint.new(Rack::File.new(DOCROOT))).
|
||||
get("/cgi/test")
|
||||
|
||||
res.should.be.ok
|
||||
res.should =~ /ruby/
|
||||
end
|
||||
|
||||
should "set Last-Modified header" do
|
||||
res = Rack::MockRequest.new(Rack::Lint.new(Rack::File.new(DOCROOT))).
|
||||
get("/cgi/test")
|
||||
|
||||
path = File.join(DOCROOT, "/cgi/test")
|
||||
|
||||
res.should.be.ok
|
||||
res["Last-Modified"].should.equal File.mtime(path).httpdate
|
||||
end
|
||||
|
||||
should "serve files with URL encoded filenames" do
|
||||
res = Rack::MockRequest.new(Rack::Lint.new(Rack::File.new(DOCROOT))).
|
||||
get("/cgi/%74%65%73%74") # "/cgi/test"
|
||||
|
||||
res.should.be.ok
|
||||
res.should =~ /ruby/
|
||||
end
|
||||
|
||||
should "not allow directory traversal" do
|
||||
res = Rack::MockRequest.new(Rack::Lint.new(Rack::File.new(DOCROOT))).
|
||||
get("/cgi/../test")
|
||||
|
||||
res.should.be.forbidden
|
||||
end
|
||||
|
||||
should "not allow directory traversal with encoded periods" do
|
||||
res = Rack::MockRequest.new(Rack::Lint.new(Rack::File.new(DOCROOT))).
|
||||
get("/%2E%2E/README")
|
||||
|
||||
res.should.be.forbidden
|
||||
end
|
||||
|
||||
should "404 if it can't find the file" do
|
||||
res = Rack::MockRequest.new(Rack::Lint.new(Rack::File.new(DOCROOT))).
|
||||
get("/cgi/blubb")
|
||||
|
||||
res.should.be.not_found
|
||||
end
|
||||
|
||||
should "detect SystemCallErrors" do
|
||||
res = Rack::MockRequest.new(Rack::Lint.new(Rack::File.new(DOCROOT))).
|
||||
get("/cgi")
|
||||
|
||||
res.should.be.not_found
|
||||
end
|
||||
|
||||
should "return bodies that respond to #to_path" do
|
||||
env = Rack::MockRequest.env_for("/cgi/test")
|
||||
status, headers, body = Rack::File.new(DOCROOT).call(env)
|
||||
|
||||
path = File.join(DOCROOT, "/cgi/test")
|
||||
|
||||
status.should.equal 200
|
||||
body.should.respond_to :to_path
|
||||
body.to_path.should.equal path
|
||||
end
|
||||
end
|
49
vendor/plugins/rack/test/spec_handler.rb
vendored
Normal file
49
vendor/plugins/rack/test/spec_handler.rb
vendored
Normal file
|
@ -0,0 +1,49 @@
|
|||
require 'rack/handler'
|
||||
|
||||
class Rack::Handler::Lobster; end
|
||||
class RockLobster; end
|
||||
|
||||
describe Rack::Handler do
|
||||
it "has registered default handlers" do
|
||||
Rack::Handler.get('cgi').should.equal Rack::Handler::CGI
|
||||
Rack::Handler.get('webrick').should.equal Rack::Handler::WEBrick
|
||||
|
||||
begin
|
||||
Rack::Handler.get('fastcgi').should.equal Rack::Handler::FastCGI
|
||||
rescue LoadError
|
||||
end
|
||||
|
||||
begin
|
||||
Rack::Handler.get('mongrel').should.equal Rack::Handler::Mongrel
|
||||
rescue LoadError
|
||||
end
|
||||
end
|
||||
|
||||
should "raise NameError if handler doesn't exist" do
|
||||
lambda {
|
||||
Rack::Handler.get('boom')
|
||||
}.should.raise(NameError)
|
||||
end
|
||||
|
||||
should "get unregistered, but already required, handler by name" do
|
||||
Rack::Handler.get('Lobster').should.equal Rack::Handler::Lobster
|
||||
end
|
||||
|
||||
should "register custom handler" do
|
||||
Rack::Handler.register('rock_lobster', 'RockLobster')
|
||||
Rack::Handler.get('rock_lobster').should.equal RockLobster
|
||||
end
|
||||
|
||||
should "not need registration for properly coded handlers even if not already required" do
|
||||
begin
|
||||
$LOAD_PATH.push File.expand_path('../unregistered_handler', __FILE__)
|
||||
Rack::Handler.get('Unregistered').should.equal Rack::Handler::Unregistered
|
||||
lambda {
|
||||
Rack::Handler.get('UnRegistered')
|
||||
}.should.raise(NameError)
|
||||
Rack::Handler.get('UnregisteredLongOne').should.equal Rack::Handler::UnregisteredLongOne
|
||||
ensure
|
||||
$LOAD_PATH.delete File.expand_path('../unregistered_handler', __FILE__)
|
||||
end
|
||||
end
|
||||
end
|
30
vendor/plugins/rack/test/spec_head.rb
vendored
Normal file
30
vendor/plugins/rack/test/spec_head.rb
vendored
Normal file
|
@ -0,0 +1,30 @@
|
|||
require 'rack/head'
|
||||
require 'rack/mock'
|
||||
|
||||
describe Rack::Head do
|
||||
def test_response(headers = {})
|
||||
app = lambda { |env| [200, {"Content-type" => "test/plain", "Content-length" => "3"}, ["foo"]] }
|
||||
request = Rack::MockRequest.env_for("/", headers)
|
||||
response = Rack::Head.new(app).call(request)
|
||||
|
||||
return response
|
||||
end
|
||||
|
||||
should "pass GET, POST, PUT, DELETE, OPTIONS, TRACE requests" do
|
||||
%w[GET POST PUT DELETE OPTIONS TRACE].each do |type|
|
||||
resp = test_response("REQUEST_METHOD" => type)
|
||||
|
||||
resp[0].should.equal(200)
|
||||
resp[1].should.equal({"Content-type" => "test/plain", "Content-length" => "3"})
|
||||
resp[2].should.equal(["foo"])
|
||||
end
|
||||
end
|
||||
|
||||
should "remove body from HEAD requests" do
|
||||
resp = test_response("REQUEST_METHOD" => "HEAD")
|
||||
|
||||
resp[0].should.equal(200)
|
||||
resp[1].should.equal({"Content-type" => "test/plain", "Content-length" => "3"})
|
||||
resp[2].should.equal([])
|
||||
end
|
||||
end
|
515
vendor/plugins/rack/test/spec_lint.rb
vendored
Normal file
515
vendor/plugins/rack/test/spec_lint.rb
vendored
Normal file
|
@ -0,0 +1,515 @@
|
|||
require 'stringio'
|
||||
require 'rack/lint'
|
||||
require 'rack/mock'
|
||||
|
||||
describe Rack::Lint do
|
||||
def env(*args)
|
||||
Rack::MockRequest.env_for("/", *args)
|
||||
end
|
||||
|
||||
should "pass valid request" do
|
||||
lambda {
|
||||
Rack::Lint.new(lambda { |env|
|
||||
[200, {"Content-type" => "test/plain", "Content-length" => "3"}, ["foo"]]
|
||||
}).call(env({}))
|
||||
}.should.not.raise
|
||||
end
|
||||
|
||||
should "notice fatal errors" do
|
||||
lambda { Rack::Lint.new(nil).call }.should.raise(Rack::Lint::LintError).
|
||||
message.should.match(/No env given/)
|
||||
end
|
||||
|
||||
should "notice environment errors" do
|
||||
lambda { Rack::Lint.new(nil).call 5 }.should.raise(Rack::Lint::LintError).
|
||||
message.should.match(/not a Hash/)
|
||||
|
||||
lambda {
|
||||
e = env
|
||||
e.delete("REQUEST_METHOD")
|
||||
Rack::Lint.new(nil).call(e)
|
||||
}.should.raise(Rack::Lint::LintError).
|
||||
message.should.match(/missing required key REQUEST_METHOD/)
|
||||
|
||||
lambda {
|
||||
e = env
|
||||
e.delete("SERVER_NAME")
|
||||
Rack::Lint.new(nil).call(e)
|
||||
}.should.raise(Rack::Lint::LintError).
|
||||
message.should.match(/missing required key SERVER_NAME/)
|
||||
|
||||
|
||||
lambda {
|
||||
Rack::Lint.new(nil).call(env("HTTP_CONTENT_TYPE" => "text/plain"))
|
||||
}.should.raise(Rack::Lint::LintError).
|
||||
message.should.match(/contains HTTP_CONTENT_TYPE/)
|
||||
|
||||
lambda {
|
||||
Rack::Lint.new(nil).call(env("HTTP_CONTENT_LENGTH" => "42"))
|
||||
}.should.raise(Rack::Lint::LintError).
|
||||
message.should.match(/contains HTTP_CONTENT_LENGTH/)
|
||||
|
||||
lambda {
|
||||
Rack::Lint.new(nil).call(env("FOO" => Object.new))
|
||||
}.should.raise(Rack::Lint::LintError).
|
||||
message.should.match(/non-string value/)
|
||||
|
||||
lambda {
|
||||
Rack::Lint.new(nil).call(env("rack.version" => "0.2"))
|
||||
}.should.raise(Rack::Lint::LintError).
|
||||
message.should.match(/must be an Array/)
|
||||
|
||||
lambda {
|
||||
Rack::Lint.new(nil).call(env("rack.url_scheme" => "gopher"))
|
||||
}.should.raise(Rack::Lint::LintError).
|
||||
message.should.match(/url_scheme unknown/)
|
||||
|
||||
lambda {
|
||||
Rack::Lint.new(nil).call(env("rack.session" => []))
|
||||
}.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).
|
||||
message.should.match(/REQUEST_METHOD/)
|
||||
|
||||
lambda {
|
||||
Rack::Lint.new(nil).call(env("SCRIPT_NAME" => "howdy"))
|
||||
}.should.raise(Rack::Lint::LintError).
|
||||
message.should.match(/must start with/)
|
||||
|
||||
lambda {
|
||||
Rack::Lint.new(nil).call(env("PATH_INFO" => "../foo"))
|
||||
}.should.raise(Rack::Lint::LintError).
|
||||
message.should.match(/must start with/)
|
||||
|
||||
lambda {
|
||||
Rack::Lint.new(nil).call(env("CONTENT_LENGTH" => "xcii"))
|
||||
}.should.raise(Rack::Lint::LintError).
|
||||
message.should.match(/Invalid CONTENT_LENGTH/)
|
||||
|
||||
lambda {
|
||||
e = env
|
||||
e.delete("PATH_INFO")
|
||||
e.delete("SCRIPT_NAME")
|
||||
Rack::Lint.new(nil).call(e)
|
||||
}.should.raise(Rack::Lint::LintError).
|
||||
message.should.match(/One of .* must be set/)
|
||||
|
||||
lambda {
|
||||
Rack::Lint.new(nil).call(env("SCRIPT_NAME" => "/"))
|
||||
}.should.raise(Rack::Lint::LintError).
|
||||
message.should.match(/cannot be .* make it ''/)
|
||||
end
|
||||
|
||||
should "notice input errors" do
|
||||
lambda {
|
||||
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?
|
||||
false
|
||||
end
|
||||
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
|
||||
result = Object.new
|
||||
def result.name
|
||||
"US-ASCII"
|
||||
end
|
||||
result
|
||||
end
|
||||
Rack::Lint.new(nil).call(env("rack.input" => input))
|
||||
}.should.raise(Rack::Lint::LintError).
|
||||
message.should.match(/does not have ASCII-8BIT as its external encoding/)
|
||||
end
|
||||
|
||||
should "notice error errors" do
|
||||
lambda {
|
||||
Rack::Lint.new(nil).call(env("rack.errors" => ""))
|
||||
}.should.raise(Rack::Lint::LintError).
|
||||
message.should.match(/does not respond to #puts/)
|
||||
end
|
||||
|
||||
should "notice status errors" do
|
||||
lambda {
|
||||
Rack::Lint.new(lambda { |env|
|
||||
["cc", {}, ""]
|
||||
}).call(env({}))
|
||||
}.should.raise(Rack::Lint::LintError).
|
||||
message.should.match(/must be >=100 seen as integer/)
|
||||
|
||||
lambda {
|
||||
Rack::Lint.new(lambda { |env|
|
||||
[42, {}, ""]
|
||||
}).call(env({}))
|
||||
}.should.raise(Rack::Lint::LintError).
|
||||
message.should.match(/must be >=100 seen as integer/)
|
||||
end
|
||||
|
||||
should "notice header errors" do
|
||||
lambda {
|
||||
Rack::Lint.new(lambda { |env|
|
||||
[200, Object.new, []]
|
||||
}).call(env({}))
|
||||
}.should.raise(Rack::Lint::LintError).
|
||||
message.should.equal("headers object should respond to #each, but doesn't (got Object as headers)")
|
||||
|
||||
lambda {
|
||||
Rack::Lint.new(lambda { |env|
|
||||
[200, {true=>false}, []]
|
||||
}).call(env({}))
|
||||
}.should.raise(Rack::Lint::LintError).
|
||||
message.should.equal("header key must be a string, was TrueClass")
|
||||
|
||||
lambda {
|
||||
Rack::Lint.new(lambda { |env|
|
||||
[200, {"Status" => "404"}, []]
|
||||
}).call(env({}))
|
||||
}.should.raise(Rack::Lint::LintError).
|
||||
message.should.match(/must not contain Status/)
|
||||
|
||||
lambda {
|
||||
Rack::Lint.new(lambda { |env|
|
||||
[200, {"Content-Type:" => "text/plain"}, []]
|
||||
}).call(env({}))
|
||||
}.should.raise(Rack::Lint::LintError).
|
||||
message.should.match(/must not contain :/)
|
||||
|
||||
lambda {
|
||||
Rack::Lint.new(lambda { |env|
|
||||
[200, {"Content-" => "text/plain"}, []]
|
||||
}).call(env({}))
|
||||
}.should.raise(Rack::Lint::LintError).
|
||||
message.should.match(/must not end/)
|
||||
|
||||
lambda {
|
||||
Rack::Lint.new(lambda { |env|
|
||||
[200, {"..%%quark%%.." => "text/plain"}, []]
|
||||
}).call(env({}))
|
||||
}.should.raise(Rack::Lint::LintError).
|
||||
message.should.equal("invalid header name: ..%%quark%%..")
|
||||
|
||||
lambda {
|
||||
Rack::Lint.new(lambda { |env|
|
||||
[200, {"Foo" => Object.new}, []]
|
||||
}).call(env({}))
|
||||
}.should.raise(Rack::Lint::LintError).
|
||||
message.should.equal("a header value must be a String, but the value of 'Foo' is a Object")
|
||||
|
||||
lambda {
|
||||
Rack::Lint.new(lambda { |env|
|
||||
[200, {"Foo" => [1, 2, 3]}, []]
|
||||
}).call(env({}))
|
||||
}.should.raise(Rack::Lint::LintError).
|
||||
message.should.equal("a header value must be a String, but the value of 'Foo' is a Array")
|
||||
|
||||
|
||||
lambda {
|
||||
Rack::Lint.new(lambda { |env|
|
||||
[200, {"Foo-Bar" => "text\000plain"}, []]
|
||||
}).call(env({}))
|
||||
}.should.raise(Rack::Lint::LintError).
|
||||
message.should.match(/invalid header/)
|
||||
|
||||
# line ends (010) should be allowed in header values.
|
||||
lambda {
|
||||
Rack::Lint.new(lambda { |env|
|
||||
[200, {"Foo-Bar" => "one\ntwo\nthree", "Content-Length" => "0", "Content-Type" => "text/plain" }, []]
|
||||
}).call(env({}))
|
||||
}.should.not.raise(Rack::Lint::LintError)
|
||||
end
|
||||
|
||||
should "notice content-type errors" do
|
||||
lambda {
|
||||
Rack::Lint.new(lambda { |env|
|
||||
[200, {"Content-length" => "0"}, []]
|
||||
}).call(env({}))
|
||||
}.should.raise(Rack::Lint::LintError).
|
||||
message.should.match(/No Content-Type/)
|
||||
|
||||
[100, 101, 204, 304].each do |status|
|
||||
lambda {
|
||||
Rack::Lint.new(lambda { |env|
|
||||
[status, {"Content-type" => "text/plain", "Content-length" => "0"}, []]
|
||||
}).call(env({}))
|
||||
}.should.raise(Rack::Lint::LintError).
|
||||
message.should.match(/Content-Type header found/)
|
||||
end
|
||||
end
|
||||
|
||||
should "notice content-length errors" do
|
||||
[100, 101, 204, 304].each do |status|
|
||||
lambda {
|
||||
Rack::Lint.new(lambda { |env|
|
||||
[status, {"Content-length" => "0"}, []]
|
||||
}).call(env({}))
|
||||
}.should.raise(Rack::Lint::LintError).
|
||||
message.should.match(/Content-Length header found/)
|
||||
end
|
||||
|
||||
lambda {
|
||||
Rack::Lint.new(lambda { |env|
|
||||
[200, {"Content-type" => "text/plain", "Content-Length" => "1"}, []]
|
||||
}).call(env({}))[2].each { }
|
||||
}.should.raise(Rack::Lint::LintError).
|
||||
message.should.match(/Content-Length header was 1, but should be 0/)
|
||||
end
|
||||
|
||||
should "notice body errors" do
|
||||
lambda {
|
||||
status, header, body = Rack::Lint.new(lambda { |env|
|
||||
[200, {"Content-type" => "text/plain","Content-length" => "3"}, [1,2,3]]
|
||||
}).call(env({}))
|
||||
body.each { |part| }
|
||||
}.should.raise(Rack::Lint::LintError).
|
||||
message.should.match(/yielded non-string/)
|
||||
end
|
||||
|
||||
should "notice input handling errors" do
|
||||
lambda {
|
||||
Rack::Lint.new(lambda { |env|
|
||||
env["rack.input"].gets("\r\n")
|
||||
[201, {"Content-type" => "text/plain", "Content-length" => "0"}, []]
|
||||
}).call(env({}))
|
||||
}.should.raise(Rack::Lint::LintError).
|
||||
message.should.match(/gets called with arguments/)
|
||||
|
||||
lambda {
|
||||
Rack::Lint.new(lambda { |env|
|
||||
env["rack.input"].read(1, 2, 3)
|
||||
[201, {"Content-type" => "text/plain", "Content-length" => "0"}, []]
|
||||
}).call(env({}))
|
||||
}.should.raise(Rack::Lint::LintError).
|
||||
message.should.match(/read called with too many arguments/)
|
||||
|
||||
lambda {
|
||||
Rack::Lint.new(lambda { |env|
|
||||
env["rack.input"].read("foo")
|
||||
[201, {"Content-type" => "text/plain", "Content-length" => "0"}, []]
|
||||
}).call(env({}))
|
||||
}.should.raise(Rack::Lint::LintError).
|
||||
message.should.match(/read called with non-integer and non-nil length/)
|
||||
|
||||
lambda {
|
||||
Rack::Lint.new(lambda { |env|
|
||||
env["rack.input"].read(-1)
|
||||
[201, {"Content-type" => "text/plain", "Content-length" => "0"}, []]
|
||||
}).call(env({}))
|
||||
}.should.raise(Rack::Lint::LintError).
|
||||
message.should.match(/read called with a negative length/)
|
||||
|
||||
lambda {
|
||||
Rack::Lint.new(lambda { |env|
|
||||
env["rack.input"].read(nil, nil)
|
||||
[201, {"Content-type" => "text/plain", "Content-length" => "0"}, []]
|
||||
}).call(env({}))
|
||||
}.should.raise(Rack::Lint::LintError).
|
||||
message.should.match(/read called with non-String buffer/)
|
||||
|
||||
lambda {
|
||||
Rack::Lint.new(lambda { |env|
|
||||
env["rack.input"].read(nil, 1)
|
||||
[201, {"Content-type" => "text/plain", "Content-length" => "0"}, []]
|
||||
}).call(env({}))
|
||||
}.should.raise(Rack::Lint::LintError).
|
||||
message.should.match(/read called with non-String buffer/)
|
||||
|
||||
lambda {
|
||||
Rack::Lint.new(lambda { |env|
|
||||
env["rack.input"].rewind(0)
|
||||
[201, {"Content-type" => "text/plain", "Content-length" => "0"}, []]
|
||||
}).call(env({}))
|
||||
}.should.raise(Rack::Lint::LintError).
|
||||
message.should.match(/rewind called with arguments/)
|
||||
|
||||
weirdio = Object.new
|
||||
class << weirdio
|
||||
def gets
|
||||
42
|
||||
end
|
||||
|
||||
def read
|
||||
23
|
||||
end
|
||||
|
||||
def each
|
||||
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
|
||||
|
||||
lambda {
|
||||
Rack::Lint.new(lambda { |env|
|
||||
env["rack.input"].gets
|
||||
[201, {"Content-type" => "text/plain", "Content-length" => "0"}, []]
|
||||
}).call(env("rack.input" => weirdio))
|
||||
}.should.raise(Rack::Lint::LintError).
|
||||
message.should.match(/gets didn't return a String/)
|
||||
|
||||
lambda {
|
||||
Rack::Lint.new(lambda { |env|
|
||||
env["rack.input"].each { |x| }
|
||||
[201, {"Content-type" => "text/plain", "Content-length" => "0"}, []]
|
||||
}).call(env("rack.input" => weirdio))
|
||||
}.should.raise(Rack::Lint::LintError).
|
||||
message.should.match(/each didn't yield a String/)
|
||||
|
||||
lambda {
|
||||
Rack::Lint.new(lambda { |env|
|
||||
env["rack.input"].read
|
||||
[201, {"Content-type" => "text/plain", "Content-length" => "0"}, []]
|
||||
}).call(env("rack.input" => weirdio))
|
||||
}.should.raise(Rack::Lint::LintError).
|
||||
message.should.match(/read didn't return nil or a String/)
|
||||
|
||||
lambda {
|
||||
Rack::Lint.new(lambda { |env|
|
||||
env["rack.input"].read
|
||||
[201, {"Content-type" => "text/plain", "Content-length" => "0"}, []]
|
||||
}).call(env("rack.input" => eof_weirdio))
|
||||
}.should.raise(Rack::Lint::LintError).
|
||||
message.should.match(/read\(nil\) returned nil on EOF/)
|
||||
|
||||
lambda {
|
||||
Rack::Lint.new(lambda { |env|
|
||||
env["rack.input"].rewind
|
||||
[201, {"Content-type" => "text/plain", "Content-length" => "0"}, []]
|
||||
}).call(env("rack.input" => weirdio))
|
||||
}.should.raise(Rack::Lint::LintError).
|
||||
message.should.match(/rewind raised Errno::ESPIPE/)
|
||||
|
||||
|
||||
lambda {
|
||||
Rack::Lint.new(lambda { |env|
|
||||
env["rack.input"].close
|
||||
[201, {"Content-type" => "text/plain", "Content-length" => "0"}, []]
|
||||
}).call(env({}))
|
||||
}.should.raise(Rack::Lint::LintError).
|
||||
message.should.match(/close must not be called/)
|
||||
end
|
||||
|
||||
should "notice error handling errors" do
|
||||
lambda {
|
||||
Rack::Lint.new(lambda { |env|
|
||||
env["rack.errors"].write(42)
|
||||
[201, {"Content-type" => "text/plain", "Content-length" => "0"}, []]
|
||||
}).call(env({}))
|
||||
}.should.raise(Rack::Lint::LintError).
|
||||
message.should.match(/write not called with a String/)
|
||||
|
||||
lambda {
|
||||
Rack::Lint.new(lambda { |env|
|
||||
env["rack.errors"].close
|
||||
[201, {"Content-type" => "text/plain", "Content-length" => "0"}, []]
|
||||
}).call(env({}))
|
||||
}.should.raise(Rack::Lint::LintError).
|
||||
message.should.match(/close must not be called/)
|
||||
end
|
||||
|
||||
should "notice HEAD errors" do
|
||||
lambda {
|
||||
Rack::Lint.new(lambda { |env|
|
||||
[200, {"Content-type" => "test/plain", "Content-length" => "3"}, []]
|
||||
}).call(env({"REQUEST_METHOD" => "HEAD"}))
|
||||
}.should.not.raise
|
||||
|
||||
lambda {
|
||||
Rack::Lint.new(lambda { |env|
|
||||
[200, {"Content-type" => "test/plain", "Content-length" => "3"}, ["foo"]]
|
||||
}).call(env({"REQUEST_METHOD" => "HEAD"}))[2].each { }
|
||||
}.should.raise(Rack::Lint::LintError).
|
||||
message.should.match(/body was given for HEAD/)
|
||||
end
|
||||
|
||||
should "pass 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_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_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_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_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_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_str)}))
|
||||
}.should.not.raise(Rack::Lint::LintError)
|
||||
end
|
||||
end
|
||||
|
||||
describe "Rack::Lint::InputWrapper" do
|
||||
should "delegate :rewind to underlying IO object" do
|
||||
io = StringIO.new("123")
|
||||
wrapper = Rack::Lint::InputWrapper.new(io)
|
||||
wrapper.read.should.equal "123"
|
||||
wrapper.read.should.equal ""
|
||||
wrapper.rewind
|
||||
wrapper.read.should.equal "123"
|
||||
end
|
||||
end
|
43
vendor/plugins/rack/test/spec_lobster.rb
vendored
Normal file
43
vendor/plugins/rack/test/spec_lobster.rb
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
require 'rack/lobster'
|
||||
require 'rack/mock'
|
||||
|
||||
describe Rack::Lobster::LambdaLobster do
|
||||
should "be a single lambda" do
|
||||
Rack::Lobster::LambdaLobster.should.be.kind_of Proc
|
||||
end
|
||||
|
||||
should "look like a lobster" do
|
||||
res = Rack::MockRequest.new(Rack::Lobster::LambdaLobster).get("/")
|
||||
res.should.be.ok
|
||||
res.body.should.include "(,(,,(,,,("
|
||||
res.body.should.include "?flip"
|
||||
end
|
||||
|
||||
should "be flippable" do
|
||||
res = Rack::MockRequest.new(Rack::Lobster::LambdaLobster).get("/?flip")
|
||||
res.should.be.ok
|
||||
res.body.should.include "(,,,(,,(,("
|
||||
end
|
||||
end
|
||||
|
||||
describe Rack::Lobster do
|
||||
should "look like a lobster" do
|
||||
res = Rack::MockRequest.new(Rack::Lobster.new).get("/")
|
||||
res.should.be.ok
|
||||
res.body.should.include "(,(,,(,,,("
|
||||
res.body.should.include "?flip"
|
||||
res.body.should.include "crash"
|
||||
end
|
||||
|
||||
should "be flippable" do
|
||||
res = Rack::MockRequest.new(Rack::Lobster.new).get("/?flip=left")
|
||||
res.should.be.ok
|
||||
res.body.should.include "(,,,(,,(,("
|
||||
end
|
||||
|
||||
should "provide crashing for testing purposes" do
|
||||
lambda {
|
||||
Rack::MockRequest.new(Rack::Lobster.new).get("/?flip=crash")
|
||||
}.should.raise
|
||||
end
|
||||
end
|
36
vendor/plugins/rack/test/spec_lock.rb
vendored
Normal file
36
vendor/plugins/rack/test/spec_lock.rb
vendored
Normal file
|
@ -0,0 +1,36 @@
|
|||
require 'rack/lock'
|
||||
require 'rack/mock'
|
||||
|
||||
class Lock
|
||||
attr_reader :synchronized
|
||||
|
||||
def initialize
|
||||
@synchronized = false
|
||||
end
|
||||
|
||||
def synchronize
|
||||
@synchronized = true
|
||||
yield
|
||||
end
|
||||
end
|
||||
|
||||
describe Rack::Lock do
|
||||
should "call synchronize on lock" do
|
||||
lock = Lock.new
|
||||
env = Rack::MockRequest.env_for("/")
|
||||
app = Rack::Lock.new(lambda { |inner_env| }, lock)
|
||||
lock.synchronized.should.equal false
|
||||
app.call(env)
|
||||
lock.synchronized.should.equal true
|
||||
end
|
||||
|
||||
should "set multithread flag to false" do
|
||||
app = Rack::Lock.new(lambda { |env| env['rack.multithread'] })
|
||||
app.call(Rack::MockRequest.env_for("/")).should.equal false
|
||||
end
|
||||
|
||||
should "reset original multithread flag when exiting lock" do
|
||||
app = Rack::Lock.new(lambda { |env| env })
|
||||
app.call(Rack::MockRequest.env_for("/"))['rack.multithread'].should.equal true
|
||||
end
|
||||
end
|
20
vendor/plugins/rack/test/spec_logger.rb
vendored
Normal file
20
vendor/plugins/rack/test/spec_logger.rb
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
require 'stringio'
|
||||
require 'rack/logger'
|
||||
|
||||
describe Rack::Logger do
|
||||
should "log 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
|
58
vendor/plugins/rack/test/spec_methodoverride.rb
vendored
Normal file
58
vendor/plugins/rack/test/spec_methodoverride.rb
vendored
Normal file
|
@ -0,0 +1,58 @@
|
|||
require 'stringio'
|
||||
require 'rack/methodoverride'
|
||||
require 'rack/mock'
|
||||
|
||||
describe Rack::MethodOverride do
|
||||
should "not affect GET requests" do
|
||||
env = Rack::MockRequest.env_for("/?_method=delete", :method => "GET")
|
||||
app = Rack::MethodOverride.new(lambda{|envx| Rack::Request.new(envx) })
|
||||
req = app.call(env)
|
||||
|
||||
req.env["REQUEST_METHOD"].should.equal "GET"
|
||||
end
|
||||
|
||||
should "modify REQUEST_METHOD for POST requests when _method parameter is set" do
|
||||
env = Rack::MockRequest.env_for("/", :method => "POST", :input => "_method=put")
|
||||
app = Rack::MethodOverride.new(lambda{|envx| Rack::Request.new(envx) })
|
||||
req = app.call(env)
|
||||
|
||||
req.env["REQUEST_METHOD"].should.equal "PUT"
|
||||
end
|
||||
|
||||
should "modify REQUEST_METHOD for POST requests when X-HTTP-Method-Override is set" do
|
||||
env = Rack::MockRequest.env_for("/",
|
||||
:method => "POST",
|
||||
"HTTP_X_HTTP_METHOD_OVERRIDE" => "PUT"
|
||||
)
|
||||
app = Rack::MethodOverride.new(lambda{|envx| Rack::Request.new(envx) })
|
||||
req = app.call(env)
|
||||
|
||||
req.env["REQUEST_METHOD"].should.equal "PUT"
|
||||
end
|
||||
|
||||
should "not modify REQUEST_METHOD if the method is unknown" do
|
||||
env = Rack::MockRequest.env_for("/", :method => "POST", :input => "_method=foo")
|
||||
app = Rack::MethodOverride.new(lambda{|envx| Rack::Request.new(envx) })
|
||||
req = app.call(env)
|
||||
|
||||
req.env["REQUEST_METHOD"].should.equal "POST"
|
||||
end
|
||||
|
||||
should "not modify REQUEST_METHOD when _method is nil" do
|
||||
env = Rack::MockRequest.env_for("/", :method => "POST", :input => "foo=bar")
|
||||
app = Rack::MethodOverride.new(lambda{|envx| Rack::Request.new(envx) })
|
||||
req = app.call(env)
|
||||
|
||||
req.env["REQUEST_METHOD"].should.equal "POST"
|
||||
end
|
||||
|
||||
should "store the original REQUEST_METHOD prior to overriding" do
|
||||
env = Rack::MockRequest.env_for("/",
|
||||
:method => "POST",
|
||||
:input => "_method=options")
|
||||
app = Rack::MethodOverride.new(lambda{|envx| Rack::Request.new(envx) })
|
||||
req = app.call(env)
|
||||
|
||||
req.env["rack.methodoverride.original_method"].should.equal "POST"
|
||||
end
|
||||
end
|
241
vendor/plugins/rack/test/spec_mock.rb
vendored
Normal file
241
vendor/plugins/rack/test/spec_mock.rb
vendored
Normal file
|
@ -0,0 +1,241 @@
|
|||
require 'yaml'
|
||||
require 'rack/mock'
|
||||
|
||||
app = lambda { |env|
|
||||
req = Rack::Request.new(env)
|
||||
|
||||
env["mock.postdata"] = env["rack.input"].read
|
||||
if req.GET["error"]
|
||||
env["rack.errors"].puts req.GET["error"]
|
||||
env["rack.errors"].flush
|
||||
end
|
||||
|
||||
Rack::Response.new(env.to_yaml,
|
||||
req.GET["status"] || 200,
|
||||
"Content-Type" => "text/yaml").finish
|
||||
}
|
||||
|
||||
describe Rack::MockRequest do
|
||||
should "return a MockResponse" do
|
||||
res = Rack::MockRequest.new(app).get("")
|
||||
res.should.be.kind_of Rack::MockResponse
|
||||
end
|
||||
|
||||
should "be able to only return the environment" do
|
||||
env = Rack::MockRequest.env_for("")
|
||||
env.should.be.kind_of Hash
|
||||
env.should.include "rack.version"
|
||||
end
|
||||
|
||||
should "provide sensible defaults" do
|
||||
res = Rack::MockRequest.new(app).request
|
||||
|
||||
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 "/"
|
||||
env["SCRIPT_NAME"].should.equal ""
|
||||
env["rack.url_scheme"].should.equal "http"
|
||||
env["mock.postdata"].should.be.empty
|
||||
end
|
||||
|
||||
should "allow GET/POST/PUT/DELETE" do
|
||||
res = Rack::MockRequest.new(app).get("", :input => "foo")
|
||||
env = YAML.load(res.body)
|
||||
env["REQUEST_METHOD"].should.equal "GET"
|
||||
|
||||
res = Rack::MockRequest.new(app).post("", :input => "foo")
|
||||
env = YAML.load(res.body)
|
||||
env["REQUEST_METHOD"].should.equal "POST"
|
||||
|
||||
res = Rack::MockRequest.new(app).put("", :input => "foo")
|
||||
env = YAML.load(res.body)
|
||||
env["REQUEST_METHOD"].should.equal "PUT"
|
||||
|
||||
res = Rack::MockRequest.new(app).delete("", :input => "foo")
|
||||
env = YAML.load(res.body)
|
||||
env["REQUEST_METHOD"].should.equal "DELETE"
|
||||
|
||||
Rack::MockRequest.env_for("/", :method => "OPTIONS")["REQUEST_METHOD"].
|
||||
should.equal "OPTIONS"
|
||||
end
|
||||
|
||||
should "set content length" do
|
||||
env = Rack::MockRequest.env_for("/", :input => "foo")
|
||||
env["CONTENT_LENGTH"].should.equal "3"
|
||||
end
|
||||
|
||||
should "allow posting" do
|
||||
res = Rack::MockRequest.new(app).get("", :input => "foo")
|
||||
env = YAML.load(res.body)
|
||||
env["mock.postdata"].should.equal "foo"
|
||||
|
||||
res = Rack::MockRequest.new(app).post("", :input => StringIO.new("foo"))
|
||||
env = YAML.load(res.body)
|
||||
env["mock.postdata"].should.equal "foo"
|
||||
end
|
||||
|
||||
should "use all parts of an URL" do
|
||||
res = Rack::MockRequest.new(app).
|
||||
get("https://bla.example.org:9292/meh/foo?bar")
|
||||
res.should.be.kind_of Rack::MockResponse
|
||||
|
||||
env = YAML.load(res.body)
|
||||
env["REQUEST_METHOD"].should.equal "GET"
|
||||
env["SERVER_NAME"].should.equal "bla.example.org"
|
||||
env["SERVER_PORT"].should.equal "9292"
|
||||
env["QUERY_STRING"].should.equal "bar"
|
||||
env["PATH_INFO"].should.equal "/meh/foo"
|
||||
env["rack.url_scheme"].should.equal "https"
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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.include "baz=2"
|
||||
env["QUERY_STRING"].should.include "foo[bar]=1"
|
||||
env["PATH_INFO"].should.equal "/foo"
|
||||
env["mock.postdata"].should.equal ""
|
||||
end
|
||||
|
||||
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.include "baz=2"
|
||||
env["QUERY_STRING"].should.include "foo[bar]=1"
|
||||
env["PATH_INFO"].should.equal "/foo"
|
||||
env["mock.postdata"].should.equal ""
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
should "behave valid according to the Rack spec" do
|
||||
lambda {
|
||||
res = Rack::MockRequest.new(app).
|
||||
get("https://bla.example.org:9292/meh/foo?bar", :lint => true)
|
||||
}.should.not.raise(Rack::Lint::LintError)
|
||||
end
|
||||
end
|
||||
|
||||
describe Rack::MockResponse do
|
||||
should "provide access to the HTTP status" do
|
||||
res = Rack::MockRequest.new(app).get("")
|
||||
res.should.be.successful
|
||||
res.should.be.ok
|
||||
|
||||
res = Rack::MockRequest.new(app).get("/?status=404")
|
||||
res.should.not.be.successful
|
||||
res.should.be.client_error
|
||||
res.should.be.not_found
|
||||
|
||||
res = Rack::MockRequest.new(app).get("/?status=501")
|
||||
res.should.not.be.successful
|
||||
res.should.be.server_error
|
||||
|
||||
res = Rack::MockRequest.new(app).get("/?status=307")
|
||||
res.should.be.redirect
|
||||
|
||||
res = Rack::MockRequest.new(app).get("/?status=201", :lint => true)
|
||||
res.should.be.empty
|
||||
end
|
||||
|
||||
should "provide access to the HTTP headers" do
|
||||
res = Rack::MockRequest.new(app).get("")
|
||||
res.should.include "Content-Type"
|
||||
res.headers["Content-Type"].should.equal "text/yaml"
|
||||
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 > 0
|
||||
res.location.should.be.nil
|
||||
end
|
||||
|
||||
should "provide access to the HTTP body" do
|
||||
res = Rack::MockRequest.new(app).get("")
|
||||
res.body.should =~ /rack/
|
||||
res.should =~ /rack/
|
||||
res.should.match(/rack/)
|
||||
res.should.satisfy { |r| r.match(/rack/) }
|
||||
end
|
||||
|
||||
should "provide access to the Rack errors" do
|
||||
res = Rack::MockRequest.new(app).get("/?error=foo", :lint => true)
|
||||
res.should.be.ok
|
||||
res.errors.should.not.be.empty
|
||||
res.errors.should.include "foo"
|
||||
end
|
||||
|
||||
should "optionally make Rack errors fatal" do
|
||||
lambda {
|
||||
Rack::MockRequest.new(app).get("/?error=foo", :fatal => true)
|
||||
}.should.raise(Rack::MockRequest::FatalWarning)
|
||||
end
|
||||
end
|
182
vendor/plugins/rack/test/spec_mongrel.rb
vendored
Normal file
182
vendor/plugins/rack/test/spec_mongrel.rb
vendored
Normal file
|
@ -0,0 +1,182 @@
|
|||
begin
|
||||
require 'rack'
|
||||
require 'rack/handler/mongrel'
|
||||
require File.expand_path('../testrequest', __FILE__)
|
||||
require 'timeout'
|
||||
|
||||
Thread.abort_on_exception = true
|
||||
$tcp_defer_accept_opts = nil
|
||||
$tcp_cork_opts = nil
|
||||
|
||||
describe Rack::Handler::Mongrel do
|
||||
extend TestRequest::Helpers
|
||||
|
||||
@server = Mongrel::HttpServer.new(@host='0.0.0.0', @port=9201)
|
||||
@server.register('/test',
|
||||
Rack::Handler::Mongrel.new(Rack::Lint.new(TestRequest.new)))
|
||||
@server.register('/stream',
|
||||
Rack::Handler::Mongrel.new(Rack::Lint.new(StreamingRequest)))
|
||||
@acc = @server.run
|
||||
|
||||
should "respond" do
|
||||
lambda {
|
||||
GET("/test")
|
||||
}.should.not.raise
|
||||
end
|
||||
|
||||
should "be a Mongrel" do
|
||||
GET("/test")
|
||||
status.should.equal 200
|
||||
response["SERVER_SOFTWARE"].should =~ /Mongrel/
|
||||
response["HTTP_VERSION"].should.equal "HTTP/1.1"
|
||||
response["SERVER_PROTOCOL"].should.equal "HTTP/1.1"
|
||||
response["SERVER_PORT"].should.equal "9201"
|
||||
response["SERVER_NAME"].should.equal "0.0.0.0"
|
||||
end
|
||||
|
||||
should "have rack headers" do
|
||||
GET("/test")
|
||||
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
|
||||
end
|
||||
|
||||
should "have CGI headers on GET" do
|
||||
GET("/test")
|
||||
response["REQUEST_METHOD"].should.equal "GET"
|
||||
response["SCRIPT_NAME"].should.equal "/test"
|
||||
response["REQUEST_PATH"].should.equal "/test"
|
||||
response["PATH_INFO"].should.be.equal ""
|
||||
response["QUERY_STRING"].should.equal ""
|
||||
response["test.postdata"].should.equal ""
|
||||
|
||||
GET("/test/foo?quux=1")
|
||||
response["REQUEST_METHOD"].should.equal "GET"
|
||||
response["SCRIPT_NAME"].should.equal "/test"
|
||||
response["REQUEST_PATH"].should.equal "/test/foo"
|
||||
response["PATH_INFO"].should.equal "/foo"
|
||||
response["QUERY_STRING"].should.equal "quux=1"
|
||||
end
|
||||
|
||||
should "have CGI headers on POST" do
|
||||
POST("/test", {"rack-form-data" => "23"}, {'X-test-header' => '42'})
|
||||
status.should.equal 200
|
||||
response["REQUEST_METHOD"].should.equal "POST"
|
||||
response["SCRIPT_NAME"].should.equal "/test"
|
||||
response["REQUEST_PATH"].should.equal "/test"
|
||||
response["QUERY_STRING"].should.equal ""
|
||||
response["HTTP_X_TEST_HEADER"].should.equal "42"
|
||||
response["test.postdata"].should.equal "rack-form-data=23"
|
||||
end
|
||||
|
||||
should "support HTTP auth" do
|
||||
GET("/test", {:user => "ruth", :passwd => "secret"})
|
||||
response["HTTP_AUTHORIZATION"].should.equal "Basic cnV0aDpzZWNyZXQ="
|
||||
end
|
||||
|
||||
should "set status" do
|
||||
GET("/test?secret")
|
||||
status.should.equal 403
|
||||
response["rack.url_scheme"].should.equal "http"
|
||||
end
|
||||
|
||||
should "provide a .run" do
|
||||
block_ran = false
|
||||
Thread.new {
|
||||
Rack::Handler::Mongrel.run(lambda {}, {:Port => 9211}) { |server|
|
||||
server.should.be.kind_of Mongrel::HttpServer
|
||||
block_ran = true
|
||||
}
|
||||
}
|
||||
sleep 1
|
||||
block_ran.should.be.true
|
||||
end
|
||||
|
||||
should "provide a .run that maps a hash" do
|
||||
block_ran = false
|
||||
Thread.new {
|
||||
map = {'/'=>lambda{},'/foo'=>lambda{}}
|
||||
Rack::Handler::Mongrel.run(map, :map => true, :Port => 9221) { |server|
|
||||
server.should.be.kind_of Mongrel::HttpServer
|
||||
server.classifier.uris.size.should.equal 2
|
||||
server.classifier.uris.should.not.include '/arf'
|
||||
server.classifier.uris.should.include '/'
|
||||
server.classifier.uris.should.include '/foo'
|
||||
block_ran = true
|
||||
}
|
||||
}
|
||||
sleep 1
|
||||
block_ran.should.be.true
|
||||
end
|
||||
|
||||
should "provide a .run that maps a urlmap" do
|
||||
block_ran = false
|
||||
Thread.new {
|
||||
map = Rack::URLMap.new({'/'=>lambda{},'/bar'=>lambda{}})
|
||||
Rack::Handler::Mongrel.run(map, {:map => true, :Port => 9231}) { |server|
|
||||
server.should.be.kind_of Mongrel::HttpServer
|
||||
server.classifier.uris.size.should.equal 2
|
||||
server.classifier.uris.should.not.include '/arf'
|
||||
server.classifier.uris.should.include '/'
|
||||
server.classifier.uris.should.include '/bar'
|
||||
block_ran = true
|
||||
}
|
||||
}
|
||||
sleep 1
|
||||
block_ran.should.be.true
|
||||
end
|
||||
|
||||
should "provide a .run that maps a urlmap restricting by host" do
|
||||
block_ran = false
|
||||
Thread.new {
|
||||
map = Rack::URLMap.new({
|
||||
'/' => lambda{},
|
||||
'/foo' => lambda{},
|
||||
'/bar' => lambda{},
|
||||
'http://localhost/' => lambda{},
|
||||
'http://localhost/bar' => lambda{},
|
||||
'http://falsehost/arf' => lambda{},
|
||||
'http://falsehost/qux' => lambda{}
|
||||
})
|
||||
opt = {:map => true, :Port => 9241, :Host => 'localhost'}
|
||||
Rack::Handler::Mongrel.run(map, opt) { |server|
|
||||
server.should.be.kind_of Mongrel::HttpServer
|
||||
server.classifier.uris.should.include '/'
|
||||
server.classifier.handler_map['/'].size.should.equal 2
|
||||
server.classifier.uris.should.include '/foo'
|
||||
server.classifier.handler_map['/foo'].size.should.equal 1
|
||||
server.classifier.uris.should.include '/bar'
|
||||
server.classifier.handler_map['/bar'].size.should.equal 2
|
||||
server.classifier.uris.should.not.include '/qux'
|
||||
server.classifier.uris.should.not.include '/arf'
|
||||
server.classifier.uris.size.should.equal 3
|
||||
block_ran = true
|
||||
}
|
||||
}
|
||||
sleep 1
|
||||
block_ran.should.be.true
|
||||
end
|
||||
|
||||
should "stream #each part of the response" do
|
||||
body = ''
|
||||
begin
|
||||
Timeout.timeout(1) do
|
||||
Net::HTTP.start(@host, @port) do |http|
|
||||
get = Net::HTTP::Get.new('/stream')
|
||||
http.request(get) do |response|
|
||||
response.read_body { |part| body << part }
|
||||
end
|
||||
end
|
||||
end
|
||||
rescue Timeout::Error
|
||||
end
|
||||
body.should.not.be.empty
|
||||
end
|
||||
|
||||
@acc.raise Mongrel::StopServer
|
||||
end
|
||||
|
||||
rescue LoadError
|
||||
warn "Skipping Rack::Handler::Mongrel tests (Mongrel is required). `gem install mongrel` and try again."
|
||||
end
|
12
vendor/plugins/rack/test/spec_nulllogger.rb
vendored
Normal file
12
vendor/plugins/rack/test/spec_nulllogger.rb
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
require 'rack/nulllogger'
|
||||
|
||||
describe Rack::NullLogger do
|
||||
should "act as a noop logger" do
|
||||
app = lambda { |env|
|
||||
env['rack.logger'].warn "b00m"
|
||||
[200, {'Content-Type' => 'text/plain'}, ["Hello, World!"]]
|
||||
}
|
||||
logger = Rack::NullLogger.new(app)
|
||||
lambda{ logger.call({}) }.should.not.raise
|
||||
end
|
||||
end
|
69
vendor/plugins/rack/test/spec_recursive.rb
vendored
Normal file
69
vendor/plugins/rack/test/spec_recursive.rb
vendored
Normal file
|
@ -0,0 +1,69 @@
|
|||
require 'rack/recursive'
|
||||
require 'rack/mock'
|
||||
|
||||
describe Rack::Recursive do
|
||||
@app1 = lambda { |env|
|
||||
res = Rack::Response.new
|
||||
res["X-Path-Info"] = env["PATH_INFO"]
|
||||
res["X-Query-String"] = env["QUERY_STRING"]
|
||||
res.finish do |inner_res|
|
||||
inner_res.write "App1"
|
||||
end
|
||||
}
|
||||
|
||||
@app2 = lambda { |env|
|
||||
Rack::Response.new.finish do |res|
|
||||
res.write "App2"
|
||||
_, _, body = env['rack.recursive.include'].call(env, "/app1")
|
||||
body.each { |b|
|
||||
res.write b
|
||||
}
|
||||
end
|
||||
}
|
||||
|
||||
@app3 = lambda { |env|
|
||||
raise Rack::ForwardRequest.new("/app1")
|
||||
}
|
||||
|
||||
@app4 = lambda { |env|
|
||||
raise Rack::ForwardRequest.new("http://example.org/app1/quux?meh")
|
||||
}
|
||||
|
||||
should "allow for subrequests" do
|
||||
res = Rack::MockRequest.new(Rack::Recursive.new(
|
||||
Rack::URLMap.new("/app1" => @app1,
|
||||
"/app2" => @app2))).
|
||||
get("/app2")
|
||||
|
||||
res.should.be.ok
|
||||
res.body.should.equal "App2App1"
|
||||
end
|
||||
|
||||
should "raise error on requests not below the app" do
|
||||
app = Rack::URLMap.new("/app1" => @app1,
|
||||
"/app" => Rack::Recursive.new(
|
||||
Rack::URLMap.new("/1" => @app1,
|
||||
"/2" => @app2)))
|
||||
|
||||
lambda {
|
||||
Rack::MockRequest.new(app).get("/app/2")
|
||||
}.should.raise(ArgumentError).
|
||||
message.should =~ /can only include below/
|
||||
end
|
||||
|
||||
should "support forwarding" do
|
||||
app = Rack::Recursive.new(Rack::URLMap.new("/app1" => @app1,
|
||||
"/app3" => @app3,
|
||||
"/app4" => @app4))
|
||||
|
||||
res = Rack::MockRequest.new(app).get("/app3")
|
||||
res.should.be.ok
|
||||
res.body.should.equal "App1"
|
||||
|
||||
res = Rack::MockRequest.new(app).get("/app4")
|
||||
res.should.be.ok
|
||||
res.body.should.equal "App1"
|
||||
res["X-Path-Info"].should.equal "/quux"
|
||||
res["X-Query-String"].should.equal "meh"
|
||||
end
|
||||
end
|
580
vendor/plugins/rack/test/spec_request.rb
vendored
Normal file
580
vendor/plugins/rack/test/spec_request.rb
vendored
Normal file
|
@ -0,0 +1,580 @@
|
|||
require 'stringio'
|
||||
require 'cgi'
|
||||
require 'rack/request'
|
||||
require 'rack/mock'
|
||||
|
||||
describe Rack::Request do
|
||||
should "wrap the rack variables" do
|
||||
req = Rack::Request.new(Rack::MockRequest.env_for("http://example.com:8080/"))
|
||||
|
||||
req.body.should.respond_to? :gets
|
||||
req.scheme.should.equal "http"
|
||||
req.request_method.should.equal "GET"
|
||||
|
||||
req.should.be.get
|
||||
req.should.not.be.post
|
||||
req.should.not.be.put
|
||||
req.should.not.be.delete
|
||||
req.should.not.be.head
|
||||
|
||||
req.script_name.should.equal ""
|
||||
req.path_info.should.equal "/"
|
||||
req.query_string.should.equal ""
|
||||
|
||||
req.host.should.equal "example.com"
|
||||
req.port.should.equal 8080
|
||||
|
||||
req.content_length.should.equal "0"
|
||||
req.content_type.should.be.nil
|
||||
end
|
||||
|
||||
should "figure out the correct host" do
|
||||
req = Rack::Request.new \
|
||||
Rack::MockRequest.env_for("/", "HTTP_HOST" => "www2.example.org")
|
||||
req.host.should.equal "www2.example.org"
|
||||
|
||||
req = Rack::Request.new \
|
||||
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)
|
||||
req.host.should.equal ""
|
||||
end
|
||||
|
||||
should "parse the query string" do
|
||||
req = Rack::Request.new(Rack::MockRequest.env_for("/?foo=bar&quux=bla"))
|
||||
req.query_string.should.equal "foo=bar&quux=bla"
|
||||
req.GET.should.equal "foo" => "bar", "quux" => "bla"
|
||||
req.POST.should.be.empty
|
||||
req.params.should.equal "foo" => "bar", "quux" => "bla"
|
||||
end
|
||||
|
||||
should "raise if rack.input is missing" do
|
||||
req = Rack::Request.new({})
|
||||
lambda { req.POST }.should.raise(RuntimeError)
|
||||
end
|
||||
|
||||
should "parse POST data when method is POST and no Content-Type given" do
|
||||
req = Rack::Request.new \
|
||||
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"
|
||||
req.GET.should.equal "foo" => "quux"
|
||||
req.POST.should.equal "foo" => "bar", "quux" => "bla"
|
||||
req.params.should.equal "foo" => "bar", "quux" => "bla"
|
||||
end
|
||||
|
||||
should "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',
|
||||
:input => "foo=bar&quux=bla")
|
||||
req.content_type.should.equal 'application/x-www-form-urlencoded;foo=bar'
|
||||
req.media_type.should.equal 'application/x-www-form-urlencoded'
|
||||
req.media_type_params['foo'].should.equal 'bar'
|
||||
req.POST.should.equal "foo" => "bar", "quux" => "bla"
|
||||
req.params.should.equal "foo" => "bar", "quux" => "bla"
|
||||
end
|
||||
|
||||
should "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'
|
||||
req.media_type.should.equal 'text/plain'
|
||||
req.media_type_params['charset'].should.equal 'utf-8'
|
||||
req.POST.should.be.empty
|
||||
req.params.should.equal "foo" => "quux"
|
||||
req.body.read.should.equal "foo=bar&quux=bla"
|
||||
end
|
||||
|
||||
should "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
|
||||
|
||||
should "rewind input after parsing POST data" do
|
||||
input = StringIO.new("foo=bar&quux=bla")
|
||||
req = Rack::Request.new \
|
||||
Rack::MockRequest.env_for("/",
|
||||
"CONTENT_TYPE" => 'application/x-www-form-urlencoded;foo=bar',
|
||||
:input => input)
|
||||
req.params.should.equal "foo" => "bar", "quux" => "bla"
|
||||
input.read.should.equal "foo=bar&quux=bla"
|
||||
end
|
||||
|
||||
should "clean up Safari's ajax POST body" do
|
||||
req = Rack::Request.new \
|
||||
Rack::MockRequest.env_for("/",
|
||||
'REQUEST_METHOD' => 'POST', :input => "foo=bar&quux=bla\0")
|
||||
req.POST.should.equal "foo" => "bar", "quux" => "bla"
|
||||
end
|
||||
|
||||
should "get value by key from params with #[]" do
|
||||
req = Rack::Request.new \
|
||||
Rack::MockRequest.env_for("?foo=quux")
|
||||
req['foo'].should.equal 'quux'
|
||||
req[:foo].should.equal 'quux'
|
||||
end
|
||||
|
||||
should "set value to key on params with #[]=" do
|
||||
req = Rack::Request.new \
|
||||
Rack::MockRequest.env_for("?foo=duh")
|
||||
req['foo'].should.equal 'duh'
|
||||
req[:foo].should.equal 'duh'
|
||||
req.params.should.equal 'foo' => 'duh'
|
||||
|
||||
req['foo'] = 'bar'
|
||||
req.params.should.equal 'foo' => 'bar'
|
||||
req['foo'].should.equal 'bar'
|
||||
req[:foo].should.equal 'bar'
|
||||
|
||||
req[:foo] = 'jaz'
|
||||
req.params.should.equal 'foo' => 'jaz'
|
||||
req['foo'].should.equal 'jaz'
|
||||
req[:foo].should.equal 'jaz'
|
||||
end
|
||||
|
||||
should "return values for the keys in the order given from values_at" do
|
||||
req = Rack::Request.new \
|
||||
Rack::MockRequest.env_for("?foo=baz&wun=der&bar=ful")
|
||||
req.values_at('foo').should.equal ['baz']
|
||||
req.values_at('foo', 'wun').should.equal ['baz', 'der']
|
||||
req.values_at('bar', 'foo', 'wun').should.equal ['ful', 'baz', 'der']
|
||||
end
|
||||
|
||||
should "extract referrer correctly" do
|
||||
req = Rack::Request.new \
|
||||
Rack::MockRequest.env_for("/", "HTTP_REFERER" => "/some/path")
|
||||
req.referer.should.equal "/some/path"
|
||||
|
||||
req = Rack::Request.new \
|
||||
Rack::MockRequest.env_for("/")
|
||||
req.referer.should.equal "/"
|
||||
end
|
||||
|
||||
should "extract user agent correctly" 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
|
||||
|
||||
should "cache, but invalidates the cache" do
|
||||
req = Rack::Request.new \
|
||||
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"
|
||||
req.GET.should.equal "bla" => "foo"
|
||||
req.GET.should.equal "bla" => "foo"
|
||||
|
||||
req.POST.should.equal "foo" => "bar", "quux" => "bla"
|
||||
req.POST.should.equal "foo" => "bar", "quux" => "bla"
|
||||
req.env["rack.input"] = StringIO.new("foo=bla&quux=bar")
|
||||
req.POST.should.equal "foo" => "bla", "quux" => "bar"
|
||||
req.POST.should.equal "foo" => "bla", "quux" => "bar"
|
||||
end
|
||||
|
||||
should "figure out if called via XHR" do
|
||||
req = Rack::Request.new(Rack::MockRequest.env_for(""))
|
||||
req.should.not.be.xhr
|
||||
|
||||
req = Rack::Request.new \
|
||||
Rack::MockRequest.env_for("", "HTTP_X_REQUESTED_WITH" => "XMLHttpRequest")
|
||||
req.should.be.xhr
|
||||
end
|
||||
|
||||
should "parse cookies" do
|
||||
req = Rack::Request.new \
|
||||
Rack::MockRequest.env_for("", "HTTP_COOKIE" => "foo=bar;quux=h&m")
|
||||
req.cookies.should.equal "foo" => "bar", "quux" => "h&m"
|
||||
req.cookies.should.equal "foo" => "bar", "quux" => "h&m"
|
||||
req.env.delete("HTTP_COOKIE")
|
||||
req.cookies.should.equal({})
|
||||
end
|
||||
|
||||
should "parse cookies according to RFC 2109" do
|
||||
req = Rack::Request.new \
|
||||
Rack::MockRequest.env_for('', 'HTTP_COOKIE' => 'foo=bar;foo=car')
|
||||
req.cookies.should.equal 'foo' => 'bar'
|
||||
end
|
||||
|
||||
should "provide setters" do
|
||||
req = Rack::Request.new(e=Rack::MockRequest.env_for(""))
|
||||
req.script_name.should.equal ""
|
||||
req.script_name = "/foo"
|
||||
req.script_name.should.equal "/foo"
|
||||
e["SCRIPT_NAME"].should.equal "/foo"
|
||||
|
||||
req.path_info.should.equal "/"
|
||||
req.path_info = "/foo"
|
||||
req.path_info.should.equal "/foo"
|
||||
e["PATH_INFO"].should.equal "/foo"
|
||||
end
|
||||
|
||||
should "provide the original env" do
|
||||
req = Rack::Request.new(e = Rack::MockRequest.env_for(""))
|
||||
req.env.should == e
|
||||
end
|
||||
|
||||
should "restore the URL" do
|
||||
Rack::Request.new(Rack::MockRequest.env_for("")).url.
|
||||
should.equal "http://example.org/"
|
||||
Rack::Request.new(Rack::MockRequest.env_for("", "SCRIPT_NAME" => "/foo")).url.
|
||||
should.equal "http://example.org/foo/"
|
||||
Rack::Request.new(Rack::MockRequest.env_for("/foo")).url.
|
||||
should.equal "http://example.org/foo"
|
||||
Rack::Request.new(Rack::MockRequest.env_for("?foo")).url.
|
||||
should.equal "http://example.org/?foo"
|
||||
Rack::Request.new(Rack::MockRequest.env_for("http://example.org:8080/")).url.
|
||||
should.equal "http://example.org:8080/"
|
||||
Rack::Request.new(Rack::MockRequest.env_for("https://example.org/")).url.
|
||||
should.equal "https://example.org/"
|
||||
|
||||
Rack::Request.new(Rack::MockRequest.env_for("https://example.com:8080/foo?foo")).url.
|
||||
should.equal "https://example.com:8080/foo?foo"
|
||||
end
|
||||
|
||||
should "restore the full path" do
|
||||
Rack::Request.new(Rack::MockRequest.env_for("")).fullpath.
|
||||
should.equal "/"
|
||||
Rack::Request.new(Rack::MockRequest.env_for("", "SCRIPT_NAME" => "/foo")).fullpath.
|
||||
should.equal "/foo/"
|
||||
Rack::Request.new(Rack::MockRequest.env_for("/foo")).fullpath.
|
||||
should.equal "/foo"
|
||||
Rack::Request.new(Rack::MockRequest.env_for("?foo")).fullpath.
|
||||
should.equal "/?foo"
|
||||
Rack::Request.new(Rack::MockRequest.env_for("http://example.org:8080/")).fullpath.
|
||||
should.equal "/"
|
||||
Rack::Request.new(Rack::MockRequest.env_for("https://example.org/")).fullpath.
|
||||
should.equal "/"
|
||||
|
||||
Rack::Request.new(Rack::MockRequest.env_for("https://example.com:8080/foo?foo")).fullpath.
|
||||
should.equal "/foo?foo"
|
||||
end
|
||||
|
||||
should "handle multiple media type parameters" do
|
||||
req = Rack::Request.new \
|
||||
Rack::MockRequest.env_for("/",
|
||||
"CONTENT_TYPE" => 'text/plain; foo=BAR,baz=bizzle dizzle;BLING=bam')
|
||||
req.should.not.be.form_data
|
||||
req.media_type_params.should.include 'foo'
|
||||
req.media_type_params['foo'].should.equal 'BAR'
|
||||
req.media_type_params.should.include 'baz'
|
||||
req.media_type_params['baz'].should.equal 'bizzle dizzle'
|
||||
req.media_type_params.should.not.include 'BLING'
|
||||
req.media_type_params.should.include 'bling'
|
||||
req.media_type_params['bling'].should.equal 'bam'
|
||||
end
|
||||
|
||||
should "parse multipart form data" do
|
||||
# Adapted from RFC 1867.
|
||||
input = <<EOF
|
||||
--AaB03x\r
|
||||
content-disposition: form-data; name="reply"\r
|
||||
\r
|
||||
yes\r
|
||||
--AaB03x\r
|
||||
content-disposition: form-data; name="fileupload"; filename="dj.jpg"\r
|
||||
Content-Type: image/jpeg\r
|
||||
Content-Transfer-Encoding: base64\r
|
||||
\r
|
||||
/9j/4AAQSkZJRgABAQAAAQABAAD//gA+Q1JFQVRPUjogZ2QtanBlZyB2MS4wICh1c2luZyBJSkcg\r
|
||||
--AaB03x--\r
|
||||
EOF
|
||||
req = Rack::Request.new Rack::MockRequest.env_for("/",
|
||||
"CONTENT_TYPE" => "multipart/form-data, boundary=AaB03x",
|
||||
"CONTENT_LENGTH" => input.size,
|
||||
:input => input)
|
||||
|
||||
req.POST.should.include "fileupload"
|
||||
req.POST.should.include "reply"
|
||||
|
||||
req.should.be.form_data
|
||||
req.content_length.should.equal input.size
|
||||
req.media_type.should.equal 'multipart/form-data'
|
||||
req.media_type_params.should.include 'boundary'
|
||||
req.media_type_params['boundary'].should.equal 'AaB03x'
|
||||
|
||||
req.POST["reply"].should.equal "yes"
|
||||
|
||||
f = req.POST["fileupload"]
|
||||
f.should.be.kind_of Hash
|
||||
f[:type].should.equal "image/jpeg"
|
||||
f[:filename].should.equal "dj.jpg"
|
||||
f.should.include :tempfile
|
||||
f[:tempfile].size.should.equal 76
|
||||
end
|
||||
|
||||
should "parse big multipart form data" do
|
||||
input = <<EOF
|
||||
--AaB03x\r
|
||||
content-disposition: form-data; name="huge"; filename="huge"\r
|
||||
\r
|
||||
#{"x"*32768}\r
|
||||
--AaB03x\r
|
||||
content-disposition: form-data; name="mean"; filename="mean"\r
|
||||
\r
|
||||
--AaB03xha\r
|
||||
--AaB03x--\r
|
||||
EOF
|
||||
req = Rack::Request.new Rack::MockRequest.env_for("/",
|
||||
"CONTENT_TYPE" => "multipart/form-data, boundary=AaB03x",
|
||||
"CONTENT_LENGTH" => input.size,
|
||||
:input => input)
|
||||
|
||||
req.POST["huge"][:tempfile].size.should.equal 32768
|
||||
req.POST["mean"][:tempfile].size.should.equal 10
|
||||
req.POST["mean"][:tempfile].read.should.equal "--AaB03xha"
|
||||
end
|
||||
|
||||
should "detect invalid multipart form data" do
|
||||
input = <<EOF
|
||||
--AaB03x\r
|
||||
content-disposition: form-data; name="huge"; filename="huge"\r
|
||||
EOF
|
||||
req = Rack::Request.new Rack::MockRequest.env_for("/",
|
||||
"CONTENT_TYPE" => "multipart/form-data, boundary=AaB03x",
|
||||
"CONTENT_LENGTH" => input.size,
|
||||
:input => input)
|
||||
|
||||
lambda { req.POST }.should.raise(EOFError)
|
||||
|
||||
input = <<EOF
|
||||
--AaB03x\r
|
||||
content-disposition: form-data; name="huge"; filename="huge"\r
|
||||
\r
|
||||
foo\r
|
||||
EOF
|
||||
req = Rack::Request.new Rack::MockRequest.env_for("/",
|
||||
"CONTENT_TYPE" => "multipart/form-data, boundary=AaB03x",
|
||||
"CONTENT_LENGTH" => input.size,
|
||||
:input => input)
|
||||
|
||||
lambda { req.POST }.should.raise(EOFError)
|
||||
|
||||
input = <<EOF
|
||||
--AaB03x\r
|
||||
content-disposition: form-data; name="huge"; filename="huge"\r
|
||||
\r
|
||||
foo\r
|
||||
EOF
|
||||
req = Rack::Request.new Rack::MockRequest.env_for("/",
|
||||
"CONTENT_TYPE" => "multipart/form-data, boundary=AaB03x",
|
||||
"CONTENT_LENGTH" => input.size,
|
||||
:input => input)
|
||||
|
||||
lambda { req.POST }.should.raise(EOFError)
|
||||
end
|
||||
|
||||
should "not try to interpret binary as utf8" do
|
||||
if /regexp/.respond_to?(:kcode) # < 1.9
|
||||
begin
|
||||
original_kcode = $KCODE
|
||||
$KCODE='UTF8'
|
||||
|
||||
input = <<EOF
|
||||
--AaB03x\r
|
||||
content-disposition: form-data; name="fileupload"; filename="junk.a"\r
|
||||
content-type: application/octet-stream\r
|
||||
\r
|
||||
#{[0x36,0xCF,0x0A,0xF8].pack('c*')}\r
|
||||
--AaB03x--\r
|
||||
EOF
|
||||
|
||||
req = Rack::Request.new Rack::MockRequest.env_for("/",
|
||||
"CONTENT_TYPE" => "multipart/form-data, boundary=AaB03x",
|
||||
"CONTENT_LENGTH" => input.size,
|
||||
:input => input)
|
||||
|
||||
lambda{req.POST}.should.not.raise(EOFError)
|
||||
req.POST["fileupload"][:tempfile].size.should.equal 4
|
||||
ensure
|
||||
$KCODE = original_kcode
|
||||
end
|
||||
else # >= 1.9
|
||||
input = <<EOF
|
||||
--AaB03x\r
|
||||
content-disposition: form-data; name="fileupload"; filename="junk.a"\r
|
||||
content-type: application/octet-stream\r
|
||||
\r
|
||||
#{[0x36,0xCF,0x0A,0xF8].pack('c*')}\r
|
||||
--AaB03x--\r
|
||||
EOF
|
||||
|
||||
req = Rack::Request.new Rack::MockRequest.env_for("/",
|
||||
"CONTENT_TYPE" => "multipart/form-data, boundary=AaB03x",
|
||||
"CONTENT_LENGTH" => input.size,
|
||||
:input => input)
|
||||
|
||||
lambda{req.POST}.should.not.raise(EOFError)
|
||||
req.POST["fileupload"][:tempfile].size.should.equal 4
|
||||
end
|
||||
end
|
||||
|
||||
should "work around buggy 1.8.* Tempfile equality" do
|
||||
input = <<EOF
|
||||
--AaB03x\r
|
||||
content-disposition: form-data; name="huge"; filename="huge"\r
|
||||
\r
|
||||
foo\r
|
||||
--AaB03x--
|
||||
EOF
|
||||
|
||||
rack_input = Tempfile.new("rackspec")
|
||||
rack_input.write(input)
|
||||
rack_input.rewind
|
||||
|
||||
req = Rack::Request.new Rack::MockRequest.env_for("/",
|
||||
"CONTENT_TYPE" => "multipart/form-data, boundary=AaB03x",
|
||||
"CONTENT_LENGTH" => input.size,
|
||||
:input => rack_input)
|
||||
|
||||
lambda{ req.POST }.should.not.raise
|
||||
lambda{ req.POST }.should.not.raise("input re-processed!")
|
||||
end
|
||||
|
||||
should "conform to the Rack spec" do
|
||||
app = lambda { |env|
|
||||
content = Rack::Request.new(env).POST["file"].inspect
|
||||
size = content.respond_to?(:bytesize) ? content.bytesize : content.size
|
||||
[200, {"Content-Type" => "text/html", "Content-Length" => size.to_s}, [content]]
|
||||
}
|
||||
|
||||
input = <<EOF
|
||||
--AaB03x\r
|
||||
content-disposition: form-data; name="reply"\r
|
||||
\r
|
||||
yes\r
|
||||
--AaB03x\r
|
||||
content-disposition: form-data; name="fileupload"; filename="dj.jpg"\r
|
||||
Content-Type: image/jpeg\r
|
||||
Content-Transfer-Encoding: base64\r
|
||||
\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)
|
||||
|
||||
res.should.be.ok
|
||||
end
|
||||
|
||||
should "parse Accept-Encoding correctly" do
|
||||
parser = lambda do |x|
|
||||
Rack::Request.new(Rack::MockRequest.env_for("", "HTTP_ACCEPT_ENCODING" => x)).accept_encoding
|
||||
end
|
||||
|
||||
parser.call(nil).should.equal([])
|
||||
|
||||
parser.call("compress, gzip").should.equal([["compress", 1.0], ["gzip", 1.0]])
|
||||
parser.call("").should.equal([])
|
||||
parser.call("*").should.equal([["*", 1.0]])
|
||||
parser.call("compress;q=0.5, gzip;q=1.0").should.equal([["compress", 0.5], ["gzip", 1.0]])
|
||||
parser.call("gzip;q=1.0, identity; q=0.5, *;q=0").should.equal([["gzip", 1.0], ["identity", 0.5], ["*", 0] ])
|
||||
|
||||
lambda { parser.call("gzip ; q=1.0") }.should.raise(RuntimeError)
|
||||
end
|
||||
|
||||
should 'provide ip information' do
|
||||
app = lambda { |env|
|
||||
request = Rack::Request.new(env)
|
||||
response = Rack::Response.new
|
||||
response.write request.ip
|
||||
response.finish
|
||||
}
|
||||
|
||||
mock = Rack::MockRequest.new(Rack::Lint.new(app))
|
||||
res = mock.get '/', 'REMOTE_ADDR' => '123.123.123.123'
|
||||
res.body.should.equal '123.123.123.123'
|
||||
|
||||
res = mock.get '/',
|
||||
'REMOTE_ADDR' => '123.123.123.123',
|
||||
'HTTP_X_FORWARDED_FOR' => '234.234.234.234'
|
||||
|
||||
res.body.should.equal '234.234.234.234'
|
||||
|
||||
res = mock.get '/',
|
||||
'REMOTE_ADDR' => '123.123.123.123',
|
||||
'HTTP_X_FORWARDED_FOR' => '234.234.234.234,212.212.212.212'
|
||||
|
||||
res.body.should.equal '234.234.234.234'
|
||||
|
||||
res = mock.get '/',
|
||||
'REMOTE_ADDR' => '123.123.123.123',
|
||||
'HTTP_X_FORWARDED_FOR' => 'unknown,234.234.234.234,212.212.212.212'
|
||||
|
||||
res.body.should.equal '234.234.234.234'
|
||||
end
|
||||
|
||||
class MyRequest < Rack::Request
|
||||
def params
|
||||
{:foo => "bar"}
|
||||
end
|
||||
end
|
||||
|
||||
should "allow subclass request to be instantiated after parent request" do
|
||||
env = Rack::MockRequest.env_for("/?foo=bar")
|
||||
|
||||
req1 = Rack::Request.new(env)
|
||||
req1.GET.should.equal "foo" => "bar"
|
||||
req1.params.should.equal "foo" => "bar"
|
||||
|
||||
req2 = MyRequest.new(env)
|
||||
req2.GET.should.equal "foo" => "bar"
|
||||
req2.params.should.equal :foo => "bar"
|
||||
end
|
||||
|
||||
should "allow parent request to be instantiated after subclass request" do
|
||||
env = Rack::MockRequest.env_for("/?foo=bar")
|
||||
|
||||
req1 = MyRequest.new(env)
|
||||
req1.GET.should.equal "foo" => "bar"
|
||||
req1.params.should.equal :foo => "bar"
|
||||
|
||||
req2 = Rack::Request.new(env)
|
||||
req2.GET.should.equal "foo" => "bar"
|
||||
req2.params.should.equal "foo" => "bar"
|
||||
end
|
||||
|
||||
(0x20...0x7E).collect { |a|
|
||||
b = a.chr
|
||||
c = CGI.escape(b)
|
||||
should "not strip '#{a}' => '#{c}' => '#{b}' escaped character from parameters when accessed as string" do
|
||||
url = "/?foo=#{c}bar#{c}"
|
||||
env = Rack::MockRequest.env_for(url)
|
||||
req2 = Rack::Request.new(env)
|
||||
req2.GET.should.equal "foo" => "#{b}bar#{b}"
|
||||
req2.params.should.equal "foo" => "#{b}bar#{b}"
|
||||
end
|
||||
}
|
||||
end
|
240
vendor/plugins/rack/test/spec_response.rb
vendored
Normal file
240
vendor/plugins/rack/test/spec_response.rb
vendored
Normal file
|
@ -0,0 +1,240 @@
|
|||
require 'set'
|
||||
require 'rack/response'
|
||||
|
||||
describe Rack::Response do
|
||||
should "have sensible default values" do
|
||||
response = Rack::Response.new
|
||||
status, header, body = response.finish
|
||||
status.should.equal 200
|
||||
header.should.equal "Content-Type" => "text/html"
|
||||
body.each { |part|
|
||||
part.should.equal ""
|
||||
}
|
||||
|
||||
response = Rack::Response.new
|
||||
status, header, body = *response
|
||||
status.should.equal 200
|
||||
header.should.equal "Content-Type" => "text/html"
|
||||
body.each { |part|
|
||||
part.should.equal ""
|
||||
}
|
||||
end
|
||||
|
||||
it "can be written to" do
|
||||
response = Rack::Response.new
|
||||
|
||||
status, header, body = response.finish do
|
||||
response.write "foo"
|
||||
response.write "bar"
|
||||
response.write "baz"
|
||||
end
|
||||
|
||||
parts = []
|
||||
body.each { |part| parts << part }
|
||||
|
||||
parts.should.equal ["foo", "bar", "baz"]
|
||||
end
|
||||
|
||||
it "can set and read headers" do
|
||||
response = Rack::Response.new
|
||||
response["Content-Type"].should.equal "text/html"
|
||||
response["Content-Type"] = "text/plain"
|
||||
response["Content-Type"].should.equal "text/plain"
|
||||
end
|
||||
|
||||
it "can set cookies" do
|
||||
response = Rack::Response.new
|
||||
|
||||
response.set_cookie "foo", "bar"
|
||||
response["Set-Cookie"].should.equal "foo=bar"
|
||||
response.set_cookie "foo2", "bar2"
|
||||
response["Set-Cookie"].should.equal ["foo=bar", "foo2=bar2"].join("\n")
|
||||
response.set_cookie "foo3", "bar3"
|
||||
response["Set-Cookie"].should.equal ["foo=bar", "foo2=bar2", "foo3=bar3"].join("\n")
|
||||
end
|
||||
|
||||
it "can set cookies with the same name for multiple domains" do
|
||||
response = Rack::Response.new
|
||||
response.set_cookie "foo", {:value => "bar", :domain => "sample.example.com"}
|
||||
response.set_cookie "foo", {:value => "bar", :domain => ".example.com"}
|
||||
response["Set-Cookie"].should.equal ["foo=bar; domain=sample.example.com", "foo=bar; domain=.example.com"].join("\n")
|
||||
end
|
||||
|
||||
it "formats the Cookie expiration date accordingly to RFC 2109" do
|
||||
response = Rack::Response.new
|
||||
|
||||
response.set_cookie "foo", {:value => "bar", :expires => Time.now+10}
|
||||
response["Set-Cookie"].should.match(
|
||||
/expires=..., \d\d-...-\d\d\d\d \d\d:\d\d:\d\d .../)
|
||||
end
|
||||
|
||||
it "can set secure cookies" do
|
||||
response = Rack::Response.new
|
||||
response.set_cookie "foo", {:value => "bar", :secure => true}
|
||||
response["Set-Cookie"].should.equal "foo=bar; secure"
|
||||
end
|
||||
|
||||
it "can set http only cookies" do
|
||||
response = Rack::Response.new
|
||||
response.set_cookie "foo", {:value => "bar", :httponly => true}
|
||||
response["Set-Cookie"].should.equal "foo=bar; HttpOnly"
|
||||
end
|
||||
|
||||
it "can delete cookies" do
|
||||
response = Rack::Response.new
|
||||
response.set_cookie "foo", "bar"
|
||||
response.set_cookie "foo2", "bar2"
|
||||
response.delete_cookie "foo"
|
||||
response["Set-Cookie"].should.equal [
|
||||
"foo2=bar2",
|
||||
"foo=; expires=Thu, 01-Jan-1970 00:00:00 GMT"
|
||||
].join("\n")
|
||||
end
|
||||
|
||||
it "can delete cookies with the same name from multiple domains" do
|
||||
response = Rack::Response.new
|
||||
response.set_cookie "foo", {:value => "bar", :domain => "sample.example.com"}
|
||||
response.set_cookie "foo", {:value => "bar", :domain => ".example.com"}
|
||||
response["Set-Cookie"].should.equal ["foo=bar; domain=sample.example.com", "foo=bar; domain=.example.com"].join("\n")
|
||||
response.delete_cookie "foo", :domain => ".example.com"
|
||||
response["Set-Cookie"].should.equal ["foo=bar; domain=sample.example.com", "foo=; domain=.example.com; expires=Thu, 01-Jan-1970 00:00:00 GMT"].join("\n")
|
||||
response.delete_cookie "foo", :domain => "sample.example.com"
|
||||
response["Set-Cookie"].should.equal ["foo=; domain=.example.com; expires=Thu, 01-Jan-1970 00:00:00 GMT",
|
||||
"foo=; domain=sample.example.com; expires=Thu, 01-Jan-1970 00:00:00 GMT"].join("\n")
|
||||
end
|
||||
|
||||
it "can do redirects" do
|
||||
response = Rack::Response.new
|
||||
response.redirect "/foo"
|
||||
status, header, body = response.finish
|
||||
|
||||
status.should.equal 302
|
||||
header["Location"].should.equal "/foo"
|
||||
|
||||
response = Rack::Response.new
|
||||
response.redirect "/foo", 307
|
||||
status, header, body = response.finish
|
||||
|
||||
status.should.equal 307
|
||||
end
|
||||
|
||||
it "has a useful constructor" do
|
||||
r = Rack::Response.new("foo")
|
||||
status, header, body = r.finish
|
||||
str = ""; body.each { |part| str << part }
|
||||
str.should.equal "foo"
|
||||
|
||||
r = Rack::Response.new(["foo", "bar"])
|
||||
status, header, body = r.finish
|
||||
str = ""; body.each { |part| str << part }
|
||||
str.should.equal "foobar"
|
||||
|
||||
r = Rack::Response.new(["foo", "bar"].to_set)
|
||||
r.write "foo"
|
||||
status, header, body = r.finish
|
||||
str = ""; body.each { |part| str << part }
|
||||
str.should.equal "foobarfoo"
|
||||
|
||||
r = Rack::Response.new([], 500)
|
||||
r.status.should.equal 500
|
||||
|
||||
r = Rack::Response.new([], "200 OK")
|
||||
r.status.should.equal 200
|
||||
end
|
||||
|
||||
it "has a constructor that can take a block" do
|
||||
r = Rack::Response.new { |res|
|
||||
res.status = 404
|
||||
res.write "foo"
|
||||
}
|
||||
status, header, body = r.finish
|
||||
str = ""; body.each { |part| str << part }
|
||||
str.should.equal "foo"
|
||||
status.should.equal 404
|
||||
end
|
||||
|
||||
it "doesn't return invalid responses" do
|
||||
r = Rack::Response.new(["foo", "bar"], 204)
|
||||
status, header, body = r.finish
|
||||
str = ""; body.each { |part| str << part }
|
||||
str.should.be.empty
|
||||
header["Content-Type"].should.equal nil
|
||||
|
||||
lambda {
|
||||
Rack::Response.new(Object.new)
|
||||
}.should.raise(TypeError).
|
||||
message.should =~ /stringable or iterable required/
|
||||
end
|
||||
|
||||
it "knows if it's empty" do
|
||||
r = Rack::Response.new
|
||||
r.should.be.empty
|
||||
r.write "foo"
|
||||
r.should.not.be.empty
|
||||
|
||||
r = Rack::Response.new
|
||||
r.should.be.empty
|
||||
r.finish
|
||||
r.should.be.empty
|
||||
|
||||
r = Rack::Response.new
|
||||
r.should.be.empty
|
||||
r.finish { }
|
||||
r.should.not.be.empty
|
||||
end
|
||||
|
||||
should "provide access to the HTTP status" do
|
||||
res = Rack::Response.new
|
||||
res.status = 200
|
||||
res.should.be.successful
|
||||
res.should.be.ok
|
||||
|
||||
res.status = 404
|
||||
res.should.not.be.successful
|
||||
res.should.be.client_error
|
||||
res.should.be.not_found
|
||||
|
||||
res.status = 501
|
||||
res.should.not.be.successful
|
||||
res.should.be.server_error
|
||||
|
||||
res.status = 307
|
||||
res.should.be.redirect
|
||||
end
|
||||
|
||||
should "provide access to the HTTP headers" do
|
||||
res = Rack::Response.new
|
||||
res["Content-Type"] = "text/yaml"
|
||||
|
||||
res.should.include "Content-Type"
|
||||
res.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.nil
|
||||
res.location.should.be.nil
|
||||
end
|
||||
|
||||
it "does not add or change Content-Length when #finish()ing" do
|
||||
res = Rack::Response.new
|
||||
res.status = 200
|
||||
res.finish
|
||||
res.headers["Content-Length"].should.be.nil
|
||||
|
||||
res = Rack::Response.new
|
||||
res.status = 200
|
||||
res.headers["Content-Length"] = "10"
|
||||
res.finish
|
||||
res.headers["Content-Length"].should.equal "10"
|
||||
end
|
||||
|
||||
it "updates Content-Length when body appended to using #write" do
|
||||
res = Rack::Response.new
|
||||
res.status = 200
|
||||
res.headers["Content-Length"].should.be.nil
|
||||
res.write "Hi"
|
||||
res.headers["Content-Length"].should.equal "2"
|
||||
res.write " there"
|
||||
res.headers["Content-Length"].should.equal "8"
|
||||
end
|
||||
|
||||
end
|
118
vendor/plugins/rack/test/spec_rewindable_input.rb
vendored
Normal file
118
vendor/plugins/rack/test/spec_rewindable_input.rb
vendored
Normal file
|
@ -0,0 +1,118 @@
|
|||
require 'stringio'
|
||||
require 'rack/rewindable_input'
|
||||
|
||||
shared "a rewindable IO object" do
|
||||
before do
|
||||
@rio = Rack::RewindableInput.new(@io)
|
||||
end
|
||||
|
||||
should "be able to handle to read()" do
|
||||
@rio.read.should.equal "hello world"
|
||||
end
|
||||
|
||||
should "be able to handle to read(nil)" do
|
||||
@rio.read(nil).should.equal "hello world"
|
||||
end
|
||||
|
||||
should "be able to handle to read(length)" do
|
||||
@rio.read(1).should.equal "h"
|
||||
end
|
||||
|
||||
should "be able to handle to read(length, buffer)" do
|
||||
buffer = ""
|
||||
result = @rio.read(1, buffer)
|
||||
result.should.equal "h"
|
||||
result.object_id.should.equal buffer.object_id
|
||||
end
|
||||
|
||||
should "be able to handle to read(nil, buffer)" do
|
||||
buffer = ""
|
||||
result = @rio.read(nil, buffer)
|
||||
result.should.equal "hello world"
|
||||
result.object_id.should.equal buffer.object_id
|
||||
end
|
||||
|
||||
should "rewind to the beginning when #rewind is called" do
|
||||
@rio.read(1)
|
||||
@rio.rewind
|
||||
@rio.read.should.equal "hello world"
|
||||
end
|
||||
|
||||
should "be able to handle gets" do
|
||||
@rio.gets.should == "hello world"
|
||||
end
|
||||
|
||||
should "be able to handle each" do
|
||||
array = []
|
||||
@rio.each do |data|
|
||||
array << data
|
||||
end
|
||||
array.should.equal(["hello world"])
|
||||
end
|
||||
|
||||
should "not buffer into a Tempfile if no data has been read yet" do
|
||||
@rio.instance_variable_get(:@rewindable_io).should.be.nil
|
||||
end
|
||||
|
||||
should "buffer into a Tempfile when data has been consumed for the first time" do
|
||||
@rio.read(1)
|
||||
tempfile = @rio.instance_variable_get(:@rewindable_io)
|
||||
tempfile.should.not.be.nil
|
||||
@rio.read(1)
|
||||
tempfile2 = @rio.instance_variable_get(:@rewindable_io)
|
||||
tempfile2.path.should == tempfile.path
|
||||
end
|
||||
|
||||
should "close the underlying tempfile upon calling #close" do
|
||||
@rio.read(1)
|
||||
tempfile = @rio.instance_variable_get(:@rewindable_io)
|
||||
@rio.close
|
||||
tempfile.should.be.closed
|
||||
end
|
||||
|
||||
should "be possible to call #close when no data has been buffered yet" do
|
||||
lambda{ @rio.close }.should.not.raise
|
||||
end
|
||||
|
||||
should "be possible to call #close multiple times" do
|
||||
lambda{
|
||||
@rio.close
|
||||
@rio.close
|
||||
}.should.not.raise
|
||||
end
|
||||
|
||||
@rio.close
|
||||
@rio = nil
|
||||
end
|
||||
|
||||
describe Rack::RewindableInput do
|
||||
describe "given an IO object that is already rewindable" do
|
||||
before do
|
||||
@io = StringIO.new("hello world")
|
||||
end
|
||||
|
||||
behaves_like "a rewindable IO object"
|
||||
end
|
||||
|
||||
describe "given an IO object that is not rewindable" do
|
||||
before do
|
||||
@io = StringIO.new("hello world")
|
||||
@io.instance_eval do
|
||||
undef :rewind
|
||||
end
|
||||
end
|
||||
|
||||
behaves_like "a rewindable IO object"
|
||||
end
|
||||
|
||||
describe "given an IO object whose rewind method raises Errno::ESPIPE" do
|
||||
before do
|
||||
@io = StringIO.new("hello world")
|
||||
def @io.rewind
|
||||
raise Errno::ESPIPE, "You can't rewind this!"
|
||||
end
|
||||
end
|
||||
|
||||
behaves_like "a rewindable IO object"
|
||||
end
|
||||
end
|
39
vendor/plugins/rack/test/spec_runtime.rb
vendored
Normal file
39
vendor/plugins/rack/test/spec_runtime.rb
vendored
Normal file
|
@ -0,0 +1,39 @@
|
|||
require 'rack/runtime'
|
||||
|
||||
describe Rack::Runtime do
|
||||
it "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
|
||||
|
||||
it "doesn't 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
|
||||
|
||||
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
|
||||
|
||||
should "allow multiple timers to be set" do
|
||||
app = lambda { |env| sleep 0.1; [200, {'Content-Type' => 'text/plain'}, "Hello, World!"] }
|
||||
runtime = Rack::Runtime.new(app, "App")
|
||||
|
||||
# wrap many times to guarantee a measurable difference
|
||||
100.times do |i|
|
||||
runtime = Rack::Runtime.new(runtime, i.to_s)
|
||||
end
|
||||
runtime = Rack::Runtime.new(runtime, "All")
|
||||
|
||||
response = runtime.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
|
83
vendor/plugins/rack/test/spec_sendfile.rb
vendored
Normal file
83
vendor/plugins/rack/test/spec_sendfile.rb
vendored
Normal file
|
@ -0,0 +1,83 @@
|
|||
require 'rack/sendfile'
|
||||
require 'rack/mock'
|
||||
|
||||
describe Rack::File do
|
||||
should "respond to #to_path" do
|
||||
Rack::File.new(Dir.pwd).should.respond_to :to_path
|
||||
end
|
||||
end
|
||||
|
||||
describe 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
|
||||
|
||||
@request = Rack::MockRequest.new(sendfile_app)
|
||||
|
||||
def request(headers={})
|
||||
yield @request.get('/', headers)
|
||||
end
|
||||
|
||||
it "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
|
||||
|
||||
it "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
|
||||
|
||||
it "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
|
||||
|
||||
it "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
|
||||
|
||||
it '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
|
||||
|
||||
it '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
|
70
vendor/plugins/rack/test/spec_session_cookie.rb
vendored
Normal file
70
vendor/plugins/rack/test/spec_session_cookie.rb
vendored
Normal file
|
@ -0,0 +1,70 @@
|
|||
require 'rack/session/cookie'
|
||||
require 'rack/mock'
|
||||
|
||||
describe Rack::Session::Cookie do
|
||||
incrementor = lambda do |env|
|
||||
env["rack.session"]["counter"] ||= 0
|
||||
env["rack.session"]["counter"] += 1
|
||||
Rack::Response.new(env["rack.session"].inspect).to_a
|
||||
end
|
||||
|
||||
it "creates a new cookie" do
|
||||
res = Rack::MockRequest.new(Rack::Session::Cookie.new(incrementor)).get("/")
|
||||
res["Set-Cookie"].should.include("rack.session=")
|
||||
res.body.should.equal '{"counter"=>1}'
|
||||
end
|
||||
|
||||
it "loads from a cookie" do
|
||||
res = Rack::MockRequest.new(Rack::Session::Cookie.new(incrementor)).get("/")
|
||||
cookie = res["Set-Cookie"]
|
||||
res = Rack::MockRequest.new(Rack::Session::Cookie.new(incrementor)).
|
||||
get("/", "HTTP_COOKIE" => cookie)
|
||||
res.body.should.equal '{"counter"=>2}'
|
||||
cookie = res["Set-Cookie"]
|
||||
res = Rack::MockRequest.new(Rack::Session::Cookie.new(incrementor)).
|
||||
get("/", "HTTP_COOKIE" => cookie)
|
||||
res.body.should.equal '{"counter"=>3}'
|
||||
end
|
||||
|
||||
it "survives broken cookies" do
|
||||
res = Rack::MockRequest.new(Rack::Session::Cookie.new(incrementor)).
|
||||
get("/", "HTTP_COOKIE" => "rack.session=blarghfasel")
|
||||
res.body.should.equal '{"counter"=>1}'
|
||||
end
|
||||
|
||||
bigcookie = lambda do |env|
|
||||
env["rack.session"]["cookie"] = "big" * 3000
|
||||
Rack::Response.new(env["rack.session"].inspect).to_a
|
||||
end
|
||||
|
||||
it "barks on too big cookies" do
|
||||
lambda{
|
||||
Rack::MockRequest.new(Rack::Session::Cookie.new(bigcookie)).
|
||||
get("/", :fatal => true)
|
||||
}.should.raise(Rack::MockRequest::FatalWarning)
|
||||
end
|
||||
|
||||
it "loads from a cookie wih integrity hash" do
|
||||
res = Rack::MockRequest.new(Rack::Session::Cookie.new(incrementor, :secret => 'test')).get("/")
|
||||
cookie = res["Set-Cookie"]
|
||||
res = Rack::MockRequest.new(Rack::Session::Cookie.new(incrementor, :secret => 'test')).
|
||||
get("/", "HTTP_COOKIE" => cookie)
|
||||
res.body.should.equal '{"counter"=>2}'
|
||||
cookie = res["Set-Cookie"]
|
||||
res = Rack::MockRequest.new(Rack::Session::Cookie.new(incrementor, :secret => 'test')).
|
||||
get("/", "HTTP_COOKIE" => cookie)
|
||||
res.body.should.equal '{"counter"=>3}'
|
||||
end
|
||||
|
||||
it "ignores tampered with session cookies" do
|
||||
app = Rack::Session::Cookie.new(incrementor, :secret => 'test')
|
||||
response1 = Rack::MockRequest.new(app).get("/")
|
||||
_, digest = response1["Set-Cookie"].split("--")
|
||||
tampered_with_cookie = "hackerman-was-here" + "--" + digest
|
||||
response2 = Rack::MockRequest.new(app).get("/", "HTTP_COOKIE" =>
|
||||
tampered_with_cookie)
|
||||
|
||||
# The tampered-with cookie is ignored, so we get back an identical Set-Cookie
|
||||
response2["Set-Cookie"].should.equal(response1["Set-Cookie"])
|
||||
end
|
||||
end
|
282
vendor/plugins/rack/test/spec_session_memcache.rb
vendored
Normal file
282
vendor/plugins/rack/test/spec_session_memcache.rb
vendored
Normal file
|
@ -0,0 +1,282 @@
|
|||
begin
|
||||
require 'rack/session/memcache'
|
||||
require 'rack/mock'
|
||||
require 'thread'
|
||||
|
||||
describe Rack::Session::Memcache do
|
||||
session_key = Rack::Session::Memcache::DEFAULT_OPTIONS[:key]
|
||||
session_match = /#{session_key}=([0-9a-fA-F]+);/
|
||||
incrementor = lambda do |env|
|
||||
env["rack.session"]["counter"] ||= 0
|
||||
env["rack.session"]["counter"] += 1
|
||||
Rack::Response.new(env["rack.session"].inspect).to_a
|
||||
end
|
||||
drop_session = proc do |env|
|
||||
env['rack.session.options'][:drop] = true
|
||||
incrementor.call(env)
|
||||
end
|
||||
renew_session = proc do |env|
|
||||
env['rack.session.options'][:renew] = true
|
||||
incrementor.call(env)
|
||||
end
|
||||
defer_session = proc do |env|
|
||||
env['rack.session.options'][:defer] = true
|
||||
incrementor.call(env)
|
||||
end
|
||||
|
||||
# test memcache connection
|
||||
Rack::Session::Memcache.new(incrementor)
|
||||
|
||||
it "faults on no connection" do
|
||||
if RUBY_VERSION < "1.9"
|
||||
lambda{
|
||||
Rack::Session::Memcache.new(incrementor, :memcache_server => 'nosuchserver')
|
||||
}.should.raise
|
||||
else
|
||||
lambda{
|
||||
Rack::Session::Memcache.new(incrementor, :memcache_server => 'nosuchserver')
|
||||
}.should.raise ArgumentError
|
||||
end
|
||||
end
|
||||
|
||||
it "connects to existing server" do
|
||||
test_pool = MemCache.new(incrementor, :namespace => 'test:rack:session')
|
||||
test_pool.namespace.should.equal 'test:rack:session'
|
||||
end
|
||||
|
||||
it "passes options to MemCache" do
|
||||
pool = Rack::Session::Memcache.new(incrementor, :namespace => 'test:rack:session')
|
||||
pool.pool.namespace.should.equal 'test:rack:session'
|
||||
end
|
||||
|
||||
it "creates a new cookie" do
|
||||
pool = Rack::Session::Memcache.new(incrementor)
|
||||
res = Rack::MockRequest.new(pool).get("/")
|
||||
res["Set-Cookie"].should.include("#{session_key}=")
|
||||
res.body.should.equal '{"counter"=>1}'
|
||||
end
|
||||
|
||||
it "determines session from a cookie" do
|
||||
pool = Rack::Session::Memcache.new(incrementor)
|
||||
req = Rack::MockRequest.new(pool)
|
||||
res = req.get("/")
|
||||
cookie = res["Set-Cookie"]
|
||||
req.get("/", "HTTP_COOKIE" => cookie).
|
||||
body.should.equal '{"counter"=>2}'
|
||||
req.get("/", "HTTP_COOKIE" => cookie).
|
||||
body.should.equal '{"counter"=>3}'
|
||||
end
|
||||
|
||||
it "survives nonexistant cookies" do
|
||||
bad_cookie = "rack.session=blarghfasel"
|
||||
pool = Rack::Session::Memcache.new(incrementor)
|
||||
res = Rack::MockRequest.new(pool).
|
||||
get("/", "HTTP_COOKIE" => bad_cookie)
|
||||
res.body.should.equal '{"counter"=>1}'
|
||||
cookie = res["Set-Cookie"][session_match]
|
||||
cookie.should.not.match(/#{bad_cookie}/)
|
||||
end
|
||||
|
||||
it "maintains freshness" do
|
||||
pool = Rack::Session::Memcache.new(incrementor, :expire_after => 3)
|
||||
res = Rack::MockRequest.new(pool).get('/')
|
||||
res.body.should.include '"counter"=>1'
|
||||
cookie = res["Set-Cookie"]
|
||||
res = Rack::MockRequest.new(pool).get('/', "HTTP_COOKIE" => cookie)
|
||||
res["Set-Cookie"].should.equal cookie
|
||||
res.body.should.include '"counter"=>2'
|
||||
puts 'Sleeping to expire session' if $DEBUG
|
||||
sleep 4
|
||||
res = Rack::MockRequest.new(pool).get('/', "HTTP_COOKIE" => cookie)
|
||||
res["Set-Cookie"].should.not.equal cookie
|
||||
res.body.should.include '"counter"=>1'
|
||||
end
|
||||
|
||||
it "deletes cookies with :drop option" do
|
||||
pool = Rack::Session::Memcache.new(incrementor)
|
||||
req = Rack::MockRequest.new(pool)
|
||||
drop = Rack::Utils::Context.new(pool, drop_session)
|
||||
dreq = Rack::MockRequest.new(drop)
|
||||
|
||||
res0 = req.get("/")
|
||||
session = (cookie = res0["Set-Cookie"])[session_match]
|
||||
res0.body.should.equal '{"counter"=>1}'
|
||||
|
||||
res1 = req.get("/", "HTTP_COOKIE" => cookie)
|
||||
res1["Set-Cookie"][session_match].should.equal session
|
||||
res1.body.should.equal '{"counter"=>2}'
|
||||
|
||||
res2 = dreq.get("/", "HTTP_COOKIE" => cookie)
|
||||
res2["Set-Cookie"].should.equal nil
|
||||
res2.body.should.equal '{"counter"=>3}'
|
||||
|
||||
res3 = req.get("/", "HTTP_COOKIE" => cookie)
|
||||
res3["Set-Cookie"][session_match].should.not.equal session
|
||||
res3.body.should.equal '{"counter"=>1}'
|
||||
end
|
||||
|
||||
it "provides new session id with :renew option" do
|
||||
pool = Rack::Session::Memcache.new(incrementor)
|
||||
req = Rack::MockRequest.new(pool)
|
||||
renew = Rack::Utils::Context.new(pool, renew_session)
|
||||
rreq = Rack::MockRequest.new(renew)
|
||||
|
||||
res0 = req.get("/")
|
||||
session = (cookie = res0["Set-Cookie"])[session_match]
|
||||
res0.body.should.equal '{"counter"=>1}'
|
||||
|
||||
res1 = req.get("/", "HTTP_COOKIE" => cookie)
|
||||
res1["Set-Cookie"][session_match].should.equal session
|
||||
res1.body.should.equal '{"counter"=>2}'
|
||||
|
||||
res2 = rreq.get("/", "HTTP_COOKIE" => cookie)
|
||||
new_cookie = res2["Set-Cookie"]
|
||||
new_session = new_cookie[session_match]
|
||||
new_session.should.not.equal session
|
||||
res2.body.should.equal '{"counter"=>3}'
|
||||
|
||||
res3 = req.get("/", "HTTP_COOKIE" => new_cookie)
|
||||
res3["Set-Cookie"][session_match].should.equal new_session
|
||||
res3.body.should.equal '{"counter"=>4}'
|
||||
end
|
||||
|
||||
it "omits cookie with :defer option" do
|
||||
pool = Rack::Session::Memcache.new(incrementor)
|
||||
req = Rack::MockRequest.new(pool)
|
||||
defer = Rack::Utils::Context.new(pool, defer_session)
|
||||
dreq = Rack::MockRequest.new(defer)
|
||||
|
||||
res0 = req.get("/")
|
||||
session = (cookie = res0["Set-Cookie"])[session_match]
|
||||
res0.body.should.equal '{"counter"=>1}'
|
||||
|
||||
res1 = req.get("/", "HTTP_COOKIE" => cookie)
|
||||
res1["Set-Cookie"][session_match].should.equal session
|
||||
res1.body.should.equal '{"counter"=>2}'
|
||||
|
||||
res2 = dreq.get("/", "HTTP_COOKIE" => cookie)
|
||||
res2["Set-Cookie"].should.equal nil
|
||||
res2.body.should.equal '{"counter"=>3}'
|
||||
|
||||
res3 = req.get("/", "HTTP_COOKIE" => cookie)
|
||||
res3["Set-Cookie"][session_match].should.equal session
|
||||
res3.body.should.equal '{"counter"=>4}'
|
||||
end
|
||||
|
||||
it "updates deep hashes correctly" 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?
|
||||
it "cleanly merges sessions when multithreaded" do
|
||||
unless $DEBUG
|
||||
1.should.equal 1 # fake assertion to appease the mighty bacon
|
||||
next
|
||||
end
|
||||
warn 'Running multithread test for Session::Memcache'
|
||||
pool = Rack::Session::Memcache.new(incrementor)
|
||||
req = Rack::MockRequest.new(pool)
|
||||
|
||||
res = req.get('/')
|
||||
res.body.should.equal '{"counter"=>1}'
|
||||
cookie = res["Set-Cookie"]
|
||||
session_id = cookie[session_match, 1]
|
||||
|
||||
delta_incrementor = lambda do |env|
|
||||
# emulate disconjoinment of threading
|
||||
env['rack.session'] = env['rack.session'].dup
|
||||
Thread.stop
|
||||
env['rack.session'][(Time.now.usec*rand).to_i] = true
|
||||
incrementor.call(env)
|
||||
end
|
||||
tses = Rack::Utils::Context.new pool, delta_incrementor
|
||||
treq = Rack::MockRequest.new(tses)
|
||||
tnum = rand(7).to_i+5
|
||||
r = Array.new(tnum) do
|
||||
Thread.new(treq) do |run|
|
||||
run.get('/', "HTTP_COOKIE" => cookie, 'rack.multithread' => true)
|
||||
end
|
||||
end.reverse.map{|t| t.run.join.value }
|
||||
r.each do |request|
|
||||
request['Set-Cookie'].should.equal cookie
|
||||
request.body.should.include '"counter"=>2'
|
||||
end
|
||||
|
||||
session = pool.pool.get(session_id)
|
||||
session.size.should.equal tnum+1 # counter
|
||||
session['counter'].should.equal 2 # meeeh
|
||||
|
||||
tnum = rand(7).to_i+5
|
||||
r = Array.new(tnum) do |i|
|
||||
delta_time = proc do |env|
|
||||
env['rack.session'][i] = Time.now
|
||||
Thread.stop
|
||||
env['rack.session'] = env['rack.session'].dup
|
||||
env['rack.session'][i] -= Time.now
|
||||
incrementor.call(env)
|
||||
end
|
||||
app = Rack::Utils::Context.new pool, time_delta
|
||||
req = Rack::MockRequest.new app
|
||||
Thread.new(req) do |run|
|
||||
run.get('/', "HTTP_COOKIE" => cookie, 'rack.multithread' => true)
|
||||
end
|
||||
end.reverse.map{|t| t.run.join.value }
|
||||
r.each do |request|
|
||||
request['Set-Cookie'].should.equal cookie
|
||||
request.body.should.include '"counter"=>3'
|
||||
end
|
||||
|
||||
session = pool.pool.get(session_id)
|
||||
session.size.should.be tnum+1
|
||||
session['counter'].should.be 3
|
||||
|
||||
drop_counter = proc do |env|
|
||||
env['rack.session'].delete 'counter'
|
||||
env['rack.session']['foo'] = 'bar'
|
||||
[200, {'Content-Type'=>'text/plain'}, env['rack.session'].inspect]
|
||||
end
|
||||
tses = Rack::Utils::Context.new pool, drop_counter
|
||||
treq = Rack::MockRequest.new(tses)
|
||||
tnum = rand(7).to_i+5
|
||||
r = Array.new(tnum) do
|
||||
Thread.new(treq) do |run|
|
||||
run.get('/', "HTTP_COOKIE" => cookie, 'rack.multithread' => true)
|
||||
end
|
||||
end.reverse.map{|t| t.run.join.value }
|
||||
r.each do |request|
|
||||
request['Set-Cookie'].should.equal cookie
|
||||
request.body.should.include '"foo"=>"bar"'
|
||||
end
|
||||
|
||||
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
|
177
vendor/plugins/rack/test/spec_session_pool.rb
vendored
Normal file
177
vendor/plugins/rack/test/spec_session_pool.rb
vendored
Normal file
|
@ -0,0 +1,177 @@
|
|||
require 'thread'
|
||||
require 'rack/mock'
|
||||
require 'rack/session/pool'
|
||||
|
||||
describe Rack::Session::Pool do
|
||||
session_key = Rack::Session::Pool::DEFAULT_OPTIONS[:key]
|
||||
session_match = /#{session_key}=[0-9a-fA-F]+;/
|
||||
|
||||
incrementor = lambda do |env|
|
||||
env["rack.session"]["counter"] ||= 0
|
||||
env["rack.session"]["counter"] += 1
|
||||
Rack::Response.new(env["rack.session"].inspect).to_a
|
||||
end
|
||||
|
||||
drop_session = lambda do |env|
|
||||
env['rack.session.options'][:drop] = true
|
||||
incrementor.call(env)
|
||||
end
|
||||
|
||||
renew_session = lambda do |env|
|
||||
env['rack.session.options'][:renew] = true
|
||||
incrementor.call(env)
|
||||
end
|
||||
|
||||
defer_session = lambda do |env|
|
||||
env['rack.session.options'][:defer] = true
|
||||
incrementor.call(env)
|
||||
end
|
||||
|
||||
it "creates a new cookie" do
|
||||
pool = Rack::Session::Pool.new(incrementor)
|
||||
res = Rack::MockRequest.new(pool).get("/")
|
||||
res["Set-Cookie"].should.match session_match
|
||||
res.body.should.equal '{"counter"=>1}'
|
||||
end
|
||||
|
||||
it "determines session from a cookie" do
|
||||
pool = Rack::Session::Pool.new(incrementor)
|
||||
req = Rack::MockRequest.new(pool)
|
||||
cookie = req.get("/")["Set-Cookie"]
|
||||
req.get("/", "HTTP_COOKIE" => cookie).
|
||||
body.should.equal '{"counter"=>2}'
|
||||
req.get("/", "HTTP_COOKIE" => cookie).
|
||||
body.should.equal '{"counter"=>3}'
|
||||
end
|
||||
|
||||
it "survives nonexistant cookies" do
|
||||
pool = Rack::Session::Pool.new(incrementor)
|
||||
res = Rack::MockRequest.new(pool).
|
||||
get("/", "HTTP_COOKIE" => "#{session_key}=blarghfasel")
|
||||
res.body.should.equal '{"counter"=>1}'
|
||||
end
|
||||
|
||||
it "deletes cookies with :drop option" do
|
||||
pool = Rack::Session::Pool.new(incrementor)
|
||||
req = Rack::MockRequest.new(pool)
|
||||
drop = Rack::Utils::Context.new(pool, drop_session)
|
||||
dreq = Rack::MockRequest.new(drop)
|
||||
|
||||
res0 = req.get("/")
|
||||
session = (cookie = res0["Set-Cookie"])[session_match]
|
||||
res0.body.should.equal '{"counter"=>1}'
|
||||
pool.pool.size.should.equal 1
|
||||
|
||||
res1 = req.get("/", "HTTP_COOKIE" => cookie)
|
||||
res1["Set-Cookie"][session_match].should.equal session
|
||||
res1.body.should.equal '{"counter"=>2}'
|
||||
pool.pool.size.should.equal 1
|
||||
|
||||
res2 = dreq.get("/", "HTTP_COOKIE" => cookie)
|
||||
res2["Set-Cookie"].should.equal nil
|
||||
res2.body.should.equal '{"counter"=>3}'
|
||||
pool.pool.size.should.equal 0
|
||||
|
||||
res3 = req.get("/", "HTTP_COOKIE" => cookie)
|
||||
res3["Set-Cookie"][session_match].should.not.equal session
|
||||
res3.body.should.equal '{"counter"=>1}'
|
||||
pool.pool.size.should.equal 1
|
||||
end
|
||||
|
||||
it "provides new session id with :renew option" do
|
||||
pool = Rack::Session::Pool.new(incrementor)
|
||||
req = Rack::MockRequest.new(pool)
|
||||
renew = Rack::Utils::Context.new(pool, renew_session)
|
||||
rreq = Rack::MockRequest.new(renew)
|
||||
|
||||
res0 = req.get("/")
|
||||
session = (cookie = res0["Set-Cookie"])[session_match]
|
||||
res0.body.should.equal '{"counter"=>1}'
|
||||
pool.pool.size.should.equal 1
|
||||
|
||||
res1 = req.get("/", "HTTP_COOKIE" => cookie)
|
||||
res1["Set-Cookie"][session_match].should.equal session
|
||||
res1.body.should.equal '{"counter"=>2}'
|
||||
pool.pool.size.should.equal 1
|
||||
|
||||
res2 = rreq.get("/", "HTTP_COOKIE" => cookie)
|
||||
new_cookie = res2["Set-Cookie"]
|
||||
new_session = new_cookie[session_match]
|
||||
new_session.should.not.equal session
|
||||
res2.body.should.equal '{"counter"=>3}'
|
||||
pool.pool.size.should.equal 1
|
||||
|
||||
res3 = req.get("/", "HTTP_COOKIE" => new_cookie)
|
||||
res3["Set-Cookie"][session_match].should.equal new_session
|
||||
res3.body.should.equal '{"counter"=>4}'
|
||||
pool.pool.size.should.equal 1
|
||||
end
|
||||
|
||||
it "omits cookie with :defer option" do
|
||||
pool = Rack::Session::Pool.new(incrementor)
|
||||
req = Rack::MockRequest.new(pool)
|
||||
defer = Rack::Utils::Context.new(pool, defer_session)
|
||||
dreq = Rack::MockRequest.new(defer)
|
||||
|
||||
res0 = req.get("/")
|
||||
session = (cookie = res0["Set-Cookie"])[session_match]
|
||||
res0.body.should.equal '{"counter"=>1}'
|
||||
pool.pool.size.should.equal 1
|
||||
|
||||
res1 = req.get("/", "HTTP_COOKIE" => cookie)
|
||||
res1["Set-Cookie"][session_match].should.equal session
|
||||
res1.body.should.equal '{"counter"=>2}'
|
||||
pool.pool.size.should.equal 1
|
||||
|
||||
res2 = dreq.get("/", "HTTP_COOKIE" => cookie)
|
||||
res2["Set-Cookie"].should.equal nil
|
||||
res2.body.should.equal '{"counter"=>3}'
|
||||
pool.pool.size.should.equal 1
|
||||
|
||||
res3 = req.get("/", "HTTP_COOKIE" => cookie)
|
||||
res3["Set-Cookie"][session_match].should.equal session
|
||||
res3.body.should.equal '{"counter"=>4}'
|
||||
pool.pool.size.should.equal 1
|
||||
end
|
||||
|
||||
# anyone know how to do this better?
|
||||
it "should merge sessions when multithreaded" do
|
||||
unless $DEBUG
|
||||
1.should.equal 1
|
||||
next
|
||||
end
|
||||
|
||||
warn 'Running multithread tests for Session::Pool'
|
||||
pool = Rack::Session::Pool.new(incrementor)
|
||||
req = Rack::MockRequest.new(pool)
|
||||
|
||||
res = req.get('/')
|
||||
res.body.should.equal '{"counter"=>1}'
|
||||
cookie = res["Set-Cookie"]
|
||||
sess_id = cookie[/#{pool.key}=([^,;]+)/,1]
|
||||
|
||||
delta_incrementor = lambda do |env|
|
||||
# emulate disconjoinment of threading
|
||||
env['rack.session'] = env['rack.session'].dup
|
||||
Thread.stop
|
||||
env['rack.session'][(Time.now.usec*rand).to_i] = true
|
||||
incrementor.call(env)
|
||||
end
|
||||
tses = Rack::Utils::Context.new pool, delta_incrementor
|
||||
treq = Rack::MockRequest.new(tses)
|
||||
tnum = rand(7).to_i+5
|
||||
r = Array.new(tnum) do
|
||||
Thread.new(treq) do |run|
|
||||
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'
|
||||
end
|
||||
|
||||
session = pool.pool[sess_id]
|
||||
session.size.should.equal tnum+1 # counter
|
||||
session['counter'].should.equal 2 # meeeh
|
||||
end
|
||||
end
|
23
vendor/plugins/rack/test/spec_showexceptions.rb
vendored
Normal file
23
vendor/plugins/rack/test/spec_showexceptions.rb
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
require 'rack/showexceptions'
|
||||
require 'rack/mock'
|
||||
|
||||
describe Rack::ShowExceptions do
|
||||
it "catches exceptions" do
|
||||
res = nil
|
||||
|
||||
req = Rack::MockRequest.new(
|
||||
Rack::ShowExceptions.new(
|
||||
lambda{|env| raise RuntimeError }
|
||||
))
|
||||
|
||||
lambda{
|
||||
res = req.get("/")
|
||||
}.should.not.raise
|
||||
|
||||
res.should.be.a.server_error
|
||||
res.status.should.equal 500
|
||||
|
||||
res.should =~ /RuntimeError/
|
||||
res.should =~ /ShowExceptions/
|
||||
end
|
||||
end
|
79
vendor/plugins/rack/test/spec_showstatus.rb
vendored
Normal file
79
vendor/plugins/rack/test/spec_showstatus.rb
vendored
Normal file
|
@ -0,0 +1,79 @@
|
|||
require 'rack/showstatus'
|
||||
require 'rack/mock'
|
||||
|
||||
describe Rack::ShowStatus do
|
||||
should "provide a default status message" do
|
||||
req = Rack::MockRequest.new(
|
||||
Rack::ShowStatus.new(lambda{|env|
|
||||
[404, {"Content-Type" => "text/plain", "Content-Length" => "0"}, []]
|
||||
}))
|
||||
|
||||
res = req.get("/", :lint => true)
|
||||
res.should.be.not_found
|
||||
res.should.be.not.empty
|
||||
|
||||
res["Content-Type"].should.equal("text/html")
|
||||
res.should =~ /404/
|
||||
res.should =~ /Not Found/
|
||||
end
|
||||
|
||||
should "let the app provide additional information" do
|
||||
req = Rack::MockRequest.new(
|
||||
Rack::ShowStatus.new(
|
||||
lambda{|env|
|
||||
env["rack.showstatus.detail"] = "gone too meta."
|
||||
[404, {"Content-Type" => "text/plain", "Content-Length" => "0"}, []]
|
||||
}))
|
||||
|
||||
res = req.get("/", :lint => true)
|
||||
res.should.be.not_found
|
||||
res.should.be.not.empty
|
||||
|
||||
res["Content-Type"].should.equal("text/html")
|
||||
res.should =~ /404/
|
||||
res.should =~ /Not Found/
|
||||
res.should =~ /too meta/
|
||||
end
|
||||
|
||||
should "not replace existing messages" do
|
||||
req = Rack::MockRequest.new(
|
||||
Rack::ShowStatus.new(
|
||||
lambda{|env|
|
||||
[404, {"Content-Type" => "text/plain", "Content-Length" => "4"}, ["foo!"]]
|
||||
}))
|
||||
|
||||
res = req.get("/", :lint => true)
|
||||
res.should.be.not_found
|
||||
|
||||
res.body.should == "foo!"
|
||||
end
|
||||
|
||||
should "pass on original headers" do
|
||||
headers = {"WWW-Authenticate" => "Basic blah"}
|
||||
|
||||
req = Rack::MockRequest.new(
|
||||
Rack::ShowStatus.new(lambda{|env| [401, headers, []] }))
|
||||
res = req.get("/", :lint => true)
|
||||
|
||||
res["WWW-Authenticate"].should.equal("Basic blah")
|
||||
end
|
||||
|
||||
should "replace existing messages if there is detail" do
|
||||
req = Rack::MockRequest.new(
|
||||
Rack::ShowStatus.new(
|
||||
lambda{|env|
|
||||
env["rack.showstatus.detail"] = "gone too meta."
|
||||
[404, {"Content-Type" => "text/plain", "Content-Length" => "4"}, ["foo!"]]
|
||||
}))
|
||||
|
||||
res = req.get("/", :lint => true)
|
||||
res.should.be.not_found
|
||||
res.should.be.not.empty
|
||||
|
||||
res["Content-Type"].should.equal("text/html")
|
||||
res["Content-Length"].should.not.equal("4")
|
||||
res.should =~ /404/
|
||||
res.should =~ /too meta/
|
||||
res.body.should.not =~ /foo/
|
||||
end
|
||||
end
|
33
vendor/plugins/rack/test/spec_static.rb
vendored
Normal file
33
vendor/plugins/rack/test/spec_static.rb
vendored
Normal file
|
@ -0,0 +1,33 @@
|
|||
require 'rack/static'
|
||||
require 'rack/mock'
|
||||
|
||||
class DummyApp
|
||||
def call(env)
|
||||
[200, {}, ["Hello World"]]
|
||||
end
|
||||
end
|
||||
|
||||
describe Rack::Static do
|
||||
root = File.expand_path(File.dirname(__FILE__))
|
||||
OPTIONS = {:urls => ["/cgi"], :root => root}
|
||||
|
||||
@request = Rack::MockRequest.new(Rack::Static.new(DummyApp.new, OPTIONS))
|
||||
|
||||
it "serves files" do
|
||||
res = @request.get("/cgi/test")
|
||||
res.should.be.ok
|
||||
res.body.should =~ /ruby/
|
||||
end
|
||||
|
||||
it "404s if url root is known but it can't find the file" do
|
||||
res = @request.get("/cgi/foo")
|
||||
res.should.be.not_found
|
||||
end
|
||||
|
||||
it "calls down the chain if url root is not known" do
|
||||
res = @request.get("/something/else")
|
||||
res.should.be.ok
|
||||
res.body.should == "Hello World"
|
||||
end
|
||||
|
||||
end
|
86
vendor/plugins/rack/test/spec_thin.rb
vendored
Normal file
86
vendor/plugins/rack/test/spec_thin.rb
vendored
Normal file
|
@ -0,0 +1,86 @@
|
|||
begin
|
||||
require 'rack/handler/thin'
|
||||
require File.expand_path('../testrequest', __FILE__)
|
||||
require 'timeout'
|
||||
|
||||
describe Rack::Handler::Thin do
|
||||
extend TestRequest::Helpers
|
||||
|
||||
@app = Rack::Lint.new(TestRequest.new)
|
||||
@server = nil
|
||||
Thin::Logging.silent = true
|
||||
|
||||
@thread = Thread.new do
|
||||
Rack::Handler::Thin.run(@app, :Host => @host='0.0.0.0', :Port => @port=9204) do |server|
|
||||
@server = server
|
||||
end
|
||||
end
|
||||
|
||||
Thread.pass until @server && @server.running?
|
||||
|
||||
should "respond" do
|
||||
GET("/")
|
||||
response.should.not.be.nil
|
||||
end
|
||||
|
||||
should "be a Thin" do
|
||||
GET("/")
|
||||
status.should.equal 200
|
||||
response["SERVER_SOFTWARE"].should =~ /thin/
|
||||
response["HTTP_VERSION"].should.equal "HTTP/1.1"
|
||||
response["SERVER_PROTOCOL"].should.equal "HTTP/1.1"
|
||||
response["SERVER_PORT"].should.equal "9204"
|
||||
response["SERVER_NAME"].should.equal "0.0.0.0"
|
||||
end
|
||||
|
||||
should "have rack headers" do
|
||||
GET("/")
|
||||
response["rack.version"].should.equal [1,0]
|
||||
response["rack.multithread"].should.equal false
|
||||
response["rack.multiprocess"].should.equal false
|
||||
response["rack.run_once"].should.equal false
|
||||
end
|
||||
|
||||
should "have CGI headers on GET" do
|
||||
GET("/")
|
||||
response["REQUEST_METHOD"].should.equal "GET"
|
||||
response["REQUEST_PATH"].should.equal "/"
|
||||
response["PATH_INFO"].should.be.equal "/"
|
||||
response["QUERY_STRING"].should.equal ""
|
||||
response["test.postdata"].should.equal ""
|
||||
|
||||
GET("/test/foo?quux=1")
|
||||
response["REQUEST_METHOD"].should.equal "GET"
|
||||
response["REQUEST_PATH"].should.equal "/test/foo"
|
||||
response["PATH_INFO"].should.equal "/test/foo"
|
||||
response["QUERY_STRING"].should.equal "quux=1"
|
||||
end
|
||||
|
||||
should "have CGI headers on POST" do
|
||||
POST("/", {"rack-form-data" => "23"}, {'X-test-header' => '42'})
|
||||
status.should.equal 200
|
||||
response["REQUEST_METHOD"].should.equal "POST"
|
||||
response["REQUEST_PATH"].should.equal "/"
|
||||
response["QUERY_STRING"].should.equal ""
|
||||
response["HTTP_X_TEST_HEADER"].should.equal "42"
|
||||
response["test.postdata"].should.equal "rack-form-data=23"
|
||||
end
|
||||
|
||||
should "support HTTP auth" do
|
||||
GET("/test", {:user => "ruth", :passwd => "secret"})
|
||||
response["HTTP_AUTHORIZATION"].should.equal "Basic cnV0aDpzZWNyZXQ="
|
||||
end
|
||||
|
||||
should "set status" do
|
||||
GET("/test?secret")
|
||||
status.should.equal 403
|
||||
response["rack.url_scheme"].should.equal "http"
|
||||
end
|
||||
|
||||
@server.stop!
|
||||
@thread.kill
|
||||
end
|
||||
|
||||
rescue LoadError
|
||||
$stderr.puts "Skipping Rack::Handler::Thin tests (Thin is required). `gem install thin` and try again."
|
||||
end
|
213
vendor/plugins/rack/test/spec_urlmap.rb
vendored
Normal file
213
vendor/plugins/rack/test/spec_urlmap.rb
vendored
Normal file
|
@ -0,0 +1,213 @@
|
|||
require 'rack/urlmap'
|
||||
require 'rack/mock'
|
||||
|
||||
describe Rack::URLMap do
|
||||
it "dispatches paths correctly" do
|
||||
app = lambda { |env|
|
||||
[200, {
|
||||
'X-ScriptName' => env['SCRIPT_NAME'],
|
||||
'X-PathInfo' => env['PATH_INFO'],
|
||||
'Content-Type' => 'text/plain'
|
||||
}, [""]]
|
||||
}
|
||||
map = Rack::URLMap.new({
|
||||
'http://foo.org/bar' => app,
|
||||
'/foo' => app,
|
||||
'/foo/bar' => app
|
||||
})
|
||||
|
||||
res = Rack::MockRequest.new(map).get("/")
|
||||
res.should.be.not_found
|
||||
|
||||
res = Rack::MockRequest.new(map).get("/qux")
|
||||
res.should.be.not_found
|
||||
|
||||
res = Rack::MockRequest.new(map).get("/foo")
|
||||
res.should.be.ok
|
||||
res["X-ScriptName"].should.equal "/foo"
|
||||
res["X-PathInfo"].should.equal ""
|
||||
|
||||
res = Rack::MockRequest.new(map).get("/foo/")
|
||||
res.should.be.ok
|
||||
res["X-ScriptName"].should.equal "/foo"
|
||||
res["X-PathInfo"].should.equal "/"
|
||||
|
||||
res = Rack::MockRequest.new(map).get("/foo/bar")
|
||||
res.should.be.ok
|
||||
res["X-ScriptName"].should.equal "/foo/bar"
|
||||
res["X-PathInfo"].should.equal ""
|
||||
|
||||
res = Rack::MockRequest.new(map).get("/foo/bar/")
|
||||
res.should.be.ok
|
||||
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"
|
||||
res["X-PathInfo"].should.equal "/quux"
|
||||
|
||||
res = Rack::MockRequest.new(map).get("/bar", 'HTTP_HOST' => 'foo.org')
|
||||
res.should.be.ok
|
||||
res["X-ScriptName"].should.equal "/bar"
|
||||
res["X-PathInfo"].should.be.empty
|
||||
|
||||
res = Rack::MockRequest.new(map).get("/bar/", 'HTTP_HOST' => 'foo.org')
|
||||
res.should.be.ok
|
||||
res["X-ScriptName"].should.equal "/bar"
|
||||
res["X-PathInfo"].should.equal '/'
|
||||
end
|
||||
|
||||
|
||||
it "dispatches hosts correctly" do
|
||||
map = Rack::URLMap.new("http://foo.org/" => lambda { |env|
|
||||
[200,
|
||||
{ "Content-Type" => "text/plain",
|
||||
"X-Position" => "foo.org",
|
||||
"X-Host" => env["HTTP_HOST"] || env["SERVER_NAME"],
|
||||
}, [""]]},
|
||||
"http://subdomain.foo.org/" => lambda { |env|
|
||||
[200,
|
||||
{ "Content-Type" => "text/plain",
|
||||
"X-Position" => "subdomain.foo.org",
|
||||
"X-Host" => env["HTTP_HOST"] || env["SERVER_NAME"],
|
||||
}, [""]]},
|
||||
"http://bar.org/" => lambda { |env|
|
||||
[200,
|
||||
{ "Content-Type" => "text/plain",
|
||||
"X-Position" => "bar.org",
|
||||
"X-Host" => env["HTTP_HOST"] || env["SERVER_NAME"],
|
||||
}, [""]]},
|
||||
"/" => lambda { |env|
|
||||
[200,
|
||||
{ "Content-Type" => "text/plain",
|
||||
"X-Position" => "default.org",
|
||||
"X-Host" => env["HTTP_HOST"] || env["SERVER_NAME"],
|
||||
}, [""]]}
|
||||
)
|
||||
|
||||
res = Rack::MockRequest.new(map).get("/")
|
||||
res.should.be.ok
|
||||
res["X-Position"].should.equal "default.org"
|
||||
|
||||
res = Rack::MockRequest.new(map).get("/", "HTTP_HOST" => "bar.org")
|
||||
res.should.be.ok
|
||||
res["X-Position"].should.equal "bar.org"
|
||||
|
||||
res = Rack::MockRequest.new(map).get("/", "HTTP_HOST" => "foo.org")
|
||||
res.should.be.ok
|
||||
res["X-Position"].should.equal "foo.org"
|
||||
|
||||
res = Rack::MockRequest.new(map).get("/", "HTTP_HOST" => "subdomain.foo.org", "SERVER_NAME" => "foo.org")
|
||||
res.should.be.ok
|
||||
res["X-Position"].should.equal "subdomain.foo.org"
|
||||
|
||||
res = Rack::MockRequest.new(map).get("http://foo.org/")
|
||||
res.should.be.ok
|
||||
res["X-Position"].should.equal "default.org"
|
||||
|
||||
res = Rack::MockRequest.new(map).get("/", "HTTP_HOST" => "example.org")
|
||||
res.should.be.ok
|
||||
res["X-Position"].should.equal "default.org"
|
||||
|
||||
res = Rack::MockRequest.new(map).get("/",
|
||||
"HTTP_HOST" => "example.org:9292",
|
||||
"SERVER_PORT" => "9292")
|
||||
res.should.be.ok
|
||||
res["X-Position"].should.equal "default.org"
|
||||
end
|
||||
|
||||
should "be nestable" do
|
||||
map = Rack::URLMap.new("/foo" =>
|
||||
Rack::URLMap.new("/bar" =>
|
||||
Rack::URLMap.new("/quux" => lambda { |env|
|
||||
[200,
|
||||
{ "Content-Type" => "text/plain",
|
||||
"X-Position" => "/foo/bar/quux",
|
||||
"X-PathInfo" => env["PATH_INFO"],
|
||||
"X-ScriptName" => env["SCRIPT_NAME"],
|
||||
}, [""]]}
|
||||
)))
|
||||
|
||||
res = Rack::MockRequest.new(map).get("/foo/bar")
|
||||
res.should.be.not_found
|
||||
|
||||
res = Rack::MockRequest.new(map).get("/foo/bar/quux")
|
||||
res.should.be.ok
|
||||
res["X-Position"].should.equal "/foo/bar/quux"
|
||||
res["X-PathInfo"].should.equal ""
|
||||
res["X-ScriptName"].should.equal "/foo/bar/quux"
|
||||
end
|
||||
|
||||
should "route root apps correctly" 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("/foo/bar")
|
||||
res.should.be.ok
|
||||
res["X-Position"].should.equal "foo"
|
||||
res["X-PathInfo"].should.equal "/bar"
|
||||
res["X-ScriptName"].should.equal "/foo"
|
||||
|
||||
res = Rack::MockRequest.new(map).get("/foo")
|
||||
res.should.be.ok
|
||||
res["X-Position"].should.equal "foo"
|
||||
res["X-PathInfo"].should.equal ""
|
||||
res["X-ScriptName"].should.equal "/foo"
|
||||
|
||||
res = Rack::MockRequest.new(map).get("/bar")
|
||||
res.should.be.ok
|
||||
res["X-Position"].should.equal "root"
|
||||
res["X-PathInfo"].should.equal "/bar"
|
||||
res["X-ScriptName"].should.equal ""
|
||||
|
||||
res = Rack::MockRequest.new(map).get("")
|
||||
res.should.be.ok
|
||||
res["X-Position"].should.equal "root"
|
||||
res["X-PathInfo"].should.equal "/"
|
||||
res["X-ScriptName"].should.equal ""
|
||||
end
|
||||
|
||||
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
|
617
vendor/plugins/rack/test/spec_utils.rb
vendored
Normal file
617
vendor/plugins/rack/test/spec_utils.rb
vendored
Normal file
|
@ -0,0 +1,617 @@
|
|||
require 'rack/utils'
|
||||
require 'rack/mock'
|
||||
|
||||
describe Rack::Utils do
|
||||
should "escape correctly" do
|
||||
Rack::Utils.escape("fo<o>bar").should.equal "fo%3Co%3Ebar"
|
||||
Rack::Utils.escape("a space").should.equal "a+space"
|
||||
Rack::Utils.escape("q1!2\"'w$5&7/z8)?\\").
|
||||
should.equal "q1%212%22%27w%245%267%2Fz8%29%3F%5C"
|
||||
end
|
||||
|
||||
should "escape correctly for multibyte characters" do
|
||||
matz_name = "\xE3\x81\xBE\xE3\x81\xA4\xE3\x82\x82\xE3\x81\xA8".unpack("a*")[0] # Matsumoto
|
||||
matz_name.force_encoding("UTF-8") if matz_name.respond_to? :force_encoding
|
||||
Rack::Utils.escape(matz_name).should.equal '%E3%81%BE%E3%81%A4%E3%82%82%E3%81%A8'
|
||||
matz_name_sep = "\xE3\x81\xBE\xE3\x81\xA4 \xE3\x82\x82\xE3\x81\xA8".unpack("a*")[0] # Matsu moto
|
||||
matz_name_sep.force_encoding("UTF-8") if matz_name_sep.respond_to? :force_encoding
|
||||
Rack::Utils.escape(matz_name_sep).should.equal '%E3%81%BE%E3%81%A4+%E3%82%82%E3%81%A8'
|
||||
end
|
||||
|
||||
should "unescape correctly" do
|
||||
Rack::Utils.unescape("fo%3Co%3Ebar").should.equal "fo<o>bar"
|
||||
Rack::Utils.unescape("a+space").should.equal "a space"
|
||||
Rack::Utils.unescape("a%20space").should.equal "a space"
|
||||
Rack::Utils.unescape("q1%212%22%27w%245%267%2Fz8%29%3F%5C").
|
||||
should.equal "q1!2\"'w$5&7/z8)?\\"
|
||||
end
|
||||
|
||||
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&foo=quux").
|
||||
should.equal "foo" => ["bar", "quux"]
|
||||
Rack::Utils.parse_query("foo=1&bar=2").
|
||||
should.equal "foo" => "1", "bar" => "2"
|
||||
Rack::Utils.parse_query("my+weird+field=q1%212%22%27w%245%267%2Fz8%29%3F").
|
||||
should.equal "my weird field" => "q1!2\"'w$5&7/z8)?"
|
||||
Rack::Utils.parse_query("foo%3Dbaz=bar").should.equal "foo=baz" => "bar"
|
||||
end
|
||||
|
||||
should "parse nested query strings correctly" do
|
||||
Rack::Utils.parse_nested_query("foo").
|
||||
should.equal "foo" => nil
|
||||
Rack::Utils.parse_nested_query("foo=").
|
||||
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"
|
||||
Rack::Utils.parse_nested_query("foo&foo=").
|
||||
should.equal "foo" => ""
|
||||
Rack::Utils.parse_nested_query("foo=1&bar=2").
|
||||
should.equal "foo" => "1", "bar" => "2"
|
||||
Rack::Utils.parse_nested_query("&foo=1&&bar=2").
|
||||
should.equal "foo" => "1", "bar" => "2"
|
||||
Rack::Utils.parse_nested_query("foo&bar=").
|
||||
should.equal "foo" => nil, "bar" => ""
|
||||
Rack::Utils.parse_nested_query("foo=bar&baz=").
|
||||
should.equal "foo" => "bar", "baz" => ""
|
||||
Rack::Utils.parse_nested_query("my+weird+field=q1%212%22%27w%245%267%2Fz8%29%3F").
|
||||
should.equal "my weird field" => "q1!2\"'w$5&7/z8)?"
|
||||
|
||||
Rack::Utils.parse_nested_query("foo[]").
|
||||
should.equal "foo" => [nil]
|
||||
Rack::Utils.parse_nested_query("foo[]=").
|
||||
should.equal "foo" => [""]
|
||||
Rack::Utils.parse_nested_query("foo[]=bar").
|
||||
should.equal "foo" => ["bar"]
|
||||
|
||||
Rack::Utils.parse_nested_query("foo[]=1&foo[]=2").
|
||||
should.equal "foo" => ["1", "2"]
|
||||
Rack::Utils.parse_nested_query("foo=bar&baz[]=1&baz[]=2&baz[]=3").
|
||||
should.equal "foo" => "bar", "baz" => ["1", "2", "3"]
|
||||
Rack::Utils.parse_nested_query("foo[]=bar&baz[]=1&baz[]=2&baz[]=3").
|
||||
should.equal "foo" => ["bar"], "baz" => ["1", "2", "3"]
|
||||
|
||||
Rack::Utils.parse_nested_query("x[y][z]=1").
|
||||
should.equal "x" => {"y" => {"z" => "1"}}
|
||||
Rack::Utils.parse_nested_query("x[y][z][]=1").
|
||||
should.equal "x" => {"y" => {"z" => ["1"]}}
|
||||
Rack::Utils.parse_nested_query("x[y][z]=1&x[y][z]=2").
|
||||
should.equal "x" => {"y" => {"z" => "2"}}
|
||||
Rack::Utils.parse_nested_query("x[y][z][]=1&x[y][z][]=2").
|
||||
should.equal "x" => {"y" => {"z" => ["1", "2"]}}
|
||||
|
||||
Rack::Utils.parse_nested_query("x[y][][z]=1").
|
||||
should.equal "x" => {"y" => [{"z" => "1"}]}
|
||||
Rack::Utils.parse_nested_query("x[y][][z][]=1").
|
||||
should.equal "x" => {"y" => [{"z" => ["1"]}]}
|
||||
Rack::Utils.parse_nested_query("x[y][][z]=1&x[y][][w]=2").
|
||||
should.equal "x" => {"y" => [{"z" => "1", "w" => "2"}]}
|
||||
|
||||
Rack::Utils.parse_nested_query("x[y][][v][w]=1").
|
||||
should.equal "x" => {"y" => [{"v" => {"w" => "1"}}]}
|
||||
Rack::Utils.parse_nested_query("x[y][][z]=1&x[y][][v][w]=2").
|
||||
should.equal "x" => {"y" => [{"z" => "1", "v" => {"w" => "2"}}]}
|
||||
|
||||
Rack::Utils.parse_nested_query("x[y][][z]=1&x[y][][z]=2").
|
||||
should.equal "x" => {"y" => [{"z" => "1"}, {"z" => "2"}]}
|
||||
Rack::Utils.parse_nested_query("x[y][][z]=1&x[y][][w]=a&x[y][][z]=2&x[y][][w]=3").
|
||||
should.equal "x" => {"y" => [{"z" => "1", "w" => "a"}, {"z" => "2", "w" => "3"}]}
|
||||
|
||||
lambda { Rack::Utils.parse_nested_query("x[y]=1&x[y]z=2") }.
|
||||
should.raise(TypeError).
|
||||
message.should.equal "expected Hash (got String) for param `y'"
|
||||
|
||||
lambda { Rack::Utils.parse_nested_query("x[y]=1&x[]=1") }.
|
||||
should.raise(TypeError).
|
||||
message.should.equal "expected Array (got Hash) for param `x'"
|
||||
|
||||
lambda { Rack::Utils.parse_nested_query("x[y]=1&x[y][][w]=2") }.
|
||||
should.raise(TypeError).
|
||||
message.should.equal "expected Array (got String) for param `y'"
|
||||
end
|
||||
|
||||
should "build query strings correctly" do
|
||||
Rack::Utils.build_query("foo" => "bar").should.equal "foo=bar"
|
||||
Rack::Utils.build_query("foo" => ["bar", "quux"]).
|
||||
should.equal "foo=bar&foo=quux"
|
||||
Rack::Utils.build_query("foo" => "1", "bar" => "2").
|
||||
should.equal "foo=1&bar=2"
|
||||
Rack::Utils.build_query("my weird field" => "q1!2\"'w$5&7/z8)?").
|
||||
should.equal "my+weird+field=q1%212%22%27w%245%267%2Fz8%29%3F"
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
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))
|
||||
Rack::Utils.select_best_encoding(a, b)
|
||||
end
|
||||
|
||||
helper.call(%w(), [["x", 1]]).should.equal(nil)
|
||||
helper.call(%w(identity), [["identity", 0.0]]).should.equal(nil)
|
||||
helper.call(%w(identity), [["*", 0.0]]).should.equal(nil)
|
||||
|
||||
helper.call(%w(identity), [["compress", 1.0], ["gzip", 1.0]]).should.equal("identity")
|
||||
|
||||
helper.call(%w(compress gzip identity), [["compress", 1.0], ["gzip", 1.0]]).should.equal("compress")
|
||||
helper.call(%w(compress gzip identity), [["compress", 0.5], ["gzip", 1.0]]).should.equal("gzip")
|
||||
|
||||
helper.call(%w(foo bar identity), []).should.equal("identity")
|
||||
helper.call(%w(foo bar identity), [["*", 1.0]]).should.equal("foo")
|
||||
helper.call(%w(foo bar identity), [["*", 1.0], ["foo", 0.9]]).should.equal("bar")
|
||||
|
||||
helper.call(%w(foo bar identity), [["foo", 0], ["bar", 0]]).should.equal("identity")
|
||||
helper.call(%w(foo bar baz identity), [["*", 0], ["identity", 0.1]]).should.equal("identity")
|
||||
end
|
||||
|
||||
should "return the bytesize of String" do
|
||||
Rack::Utils.bytesize("FOO\xE2\x82\xAC").should.equal 6
|
||||
end
|
||||
|
||||
should "return status code for integer" do
|
||||
Rack::Utils.status_code(200).should.equal 200
|
||||
end
|
||||
|
||||
should "return status code for string" do
|
||||
Rack::Utils.status_code("200").should.equal 200
|
||||
end
|
||||
|
||||
should "return status code for symbol" do
|
||||
Rack::Utils.status_code(:ok).should.equal 200
|
||||
end
|
||||
end
|
||||
|
||||
describe Rack::Utils::HeaderHash do
|
||||
should "retain header case" do
|
||||
h = Rack::Utils::HeaderHash.new("Content-MD5" => "d5ff4e2a0 ...")
|
||||
h['ETag'] = 'Boo!'
|
||||
h.to_hash.should.equal "Content-MD5" => "d5ff4e2a0 ...", "ETag" => 'Boo!'
|
||||
end
|
||||
|
||||
should "check existence of keys case insensitively" do
|
||||
h = Rack::Utils::HeaderHash.new("Content-MD5" => "d5ff4e2a0 ...")
|
||||
h.should.include 'content-md5'
|
||||
h.should.not.include 'ETag'
|
||||
end
|
||||
|
||||
should "merge case-insensitively" do
|
||||
h = Rack::Utils::HeaderHash.new("ETag" => 'HELLO', "content-length" => '123')
|
||||
merged = h.merge("Etag" => 'WORLD', 'Content-Length' => '321', "Foo" => 'BAR')
|
||||
merged.should.equal "Etag"=>'WORLD', "Content-Length"=>'321', "Foo"=>'BAR'
|
||||
end
|
||||
|
||||
should "overwrite case insensitively and assume the new key's case" do
|
||||
h = Rack::Utils::HeaderHash.new("Foo-Bar" => "baz")
|
||||
h["foo-bar"] = "bizzle"
|
||||
h["FOO-BAR"].should.equal "bizzle"
|
||||
h.length.should.equal 1
|
||||
h.to_hash.should.equal "foo-bar" => "bizzle"
|
||||
end
|
||||
|
||||
should "be converted to real Hash" do
|
||||
h = Rack::Utils::HeaderHash.new("foo" => "bar")
|
||||
h.to_hash.should.be.instance_of Hash
|
||||
end
|
||||
|
||||
should "convert Array values to Strings when converting to Hash" do
|
||||
h = Rack::Utils::HeaderHash.new("foo" => ["bar", "baz"])
|
||||
h.to_hash.should.equal({ "foo" => "bar\nbaz" })
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
describe Rack::Utils::Context do
|
||||
class ContextTest
|
||||
attr_reader :app
|
||||
def initialize app; @app=app; end
|
||||
def call env; context env; end
|
||||
def context env, app=@app; app.call(env); end
|
||||
end
|
||||
test_target1 = proc{|e| e.to_s+' world' }
|
||||
test_target2 = proc{|e| e.to_i+2 }
|
||||
test_target3 = proc{|e| nil }
|
||||
test_target4 = proc{|e| [200,{'Content-Type'=>'text/plain', 'Content-Length'=>'0'},['']] }
|
||||
test_app = ContextTest.new test_target4
|
||||
|
||||
should "set context correctly" do
|
||||
test_app.app.should.equal test_target4
|
||||
c1 = Rack::Utils::Context.new(test_app, test_target1)
|
||||
c1.for.should.equal test_app
|
||||
c1.app.should.equal test_target1
|
||||
c2 = Rack::Utils::Context.new(test_app, test_target2)
|
||||
c2.for.should.equal test_app
|
||||
c2.app.should.equal test_target2
|
||||
end
|
||||
|
||||
should "alter app on recontexting" do
|
||||
c1 = Rack::Utils::Context.new(test_app, test_target1)
|
||||
c2 = c1.recontext(test_target2)
|
||||
c2.for.should.equal test_app
|
||||
c2.app.should.equal test_target2
|
||||
c3 = c2.recontext(test_target3)
|
||||
c3.for.should.equal test_app
|
||||
c3.app.should.equal test_target3
|
||||
end
|
||||
|
||||
should "run different apps" do
|
||||
c1 = Rack::Utils::Context.new test_app, test_target1
|
||||
c2 = c1.recontext test_target2
|
||||
c3 = c2.recontext test_target3
|
||||
c4 = c3.recontext test_target4
|
||||
a4 = Rack::Lint.new c4
|
||||
a5 = Rack::Lint.new test_app
|
||||
r1 = c1.call('hello')
|
||||
r1.should.equal 'hello world'
|
||||
r2 = c2.call(2)
|
||||
r2.should.equal 4
|
||||
r3 = c3.call(:misc_symbol)
|
||||
r3.should.be.nil
|
||||
r4 = Rack::MockRequest.new(a4).get('/')
|
||||
r4.status.should.equal 200
|
||||
r5 = Rack::MockRequest.new(a5).get('/')
|
||||
r5.status.should.equal 200
|
||||
r4.body.should.equal r5.body
|
||||
end
|
||||
end
|
||||
|
||||
describe Rack::Utils::Multipart do
|
||||
def multipart_fixture(name)
|
||||
file = multipart_file(name)
|
||||
data = File.open(file, 'rb') { |io| io.read }
|
||||
|
||||
type = "multipart/form-data; boundary=AaB03x"
|
||||
length = data.respond_to?(:bytesize) ? data.bytesize : data.size
|
||||
|
||||
{ "CONTENT_TYPE" => type,
|
||||
"CONTENT_LENGTH" => length.to_s,
|
||||
:input => StringIO.new(data) }
|
||||
end
|
||||
|
||||
def multipart_file(name)
|
||||
File.join(File.dirname(__FILE__), "multipart", name.to_s)
|
||||
end
|
||||
|
||||
should "return nil if content type is not multipart" do
|
||||
env = Rack::MockRequest.env_for("/",
|
||||
"CONTENT_TYPE" => 'application/x-www-form-urlencoded')
|
||||
Rack::Utils::Multipart.parse_multipart(env).should.equal nil
|
||||
end
|
||||
|
||||
should "parse multipart upload with text file" do
|
||||
env = Rack::MockRequest.env_for("/", multipart_fixture(:text))
|
||||
params = Rack::Utils::Multipart.parse_multipart(env)
|
||||
params["submit-name"].should.equal "Larry"
|
||||
params["files"][:type].should.equal "text/plain"
|
||||
params["files"][:filename].should.equal "file1.txt"
|
||||
params["files"][:head].should.equal "Content-Disposition: form-data; " +
|
||||
"name=\"files\"; filename=\"file1.txt\"\r\n" +
|
||||
"Content-Type: text/plain\r\n"
|
||||
params["files"][:name].should.equal "files"
|
||||
params["files"][:tempfile].read.should.equal "contents"
|
||||
end
|
||||
|
||||
should "parse multipart upload with nested parameters" do
|
||||
env = Rack::MockRequest.env_for("/", multipart_fixture(:nested))
|
||||
params = Rack::Utils::Multipart.parse_multipart(env)
|
||||
params["foo"]["submit-name"].should.equal "Larry"
|
||||
params["foo"]["files"][:type].should.equal "text/plain"
|
||||
params["foo"]["files"][:filename].should.equal "file1.txt"
|
||||
params["foo"]["files"][:head].should.equal "Content-Disposition: form-data; " +
|
||||
"name=\"foo[files]\"; filename=\"file1.txt\"\r\n" +
|
||||
"Content-Type: text/plain\r\n"
|
||||
params["foo"]["files"][:name].should.equal "foo[files]"
|
||||
params["foo"]["files"][:tempfile].read.should.equal "contents"
|
||||
end
|
||||
|
||||
should "parse multipart upload with binary file" do
|
||||
env = Rack::MockRequest.env_for("/", multipart_fixture(:binary))
|
||||
params = Rack::Utils::Multipart.parse_multipart(env)
|
||||
params["submit-name"].should.equal "Larry"
|
||||
params["files"][:type].should.equal "image/png"
|
||||
params["files"][:filename].should.equal "rack-logo.png"
|
||||
params["files"][:head].should.equal "Content-Disposition: form-data; " +
|
||||
"name=\"files\"; filename=\"rack-logo.png\"\r\n" +
|
||||
"Content-Type: image/png\r\n"
|
||||
params["files"][:name].should.equal "files"
|
||||
params["files"][:tempfile].read.length.should.equal 26473
|
||||
end
|
||||
|
||||
should "parse multipart upload with empty file" do
|
||||
env = Rack::MockRequest.env_for("/", multipart_fixture(:empty))
|
||||
params = Rack::Utils::Multipart.parse_multipart(env)
|
||||
params["submit-name"].should.equal "Larry"
|
||||
params["files"][:type].should.equal "text/plain"
|
||||
params["files"][:filename].should.equal "file1.txt"
|
||||
params["files"][:head].should.equal "Content-Disposition: form-data; " +
|
||||
"name=\"files\"; filename=\"file1.txt\"\r\n" +
|
||||
"Content-Type: text/plain\r\n"
|
||||
params["files"][:name].should.equal "files"
|
||||
params["files"][:tempfile].read.should.equal ""
|
||||
end
|
||||
|
||||
should "parse multipart upload with filename with semicolons" do
|
||||
env = Rack::MockRequest.env_for("/", multipart_fixture(:semicolon))
|
||||
params = Rack::Utils::Multipart.parse_multipart(env)
|
||||
params["files"][:type].should.equal "text/plain"
|
||||
params["files"][:filename].should.equal "fi;le1.txt"
|
||||
params["files"][:head].should.equal "Content-Disposition: form-data; " +
|
||||
"name=\"files\"; filename=\"fi;le1.txt\"\r\n" +
|
||||
"Content-Type: text/plain\r\n"
|
||||
params["files"][:name].should.equal "files"
|
||||
params["files"][:tempfile].read.should.equal "contents"
|
||||
end
|
||||
|
||||
should "not include file params if no file was selected" do
|
||||
env = Rack::MockRequest.env_for("/", multipart_fixture(:none))
|
||||
params = Rack::Utils::Multipart.parse_multipart(env)
|
||||
params["submit-name"].should.equal "Larry"
|
||||
params["files"].should.equal nil
|
||||
params.keys.should.not.include "files"
|
||||
end
|
||||
|
||||
should "parse IE multipart upload and clean up filename" do
|
||||
env = Rack::MockRequest.env_for("/", multipart_fixture(:ie))
|
||||
params = Rack::Utils::Multipart.parse_multipart(env)
|
||||
params["files"][:type].should.equal "text/plain"
|
||||
params["files"][:filename].should.equal "file1.txt"
|
||||
params["files"][:head].should.equal "Content-Disposition: form-data; " +
|
||||
"name=\"files\"; " +
|
||||
'filename="C:\Documents and Settings\Administrator\Desktop\file1.txt"' +
|
||||
"\r\nContent-Type: text/plain\r\n"
|
||||
params["files"][:name].should.equal "files"
|
||||
params["files"][:tempfile].read.should.equal "contents"
|
||||
end
|
||||
|
||||
should "parse filename and modification param" do
|
||||
env = Rack::MockRequest.env_for("/", multipart_fixture(:filename_and_modification_param))
|
||||
params = Rack::Utils::Multipart.parse_multipart(env)
|
||||
params["files"][:type].should.equal "image/jpeg"
|
||||
params["files"][:filename].should.equal "genome.jpeg"
|
||||
params["files"][:head].should.equal "Content-Type: image/jpeg\r\n" +
|
||||
"Content-Disposition: attachment; " +
|
||||
"name=\"files\"; " +
|
||||
"filename=genome.jpeg; " +
|
||||
"modification-date=\"Wed, 12 Feb 1997 16:29:51 -0500\";\r\n" +
|
||||
"Content-Description: a complete map of the human genome\r\n"
|
||||
params["files"][:name].should.equal "files"
|
||||
params["files"][:tempfile].read.should.equal "contents"
|
||||
end
|
||||
|
||||
should "parse filename with escaped quotes" do
|
||||
env = Rack::MockRequest.env_for("/", multipart_fixture(:filename_with_escaped_quotes))
|
||||
params = Rack::Utils::Multipart.parse_multipart(env)
|
||||
params["files"][:type].should.equal "application/octet-stream"
|
||||
params["files"][:filename].should.equal "escape \"quotes"
|
||||
params["files"][:head].should.equal "Content-Disposition: form-data; " +
|
||||
"name=\"files\"; " +
|
||||
"filename=\"escape \\\"quotes\"\r\n" +
|
||||
"Content-Type: application/octet-stream\r\n"
|
||||
params["files"][:name].should.equal "files"
|
||||
params["files"][:tempfile].read.should.equal "contents"
|
||||
end
|
||||
|
||||
should "parse filename with percent escaped quotes" do
|
||||
env = Rack::MockRequest.env_for("/", multipart_fixture(:filename_with_percent_escaped_quotes))
|
||||
params = Rack::Utils::Multipart.parse_multipart(env)
|
||||
params["files"][:type].should.equal "application/octet-stream"
|
||||
params["files"][:filename].should.equal "escape \"quotes"
|
||||
params["files"][:head].should.equal "Content-Disposition: form-data; " +
|
||||
"name=\"files\"; " +
|
||||
"filename=\"escape %22quotes\"\r\n" +
|
||||
"Content-Type: application/octet-stream\r\n"
|
||||
params["files"][:name].should.equal "files"
|
||||
params["files"][:tempfile].read.should.equal "contents"
|
||||
end
|
||||
|
||||
should "parse filename with unescaped quotes" do
|
||||
env = Rack::MockRequest.env_for("/", multipart_fixture(:filename_with_unescaped_quotes))
|
||||
params = Rack::Utils::Multipart.parse_multipart(env)
|
||||
params["files"][:type].should.equal "application/octet-stream"
|
||||
params["files"][:filename].should.equal "escape \"quotes"
|
||||
params["files"][:head].should.equal "Content-Disposition: form-data; " +
|
||||
"name=\"files\"; " +
|
||||
"filename=\"escape \"quotes\"\r\n" +
|
||||
"Content-Type: application/octet-stream\r\n"
|
||||
params["files"][:name].should.equal "files"
|
||||
params["files"][:tempfile].read.should.equal "contents"
|
||||
end
|
||||
|
||||
should "parse filename with escaped quotes and modification param" do
|
||||
env = Rack::MockRequest.env_for("/", multipart_fixture(:filename_with_escaped_quotes_and_modification_param))
|
||||
params = Rack::Utils::Multipart.parse_multipart(env)
|
||||
params["files"][:type].should.equal "image/jpeg"
|
||||
params["files"][:filename].should.equal "\"human\" genome.jpeg"
|
||||
params["files"][:head].should.equal "Content-Type: image/jpeg\r\n" +
|
||||
"Content-Disposition: attachment; " +
|
||||
"name=\"files\"; " +
|
||||
"filename=\"\"human\" genome.jpeg\"; " +
|
||||
"modification-date=\"Wed, 12 Feb 1997 16:29:51 -0500\";\r\n" +
|
||||
"Content-Description: a complete map of the human genome\r\n"
|
||||
params["files"][:name].should.equal "files"
|
||||
params["files"][:tempfile].read.should.equal "contents"
|
||||
end
|
||||
|
||||
it "rewinds input after parsing upload" do
|
||||
options = multipart_fixture(:text)
|
||||
input = options[:input]
|
||||
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"
|
||||
input.read.length.should.equal 197
|
||||
end
|
||||
|
||||
it "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
|
||||
|
||||
it "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
|
||||
|
||||
it "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
|
||||
|
||||
it "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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
end
|
122
vendor/plugins/rack/test/spec_webrick.rb
vendored
Normal file
122
vendor/plugins/rack/test/spec_webrick.rb
vendored
Normal file
|
@ -0,0 +1,122 @@
|
|||
require 'rack/mock'
|
||||
require File.expand_path('../testrequest', __FILE__)
|
||||
|
||||
Thread.abort_on_exception = true
|
||||
|
||||
describe Rack::Handler::WEBrick do
|
||||
extend TestRequest::Helpers
|
||||
|
||||
@server = WEBrick::HTTPServer.new(:Host => @host='0.0.0.0',
|
||||
:Port => @port=9202,
|
||||
:Logger => WEBrick::Log.new(nil, WEBrick::BasicLog::WARN),
|
||||
:AccessLog => [])
|
||||
@server.mount "/test", Rack::Handler::WEBrick,
|
||||
Rack::Lint.new(TestRequest.new)
|
||||
Thread.new { @server.start }
|
||||
trap(:INT) { @server.shutdown }
|
||||
|
||||
should "respond" do
|
||||
lambda {
|
||||
GET("/test")
|
||||
}.should.not.raise
|
||||
end
|
||||
|
||||
should "be a WEBrick" do
|
||||
GET("/test")
|
||||
status.should.equal 200
|
||||
response["SERVER_SOFTWARE"].should =~ /WEBrick/
|
||||
response["HTTP_VERSION"].should.equal "HTTP/1.1"
|
||||
response["SERVER_PROTOCOL"].should.equal "HTTP/1.1"
|
||||
response["SERVER_PORT"].should.equal "9202"
|
||||
response["SERVER_NAME"].should.equal "0.0.0.0"
|
||||
end
|
||||
|
||||
should "have rack headers" do
|
||||
GET("/test")
|
||||
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
|
||||
end
|
||||
|
||||
should "have CGI headers on GET" do
|
||||
GET("/test")
|
||||
response["REQUEST_METHOD"].should.equal "GET"
|
||||
response["SCRIPT_NAME"].should.equal "/test"
|
||||
response["REQUEST_PATH"].should.equal "/"
|
||||
response["PATH_INFO"].should.be.equal ""
|
||||
response["QUERY_STRING"].should.equal ""
|
||||
response["test.postdata"].should.equal ""
|
||||
|
||||
GET("/test/foo?quux=1")
|
||||
response["REQUEST_METHOD"].should.equal "GET"
|
||||
response["SCRIPT_NAME"].should.equal "/test"
|
||||
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"
|
||||
response["REQUEST_PATH"].should.equal "/"
|
||||
response["PATH_INFO"].should.equal "/foo%25encoding"
|
||||
response["QUERY_STRING"].should.equal "quux=1"
|
||||
end
|
||||
|
||||
should "have CGI headers on POST" do
|
||||
POST("/test", {"rack-form-data" => "23"}, {'X-test-header' => '42'})
|
||||
status.should.equal 200
|
||||
response["REQUEST_METHOD"].should.equal "POST"
|
||||
response["SCRIPT_NAME"].should.equal "/test"
|
||||
response["REQUEST_PATH"].should.equal "/"
|
||||
response["QUERY_STRING"].should.equal ""
|
||||
response["HTTP_X_TEST_HEADER"].should.equal "42"
|
||||
response["test.postdata"].should.equal "rack-form-data=23"
|
||||
end
|
||||
|
||||
should "support HTTP auth" do
|
||||
GET("/test", {:user => "ruth", :passwd => "secret"})
|
||||
response["HTTP_AUTHORIZATION"].should.equal "Basic cnV0aDpzZWNyZXQ="
|
||||
end
|
||||
|
||||
should "set status" do
|
||||
GET("/test?secret")
|
||||
status.should.equal 403
|
||||
response["rack.url_scheme"].should.equal "http"
|
||||
end
|
||||
|
||||
should "correctly set cookies" do
|
||||
@server.mount "/cookie-test", Rack::Handler::WEBrick,
|
||||
Rack::Lint.new(lambda { |req|
|
||||
res = Rack::Response.new
|
||||
res.set_cookie "one", "1"
|
||||
res.set_cookie "two", "2"
|
||||
res.finish
|
||||
})
|
||||
|
||||
Net::HTTP.start(@host, @port) { |http|
|
||||
res = http.get("/cookie-test")
|
||||
res.code.to_i.should.equal 200
|
||||
res.get_fields("set-cookie").should.equal ["one=1", "two=2"]
|
||||
}
|
||||
end
|
||||
|
||||
should "provide a .run" do
|
||||
block_ran = false
|
||||
catch(:done) {
|
||||
Rack::Handler::WEBrick.run(lambda {},
|
||||
{:Port => 9210,
|
||||
:Logger => WEBrick::Log.new(nil, WEBrick::BasicLog::WARN),
|
||||
:AccessLog => []}) { |server|
|
||||
block_ran = true
|
||||
server.should.be.kind_of WEBrick::HTTPServer
|
||||
@s = server
|
||||
throw :done
|
||||
}
|
||||
}
|
||||
block_ran.should.be.true
|
||||
@s.shutdown
|
||||
end
|
||||
|
||||
@server.shutdown
|
||||
end
|
77
vendor/plugins/rack/test/testrequest.rb
vendored
Normal file
77
vendor/plugins/rack/test/testrequest.rb
vendored
Normal file
|
@ -0,0 +1,77 @@
|
|||
require 'yaml'
|
||||
require 'net/http'
|
||||
|
||||
class TestRequest
|
||||
NOSERIALIZE = [Method, Proc]
|
||||
|
||||
def call(env)
|
||||
status = env["QUERY_STRING"] =~ /secret/ ? 403 : 200
|
||||
env["test.postdata"] = env["rack.input"].read
|
||||
minienv = env.dup
|
||||
# This may in the future want to replace with a dummy value instead.
|
||||
minienv.delete_if { |k,v| NOSERIALIZE.any? { |c| v.kind_of?(c) } }
|
||||
body = minienv.to_yaml
|
||||
size = body.respond_to?(:bytesize) ? body.bytesize : body.size
|
||||
[status, {"Content-Type" => "text/yaml", "Content-Length" => size.to_s}, [body]]
|
||||
end
|
||||
|
||||
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)
|
||||
passwd = header.delete(:passwd)
|
||||
|
||||
get = Net::HTTP::Get.new(path, header)
|
||||
get.basic_auth user, passwd if user && passwd
|
||||
http.request(get) { |response|
|
||||
@status = response.code.to_i
|
||||
begin
|
||||
@response = YAML.load(response.body)
|
||||
rescue TypeError, ArgumentError
|
||||
@response = nil
|
||||
end
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def POST(path, formdata={}, header={})
|
||||
Net::HTTP.start(@host, @port) { |http|
|
||||
user = header.delete(:user)
|
||||
passwd = header.delete(:passwd)
|
||||
|
||||
post = Net::HTTP::Post.new(path, header)
|
||||
post.form_data = formdata
|
||||
post.basic_auth user, passwd if user && passwd
|
||||
http.request(post) { |response|
|
||||
@status = response.code.to_i
|
||||
@response = YAML.load(response.body)
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class StreamingRequest
|
||||
def self.call(env)
|
||||
[200, {"Content-Type" => "text/plain"}, new]
|
||||
end
|
||||
|
||||
def each
|
||||
yield "hello there!\n"
|
||||
sleep 5
|
||||
yield "that is all.\n"
|
||||
end
|
||||
end
|
7
vendor/plugins/rack/test/unregistered_handler/rack/handler/unregistered.rb
vendored
Normal file
7
vendor/plugins/rack/test/unregistered_handler/rack/handler/unregistered.rb
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
module Rack
|
||||
module Handler
|
||||
# this class doesn't do anything, we're just seeing if we get it.
|
||||
class Unregistered
|
||||
end
|
||||
end
|
||||
end
|
7
vendor/plugins/rack/test/unregistered_handler/rack/handler/unregistered_long_one.rb
vendored
Normal file
7
vendor/plugins/rack/test/unregistered_handler/rack/handler/unregistered_long_one.rb
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
module Rack
|
||||
module Handler
|
||||
# this class doesn't do anything, we're just seeing if we get it.
|
||||
class UnregisteredLongOne
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Add table
Add a link
Reference in a new issue