rack 2.0.9 → 2.1.4

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 (189) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +77 -0
  3. data/{COPYING → MIT-LICENSE} +4 -2
  4. data/README.rdoc +77 -117
  5. data/Rakefile +25 -18
  6. data/SPEC +3 -4
  7. data/bin/rackup +1 -0
  8. data/example/lobster.ru +2 -0
  9. data/example/protectedlobster.rb +3 -1
  10. data/example/protectedlobster.ru +2 -0
  11. data/lib/rack.rb +63 -60
  12. data/lib/rack/auth/abstract/handler.rb +3 -1
  13. data/lib/rack/auth/abstract/request.rb +2 -0
  14. data/lib/rack/auth/basic.rb +4 -1
  15. data/lib/rack/auth/digest/md5.rb +9 -7
  16. data/lib/rack/auth/digest/nonce.rb +6 -3
  17. data/lib/rack/auth/digest/params.rb +4 -2
  18. data/lib/rack/auth/digest/request.rb +2 -0
  19. data/lib/rack/body_proxy.rb +3 -6
  20. data/lib/rack/builder.rb +39 -15
  21. data/lib/rack/cascade.rb +6 -5
  22. data/lib/rack/chunked.rb +29 -6
  23. data/lib/rack/common_logger.rb +9 -8
  24. data/lib/rack/conditional_get.rb +3 -1
  25. data/lib/rack/config.rb +2 -0
  26. data/lib/rack/content_length.rb +3 -1
  27. data/lib/rack/content_type.rb +3 -1
  28. data/lib/rack/core_ext/regexp.rb +14 -0
  29. data/lib/rack/deflater.rb +32 -17
  30. data/lib/rack/directory.rb +19 -16
  31. data/lib/rack/etag.rb +3 -1
  32. data/lib/rack/events.rb +5 -3
  33. data/lib/rack/file.rb +4 -173
  34. data/lib/rack/files.rb +178 -0
  35. data/lib/rack/handler.rb +7 -2
  36. data/lib/rack/handler/cgi.rb +3 -1
  37. data/lib/rack/handler/fastcgi.rb +4 -2
  38. data/lib/rack/handler/lsws.rb +3 -1
  39. data/lib/rack/handler/scgi.rb +9 -6
  40. data/lib/rack/handler/thin.rb +3 -1
  41. data/lib/rack/handler/webrick.rb +4 -2
  42. data/lib/rack/head.rb +2 -0
  43. data/lib/rack/lint.rb +14 -11
  44. data/lib/rack/lobster.rb +7 -5
  45. data/lib/rack/lock.rb +2 -0
  46. data/lib/rack/logger.rb +2 -0
  47. data/lib/rack/media_type.rb +10 -5
  48. data/lib/rack/method_override.rb +4 -2
  49. data/lib/rack/mime.rb +9 -1
  50. data/lib/rack/mock.rb +74 -15
  51. data/lib/rack/multipart.rb +5 -3
  52. data/lib/rack/multipart/generator.rb +6 -7
  53. data/lib/rack/multipart/parser.rb +51 -45
  54. data/lib/rack/multipart/uploaded_file.rb +2 -0
  55. data/lib/rack/null_logger.rb +2 -0
  56. data/lib/rack/query_parser.rb +51 -25
  57. data/lib/rack/recursive.rb +7 -5
  58. data/lib/rack/reloader.rb +10 -4
  59. data/lib/rack/request.rb +79 -26
  60. data/lib/rack/response.rb +71 -31
  61. data/lib/rack/rewindable_input.rb +4 -2
  62. data/lib/rack/runtime.rb +4 -2
  63. data/lib/rack/sendfile.rb +15 -8
  64. data/lib/rack/server.rb +88 -18
  65. data/lib/rack/session/abstract/id.rb +30 -20
  66. data/lib/rack/session/cookie.rb +10 -9
  67. data/lib/rack/session/memcache.rb +4 -93
  68. data/lib/rack/session/pool.rb +4 -2
  69. data/lib/rack/show_exceptions.rb +15 -9
  70. data/lib/rack/show_status.rb +4 -2
  71. data/lib/rack/static.rb +15 -10
  72. data/lib/rack/tempfile_reaper.rb +2 -0
  73. data/lib/rack/urlmap.rb +11 -2
  74. data/lib/rack/utils.rb +59 -72
  75. data/rack.gemspec +17 -7
  76. metadata +33 -175
  77. data/HISTORY.md +0 -505
  78. data/test/builder/an_underscore_app.rb +0 -5
  79. data/test/builder/anything.rb +0 -5
  80. data/test/builder/comment.ru +0 -4
  81. data/test/builder/end.ru +0 -5
  82. data/test/builder/line.ru +0 -1
  83. data/test/builder/options.ru +0 -2
  84. data/test/cgi/assets/folder/test.js +0 -1
  85. data/test/cgi/assets/fonts/font.eot +0 -1
  86. data/test/cgi/assets/images/image.png +0 -1
  87. data/test/cgi/assets/index.html +0 -1
  88. data/test/cgi/assets/javascripts/app.js +0 -1
  89. data/test/cgi/assets/stylesheets/app.css +0 -1
  90. data/test/cgi/lighttpd.conf +0 -26
  91. data/test/cgi/rackup_stub.rb +0 -6
  92. data/test/cgi/sample_rackup.ru +0 -5
  93. data/test/cgi/test +0 -9
  94. data/test/cgi/test+directory/test+file +0 -1
  95. data/test/cgi/test.fcgi +0 -9
  96. data/test/cgi/test.gz +0 -0
  97. data/test/cgi/test.ru +0 -5
  98. data/test/gemloader.rb +0 -10
  99. data/test/helper.rb +0 -34
  100. data/test/multipart/bad_robots +0 -259
  101. data/test/multipart/binary +0 -0
  102. data/test/multipart/content_type_and_no_filename +0 -6
  103. data/test/multipart/empty +0 -10
  104. data/test/multipart/fail_16384_nofile +0 -814
  105. data/test/multipart/file1.txt +0 -1
  106. data/test/multipart/filename_and_modification_param +0 -7
  107. data/test/multipart/filename_and_no_name +0 -6
  108. data/test/multipart/filename_with_encoded_words +0 -7
  109. data/test/multipart/filename_with_escaped_quotes +0 -6
  110. data/test/multipart/filename_with_escaped_quotes_and_modification_param +0 -7
  111. data/test/multipart/filename_with_null_byte +0 -7
  112. data/test/multipart/filename_with_percent_escaped_quotes +0 -6
  113. data/test/multipart/filename_with_single_quote +0 -7
  114. data/test/multipart/filename_with_unescaped_percentages +0 -6
  115. data/test/multipart/filename_with_unescaped_percentages2 +0 -6
  116. data/test/multipart/filename_with_unescaped_percentages3 +0 -6
  117. data/test/multipart/filename_with_unescaped_quotes +0 -6
  118. data/test/multipart/ie +0 -6
  119. data/test/multipart/invalid_character +0 -6
  120. data/test/multipart/mixed_files +0 -21
  121. data/test/multipart/nested +0 -10
  122. data/test/multipart/none +0 -9
  123. data/test/multipart/quoted +0 -15
  124. data/test/multipart/rack-logo.png +0 -0
  125. data/test/multipart/semicolon +0 -6
  126. data/test/multipart/text +0 -15
  127. data/test/multipart/three_files_three_fields +0 -31
  128. data/test/multipart/unity3d_wwwform +0 -11
  129. data/test/multipart/webkit +0 -32
  130. data/test/rackup/config.ru +0 -31
  131. data/test/registering_handler/rack/handler/registering_myself.rb +0 -8
  132. data/test/spec_auth_basic.rb +0 -89
  133. data/test/spec_auth_digest.rb +0 -260
  134. data/test/spec_body_proxy.rb +0 -85
  135. data/test/spec_builder.rb +0 -233
  136. data/test/spec_cascade.rb +0 -63
  137. data/test/spec_cgi.rb +0 -84
  138. data/test/spec_chunked.rb +0 -103
  139. data/test/spec_common_logger.rb +0 -95
  140. data/test/spec_conditional_get.rb +0 -103
  141. data/test/spec_config.rb +0 -23
  142. data/test/spec_content_length.rb +0 -86
  143. data/test/spec_content_type.rb +0 -46
  144. data/test/spec_deflater.rb +0 -375
  145. data/test/spec_directory.rb +0 -148
  146. data/test/spec_etag.rb +0 -108
  147. data/test/spec_events.rb +0 -133
  148. data/test/spec_fastcgi.rb +0 -85
  149. data/test/spec_file.rb +0 -264
  150. data/test/spec_handler.rb +0 -57
  151. data/test/spec_head.rb +0 -46
  152. data/test/spec_lint.rb +0 -515
  153. data/test/spec_lobster.rb +0 -59
  154. data/test/spec_lock.rb +0 -204
  155. data/test/spec_logger.rb +0 -24
  156. data/test/spec_media_type.rb +0 -42
  157. data/test/spec_method_override.rb +0 -110
  158. data/test/spec_mime.rb +0 -51
  159. data/test/spec_mock.rb +0 -359
  160. data/test/spec_multipart.rb +0 -722
  161. data/test/spec_null_logger.rb +0 -21
  162. data/test/spec_recursive.rb +0 -75
  163. data/test/spec_request.rb +0 -1407
  164. data/test/spec_response.rb +0 -528
  165. data/test/spec_rewindable_input.rb +0 -128
  166. data/test/spec_runtime.rb +0 -50
  167. data/test/spec_sendfile.rb +0 -125
  168. data/test/spec_server.rb +0 -193
  169. data/test/spec_session_abstract_id.rb +0 -31
  170. data/test/spec_session_abstract_session_hash.rb +0 -45
  171. data/test/spec_session_cookie.rb +0 -442
  172. data/test/spec_session_memcache.rb +0 -357
  173. data/test/spec_session_persisted_secure_secure_session_hash.rb +0 -73
  174. data/test/spec_session_pool.rb +0 -247
  175. data/test/spec_show_exceptions.rb +0 -93
  176. data/test/spec_show_status.rb +0 -104
  177. data/test/spec_static.rb +0 -184
  178. data/test/spec_tempfile_reaper.rb +0 -64
  179. data/test/spec_thin.rb +0 -96
  180. data/test/spec_urlmap.rb +0 -237
  181. data/test/spec_utils.rb +0 -742
  182. data/test/spec_version.rb +0 -11
  183. data/test/spec_webrick.rb +0 -206
  184. data/test/static/another/index.html +0 -1
  185. data/test/static/foo.html +0 -1
  186. data/test/static/index.html +0 -1
  187. data/test/testrequest.rb +0 -78
  188. data/test/unregistered_handler/rack/handler/unregistered.rb +0 -7
  189. data/test/unregistered_handler/rack/handler/unregistered_long_one.rb +0 -7
