qoobaa-rack 1.0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. data/COPYING +18 -0
  2. data/KNOWN-ISSUES +18 -0
  3. data/RDOX +0 -0
  4. data/README +353 -0
  5. data/Rakefile +164 -0
  6. data/SPEC +164 -0
  7. data/bin/rackup +176 -0
  8. data/contrib/rack_logo.svg +111 -0
  9. data/example/lobster.ru +4 -0
  10. data/example/protectedlobster.rb +14 -0
  11. data/example/protectedlobster.ru +8 -0
  12. data/lib/rack/adapter/camping.rb +22 -0
  13. data/lib/rack/auth/abstract/handler.rb +37 -0
  14. data/lib/rack/auth/abstract/request.rb +37 -0
  15. data/lib/rack/auth/basic.rb +58 -0
  16. data/lib/rack/auth/digest/md5.rb +124 -0
  17. data/lib/rack/auth/digest/nonce.rb +51 -0
  18. data/lib/rack/auth/digest/params.rb +55 -0
  19. data/lib/rack/auth/digest/request.rb +40 -0
  20. data/lib/rack/auth/openid.rb +487 -0
  21. data/lib/rack/builder.rb +63 -0
  22. data/lib/rack/cascade.rb +41 -0
  23. data/lib/rack/chunked.rb +49 -0
  24. data/lib/rack/commonlogger.rb +52 -0
  25. data/lib/rack/conditionalget.rb +47 -0
  26. data/lib/rack/content_length.rb +29 -0
  27. data/lib/rack/content_type.rb +23 -0
  28. data/lib/rack/deflater.rb +96 -0
  29. data/lib/rack/directory.rb +153 -0
  30. data/lib/rack/file.rb +88 -0
  31. data/lib/rack/handler/cgi.rb +61 -0
  32. data/lib/rack/handler/evented_mongrel.rb +8 -0
  33. data/lib/rack/handler/fastcgi.rb +88 -0
  34. data/lib/rack/handler/lsws.rb +60 -0
  35. data/lib/rack/handler/mongrel.rb +87 -0
  36. data/lib/rack/handler/scgi.rb +62 -0
  37. data/lib/rack/handler/swiftiplied_mongrel.rb +8 -0
  38. data/lib/rack/handler/thin.rb +18 -0
  39. data/lib/rack/handler/webrick.rb +71 -0
  40. data/lib/rack/handler.rb +69 -0
  41. data/lib/rack/head.rb +19 -0
  42. data/lib/rack/lint.rb +546 -0
  43. data/lib/rack/lobster.rb +65 -0
  44. data/lib/rack/lock.rb +16 -0
  45. data/lib/rack/methodoverride.rb +27 -0
  46. data/lib/rack/mime.rb +204 -0
  47. data/lib/rack/mock.rb +187 -0
  48. data/lib/rack/recursive.rb +57 -0
  49. data/lib/rack/reloader.rb +107 -0
  50. data/lib/rack/request.rb +248 -0
  51. data/lib/rack/response.rb +183 -0
  52. data/lib/rack/rewindable_input.rb +100 -0
  53. data/lib/rack/session/abstract/id.rb +142 -0
  54. data/lib/rack/session/cookie.rb +91 -0
  55. data/lib/rack/session/memcache.rb +109 -0
  56. data/lib/rack/session/pool.rb +100 -0
  57. data/lib/rack/showexceptions.rb +349 -0
  58. data/lib/rack/showstatus.rb +106 -0
  59. data/lib/rack/static.rb +38 -0
  60. data/lib/rack/urlmap.rb +55 -0
  61. data/lib/rack/utils.rb +528 -0
  62. data/lib/rack.rb +90 -0
  63. data/rack.gemspec +60 -0
  64. data/test/cgi/lighttpd.conf +20 -0
  65. data/test/cgi/test +9 -0
  66. data/test/cgi/test.fcgi +8 -0
  67. data/test/cgi/test.ru +7 -0
  68. data/test/multipart/binary +0 -0
  69. data/test/multipart/empty +10 -0
  70. data/test/multipart/file1.txt +1 -0
  71. data/test/multipart/ie +6 -0
  72. data/test/multipart/nested +10 -0
  73. data/test/multipart/none +9 -0
  74. data/test/multipart/text +10 -0
  75. data/test/spec_rack_auth_basic.rb +73 -0
  76. data/test/spec_rack_auth_digest.rb +226 -0
  77. data/test/spec_rack_auth_openid.rb +84 -0
  78. data/test/spec_rack_builder.rb +84 -0
  79. data/test/spec_rack_camping.rb +51 -0
  80. data/test/spec_rack_cascade.rb +48 -0
  81. data/test/spec_rack_cgi.rb +89 -0
  82. data/test/spec_rack_chunked.rb +62 -0
  83. data/test/spec_rack_commonlogger.rb +61 -0
  84. data/test/spec_rack_conditionalget.rb +41 -0
  85. data/test/spec_rack_content_length.rb +43 -0
  86. data/test/spec_rack_content_type.rb +30 -0
  87. data/test/spec_rack_deflater.rb +127 -0
  88. data/test/spec_rack_directory.rb +61 -0
  89. data/test/spec_rack_fastcgi.rb +89 -0
  90. data/test/spec_rack_file.rb +75 -0
  91. data/test/spec_rack_handler.rb +43 -0
  92. data/test/spec_rack_head.rb +30 -0
  93. data/test/spec_rack_lint.rb +521 -0
  94. data/test/spec_rack_lobster.rb +45 -0
  95. data/test/spec_rack_lock.rb +38 -0
  96. data/test/spec_rack_methodoverride.rb +60 -0
  97. data/test/spec_rack_mock.rb +243 -0
  98. data/test/spec_rack_mongrel.rb +189 -0
  99. data/test/spec_rack_recursive.rb +77 -0
  100. data/test/spec_rack_request.rb +504 -0
  101. data/test/spec_rack_response.rb +218 -0
  102. data/test/spec_rack_rewindable_input.rb +118 -0
  103. data/test/spec_rack_session_cookie.rb +82 -0
  104. data/test/spec_rack_session_memcache.rb +250 -0
  105. data/test/spec_rack_session_pool.rb +172 -0
  106. data/test/spec_rack_showexceptions.rb +21 -0
  107. data/test/spec_rack_showstatus.rb +72 -0
  108. data/test/spec_rack_static.rb +37 -0
  109. data/test/spec_rack_thin.rb +91 -0
  110. data/test/spec_rack_urlmap.rb +185 -0
  111. data/test/spec_rack_utils.rb +467 -0
  112. data/test/spec_rack_webrick.rb +130 -0
  113. data/test/testrequest.rb +57 -0
  114. data/test/unregistered_handler/rack/handler/unregistered.rb +7 -0
  115. data/test/unregistered_handler/rack/handler/unregistered_long_one.rb +7 -0
  116. metadata +276 -0
