rack 0.1.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of rack might be problematic. Click here for more details.

Files changed (54) hide show
  1. data/AUTHORS +3 -0
  2. data/COPYING +18 -0
  3. data/KNOWN-ISSUES +18 -0
  4. data/RDOX +144 -0
  5. data/README +154 -0
  6. data/Rakefile +174 -0
  7. data/SPEC +132 -0
  8. data/bin/rackup +148 -0
  9. data/contrib/rack_logo.svg +111 -0
  10. data/example/lobster.ru +4 -0
  11. data/lib/rack.rb +67 -0
  12. data/lib/rack/adapter/camping.rb +16 -0
  13. data/lib/rack/adapter/rails.rb +65 -0
  14. data/lib/rack/builder.rb +52 -0
  15. data/lib/rack/cascade.rb +26 -0
  16. data/lib/rack/commonlogger.rb +56 -0
  17. data/lib/rack/file.rb +108 -0
  18. data/lib/rack/handler/cgi.rb +57 -0
  19. data/lib/rack/handler/fastcgi.rb +81 -0
  20. data/lib/rack/handler/mongrel.rb +57 -0
  21. data/lib/rack/handler/webrick.rb +56 -0
  22. data/lib/rack/lint.rb +394 -0
  23. data/lib/rack/lobster.rb +65 -0
  24. data/lib/rack/mock.rb +183 -0
  25. data/lib/rack/recursive.rb +57 -0
  26. data/lib/rack/reloader.rb +64 -0
  27. data/lib/rack/request.rb +112 -0
  28. data/lib/rack/response.rb +114 -0
  29. data/lib/rack/showexceptions.rb +344 -0
  30. data/lib/rack/urlmap.rb +50 -0
  31. data/lib/rack/utils.rb +176 -0
  32. data/test/cgi/lighttpd.conf +20 -0
  33. data/test/cgi/test +9 -0
  34. data/test/cgi/test.fcgi +9 -0
  35. data/test/cgi/test.ru +7 -0
  36. data/test/spec_rack_camping.rb +44 -0
  37. data/test/spec_rack_cascade.rb +35 -0
  38. data/test/spec_rack_cgi.rb +82 -0
  39. data/test/spec_rack_commonlogger.rb +32 -0
  40. data/test/spec_rack_fastcgi.rb +82 -0
  41. data/test/spec_rack_file.rb +32 -0
  42. data/test/spec_rack_lint.rb +317 -0
  43. data/test/spec_rack_lobster.rb +45 -0
  44. data/test/spec_rack_mock.rb +150 -0
  45. data/test/spec_rack_mongrel.rb +87 -0
  46. data/test/spec_rack_recursive.rb +77 -0
  47. data/test/spec_rack_request.rb +219 -0
  48. data/test/spec_rack_response.rb +110 -0
  49. data/test/spec_rack_showexceptions.rb +21 -0
  50. data/test/spec_rack_urlmap.rb +140 -0
  51. data/test/spec_rack_utils.rb +57 -0
  52. data/test/spec_rack_webrick.rb +89 -0
  53. data/test/testrequest.rb +43 -0
  54. metadata +117 -0