@@ -1,528 +0,0 @@
1
- require 'minitest/autorun'
2
- require 'rack'
3
- require 'rack/response'
4
- require 'stringio'
5
-
6
- describe Rack::Response do
7
- it 'has cache-control methods' do
8
- response = Rack::Response.new
9
- cc = 'foo'
10
- response.cache_control = cc
11
- assert_equal cc, response.cache_control
12
- assert_equal cc, response.to_a[2]['Cache-Control']
13
- end
14
-
15
- it 'has an etag method' do
16
- response = Rack::Response.new
17
- etag = 'foo'
18
- response.etag = etag
19
- assert_equal etag, response.etag
20
- assert_equal etag, response.to_a[2]['ETag']
21
- end
22
-
23
- it "have sensible default values" do
24
- response = Rack::Response.new
25
- status, header, body = response.finish
26
- status.must_equal 200
27
- header.must_equal({})
28
- body.each { |part|
29
- part.must_equal ""
30
- }
31
-
32
- response = Rack::Response.new
33
- status, header, body = *response
34
- status.must_equal 200
35
- header.must_equal({})
36
- body.each { |part|
37
- part.must_equal ""
38
- }
39
- end
40
-
41
- it "can be written to" do
42
- response = Rack::Response.new
43
-
44
- _, _, body = response.finish do
45
- response.write "foo"
46
- response.write "bar"
47
- response.write "baz"
48
- end
49
-
50
- parts = []
51
- body.each { |part| parts << part }
52
-
53
- parts.must_equal ["foo", "bar", "baz"]
54
- end
55
-
56
- it "can set and read headers" do
57
- response = Rack::Response.new
58
- response["Content-Type"].must_be_nil
59
- response["Content-Type"] = "text/plain"
60
- response["Content-Type"].must_equal "text/plain"
61
- end
62
-
63
- it "can override the initial Content-Type with a different case" do
64
- response = Rack::Response.new("", 200, "content-type" => "text/plain")
65
- response["Content-Type"].must_equal "text/plain"
66
- end
67
-
68
- it "can set cookies" do
69
- response = Rack::Response.new
70
-
71
- response.set_cookie "foo", "bar"
72
- response["Set-Cookie"].must_equal "foo=bar"
73
- response.set_cookie "foo2", "bar2"
74
- response["Set-Cookie"].must_equal ["foo=bar", "foo2=bar2"].join("\n")
75
- response.set_cookie "foo3", "bar3"
76
- response["Set-Cookie"].must_equal ["foo=bar", "foo2=bar2", "foo3=bar3"].join("\n")
77
- end
78
-
79
- it "can set cookies with the same name for multiple domains" do
80
- response = Rack::Response.new
81
- response.set_cookie "foo", {:value => "bar", :domain => "sample.example.com"}
82
- response.set_cookie "foo", {:value => "bar", :domain => ".example.com"}
83
- response["Set-Cookie"].must_equal ["foo=bar; domain=sample.example.com", "foo=bar; domain=.example.com"].join("\n")
84
- end
85
-
86
- it "formats the Cookie expiration date accordingly to RFC 6265" do
87
- response = Rack::Response.new
88
-
89
- response.set_cookie "foo", {:value => "bar", :expires => Time.now+10}
90
- response["Set-Cookie"].must_match(
91
- /expires=..., \d\d ... \d\d\d\d \d\d:\d\d:\d\d .../)
92
- end
93
-
94
- it "can set secure cookies" do
95
- response = Rack::Response.new
96
- response.set_cookie "foo", {:value => "bar", :secure => true}
97
- response["Set-Cookie"].must_equal "foo=bar; secure"
98
- end
99
-
100
- it "can set http only cookies" do
101
- response = Rack::Response.new
102
- response.set_cookie "foo", {:value => "bar", :httponly => true}
103
- response["Set-Cookie"].must_equal "foo=bar; HttpOnly"
104
- end
105
-
106
- it "can set http only cookies with :http_only" do
107
- response = Rack::Response.new
108
- response.set_cookie "foo", {:value => "bar", :http_only => true}
109
- response["Set-Cookie"].must_equal "foo=bar; HttpOnly"
110
- end
111
-
112
- it "can set prefers :httponly for http only cookie setting when :httponly and :http_only provided" do
113
- response = Rack::Response.new
114
- response.set_cookie "foo", {:value => "bar", :httponly => false, :http_only => true}
115
- response["Set-Cookie"].must_equal "foo=bar"
116
- end
117
-
118
- it "can set SameSite cookies with symbol value :none" do
119
- response = Rack::Response.new
120
- response.set_cookie "foo", { value: "bar", same_site: :none }
121
- response["Set-Cookie"].must_equal "foo=bar; SameSite=None"
122
- end
123
-
124
- it "can set SameSite cookies with symbol value :None" do
125
- response = Rack::Response.new
126
- response.set_cookie "foo", { value: "bar", same_site: :None }
127
- response["Set-Cookie"].must_equal "foo=bar; SameSite=None"
128
- end
129
-
130
- it "can set SameSite cookies with string value 'None'" do
131
- response = Rack::Response.new
132
- response.set_cookie "foo", { value: "bar", same_site: "None" }
133
- response["Set-Cookie"].must_equal "foo=bar; SameSite=None"
134
- end
135
-
136
- it "can set SameSite cookies with symbol value :lax" do
137
- response = Rack::Response.new
138
- response.set_cookie "foo", {:value => "bar", :same_site => :lax}
139
- response["Set-Cookie"].must_equal "foo=bar; SameSite=Lax"
140
- end
141
-
142
- it "can set SameSite cookies with symbol value :Lax" do
143
- response = Rack::Response.new
144
- response.set_cookie "foo", {:value => "bar", :same_site => :lax}
145
- response["Set-Cookie"].must_equal "foo=bar; SameSite=Lax"
146
- end
147
-
148
- it "can set SameSite cookies with string value 'Lax'" do
149
- response = Rack::Response.new
150
- response.set_cookie "foo", {:value => "bar", :same_site => "Lax"}
151
- response["Set-Cookie"].must_equal "foo=bar; SameSite=Lax"
152
- end
153
-
154
- it "can set SameSite cookies with boolean value true" do
155
- response = Rack::Response.new
156
- response.set_cookie "foo", {:value => "bar", :same_site => true}
157
- response["Set-Cookie"].must_equal "foo=bar; SameSite=Strict"
158
- end
159
-
160
- it "can set SameSite cookies with symbol value :strict" do
161
- response = Rack::Response.new
162
- response.set_cookie "foo", {:value => "bar", :same_site => :strict}
163
- response["Set-Cookie"].must_equal "foo=bar; SameSite=Strict"
164
- end
165
-
166
- it "can set SameSite cookies with symbol value :Strict" do
167
- response = Rack::Response.new
168
- response.set_cookie "foo", {:value => "bar", :same_site => :Strict}
169
- response["Set-Cookie"].must_equal "foo=bar; SameSite=Strict"
170
- end
171
-
172
- it "can set SameSite cookies with string value 'Strict'" do
173
- response = Rack::Response.new
174
- response.set_cookie "foo", {:value => "bar", :same_site => "Strict"}
175
- response["Set-Cookie"].must_equal "foo=bar; SameSite=Strict"
176
- end
177
-
178
- it "validates the SameSite option value" do
179
- response = Rack::Response.new
180
- lambda {
181
- response.set_cookie "foo", {:value => "bar", :same_site => "Foo"}
182
- }.must_raise(ArgumentError).
183
- message.must_match(/Invalid SameSite value: "Foo"/)
184
- end
185
-
186
- it "can set SameSite cookies with symbol value" do
187
- response = Rack::Response.new
188
- response.set_cookie "foo", {:value => "bar", :same_site => :Strict}
189
- response["Set-Cookie"].must_equal "foo=bar; SameSite=Strict"
190
- end
191
-
192
- [ nil, false ].each do |non_truthy|
193
- it "omits SameSite attribute given a #{non_truthy.inspect} value" do
194
- response = Rack::Response.new
195
- response.set_cookie "foo", {:value => "bar", :same_site => non_truthy}
196
- response["Set-Cookie"].must_equal "foo=bar"
197
- end
198
- end
199
-
200
- it "can delete cookies" do
201
- response = Rack::Response.new
202
- response.set_cookie "foo", "bar"
203
- response.set_cookie "foo2", "bar2"
204
- response.delete_cookie "foo"
205
- response["Set-Cookie"].must_equal [
206
- "foo2=bar2",
207
- "foo=; max-age=0; expires=Thu, 01 Jan 1970 00:00:00 -0000"
208
- ].join("\n")
209
- end
210
-
211
- it "can delete cookies with the same name from multiple domains" do
212
- response = Rack::Response.new
213
- response.set_cookie "foo", {:value => "bar", :domain => "sample.example.com"}
214
- response.set_cookie "foo", {:value => "bar", :domain => ".example.com"}
215
- response["Set-Cookie"].must_equal ["foo=bar; domain=sample.example.com", "foo=bar; domain=.example.com"].join("\n")
216
- response.delete_cookie "foo", :domain => ".example.com"
217
- response["Set-Cookie"].must_equal ["foo=bar; domain=sample.example.com", "foo=; domain=.example.com; max-age=0; expires=Thu, 01 Jan 1970 00:00:00 -0000"].join("\n")
218
- response.delete_cookie "foo", :domain => "sample.example.com"
219
- response["Set-Cookie"].must_equal ["foo=; domain=.example.com; max-age=0; expires=Thu, 01 Jan 1970 00:00:00 -0000",
220
- "foo=; domain=sample.example.com; max-age=0; expires=Thu, 01 Jan 1970 00:00:00 -0000"].join("\n")
221
- end
222
-
223
- it "can delete cookies with the same name with different paths" do
224
- response = Rack::Response.new
225
- response.set_cookie "foo", {:value => "bar", :path => "/"}
226
- response.set_cookie "foo", {:value => "bar", :path => "/path"}
227
- response["Set-Cookie"].must_equal ["foo=bar; path=/",
228
- "foo=bar; path=/path"].join("\n")
229
-
230
- response.delete_cookie "foo", :path => "/path"
231
- response["Set-Cookie"].must_equal ["foo=bar; path=/",
232
- "foo=; path=/path; max-age=0; expires=Thu, 01 Jan 1970 00:00:00 -0000"].join("\n")
233
- end
234
-
235
- it "can do redirects" do
236
- response = Rack::Response.new
237
- response.redirect "/foo"
238
- status, header, body = response.finish
239
- status.must_equal 302
240
- header["Location"].must_equal "/foo"
241
-
242
- response = Rack::Response.new
243
- response.redirect "/foo", 307
244
- status, header, body = response.finish
245
-
246
- status.must_equal 307
247
- end
248
-
249
- it "has a useful constructor" do
250
- r = Rack::Response.new("foo")
251
- status, header, body = r.finish
252
- str = ""; body.each { |part| str << part }
253
- str.must_equal "foo"
254
-
255
- r = Rack::Response.new(["foo", "bar"])
256
- status, header, body = r.finish
257
- str = ""; body.each { |part| str << part }
258
- str.must_equal "foobar"
259
-
260
- object_with_each = Object.new
261
- def object_with_each.each
262
- yield "foo"
263
- yield "bar"
264
- end
265
- r = Rack::Response.new(object_with_each)
266
- r.write "foo"
267
- status, header, body = r.finish
268
- str = ""; body.each { |part| str << part }
269
- str.must_equal "foobarfoo"
270
-
271
- r = Rack::Response.new([], 500)
272
- r.status.must_equal 500
273
-
274
- r = Rack::Response.new([], "200 OK")
275
- r.status.must_equal 200
276
- end
277
-
278
- it "has a constructor that can take a block" do
279
- r = Rack::Response.new { |res|
280
- res.status = 404
281
- res.write "foo"
282
- }
283
- status, _, body = r.finish
284
- str = ""; body.each { |part| str << part }
285
- str.must_equal "foo"
286
- status.must_equal 404
287
- end
288
-
289
- it "doesn't return invalid responses" do
290
- r = Rack::Response.new(["foo", "bar"], 204)
291
- _, header, body = r.finish
292
- str = ""; body.each { |part| str << part }
293
- str.must_be :empty?
294
- header["Content-Type"].must_be_nil
295
- header['Content-Length'].must_be_nil
296
-
297
- lambda {
298
- Rack::Response.new(Object.new)
299
- }.must_raise(TypeError).
300
- message.must_match(/stringable or iterable required/)
301
- end
302
-
303
- it "knows if it's empty" do
304
- r = Rack::Response.new
305
- r.must_be :empty?
306
- r.write "foo"
307
- r.wont_be :empty?
308
-
309
- r = Rack::Response.new
310
- r.must_be :empty?
311
- r.finish
312
- r.must_be :empty?
313
-
314
- r = Rack::Response.new
315
- r.must_be :empty?
316
- r.finish { }
317
- r.wont_be :empty?
318
- end
319
-
320
- it "provide access to the HTTP status" do
321
- res = Rack::Response.new
322
- res.status = 200
323
- res.must_be :successful?
324
- res.must_be :ok?
325
-
326
- res.status = 201
327
- res.must_be :successful?
328
- res.must_be :created?
329
-
330
- res.status = 202
331
- res.must_be :successful?
332
- res.must_be :accepted?
333
-
334
- res.status = 204
335
- res.must_be :successful?
336
- res.must_be :no_content?
337
-
338
- res.status = 301
339
- res.must_be :redirect?
340
- res.must_be :moved_permanently?
341
-
342
- res.status = 302
343
- res.must_be :redirect?
344
-
345
- res.status = 303
346
- res.must_be :redirect?
347
-
348
- res.status = 307
349
- res.must_be :redirect?
350
-
351
- res.status = 308
352
- res.must_be :redirect?
353
-
354
- res.status = 400
355
- res.wont_be :successful?
356
- res.must_be :client_error?
357
- res.must_be :bad_request?
358
-
359
- res.status = 401
360
- res.wont_be :successful?
361
- res.must_be :client_error?
362
- res.must_be :unauthorized?
363
-
364
- res.status = 404
365
- res.wont_be :successful?
366
- res.must_be :client_error?
367
- res.must_be :not_found?
368
-
369
- res.status = 405
370
- res.wont_be :successful?
371
- res.must_be :client_error?
372
- res.must_be :method_not_allowed?
373
-
374
- res.status = 412
375
- res.wont_be :successful?
376
- res.must_be :client_error?
377
- res.must_be :precondition_failed?
378
-
379
- res.status = 422
380
- res.wont_be :successful?
381
- res.must_be :client_error?
382
- res.must_be :unprocessable?
383
-
384
- res.status = 501
385
- res.wont_be :successful?
386
- res.must_be :server_error?
387
- end
388
-
389
- it "provide access to the HTTP headers" do
390
- res = Rack::Response.new
391
- res["Content-Type"] = "text/yaml"
392
-
393
- res.must_include "Content-Type"
394
- res.headers["Content-Type"].must_equal "text/yaml"
395
- res["Content-Type"].must_equal "text/yaml"
396
- res.content_type.must_equal "text/yaml"
397
- res.content_length.must_be_nil
398
- res.location.must_be_nil
399
- end
400
-
401
- it "does not add or change Content-Length when #finish()ing" do
402
- res = Rack::Response.new
403
- res.status = 200
404
- res.finish
405
- res.headers["Content-Length"].must_be_nil
406
-
407
- res = Rack::Response.new
408
- res.status = 200
409
- res.headers["Content-Length"] = "10"
410
- res.finish
411
- res.headers["Content-Length"].must_equal "10"
412
- end
413
-
414
- it "updates Content-Length when body appended to using #write" do
415
- res = Rack::Response.new
416
- res.status = 200
417
- res.headers["Content-Length"].must_be_nil
418
- res.write "Hi"
419
- res.headers["Content-Length"].must_equal "2"
420
- res.write " there"
421
- res.headers["Content-Length"].must_equal "8"
422
- end
423
-
424
- it "calls close on #body" do
425
- res = Rack::Response.new
426
- res.body = StringIO.new
427
- res.close
428
- res.body.must_be :closed?
429
- end
430
-
431
- it "calls close on #body when 204 or 304" do
432
- res = Rack::Response.new
433
- res.body = StringIO.new
434
- res.finish
435
- res.body.wont_be :closed?
436
-
437
- res.status = 204
438
- _, _, b = res.finish
439
- res.body.must_be :closed?
440
- b.wont_equal res.body
441
-
442
- res.body = StringIO.new
443
- res.status = 205
444
- _, _, b = res.finish
445
- res.body.wont_be :closed?
446
- b.wont_equal res.body
447
-
448
- res.body = StringIO.new
449
- res.status = 304
450
- _, _, b = res.finish
451
- res.body.must_be :closed?
452
- b.wont_equal res.body
453
- end
454
-
455
- it "wraps the body from #to_ary to prevent infinite loops" do
456
- res = Rack::Response.new
457
- res.finish.last.wont_respond_to(:to_ary)
458
- lambda { res.finish.last.to_ary }.must_raise NoMethodError
459
- end
460
- end
461
-
462
- describe Rack::Response, 'headers' do
463
- before do
464
- @response = Rack::Response.new([], 200, { 'Foo' => '1' })
465
- end
466
-
467
- it 'has_header?' do
468
- lambda { @response.has_header? nil }.must_raise NoMethodError
469
-
470
- @response.has_header?('Foo').must_equal true
471
- @response.has_header?('foo').must_equal true
472
- end
473
-
474
- it 'get_header' do
475
- lambda { @response.get_header nil }.must_raise NoMethodError
476
-
477
- @response.get_header('Foo').must_equal '1'
478
- @response.get_header('foo').must_equal '1'
479
- end
480
-
481
- it 'set_header' do
482
- lambda { @response.set_header nil, '1' }.must_raise NoMethodError
483
-
484
- @response.set_header('Foo', '2').must_equal '2'
485
- @response.has_header?('Foo').must_equal true
486
- @response.get_header('Foo').must_equal('2')
487
-
488
- @response.set_header('Foo', nil).must_be_nil
489
- @response.has_header?('Foo').must_equal true
490
- @response.get_header('Foo').must_be_nil
491
- end
492
-
493
- it 'add_header' do
494
- lambda { @response.add_header nil, '1' }.must_raise NoMethodError
495
-
496
- # Add a value to an existing header
497
- @response.add_header('Foo', '2').must_equal '1,2'
498
- @response.get_header('Foo').must_equal '1,2'
499
-
500
- # Add nil to an existing header
501
- @response.add_header('Foo', nil).must_equal '1,2'
502
- @response.get_header('Foo').must_equal '1,2'
503
-
504
- # Add nil to a nonexistent header
505
- @response.add_header('Bar', nil).must_be_nil
506
- @response.has_header?('Bar').must_equal false
507
- @response.get_header('Bar').must_be_nil
508
-
509
- # Add a value to a nonexistent header
510
- @response.add_header('Bar', '1').must_equal '1'
511
- @response.has_header?('Bar').must_equal true
512
- @response.get_header('Bar').must_equal '1'
513
- end
514
-
515
- it 'delete_header' do
516
- lambda { @response.delete_header nil }.must_raise NoMethodError
517
-
518
- @response.delete_header('Foo').must_equal '1'
519
- (!!@response.has_header?('Foo')).must_equal false
520
-
521
- @response.delete_header('Foo').must_be_nil
522
- @response.has_header?('Foo').must_equal false
523
-
524
- @response.set_header('Foo', 1)
525
- @response.delete_header('foo').must_equal 1
526
- @response.has_header?('Foo').must_equal false
527
- end
528
- end