@@ -0,0 +1,504 @@
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
+ req.should.not.be.head
20
+
21
+ req.script_name.should.equal ""
22
+ req.path_info.should.equal "/"
23
+ req.query_string.should.equal ""
24
+
25
+ req.host.should.equal "example.com"
26
+ req.port.should.equal 8080
27
+
28
+ req.content_length.should.equal "0"
29
+ req.content_type.should.be.nil
30
+ end
31
+
32
+ specify "can figure out the correct host" do
33
+ req = Rack::Request.new \
34
+ Rack::MockRequest.env_for("/", "HTTP_HOST" => "www2.example.org")
35
+ req.host.should.equal "www2.example.org"
36
+
37
+ req = Rack::Request.new \
38
+ Rack::MockRequest.env_for("/", "SERVER_NAME" => "example.org:9292")
39
+ req.host.should.equal "example.org"
40
+ end
41
+
42
+ specify "can parse the query string" do
43
+ req = Rack::Request.new(Rack::MockRequest.env_for("/?foo=bar&quux=bla"))
44
+ req.query_string.should.equal "foo=bar&quux=bla"
45
+ req.GET.should.equal "foo" => "bar", "quux" => "bla"
46
+ req.POST.should.be.empty
47
+ req.params.should.equal "foo" => "bar", "quux" => "bla"
48
+ end
49
+
50
+ specify "raises if rack.input is missing" do
51
+ req = Rack::Request.new({})
52
+ lambda { req.POST }.should.raise(RuntimeError)
53
+ end
54
+
55
+ specify "can parse POST data" do
56
+ req = Rack::Request.new \
57
+ Rack::MockRequest.env_for("/?foo=quux", :input => "foo=bar&quux=bla")
58
+ req.content_type.should.be.nil
59
+ req.media_type.should.be.nil
60
+ req.query_string.should.equal "foo=quux"
61
+ req.GET.should.equal "foo" => "quux"
62
+ req.POST.should.equal "foo" => "bar", "quux" => "bla"
63
+ req.params.should.equal "foo" => "bar", "quux" => "bla"
64
+ end
65
+
66
+ specify "can parse POST data with explicit content type" do
67
+ req = Rack::Request.new \
68
+ Rack::MockRequest.env_for("/",
69
+ "CONTENT_TYPE" => 'application/x-www-form-urlencoded;foo=bar',
70
+ :input => "foo=bar&quux=bla")
71
+ req.content_type.should.equal 'application/x-www-form-urlencoded;foo=bar'
72
+ req.media_type.should.equal 'application/x-www-form-urlencoded'
73
+ req.media_type_params['foo'].should.equal 'bar'
74
+ req.POST.should.equal "foo" => "bar", "quux" => "bla"
75
+ req.params.should.equal "foo" => "bar", "quux" => "bla"
76
+ end
77
+
78
+ specify "does not parse POST data when media type is not form-data" do
79
+ req = Rack::Request.new \
80
+ Rack::MockRequest.env_for("/?foo=quux",
81
+ "CONTENT_TYPE" => 'text/plain;charset=utf-8',
82
+ :input => "foo=bar&quux=bla")
83
+ req.content_type.should.equal 'text/plain;charset=utf-8'
84
+ req.media_type.should.equal 'text/plain'
85
+ req.media_type_params['charset'].should.equal 'utf-8'
86
+ req.POST.should.be.empty
87
+ req.params.should.equal "foo" => "quux"
88
+ req.body.read.should.equal "foo=bar&quux=bla"
89
+ end
90
+
91
+ specify "rewinds input after parsing POST data" do
92
+ input = StringIO.new("foo=bar&quux=bla")
93
+ req = Rack::Request.new \
94
+ Rack::MockRequest.env_for("/",
95
+ "CONTENT_TYPE" => 'application/x-www-form-urlencoded;foo=bar',
96
+ :input => input)
97
+ req.params.should.equal "foo" => "bar", "quux" => "bla"
98
+ input.read.should.equal "foo=bar&quux=bla"
99
+ end
100
+
101
+ specify "cleans up Safari's ajax POST body" do
102
+ req = Rack::Request.new \
103
+ Rack::MockRequest.env_for("/", :input => "foo=bar&quux=bla\0")
104
+ req.POST.should.equal "foo" => "bar", "quux" => "bla"
105
+ end
106
+
107
+ specify "can get value by key from params with #[]" do
108
+ req = Rack::Request.new \
109
+ Rack::MockRequest.env_for("?foo=quux")
110
+ req['foo'].should.equal 'quux'
111
+ req[:foo].should.equal 'quux'
112
+ end
113
+
114
+ specify "can set value to key on params with #[]=" do
115
+ req = Rack::Request.new \
116
+ Rack::MockRequest.env_for("?foo=duh")
117
+ req['foo'].should.equal 'duh'
118
+ req[:foo].should.equal 'duh'
119
+ req.params.should.equal 'foo' => 'duh'
120
+
121
+ req['foo'] = 'bar'
122
+ req.params.should.equal 'foo' => 'bar'
123
+ req['foo'].should.equal 'bar'
124
+ req[:foo].should.equal 'bar'
125
+
126
+ req[:foo] = 'jaz'
127
+ req.params.should.equal 'foo' => 'jaz'
128
+ req['foo'].should.equal 'jaz'
129
+ req[:foo].should.equal 'jaz'
130
+ end
131
+
132
+ specify "values_at answers values by keys in order given" do
133
+ req = Rack::Request.new \
134
+ Rack::MockRequest.env_for("?foo=baz&wun=der&bar=ful")
135
+ req.values_at('foo').should.equal ['baz']
136
+ req.values_at('foo', 'wun').should.equal ['baz', 'der']
137
+ req.values_at('bar', 'foo', 'wun').should.equal ['ful', 'baz', 'der']
138
+ end
139
+
140
+ specify "referrer should be extracted correct" do
141
+ req = Rack::Request.new \
142
+ Rack::MockRequest.env_for("/", "HTTP_REFERER" => "/some/path")
143
+ req.referer.should.equal "/some/path"
144
+
145
+ req = Rack::Request.new \
146
+ Rack::MockRequest.env_for("/")
147
+ req.referer.should.equal "/"
148
+ end
149
+
150
+ specify "can cache, but invalidates the cache" do
151
+ req = Rack::Request.new \
152
+ Rack::MockRequest.env_for("/?foo=quux", :input => "foo=bar&quux=bla")
153
+ req.GET.should.equal "foo" => "quux"
154
+ req.GET.should.equal "foo" => "quux"
155
+ req.env["QUERY_STRING"] = "bla=foo"
156
+ req.GET.should.equal "bla" => "foo"
157
+ req.GET.should.equal "bla" => "foo"
158
+
159
+ req.POST.should.equal "foo" => "bar", "quux" => "bla"
160
+ req.POST.should.equal "foo" => "bar", "quux" => "bla"
161
+ req.env["rack.input"] = StringIO.new("foo=bla&quux=bar")
162
+ req.POST.should.equal "foo" => "bla", "quux" => "bar"
163
+ req.POST.should.equal "foo" => "bla", "quux" => "bar"
164
+ end
165
+
166
+ specify "can figure out if called via XHR" do
167
+ req = Rack::Request.new(Rack::MockRequest.env_for(""))
168
+ req.should.not.be.xhr
169
+
170
+ req = Rack::Request.new \
171
+ Rack::MockRequest.env_for("", "HTTP_X_REQUESTED_WITH" => "XMLHttpRequest")
172
+ req.should.be.xhr
173
+ end
174
+
175
+ specify "can parse cookies" do
176
+ req = Rack::Request.new \
177
+ Rack::MockRequest.env_for("", "HTTP_COOKIE" => "foo=bar;quux=h&m")
178
+ req.cookies.should.equal "foo" => "bar", "quux" => "h&m"
179
+ req.cookies.should.equal "foo" => "bar", "quux" => "h&m"
180
+ req.env.delete("HTTP_COOKIE")
181
+ req.cookies.should.equal({})
182
+ end
183
+
184
+ specify "parses cookies according to RFC 2109" do
185
+ req = Rack::Request.new \
186
+ Rack::MockRequest.env_for('', 'HTTP_COOKIE' => 'foo=bar;foo=car')
187
+ req.cookies.should.equal 'foo' => 'bar'
188
+ end
189
+
190
+ specify "provides setters" do
191
+ req = Rack::Request.new(e=Rack::MockRequest.env_for(""))
192
+ req.script_name.should.equal ""
193
+ req.script_name = "/foo"
194
+ req.script_name.should.equal "/foo"
195
+ e["SCRIPT_NAME"].should.equal "/foo"
196
+
197
+ req.path_info.should.equal "/"
198
+ req.path_info = "/foo"
199
+ req.path_info.should.equal "/foo"
200
+ e["PATH_INFO"].should.equal "/foo"
201
+ end
202
+
203
+ specify "provides the original env" do
204
+ req = Rack::Request.new(e=Rack::MockRequest.env_for(""))
205
+ req.env.should.be e
206
+ end
207
+
208
+ specify "can restore the URL" do
209
+ Rack::Request.new(Rack::MockRequest.env_for("")).url.
210
+ should.equal "http://example.org/"
211
+ Rack::Request.new(Rack::MockRequest.env_for("", "SCRIPT_NAME" => "/foo")).url.
212
+ should.equal "http://example.org/foo/"
213
+ Rack::Request.new(Rack::MockRequest.env_for("/foo")).url.
214
+ should.equal "http://example.org/foo"
215
+ Rack::Request.new(Rack::MockRequest.env_for("?foo")).url.
216
+ should.equal "http://example.org/?foo"
217
+ Rack::Request.new(Rack::MockRequest.env_for("http://example.org:8080/")).url.
218
+ should.equal "http://example.org:8080/"
219
+ Rack::Request.new(Rack::MockRequest.env_for("https://example.org/")).url.
220
+ should.equal "https://example.org/"
221
+
222
+ Rack::Request.new(Rack::MockRequest.env_for("https://example.com:8080/foo?foo")).url.
223
+ should.equal "https://example.com:8080/foo?foo"
224
+ end
225
+
226
+ specify "can restore the full path" do
227
+ Rack::Request.new(Rack::MockRequest.env_for("")).fullpath.
228
+ should.equal "/"
229
+ Rack::Request.new(Rack::MockRequest.env_for("", "SCRIPT_NAME" => "/foo")).fullpath.
230
+ should.equal "/foo/"
231
+ Rack::Request.new(Rack::MockRequest.env_for("/foo")).fullpath.
232
+ should.equal "/foo"
233
+ Rack::Request.new(Rack::MockRequest.env_for("?foo")).fullpath.
234
+ should.equal "/?foo"
235
+ Rack::Request.new(Rack::MockRequest.env_for("http://example.org:8080/")).fullpath.
236
+ should.equal "/"
237
+ Rack::Request.new(Rack::MockRequest.env_for("https://example.org/")).fullpath.
238
+ should.equal "/"
239
+
240
+ Rack::Request.new(Rack::MockRequest.env_for("https://example.com:8080/foo?foo")).fullpath.
241
+ should.equal "/foo?foo"
242
+ end
243
+
244
+ specify "can handle multiple media type parameters" do
245
+ req = Rack::Request.new \
246
+ Rack::MockRequest.env_for("/",
247
+ "CONTENT_TYPE" => 'text/plain; foo=BAR,baz=bizzle dizzle;BLING=bam')
248
+ req.should.not.be.form_data
249
+ req.media_type_params.should.include 'foo'
250
+ req.media_type_params['foo'].should.equal 'BAR'
251
+ req.media_type_params.should.include 'baz'
252
+ req.media_type_params['baz'].should.equal 'bizzle dizzle'
253
+ req.media_type_params.should.not.include 'BLING'
254
+ req.media_type_params.should.include 'bling'
255
+ req.media_type_params['bling'].should.equal 'bam'
256
+ end
257
+
258
+ specify "can parse multipart form data" do
259
+ # Adapted from RFC 1867.
260
+ input = <<EOF
261
+ --AaB03x\r
262
+ content-disposition: form-data; name="reply"\r
263
+ \r
264
+ yes\r
265
+ --AaB03x\r
266
+ content-disposition: form-data; name="fileupload"; filename="dj.jpg"\r
267
+ Content-Type: image/jpeg\r
268
+ Content-Transfer-Encoding: base64\r
269
+ \r
270
+ /9j/4AAQSkZJRgABAQAAAQABAAD//gA+Q1JFQVRPUjogZ2QtanBlZyB2MS4wICh1c2luZyBJSkcg\r
271
+ --AaB03x--\r
272
+ EOF
273
+ req = Rack::Request.new Rack::MockRequest.env_for("/",
274
+ "CONTENT_TYPE" => "multipart/form-data, boundary=AaB03x",
275
+ "CONTENT_LENGTH" => input.size,
276
+ :input => input)
277
+
278
+ req.POST.should.include "fileupload"
279
+ req.POST.should.include "reply"
280
+
281
+ req.should.be.form_data
282
+ req.content_length.should.equal input.size
283
+ req.media_type.should.equal 'multipart/form-data'
284
+ req.media_type_params.should.include 'boundary'
285
+ req.media_type_params['boundary'].should.equal 'AaB03x'
286
+
287
+ req.POST["reply"].should.equal "yes"
288
+
289
+ f = req.POST["fileupload"]
290
+ f.should.be.kind_of Hash
291
+ f[:type].should.equal "image/jpeg"
292
+ f[:filename].should.equal "dj.jpg"
293
+ f.should.include :tempfile
294
+ f[:tempfile].size.should.equal 76
295
+ end
296
+
297
+ specify "can parse big multipart form data" do
298
+ input = <<EOF
299
+ --AaB03x\r
300
+ content-disposition: form-data; name="huge"; filename="huge"\r
301
+ \r
302
+ #{"x"*32768}\r
303
+ --AaB03x\r
304
+ content-disposition: form-data; name="mean"; filename="mean"\r
305
+ \r
306
+ --AaB03xha\r
307
+ --AaB03x--\r
308
+ EOF
309
+ req = Rack::Request.new Rack::MockRequest.env_for("/",
310
+ "CONTENT_TYPE" => "multipart/form-data, boundary=AaB03x",
311
+ "CONTENT_LENGTH" => input.size,
312
+ :input => input)
313
+
314
+ req.POST["huge"][:tempfile].size.should.equal 32768
315
+ req.POST["mean"][:tempfile].size.should.equal 10
316
+ req.POST["mean"][:tempfile].read.should.equal "--AaB03xha"
317
+ end
318
+
319
+ specify "can detect invalid multipart form data" do
320
+ input = <<EOF
321
+ --AaB03x\r
322
+ content-disposition: form-data; name="huge"; filename="huge"\r
323
+ EOF
324
+ req = Rack::Request.new Rack::MockRequest.env_for("/",
325
+ "CONTENT_TYPE" => "multipart/form-data, boundary=AaB03x",
326
+ "CONTENT_LENGTH" => input.size,
327
+ :input => input)
328
+
329
+ lambda { req.POST }.should.raise(EOFError)
330
+
331
+ input = <<EOF
332
+ --AaB03x\r
333
+ content-disposition: form-data; name="huge"; filename="huge"\r
334
+ \r
335
+ foo\r
336
+ EOF
337
+ req = Rack::Request.new Rack::MockRequest.env_for("/",
338
+ "CONTENT_TYPE" => "multipart/form-data, boundary=AaB03x",
339
+ "CONTENT_LENGTH" => input.size,
340
+ :input => input)
341
+
342
+ lambda { req.POST }.should.raise(EOFError)
343
+
344
+ input = <<EOF
345
+ --AaB03x\r
346
+ content-disposition: form-data; name="huge"; filename="huge"\r
347
+ \r
348
+ foo\r
349
+ EOF
350
+ req = Rack::Request.new Rack::MockRequest.env_for("/",
351
+ "CONTENT_TYPE" => "multipart/form-data, boundary=AaB03x",
352
+ "CONTENT_LENGTH" => input.size,
353
+ :input => input)
354
+
355
+ lambda { req.POST }.should.raise(EOFError)
356
+ end
357
+
358
+ specify "shouldn't try to interpret binary as utf8" do
359
+ begin
360
+ original_kcode = $KCODE
361
+ $KCODE='UTF8'
362
+
363
+ input = <<EOF
364
+ --AaB03x\r
365
+ content-disposition: form-data; name="fileupload"; filename="junk.a"\r
366
+ content-type: application/octet-stream\r
367
+ \r
368
+ #{[0x36,0xCF,0x0A,0xF8].pack('c*')}\r
369
+ --AaB03x--\r
370
+ EOF
371
+
372
+ req = Rack::Request.new Rack::MockRequest.env_for("/",
373
+ "CONTENT_TYPE" => "multipart/form-data, boundary=AaB03x",
374
+ "CONTENT_LENGTH" => input.size,
375
+ :input => input)
376
+
377
+ lambda{req.POST}.should.not.raise(EOFError)
378
+ req.POST["fileupload"][:tempfile].size.should.equal 4
379
+ ensure
380
+ $KCODE = original_kcode
381
+ end
382
+ end
383
+
384
+
385
+ specify "should work around buggy 1.8.* Tempfile equality" do
386
+ input = <<EOF
387
+ --AaB03x\r
388
+ content-disposition: form-data; name="huge"; filename="huge"\r
389
+ \r
390
+ foo\r
391
+ --AaB03x--
392
+ EOF
393
+
394
+ rack_input = Tempfile.new("rackspec")
395
+ rack_input.write(input)
396
+ rack_input.rewind
397
+
398
+ req = Rack::Request.new Rack::MockRequest.env_for("/",
399
+ "CONTENT_TYPE" => "multipart/form-data, boundary=AaB03x",
400
+ "CONTENT_LENGTH" => input.size,
401
+ :input => rack_input)
402
+
403
+ lambda {req.POST}.should.not.raise
404
+ lambda {req.POST}.should.blaming("input re-processed!").not.raise
405
+ end
406
+
407
+ specify "does conform to the Rack spec" do
408
+ app = lambda { |env|
409
+ content = Rack::Request.new(env).POST["file"].inspect
410
+ size = content.respond_to?(:bytesize) ? content.bytesize : content.size
411
+ [200, {"Content-Type" => "text/html", "Content-Length" => size.to_s}, [content]]
412
+ }
413
+
414
+ input = <<EOF
415
+ --AaB03x\r
416
+ content-disposition: form-data; name="reply"\r
417
+ \r
418
+ yes\r
419
+ --AaB03x\r
420
+ content-disposition: form-data; name="fileupload"; filename="dj.jpg"\r
421
+ Content-Type: image/jpeg\r
422
+ Content-Transfer-Encoding: base64\r
423
+ \r
424
+ /9j/4AAQSkZJRgABAQAAAQABAAD//gA+Q1JFQVRPUjogZ2QtanBlZyB2MS4wICh1c2luZyBJSkcg\r
425
+ --AaB03x--\r
426
+ EOF
427
+ res = Rack::MockRequest.new(Rack::Lint.new(app)).get "/",
428
+ "CONTENT_TYPE" => "multipart/form-data, boundary=AaB03x",
429
+ "CONTENT_LENGTH" => input.size.to_s, "rack.input" => StringIO.new(input)
430
+
431
+ res.should.be.ok
432
+ end
433
+
434
+ specify "should parse Accept-Encoding correctly" do
435
+ parser = lambda do |x|
436
+ Rack::Request.new(Rack::MockRequest.env_for("", "HTTP_ACCEPT_ENCODING" => x)).accept_encoding
437
+ end
438
+
439
+ parser.call(nil).should.equal([])
440
+
441
+ parser.call("compress, gzip").should.equal([["compress", 1.0], ["gzip", 1.0]])
442
+ parser.call("").should.equal([])
443
+ parser.call("*").should.equal([["*", 1.0]])
444
+ parser.call("compress;q=0.5, gzip;q=1.0").should.equal([["compress", 0.5], ["gzip", 1.0]])
445
+ parser.call("gzip;q=1.0, identity; q=0.5, *;q=0").should.equal([["gzip", 1.0], ["identity", 0.5], ["*", 0] ])
446
+
447
+ lambda { parser.call("gzip ; q=1.0") }.should.raise(RuntimeError)
448
+ end
449
+
450
+ specify 'should provide ip information' do
451
+ app = lambda { |env|
452
+ request = Rack::Request.new(env)
453
+ response = Rack::Response.new
454
+ response.write request.ip
455
+ response.finish
456
+ }
457
+
458
+ mock = Rack::MockRequest.new(Rack::Lint.new(app))
459
+ res = mock.get '/', 'REMOTE_ADDR' => '123.123.123.123'
460
+ res.body.should.equal '123.123.123.123'
461
+
462
+ res = mock.get '/',
463
+ 'REMOTE_ADDR' => '123.123.123.123',
464
+ 'HTTP_X_FORWARDED_FOR' => '234.234.234.234'
465
+
466
+ res.body.should.equal '234.234.234.234'
467
+
468
+ res = mock.get '/',
469
+ 'REMOTE_ADDR' => '123.123.123.123',
470
+ 'HTTP_X_FORWARDED_FOR' => '234.234.234.234,212.212.212.212'
471
+
472
+ res.body.should.equal '212.212.212.212'
473
+ end
474
+
475
+ class MyRequest < Rack::Request
476
+ def params
477
+ {:foo => "bar"}
478
+ end
479
+ end
480
+
481
+ specify "should allow subclass request to be instantiated after parent request" do
482
+ env = Rack::MockRequest.env_for("/?foo=bar")
483
+
484
+ req1 = Rack::Request.new(env)
485
+ req1.GET.should.equal "foo" => "bar"
486
+ req1.params.should.equal "foo" => "bar"
487
+
488
+ req2 = MyRequest.new(env)
489
+ req2.GET.should.equal "foo" => "bar"
490
+ req2.params.should.equal :foo => "bar"
491
+ end
492
+
493
+ specify "should allow parent request to be instantiated after subclass request" do
494
+ env = Rack::MockRequest.env_for("/?foo=bar")
495
+
496
+ req1 = MyRequest.new(env)
497
+ req1.GET.should.equal "foo" => "bar"
498
+ req1.params.should.equal :foo => "bar"
499
+
500
+ req2 = Rack::Request.new(env)
501
+ req2.GET.should.equal "foo" => "bar"
502
+ req2.params.should.equal "foo" => "bar"
503
+ end
504
+ end