@@ -0,0 +1,150 @@
1
+ require 'yaml'
2
+ require 'rack/mock'
3
+ require 'rack/request'
4
+ require 'rack/response'
5
+
6
+ app = lambda { |env|
7
+ req = Rack::Request.new(env)
8
+
9
+ env["mock.postdata"] = env["rack.input"].read
10
+ if req.GET["error"]
11
+ env["rack.errors"].puts req.GET["error"]
12
+ env["rack.errors"].flush
13
+ end
14
+
15
+ Rack::Response.new(env.to_yaml,
16
+ req.GET["status"] || 200,
17
+ "Content-Type" => "text/yaml").finish
18
+ }
19
+
20
+ context "Rack::MockRequest" do
21
+ specify "should return a MockResponse" do
22
+ res = Rack::MockRequest.new(app).get("")
23
+ res.should.be.kind_of Rack::MockResponse
24
+ end
25
+
26
+ specify "should be able to only return the environment" do
27
+ env = Rack::MockRequest.env_for("")
28
+ env.should.be.kind_of Hash
29
+ env.should.include "rack.version"
30
+ end
31
+
32
+ specify "should provide sensible defaults" do
33
+ res = Rack::MockRequest.new(app).request
34
+
35
+ env = YAML.load(res.body)
36
+ env["REQUEST_METHOD"].should.equal "GET"
37
+ env["SERVER_NAME"].should.equal "example.org"
38
+ env["SERVER_PORT"].should.equal "80"
39
+ env["QUERY_STRING"].should.equal ""
40
+ env["PATH_INFO"].should.equal "/"
41
+ env["SCRIPT_NAME"].should.equal ""
42
+ env["rack.url_scheme"].should.equal "http"
43
+ env["mock.postdata"].should.be.empty
44
+ end
45
+
46
+ specify "should allow GET/POST/PUT/DELETE" do
47
+ res = Rack::MockRequest.new(app).get("", :input => "foo")
48
+ env = YAML.load(res.body)
49
+ env["REQUEST_METHOD"].should.equal "GET"
50
+
51
+ res = Rack::MockRequest.new(app).post("", :input => "foo")
52
+ env = YAML.load(res.body)
53
+ env["REQUEST_METHOD"].should.equal "POST"
54
+
55
+ res = Rack::MockRequest.new(app).put("", :input => "foo")
56
+ env = YAML.load(res.body)
57
+ env["REQUEST_METHOD"].should.equal "PUT"
58
+
59
+ res = Rack::MockRequest.new(app).delete("", :input => "foo")
60
+ env = YAML.load(res.body)
61
+ env["REQUEST_METHOD"].should.equal "DELETE"
62
+
63
+ Rack::MockRequest.env_for("/", :method => "OPTIONS")["REQUEST_METHOD"].
64
+ should.equal "OPTIONS"
65
+ end
66
+
67
+ specify "should allow posting" do
68
+ res = Rack::MockRequest.new(app).get("", :input => "foo")
69
+ env = YAML.load(res.body)
70
+ env["mock.postdata"].should.equal "foo"
71
+
72
+ res = Rack::MockRequest.new(app).post("", :input => StringIO.new("foo"))
73
+ env = YAML.load(res.body)
74
+ env["mock.postdata"].should.equal "foo"
75
+ end
76
+
77
+ specify "should use all parts of an URL" do
78
+ res = Rack::MockRequest.new(app).
79
+ get("https://bla.example.org:9292/meh/foo?bar")
80
+ res.should.be.kind_of Rack::MockResponse
81
+
82
+ env = YAML.load(res.body)
83
+ env["REQUEST_METHOD"].should.equal "GET"
84
+ env["SERVER_NAME"].should.equal "bla.example.org"
85
+ env["SERVER_PORT"].should.equal "9292"
86
+ env["QUERY_STRING"].should.equal "bar"
87
+ env["PATH_INFO"].should.equal "/meh/foo"
88
+ env["rack.url_scheme"].should.equal "https"
89
+ end
90
+
91
+ specify "should behave valid according to the Rack spec" do
92
+ lambda {
93
+ res = Rack::MockRequest.new(app).
94
+ get("https://bla.example.org:9292/meh/foo?bar", :lint => true)
95
+ }.should.not.raise(Rack::Lint::LintError)
96
+ end
97
+ end
98
+
99
+ context "Rack::MockResponse" do
100
+ specify "should provide access to the HTTP status" do
101
+ res = Rack::MockRequest.new(app).get("")
102
+ res.should.be.successful
103
+ res.should.be.ok
104
+
105
+ res = Rack::MockRequest.new(app).get("/?status=404")
106
+ res.should.not.be.successful
107
+ res.should.be.client_error
108
+ res.should.be.not_found
109
+
110
+ res = Rack::MockRequest.new(app).get("/?status=501")
111
+ res.should.not.be.successful
112
+ res.should.be.server_error
113
+
114
+ res = Rack::MockRequest.new(app).get("/?status=307")
115
+ res.should.be.redirect
116
+
117
+ res = Rack::MockRequest.new(app).get("/?status=201", :lint => true)
118
+ res.should.be.empty
119
+ end
120
+
121
+ specify "should provide access to the HTTP headers" do
122
+ res = Rack::MockRequest.new(app).get("")
123
+ res.should.include "Content-Type"
124
+ res.headers["Content-Type"].should.equal "text/yaml"
125
+ res.original_headers["Content-Type"].should.equal "text/yaml"
126
+ res["Content-Type"].should.equal "text/yaml"
127
+ res.content_type.should.equal "text/yaml"
128
+ res.content_length.should.be.nil
129
+ end
130
+
131
+ specify "should provide access to the HTTP body" do
132
+ res = Rack::MockRequest.new(app).get("")
133
+ res.body.should =~ /rack/
134
+ res.should =~ /rack/
135
+ res.should.match(/rack/)
136
+ end
137
+
138
+ specify "should provide access to the Rack errors" do
139
+ res = Rack::MockRequest.new(app).get("/?error=foo", :lint => true)
140
+ res.should.be.ok
141
+ res.errors.should.not.be.empty
142
+ res.errors.should.include "foo"
143
+ end
144
+
145
+ specify "should optionally make Rack errors fatal" do
146
+ lambda {
147
+ Rack::MockRequest.new(app).get("/?error=foo", :fatal => true)
148
+ }.should.raise(Rack::MockRequest::FatalWarning)
149
+ end
150
+ end
@@ -0,0 +1,87 @@
1
+ require 'test/spec'
2
+
3
+ require 'rack/handler/mongrel'
4
+ require 'rack/lint'
5
+ require 'testrequest'
6
+
7
+ Thread.abort_on_exception = true
8
+ $tcp_defer_accept_opts = nil
9
+ $tcp_cork_opts = nil
10
+
11
+ context "Rack::Handler::Mongrel" do
12
+ include TestRequest::Helpers
13
+
14
+ setup do
15
+ server = Mongrel::HttpServer.new(@host='0.0.0.0', @port=9201)
16
+ server.register('/test',
17
+ Rack::Handler::Mongrel.new(Rack::Lint.new(TestRequest.new)))
18
+ @acc = server.run
19
+ end
20
+
21
+ specify "should respond" do
22
+ lambda {
23
+ GET("/test")
24
+ }.should.not.raise
25
+ end
26
+
27
+ specify "should be a Mongrel" do
28
+ GET("/test")
29
+ status.should.be 200
30
+ response["SERVER_SOFTWARE"].should =~ /Mongrel/
31
+ response["HTTP_VERSION"].should.equal "HTTP/1.1"
32
+ response["SERVER_PROTOCOL"].should.equal "HTTP/1.1"
33
+ response["SERVER_PORT"].should.equal "9201"
34
+ response["SERVER_NAME"].should.equal "0.0.0.0"
35
+ end
36
+
37
+ specify "should have rack headers" do
38
+ GET("/test")
39
+ response["rack.version"].should.equal [0,1]
40
+ response["rack.multithread"].should.be true
41
+ response["rack.multiprocess"].should.be false
42
+ response["rack.run_once"].should.be false
43
+ end
44
+
45
+ specify "should have CGI headers on GET" do
46
+ GET("/test")
47
+ response["REQUEST_METHOD"].should.equal "GET"
48
+ response["SCRIPT_NAME"].should.equal "/test"
49
+ response["REQUEST_PATH"].should.equal "/test"
50
+ response["PATH_INFO"].should.be.nil
51
+ response["QUERY_STRING"].should.equal ""
52
+ response["test.postdata"].should.equal ""
53
+
54
+ GET("/test/foo?quux=1")
55
+ response["REQUEST_METHOD"].should.equal "GET"
56
+ response["SCRIPT_NAME"].should.equal "/test"
57
+ response["REQUEST_PATH"].should.equal "/test/foo"
58
+ response["PATH_INFO"].should.equal "/foo"
59
+ response["QUERY_STRING"].should.equal "quux=1"
60
+ end
61
+
62
+ specify "should have CGI headers on POST" do
63
+ POST("/test", {"rack-form-data" => "23"}, {'X-test-header' => '42'})
64
+ status.should.equal 200
65
+ response["REQUEST_METHOD"].should.equal "POST"
66
+ response["SCRIPT_NAME"].should.equal "/test"
67
+ response["REQUEST_PATH"].should.equal "/test"
68
+ response["QUERY_STRING"].should.equal ""
69
+ response["HTTP_X_TEST_HEADER"].should.equal "42"
70
+ response["test.postdata"].should.equal "rack-form-data=23"
71
+ end
72
+
73
+ specify "should support HTTP auth" do
74
+ GET("/test", {:user => "ruth", :passwd => "secret"})
75
+ response["HTTP_AUTHORIZATION"].should.equal "Basic cnV0aDpzZWNyZXQ="
76
+ end
77
+
78
+ specify "should set status" do
79
+ GET("/test?secret")
80
+ status.should.equal 403
81
+ response["rack.url_scheme"].should.equal "http"
82
+ end
83
+
84
+ teardown do
85
+ @acc.raise Mongrel::StopServer
86
+ end
87
+ end
@@ -0,0 +1,77 @@
1
+ require 'test/spec'
2
+
3
+ require 'rack/recursive'
4
+ require 'rack/urlmap'
5
+ require 'rack/response'
6
+ require 'rack/mock'
7
+
8
+ context "Rack::Recursive" do
9
+ setup do
10
+
11
+ @app1 = lambda { |env|
12
+ res = Rack::Response.new
13
+ res["X-Path-Info"] = env["PATH_INFO"]
14
+ res["X-Query-String"] = env["QUERY_STRING"]
15
+ res.finish do |res|
16
+ res.write "App1"
17
+ end
18
+ }
19
+
20
+ @app2 = lambda { |env|
21
+ Rack::Response.new.finish do |res|
22
+ res.write "App2"
23
+ _, _, body = env['rack.recursive.include'].call(env, "/app1")
24
+ body.each { |b|
25
+ res.write b
26
+ }
27
+ end
28
+ }
29
+
30
+ @app3 = lambda { |env|
31
+ raise Rack::ForwardRequest.new("/app1")
32
+ }
33
+
34
+ @app4 = lambda { |env|
35
+ raise Rack::ForwardRequest.new("http://example.org/app1/quux?meh")
36
+ }
37
+
38
+ end
39
+
40
+ specify "should allow for subrequests" do
41
+ res = Rack::MockRequest.new(Rack::Recursive.new(
42
+ Rack::URLMap.new("/app1" => @app1,
43
+ "/app2" => @app2))).
44
+ get("/app2")
45
+
46
+ res.should.be.ok
47
+ res.body.should.equal "App2App1"
48
+ end
49
+
50
+ specify "should raise error on requests not below the app" do
51
+ app = Rack::URLMap.new("/app1" => @app1,
52
+ "/app" => Rack::Recursive.new(
53
+ Rack::URLMap.new("/1" => @app1,
54
+ "/2" => @app2)))
55
+
56
+ lambda {
57
+ Rack::MockRequest.new(app).get("/app/2")
58
+ }.should.raise(ArgumentError).
59
+ message.should =~ /can only include below/
60
+ end
61
+
62
+ specify "should support forwarding" do
63
+ app = Rack::Recursive.new(Rack::URLMap.new("/app1" => @app1,
64
+ "/app3" => @app3,
65
+ "/app4" => @app4))
66
+
67
+ res = Rack::MockRequest.new(app).get("/app3")
68
+ res.should.be.ok
69
+ res.body.should.equal "App1"
70
+
71
+ res = Rack::MockRequest.new(app).get("/app4")
72
+ res.should.be.ok
73
+ res.body.should.equal "App1"
74
+ res["X-Path-Info"].should.equal "/quux"
75
+ res["X-Query-String"].should.equal "meh"
76
+ end
77
+ end
@@ -0,0 +1,219 @@
1
+ require 'test/spec'
2
+ require 'stringio'
3
+
4
+ require 'rack/request'
5
+ require 'rack/mock'
6
+
7
+ context "Rack::Request" do
8
+ specify "wraps the rack variables" do
9
+ req = Rack::Request.new(Rack::MockRequest.env_for("http://example.com:8080/"))
10
+
11
+ req.body.should.respond_to? :gets
12
+ req.scheme.should.equal "http"
13
+ req.request_method.should.equal "GET"
14
+
15
+ req.should.be.get
16
+ req.should.not.be.post
17
+ req.should.not.be.put
18
+ req.should.not.be.delete
19
+
20
+ req.script_name.should.equal ""
21
+ req.path_info.should.equal "/"
22
+ req.query_string.should.equal ""
23
+
24
+ req.host.should.equal "example.com"
25
+ req.port.should.equal 8080
26
+ end
27
+
28
+ specify "can figure out the correct host" do
29
+ req = Rack::Request.new \
30
+ Rack::MockRequest.env_for("/", "HTTP_HOST" => "www2.example.org")
31
+ req.host.should.equal "www2.example.org"
32
+
33
+ req = Rack::Request.new \
34
+ Rack::MockRequest.env_for("/", "SERVER_NAME" => "example.org:9292")
35
+ req.host.should.equal "example.org"
36
+ end
37
+
38
+ specify "can parse the query string" do
39
+ req = Rack::Request.new(Rack::MockRequest.env_for("/?foo=bar&quux=bla"))
40
+ req.query_string.should.equal "foo=bar&quux=bla"
41
+ req.GET.should.equal "foo" => "bar", "quux" => "bla"
42
+ req.POST.should.be.empty
43
+ req.params.should.equal "foo" => "bar", "quux" => "bla"
44
+ end
45
+
46
+ specify "can parse POST data" do
47
+ req = Rack::Request.new \
48
+ Rack::MockRequest.env_for("/?foo=quux", :input => "foo=bar&quux=bla")
49
+ req.query_string.should.equal "foo=quux"
50
+ req.GET.should.equal "foo" => "quux"
51
+ req.POST.should.equal "foo" => "bar", "quux" => "bla"
52
+ req.params.should.equal "foo" => "bar", "quux" => "bla"
53
+ end
54
+
55
+
56
+ specify "can cache, but invalidates the cache" do
57
+ req = Rack::Request.new \
58
+ Rack::MockRequest.env_for("/?foo=quux", :input => "foo=bar&quux=bla")
59
+ req.GET.should.equal "foo" => "quux"
60
+ req.GET.should.equal "foo" => "quux"
61
+ req.env["QUERY_STRING"] = "bla=foo"
62
+ req.GET.should.equal "bla" => "foo"
63
+ req.GET.should.equal "bla" => "foo"
64
+
65
+ req.POST.should.equal "foo" => "bar", "quux" => "bla"
66
+ req.POST.should.equal "foo" => "bar", "quux" => "bla"
67
+ req.env["rack.input"] = StringIO.new("foo=bla&quux=bar")
68
+ req.POST.should.equal "foo" => "bla", "quux" => "bar"
69
+ req.POST.should.equal "foo" => "bla", "quux" => "bar"
70
+ end
71
+
72
+ specify "can figure out if called via XHR" do
73
+ req = Rack::Request.new(Rack::MockRequest.env_for(""))
74
+ req.should.not.be.xhr
75
+
76
+ req = Rack::Request.new \
77
+ Rack::MockRequest.env_for("", "HTTP_X_REQUESTED_WITH" => "XMLHttpRequest")
78
+ req.should.be.xhr
79
+ end
80
+
81
+ specify "can parse cookies" do
82
+ req = Rack::Request.new \
83
+ Rack::MockRequest.env_for("", "HTTP_COOKIE" => "foo=bar;quux=h&m")
84
+ req.cookies.should.equal "foo" => "bar", "quux" => "h&m"
85
+ req.cookies.should.equal "foo" => "bar", "quux" => "h&m"
86
+ req.env.delete("HTTP_COOKIE")
87
+ req.cookies.should.equal({})
88
+ end
89
+
90
+ specify "provides setters" do
91
+ req = Rack::Request.new(e=Rack::MockRequest.env_for(""))
92
+ req.script_name.should.equal ""
93
+ req.script_name = "/foo"
94
+ req.script_name.should.equal "/foo"
95
+ e["SCRIPT_NAME"].should.equal "/foo"
96
+
97
+ req.path_info.should.equal "/"
98
+ req.path_info = "/foo"
99
+ req.path_info.should.equal "/foo"
100
+ e["PATH_INFO"].should.equal "/foo"
101
+ end
102
+
103
+ specify "provides the original env" do
104
+ req = Rack::Request.new(e=Rack::MockRequest.env_for(""))
105
+ req.env.should.be e
106
+ end
107
+
108
+ specify "can restore the URL" do
109
+ Rack::Request.new(Rack::MockRequest.env_for("")).url.
110
+ should.equal "http://example.org/"
111
+ Rack::Request.new(Rack::MockRequest.env_for("", "SCRIPT_NAME" => "/foo")).url.
112
+ should.equal "http://example.org/foo/"
113
+ Rack::Request.new(Rack::MockRequest.env_for("/foo")).url.
114
+ should.equal "http://example.org/foo"
115
+ Rack::Request.new(Rack::MockRequest.env_for("?foo")).url.
116
+ should.equal "http://example.org/?foo"
117
+ Rack::Request.new(Rack::MockRequest.env_for("http://example.org:8080/")).url.
118
+ should.equal "http://example.org:8080/"
119
+ Rack::Request.new(Rack::MockRequest.env_for("https://example.org/")).url.
120
+ should.equal "https://example.org/"
121
+
122
+ Rack::Request.new(Rack::MockRequest.env_for("https://example.com:8080/foo?foo")).url.
123
+ should.equal "https://example.com:8080/foo?foo"
124
+ end
125
+
126
+ specify "can parse multipart form data" do
127
+ # Adapted from RFC 1867.
128
+ input = <<EOF
129
+ --AaB03x\r
130
+ content-disposition: form-data; name="reply"\r
131
+ \r
132
+ yes\r
133
+ --AaB03x\r
134
+ content-disposition: form-data; name="fileupload"; filename="dj.jpg"\r
135
+ Content-Type: image/jpeg\r
136
+ Content-Transfer-Encoding: base64\r
137
+ \r
138
+ /9j/4AAQSkZJRgABAQAAAQABAAD//gA+Q1JFQVRPUjogZ2QtanBlZyB2MS4wICh1c2luZyBJSkcg\r
139
+ --AaB03x--\r
140
+ EOF
141
+ req = Rack::Request.new Rack::MockRequest.env_for("/",
142
+ "CONTENT_TYPE" => "multipart/form-data, boundary=AaB03x",
143
+ "CONTENT_LENGTH" => input.size,
144
+ :input => input)
145
+
146
+ req.POST.should.include "fileupload"
147
+ req.POST.should.include "reply"
148
+
149
+ req.POST["reply"].should.equal "yes"
150
+
151
+ f = req.POST["fileupload"]
152
+ f.should.be.kind_of Hash
153
+ f[:type].should.equal "image/jpeg"
154
+ f[:filename].should.equal "dj.jpg"
155
+ f.should.include :tempfile
156
+ f[:tempfile].size.should.equal 76
157
+ end
158
+
159
+ specify "can parse big multipart form data" do
160
+ input = <<EOF
161
+ --AaB03x\r
162
+ content-disposition: form-data; name="huge"; filename="huge"\r
163
+ \r
164
+ #{"x"*32768}\r
165
+ --AaB03x\r
166
+ content-disposition: form-data; name="mean"; filename="mean"\r
167
+ \r
168
+ --AaB03xha\r
169
+ --AaB03x--\r
170
+ EOF
171
+ req = Rack::Request.new Rack::MockRequest.env_for("/",
172
+ "CONTENT_TYPE" => "multipart/form-data, boundary=AaB03x",
173
+ "CONTENT_LENGTH" => input.size,
174
+ :input => input)
175
+
176
+ req.POST["huge"][:tempfile].size.should.equal 32768
177
+ req.POST["mean"][:tempfile].size.should.equal 10
178
+ req.POST["mean"][:tempfile].read.should.equal "--AaB03xha"
179
+ end
180
+
181
+ specify "can detect invalid multipart form data" do
182
+ input = <<EOF
183
+ --AaB03x\r
184
+ content-disposition: form-data; name="huge"; filename="huge"\r
185
+ EOF
186
+ req = Rack::Request.new Rack::MockRequest.env_for("/",
187
+ "CONTENT_TYPE" => "multipart/form-data, boundary=AaB03x",
188
+ "CONTENT_LENGTH" => input.size,
189
+ :input => input)
190
+
191
+ lambda { req.POST }.should.raise(EOFError)
192
+
193
+ input = <<EOF
194
+ --AaB03x\r
195
+ content-disposition: form-data; name="huge"; filename="huge"\r
196
+ \r
197
+ foo\r
198
+ EOF
199
+ req = Rack::Request.new Rack::MockRequest.env_for("/",
200
+ "CONTENT_TYPE" => "multipart/form-data, boundary=AaB03x",
201
+ "CONTENT_LENGTH" => input.size,
202
+ :input => input)
203
+
204
+ lambda { req.POST }.should.raise(EOFError)
205
+
206
+ input = <<EOF
207
+ --AaB03x\r
208
+ content-disposition: form-data; name="huge"; filename="huge"\r
209
+ \r
210
+ foo\r
211
+ EOF
212
+ req = Rack::Request.new Rack::MockRequest.env_for("/",
213
+ "CONTENT_TYPE" => "multipart/form-data, boundary=AaB03x",
214
+ "CONTENT_LENGTH" => input.size,
215
+ :input => input)
216
+
217
+ lambda { req.POST }.should.raise(EOFError)
218
+ end
219
+ end