rack 1.4.7 → 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 (183) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +77 -0
  3. data/{COPYING → MIT-LICENSE} +4 -2
  4. data/README.rdoc +122 -456
  5. data/Rakefile +32 -31
  6. data/SPEC +119 -29
  7. data/bin/rackup +1 -0
  8. data/contrib/rack_logo.svg +164 -111
  9. data/example/lobster.ru +2 -0
  10. data/example/protectedlobster.rb +4 -2
  11. data/example/protectedlobster.ru +3 -1
  12. data/lib/rack/auth/abstract/handler.rb +7 -5
  13. data/lib/rack/auth/abstract/request.rb +8 -6
  14. data/lib/rack/auth/basic.rb +5 -2
  15. data/lib/rack/auth/digest/md5.rb +10 -8
  16. data/lib/rack/auth/digest/nonce.rb +6 -3
  17. data/lib/rack/auth/digest/params.rb +5 -4
  18. data/lib/rack/auth/digest/request.rb +4 -2
  19. data/lib/rack/body_proxy.rb +11 -9
  20. data/lib/rack/builder.rb +63 -20
  21. data/lib/rack/cascade.rb +10 -9
  22. data/lib/rack/chunked.rb +45 -11
  23. data/lib/rack/{commonlogger.rb → common_logger.rb} +24 -15
  24. data/lib/rack/{conditionalget.rb → conditional_get.rb} +20 -6
  25. data/lib/rack/config.rb +7 -0
  26. data/lib/rack/content_length.rb +12 -6
  27. data/lib/rack/content_type.rb +4 -2
  28. data/lib/rack/core_ext/regexp.rb +14 -0
  29. data/lib/rack/deflater.rb +73 -42
  30. data/lib/rack/directory.rb +77 -56
  31. data/lib/rack/etag.rb +25 -13
  32. data/lib/rack/events.rb +156 -0
  33. data/lib/rack/file.rb +4 -143
  34. data/lib/rack/files.rb +178 -0
  35. data/lib/rack/handler/cgi.rb +18 -17
  36. data/lib/rack/handler/fastcgi.rb +21 -17
  37. data/lib/rack/handler/lsws.rb +14 -12
  38. data/lib/rack/handler/scgi.rb +27 -21
  39. data/lib/rack/handler/thin.rb +19 -5
  40. data/lib/rack/handler/webrick.rb +66 -24
  41. data/lib/rack/handler.rb +29 -19
  42. data/lib/rack/head.rb +21 -14
  43. data/lib/rack/lint.rb +259 -65
  44. data/lib/rack/lobster.rb +17 -10
  45. data/lib/rack/lock.rb +19 -10
  46. data/lib/rack/logger.rb +4 -2
  47. data/lib/rack/media_type.rb +43 -0
  48. data/lib/rack/method_override.rb +52 -0
  49. data/lib/rack/mime.rb +43 -6
  50. data/lib/rack/mock.rb +109 -44
  51. data/lib/rack/multipart/generator.rb +11 -12
  52. data/lib/rack/multipart/parser.rb +302 -115
  53. data/lib/rack/multipart/uploaded_file.rb +4 -3
  54. data/lib/rack/multipart.rb +40 -9
  55. data/lib/rack/null_logger.rb +39 -0
  56. data/lib/rack/query_parser.rb +218 -0
  57. data/lib/rack/recursive.rb +14 -11
  58. data/lib/rack/reloader.rb +12 -5
  59. data/lib/rack/request.rb +484 -270
  60. data/lib/rack/response.rb +196 -77
  61. data/lib/rack/rewindable_input.rb +5 -14
  62. data/lib/rack/runtime.rb +13 -6
  63. data/lib/rack/sendfile.rb +44 -20
  64. data/lib/rack/server.rb +175 -61
  65. data/lib/rack/session/abstract/id.rb +276 -133
  66. data/lib/rack/session/cookie.rb +75 -40
  67. data/lib/rack/session/memcache.rb +4 -87
  68. data/lib/rack/session/pool.rb +24 -18
  69. data/lib/rack/show_exceptions.rb +392 -0
  70. data/lib/rack/{showstatus.rb → show_status.rb} +11 -9
  71. data/lib/rack/static.rb +65 -38
  72. data/lib/rack/tempfile_reaper.rb +24 -0
  73. data/lib/rack/urlmap.rb +40 -15
  74. data/lib/rack/utils.rb +316 -285
  75. data/lib/rack.rb +78 -23
  76. data/rack.gemspec +26 -19
  77. metadata +44 -209
  78. data/KNOWN-ISSUES +0 -30
  79. data/lib/rack/backports/uri/common_18.rb +0 -56
  80. data/lib/rack/backports/uri/common_192.rb +0 -52
  81. data/lib/rack/backports/uri/common_193.rb +0 -29
  82. data/lib/rack/handler/evented_mongrel.rb +0 -8
  83. data/lib/rack/handler/mongrel.rb +0 -100
  84. data/lib/rack/handler/swiftiplied_mongrel.rb +0 -8
  85. data/lib/rack/methodoverride.rb +0 -33
  86. data/lib/rack/nulllogger.rb +0 -18
  87. data/lib/rack/showexceptions.rb +0 -378
  88. data/test/builder/anything.rb +0 -5
  89. data/test/builder/comment.ru +0 -4
  90. data/test/builder/end.ru +0 -5
  91. data/test/builder/line.ru +0 -1
  92. data/test/builder/options.ru +0 -2
  93. data/test/cgi/assets/folder/test.js +0 -1
  94. data/test/cgi/assets/fonts/font.eot +0 -1
  95. data/test/cgi/assets/images/image.png +0 -1
  96. data/test/cgi/assets/index.html +0 -1
  97. data/test/cgi/assets/javascripts/app.js +0 -1
  98. data/test/cgi/assets/stylesheets/app.css +0 -1
  99. data/test/cgi/lighttpd.conf +0 -26
  100. data/test/cgi/lighttpd.errors +0 -1
  101. data/test/cgi/rackup_stub.rb +0 -6
  102. data/test/cgi/sample_rackup.ru +0 -5
  103. data/test/cgi/test +0 -9
  104. data/test/cgi/test+directory/test+file +0 -1
  105. data/test/cgi/test.fcgi +0 -8
  106. data/test/cgi/test.ru +0 -5
  107. data/test/gemloader.rb +0 -10
  108. data/test/multipart/bad_robots +0 -259
  109. data/test/multipart/binary +0 -0
  110. data/test/multipart/content_type_and_no_filename +0 -6
  111. data/test/multipart/empty +0 -10
  112. data/test/multipart/fail_16384_nofile +0 -814
  113. data/test/multipart/file1.txt +0 -1
  114. data/test/multipart/filename_and_modification_param +0 -7
  115. data/test/multipart/filename_with_escaped_quotes +0 -6
  116. data/test/multipart/filename_with_escaped_quotes_and_modification_param +0 -7
  117. data/test/multipart/filename_with_percent_escaped_quotes +0 -6
  118. data/test/multipart/filename_with_unescaped_percentages +0 -6
  119. data/test/multipart/filename_with_unescaped_percentages2 +0 -6
  120. data/test/multipart/filename_with_unescaped_percentages3 +0 -6
  121. data/test/multipart/filename_with_unescaped_quotes +0 -6
  122. data/test/multipart/ie +0 -6
  123. data/test/multipart/mixed_files +0 -21
  124. data/test/multipart/nested +0 -10
  125. data/test/multipart/none +0 -9
  126. data/test/multipart/semicolon +0 -6
  127. data/test/multipart/text +0 -15
  128. data/test/multipart/three_files_three_fields +0 -31
  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.rb +0 -57
  133. data/test/spec_auth_basic.rb +0 -81
  134. data/test/spec_auth_digest.rb +0 -259
  135. data/test/spec_body_proxy.rb +0 -69
  136. data/test/spec_builder.rb +0 -207
  137. data/test/spec_cascade.rb +0 -61
  138. data/test/spec_cgi.rb +0 -102
  139. data/test/spec_chunked.rb +0 -87
  140. data/test/spec_commonlogger.rb +0 -57
  141. data/test/spec_conditionalget.rb +0 -102
  142. data/test/spec_config.rb +0 -22
  143. data/test/spec_content_length.rb +0 -86
  144. data/test/spec_content_type.rb +0 -45
  145. data/test/spec_deflater.rb +0 -187
  146. data/test/spec_directory.rb +0 -88
  147. data/test/spec_etag.rb +0 -98
  148. data/test/spec_fastcgi.rb +0 -107
  149. data/test/spec_file.rb +0 -200
  150. data/test/spec_handler.rb +0 -59
  151. data/test/spec_head.rb +0 -48
  152. data/test/spec_lint.rb +0 -515
  153. data/test/spec_lobster.rb +0 -58
  154. data/test/spec_lock.rb +0 -167
  155. data/test/spec_logger.rb +0 -23
  156. data/test/spec_methodoverride.rb +0 -72
  157. data/test/spec_mock.rb +0 -269
  158. data/test/spec_mongrel.rb +0 -182
  159. data/test/spec_multipart.rb +0 -479
  160. data/test/spec_nulllogger.rb +0 -23
  161. data/test/spec_recursive.rb +0 -72
  162. data/test/spec_request.rb +0 -955
  163. data/test/spec_response.rb +0 -313
  164. data/test/spec_rewindable_input.rb +0 -118
  165. data/test/spec_runtime.rb +0 -49
  166. data/test/spec_sendfile.rb +0 -90
  167. data/test/spec_server.rb +0 -121
  168. data/test/spec_session_abstract_id.rb +0 -43
  169. data/test/spec_session_cookie.rb +0 -361
  170. data/test/spec_session_memcache.rb +0 -321
  171. data/test/spec_session_pool.rb +0 -209
  172. data/test/spec_showexceptions.rb +0 -92
  173. data/test/spec_showstatus.rb +0 -84
  174. data/test/spec_static.rb +0 -145
  175. data/test/spec_thin.rb +0 -86
  176. data/test/spec_urlmap.rb +0 -213
  177. data/test/spec_utils.rb +0 -554
  178. data/test/spec_webrick.rb +0 -143
  179. data/test/static/another/index.html +0 -1
  180. data/test/static/index.html +0 -1
  181. data/test/testrequest.rb +0 -78
  182. data/test/unregistered_handler/rack/handler/unregistered.rb +0 -7
  183. data/test/unregistered_handler/rack/handler/unregistered_long_one.rb +0 -7
@@ -1,313 +0,0 @@
1
- require 'rack/response'
2
- require 'stringio'
3
-
4
- describe Rack::Response do
5
- should "have sensible default values" do
6
- response = Rack::Response.new
7
- status, header, body = response.finish
8
- status.should.equal 200
9
- header.should.equal "Content-Type" => "text/html"
10
- body.each { |part|
11
- part.should.equal ""
12
- }
13
-
14
- response = Rack::Response.new
15
- status, header, body = *response
16
- status.should.equal 200
17
- header.should.equal "Content-Type" => "text/html"
18
- body.each { |part|
19
- part.should.equal ""
20
- }
21
- end
22
-
23
- it "can be written to" do
24
- response = Rack::Response.new
25
-
26
- _, _, body = response.finish do
27
- response.write "foo"
28
- response.write "bar"
29
- response.write "baz"
30
- end
31
-
32
- parts = []
33
- body.each { |part| parts << part }
34
-
35
- parts.should.equal ["foo", "bar", "baz"]
36
- end
37
-
38
- it "can set and read headers" do
39
- response = Rack::Response.new
40
- response["Content-Type"].should.equal "text/html"
41
- response["Content-Type"] = "text/plain"
42
- response["Content-Type"].should.equal "text/plain"
43
- end
44
-
45
- it "can override the initial Content-Type with a different case" do
46
- response = Rack::Response.new("", 200, "content-type" => "text/plain")
47
- response["Content-Type"].should.equal "text/plain"
48
- end
49
-
50
- it "can set cookies" do
51
- response = Rack::Response.new
52
-
53
- response.set_cookie "foo", "bar"
54
- response["Set-Cookie"].should.equal "foo=bar"
55
- response.set_cookie "foo2", "bar2"
56
- response["Set-Cookie"].should.equal ["foo=bar", "foo2=bar2"].join("\n")
57
- response.set_cookie "foo3", "bar3"
58
- response["Set-Cookie"].should.equal ["foo=bar", "foo2=bar2", "foo3=bar3"].join("\n")
59
- end
60
-
61
- it "can set cookies with the same name for multiple domains" do
62
- response = Rack::Response.new
63
- response.set_cookie "foo", {:value => "bar", :domain => "sample.example.com"}
64
- response.set_cookie "foo", {:value => "bar", :domain => ".example.com"}
65
- response["Set-Cookie"].should.equal ["foo=bar; domain=sample.example.com", "foo=bar; domain=.example.com"].join("\n")
66
- end
67
-
68
- it "formats the Cookie expiration date accordingly to RFC 2109" do
69
- response = Rack::Response.new
70
-
71
- response.set_cookie "foo", {:value => "bar", :expires => Time.now+10}
72
- response["Set-Cookie"].should.match(
73
- /expires=..., \d\d-...-\d\d\d\d \d\d:\d\d:\d\d .../)
74
- end
75
-
76
- it "can set secure cookies" do
77
- response = Rack::Response.new
78
- response.set_cookie "foo", {:value => "bar", :secure => true}
79
- response["Set-Cookie"].should.equal "foo=bar; secure"
80
- end
81
-
82
- it "can set http only cookies" do
83
- response = Rack::Response.new
84
- response.set_cookie "foo", {:value => "bar", :httponly => true}
85
- response["Set-Cookie"].should.equal "foo=bar; HttpOnly"
86
- end
87
-
88
- it "can delete cookies" do
89
- response = Rack::Response.new
90
- response.set_cookie "foo", "bar"
91
- response.set_cookie "foo2", "bar2"
92
- response.delete_cookie "foo"
93
- response["Set-Cookie"].should.equal [
94
- "foo2=bar2",
95
- "foo=; expires=Thu, 01-Jan-1970 00:00:00 GMT"
96
- ].join("\n")
97
- end
98
-
99
- it "can delete cookies with the same name from multiple domains" do
100
- response = Rack::Response.new
101
- response.set_cookie "foo", {:value => "bar", :domain => "sample.example.com"}
102
- response.set_cookie "foo", {:value => "bar", :domain => ".example.com"}
103
- response["Set-Cookie"].should.equal ["foo=bar; domain=sample.example.com", "foo=bar; domain=.example.com"].join("\n")
104
- response.delete_cookie "foo", :domain => ".example.com"
105
- 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")
106
- response.delete_cookie "foo", :domain => "sample.example.com"
107
- response["Set-Cookie"].should.equal ["foo=; domain=.example.com; expires=Thu, 01-Jan-1970 00:00:00 GMT",
108
- "foo=; domain=sample.example.com; expires=Thu, 01-Jan-1970 00:00:00 GMT"].join("\n")
109
- end
110
-
111
- it "can delete cookies with the same name with different paths" do
112
- response = Rack::Response.new
113
- response.set_cookie "foo", {:value => "bar", :path => "/"}
114
- response.set_cookie "foo", {:value => "bar", :path => "/path"}
115
- response["Set-Cookie"].should.equal ["foo=bar; path=/",
116
- "foo=bar; path=/path"].join("\n")
117
-
118
- response.delete_cookie "foo", :path => "/path"
119
- response["Set-Cookie"].should.equal ["foo=bar; path=/",
120
- "foo=; path=/path; expires=Thu, 01-Jan-1970 00:00:00 GMT"].join("\n")
121
- end
122
-
123
- it "can do redirects" do
124
- response = Rack::Response.new
125
- response.redirect "/foo"
126
- status, header, body = response.finish
127
- status.should.equal 302
128
- header["Location"].should.equal "/foo"
129
-
130
- response = Rack::Response.new
131
- response.redirect "/foo", 307
132
- status, header, body = response.finish
133
-
134
- status.should.equal 307
135
- end
136
-
137
- it "has a useful constructor" do
138
- r = Rack::Response.new("foo")
139
- status, header, body = r.finish
140
- str = ""; body.each { |part| str << part }
141
- str.should.equal "foo"
142
-
143
- r = Rack::Response.new(["foo", "bar"])
144
- status, header, body = r.finish
145
- str = ""; body.each { |part| str << part }
146
- str.should.equal "foobar"
147
-
148
- object_with_each = Object.new
149
- def object_with_each.each
150
- yield "foo"
151
- yield "bar"
152
- end
153
- r = Rack::Response.new(object_with_each)
154
- r.write "foo"
155
- status, header, body = r.finish
156
- str = ""; body.each { |part| str << part }
157
- str.should.equal "foobarfoo"
158
-
159
- r = Rack::Response.new([], 500)
160
- r.status.should.equal 500
161
-
162
- r = Rack::Response.new([], "200 OK")
163
- r.status.should.equal 200
164
- end
165
-
166
- it "has a constructor that can take a block" do
167
- r = Rack::Response.new { |res|
168
- res.status = 404
169
- res.write "foo"
170
- }
171
- status, _, body = r.finish
172
- str = ""; body.each { |part| str << part }
173
- str.should.equal "foo"
174
- status.should.equal 404
175
- end
176
-
177
- it "doesn't return invalid responses" do
178
- r = Rack::Response.new(["foo", "bar"], 204)
179
- _, header, body = r.finish
180
- str = ""; body.each { |part| str << part }
181
- str.should.be.empty
182
- header["Content-Type"].should.equal nil
183
- header['Content-Length'].should.equal nil
184
-
185
- lambda {
186
- Rack::Response.new(Object.new)
187
- }.should.raise(TypeError).
188
- message.should =~ /stringable or iterable required/
189
- end
190
-
191
- it "knows if it's empty" do
192
- r = Rack::Response.new
193
- r.should.be.empty
194
- r.write "foo"
195
- r.should.not.be.empty
196
-
197
- r = Rack::Response.new
198
- r.should.be.empty
199
- r.finish
200
- r.should.be.empty
201
-
202
- r = Rack::Response.new
203
- r.should.be.empty
204
- r.finish { }
205
- r.should.not.be.empty
206
- end
207
-
208
- should "provide access to the HTTP status" do
209
- res = Rack::Response.new
210
- res.status = 200
211
- res.should.be.successful
212
- res.should.be.ok
213
-
214
- res.status = 400
215
- res.should.not.be.successful
216
- res.should.be.client_error
217
- res.should.be.bad_request
218
-
219
- res.status = 404
220
- res.should.not.be.successful
221
- res.should.be.client_error
222
- res.should.be.not_found
223
-
224
- res.status = 405
225
- res.should.not.be.successful
226
- res.should.be.client_error
227
- res.should.be.method_not_allowed
228
-
229
- res.status = 422
230
- res.should.not.be.successful
231
- res.should.be.client_error
232
- res.should.be.unprocessable
233
-
234
- res.status = 501
235
- res.should.not.be.successful
236
- res.should.be.server_error
237
-
238
- res.status = 307
239
- res.should.be.redirect
240
- end
241
-
242
- should "provide access to the HTTP headers" do
243
- res = Rack::Response.new
244
- res["Content-Type"] = "text/yaml"
245
-
246
- res.should.include "Content-Type"
247
- res.headers["Content-Type"].should.equal "text/yaml"
248
- res["Content-Type"].should.equal "text/yaml"
249
- res.content_type.should.equal "text/yaml"
250
- res.content_length.should.be.nil
251
- res.location.should.be.nil
252
- end
253
-
254
- it "does not add or change Content-Length when #finish()ing" do
255
- res = Rack::Response.new
256
- res.status = 200
257
- res.finish
258
- res.headers["Content-Length"].should.be.nil
259
-
260
- res = Rack::Response.new
261
- res.status = 200
262
- res.headers["Content-Length"] = "10"
263
- res.finish
264
- res.headers["Content-Length"].should.equal "10"
265
- end
266
-
267
- it "updates Content-Length when body appended to using #write" do
268
- res = Rack::Response.new
269
- res.status = 200
270
- res.headers["Content-Length"].should.be.nil
271
- res.write "Hi"
272
- res.headers["Content-Length"].should.equal "2"
273
- res.write " there"
274
- res.headers["Content-Length"].should.equal "8"
275
- end
276
-
277
- it "calls close on #body" do
278
- res = Rack::Response.new
279
- res.body = StringIO.new
280
- res.close
281
- res.body.should.be.closed
282
- end
283
-
284
- it "calls close on #body when 204, 205, or 304" do
285
- res = Rack::Response.new
286
- res.body = StringIO.new
287
- res.finish
288
- res.body.should.not.be.closed
289
-
290
- res.status = 204
291
- _, _, b = res.finish
292
- res.body.should.be.closed
293
- b.should.not == res.body
294
-
295
- res.body = StringIO.new
296
- res.status = 205
297
- _, _, b = res.finish
298
- res.body.should.be.closed
299
- b.should.not == res.body
300
-
301
- res.body = StringIO.new
302
- res.status = 304
303
- _, _, b = res.finish
304
- res.body.should.be.closed
305
- b.should.not == res.body
306
- end
307
-
308
- it "wraps the body from #to_ary to prevent infinite loops" do
309
- res = Rack::Response.new
310
- res.finish.last.should.not.respond_to?(:to_ary)
311
- lambda { res.finish.last.to_ary }.should.raise(NoMethodError)
312
- end
313
- end
@@ -1,118 +0,0 @@
1
- require 'stringio'
2
- require 'rack/rewindable_input'
3
-
4
- shared "a rewindable IO object" do
5
- before do
6
- @rio = Rack::RewindableInput.new(@io)
7
- end
8
-
9
- should "be able to handle to read()" do
10
- @rio.read.should.equal "hello world"
11
- end
12
-
13
- should "be able to handle to read(nil)" do
14
- @rio.read(nil).should.equal "hello world"
15
- end
16
-
17
- should "be able to handle to read(length)" do
18
- @rio.read(1).should.equal "h"
19
- end
20
-
21
- should "be able to handle to read(length, buffer)" do
22
- buffer = ""
23
- result = @rio.read(1, buffer)
24
- result.should.equal "h"
25
- result.object_id.should.equal buffer.object_id
26
- end
27
-
28
- should "be able to handle to read(nil, buffer)" do
29
- buffer = ""
30
- result = @rio.read(nil, buffer)
31
- result.should.equal "hello world"
32
- result.object_id.should.equal buffer.object_id
33
- end
34
-
35
- should "rewind to the beginning when #rewind is called" do
36
- @rio.read(1)
37
- @rio.rewind
38
- @rio.read.should.equal "hello world"
39
- end
40
-
41
- should "be able to handle gets" do
42
- @rio.gets.should == "hello world"
43
- end
44
-
45
- should "be able to handle each" do
46
- array = []
47
- @rio.each do |data|
48
- array << data
49
- end
50
- array.should.equal(["hello world"])
51
- end
52
-
53
- should "not buffer into a Tempfile if no data has been read yet" do
54
- @rio.instance_variable_get(:@rewindable_io).should.be.nil
55
- end
56
-
57
- should "buffer into a Tempfile when data has been consumed for the first time" do
58
- @rio.read(1)
59
- tempfile = @rio.instance_variable_get(:@rewindable_io)
60
- tempfile.should.not.be.nil
61
- @rio.read(1)
62
- tempfile2 = @rio.instance_variable_get(:@rewindable_io)
63
- tempfile2.path.should == tempfile.path
64
- end
65
-
66
- should "close the underlying tempfile upon calling #close" do
67
- @rio.read(1)
68
- tempfile = @rio.instance_variable_get(:@rewindable_io)
69
- @rio.close
70
- tempfile.should.be.closed
71
- end
72
-
73
- should "be possible to call #close when no data has been buffered yet" do
74
- lambda{ @rio.close }.should.not.raise
75
- end
76
-
77
- should "be possible to call #close multiple times" do
78
- lambda{
79
- @rio.close
80
- @rio.close
81
- }.should.not.raise
82
- end
83
-
84
- @rio.close
85
- @rio = nil
86
- end
87
-
88
- describe Rack::RewindableInput do
89
- describe "given an IO object that is already rewindable" do
90
- before do
91
- @io = StringIO.new("hello world")
92
- end
93
-
94
- behaves_like "a rewindable IO object"
95
- end
96
-
97
- describe "given an IO object that is not rewindable" do
98
- before do
99
- @io = StringIO.new("hello world")
100
- @io.instance_eval do
101
- undef :rewind
102
- end
103
- end
104
-
105
- behaves_like "a rewindable IO object"
106
- end
107
-
108
- describe "given an IO object whose rewind method raises Errno::ESPIPE" do
109
- before do
110
- @io = StringIO.new("hello world")
111
- def @io.rewind
112
- raise Errno::ESPIPE, "You can't rewind this!"
113
- end
114
- end
115
-
116
- behaves_like "a rewindable IO object"
117
- end
118
- end
data/test/spec_runtime.rb DELETED
@@ -1,49 +0,0 @@
1
- require 'rack/lint'
2
- require 'rack/mock'
3
- require 'rack/runtime'
4
-
5
- describe Rack::Runtime do
6
- def runtime_app(app, *args)
7
- Rack::Lint.new Rack::Runtime.new(app, *args)
8
- end
9
-
10
- def request
11
- Rack::MockRequest.env_for
12
- end
13
-
14
- it "sets X-Runtime is none is set" do
15
- app = lambda { |env| [200, {'Content-Type' => 'text/plain'}, "Hello, World!"] }
16
- response = runtime_app(app).call(request)
17
- response[1]['X-Runtime'].should =~ /[\d\.]+/
18
- end
19
-
20
- it "doesn't set the X-Runtime if it is already set" do
21
- app = lambda { |env| [200, {'Content-Type' => 'text/plain', "X-Runtime" => "foobar"}, "Hello, World!"] }
22
- response = runtime_app(app).call(request)
23
- response[1]['X-Runtime'].should == "foobar"
24
- end
25
-
26
- should "allow a suffix to be set" do
27
- app = lambda { |env| [200, {'Content-Type' => 'text/plain'}, "Hello, World!"] }
28
- response = runtime_app(app, "Test").call(request)
29
- response[1]['X-Runtime-Test'].should =~ /[\d\.]+/
30
- end
31
-
32
- should "allow multiple timers to be set" do
33
- app = lambda { |env| sleep 0.1; [200, {'Content-Type' => 'text/plain'}, "Hello, World!"] }
34
- runtime = runtime_app(app, "App")
35
-
36
- # wrap many times to guarantee a measurable difference
37
- 100.times do |i|
38
- runtime = Rack::Runtime.new(runtime, i.to_s)
39
- end
40
- runtime = Rack::Runtime.new(runtime, "All")
41
-
42
- response = runtime.call(request)
43
-
44
- response[1]['X-Runtime-App'].should =~ /[\d\.]+/
45
- response[1]['X-Runtime-All'].should =~ /[\d\.]+/
46
-
47
- Float(response[1]['X-Runtime-All']).should > Float(response[1]['X-Runtime-App'])
48
- end
49
- end
@@ -1,90 +0,0 @@
1
- require 'fileutils'
2
- require 'rack/lint'
3
- require 'rack/sendfile'
4
- require 'rack/mock'
5
- require 'tmpdir'
6
-
7
- describe Rack::File do
8
- should "respond to #to_path" do
9
- Rack::File.new(Dir.pwd).should.respond_to :to_path
10
- end
11
- end
12
-
13
- describe Rack::Sendfile do
14
- def sendfile_body
15
- FileUtils.touch File.join(Dir.tmpdir, "rack_sendfile")
16
- res = ['Hello World']
17
- def res.to_path ; File.join(Dir.tmpdir, "rack_sendfile") ; end
18
- res
19
- end
20
-
21
- def simple_app(body=sendfile_body)
22
- lambda { |env| [200, {'Content-Type' => 'text/plain'}, body] }
23
- end
24
-
25
- def sendfile_app(body=sendfile_body)
26
- Rack::Lint.new Rack::Sendfile.new(simple_app(body))
27
- end
28
-
29
- @request = Rack::MockRequest.new(sendfile_app)
30
-
31
- def request(headers={})
32
- yield @request.get('/', headers)
33
- end
34
-
35
- it "does nothing when no X-Sendfile-Type header present" do
36
- request do |response|
37
- response.should.be.ok
38
- response.body.should.equal 'Hello World'
39
- response.headers.should.not.include 'X-Sendfile'
40
- end
41
- end
42
-
43
- it "sets X-Sendfile response header and discards body" do
44
- request 'HTTP_X_SENDFILE_TYPE' => 'X-Sendfile' do |response|
45
- response.should.be.ok
46
- response.body.should.be.empty
47
- response.headers['Content-Length'].should.equal '0'
48
- response.headers['X-Sendfile'].should.equal File.join(Dir.tmpdir, "rack_sendfile")
49
- end
50
- end
51
-
52
- it "sets X-Lighttpd-Send-File response header and discards body" do
53
- request 'HTTP_X_SENDFILE_TYPE' => 'X-Lighttpd-Send-File' do |response|
54
- response.should.be.ok
55
- response.body.should.be.empty
56
- response.headers['Content-Length'].should.equal '0'
57
- response.headers['X-Lighttpd-Send-File'].should.equal File.join(Dir.tmpdir, "rack_sendfile")
58
- end
59
- end
60
-
61
- it "sets X-Accel-Redirect response header and discards body" do
62
- headers = {
63
- 'HTTP_X_SENDFILE_TYPE' => 'X-Accel-Redirect',
64
- 'HTTP_X_ACCEL_MAPPING' => "#{Dir.tmpdir}/=/foo/bar/"
65
- }
66
- request headers do |response|
67
- response.should.be.ok
68
- response.body.should.be.empty
69
- response.headers['Content-Length'].should.equal '0'
70
- response.headers['X-Accel-Redirect'].should.equal '/foo/bar/rack_sendfile'
71
- end
72
- end
73
-
74
- it 'writes to rack.error when no X-Accel-Mapping is specified' do
75
- request 'HTTP_X_SENDFILE_TYPE' => 'X-Accel-Redirect' do |response|
76
- response.should.be.ok
77
- response.body.should.equal 'Hello World'
78
- response.headers.should.not.include 'X-Accel-Redirect'
79
- response.errors.should.include 'X-Accel-Mapping'
80
- end
81
- end
82
-
83
- it 'does nothing when body does not respond to #to_path' do
84
- @request = Rack::MockRequest.new(sendfile_app(['Not a file...']))
85
- request 'HTTP_X_SENDFILE_TYPE' => 'X-Sendfile' do |response|
86
- response.body.should.equal 'Not a file...'
87
- response.headers.should.not.include 'X-Sendfile'
88
- end
89
- end
90
- end
data/test/spec_server.rb DELETED
@@ -1,121 +0,0 @@
1
- require 'rack'
2
- require 'rack/server'
3
- require 'tempfile'
4
- require 'socket'
5
- require 'open-uri'
6
-
7
- describe Rack::Server do
8
-
9
- def app
10
- lambda { |env| [200, {'Content-Type' => 'text/plain'}, ['success']] }
11
- end
12
-
13
- def with_stderr
14
- old, $stderr = $stderr, StringIO.new
15
- yield $stderr
16
- ensure
17
- $stderr = old
18
- end
19
-
20
- it "overrides :config if :app is passed in" do
21
- server = Rack::Server.new(:app => "FOO")
22
- server.app.should == "FOO"
23
- end
24
-
25
- should "not include Rack::Lint in deployment or none environments" do
26
- server = Rack::Server.new(:app => 'foo')
27
- server.middleware['deployment'].flatten.should.not.include(Rack::Lint)
28
- server.middleware['none'].flatten.should.not.include(Rack::Lint)
29
- end
30
-
31
- should "not include Rack::ShowExceptions in deployment or none environments" do
32
- server = Rack::Server.new(:app => 'foo')
33
- server.middleware['deployment'].flatten.should.not.include(Rack::ShowExceptions)
34
- server.middleware['none'].flatten.should.not.include(Rack::ShowExceptions)
35
- end
36
-
37
- should "support CGI" do
38
- begin
39
- o, ENV["REQUEST_METHOD"] = ENV["REQUEST_METHOD"], 'foo'
40
- server = Rack::Server.new(:app => 'foo')
41
- server.server.name =~ /CGI/
42
- Rack::Server.logging_middleware.call(server).should.eql(nil)
43
- ensure
44
- ENV['REQUEST_METHOD'] = o
45
- end
46
- end
47
-
48
- should "not force any middleware under the none configuration" do
49
- server = Rack::Server.new(:app => 'foo')
50
- server.middleware['none'].should.be.empty
51
- end
52
-
53
- should "use a full path to the pidfile" do
54
- # avoids issues with daemonize chdir
55
- opts = Rack::Server.new.send(:parse_options, %w[--pid testing.pid])
56
- opts[:pid].should.eql(::File.expand_path('testing.pid'))
57
- end
58
-
59
- should "run a server" do
60
- pidfile = Tempfile.open('pidfile') { |f| break f }.path
61
- FileUtils.rm pidfile
62
- server = Rack::Server.new(
63
- :app => app,
64
- :environment => 'none',
65
- :pid => pidfile,
66
- :Port => TCPServer.open('127.0.0.1', 0){|s| s.addr[1] },
67
- :Host => '127.0.0.1',
68
- :daemonize => false,
69
- :server => 'webrick'
70
- )
71
- t = Thread.new { server.start { |s| Thread.current[:server] = s } }
72
- t.join(0.01) until t[:server] && t[:server].status != :Stop
73
- body = open("http://127.0.0.1:#{server.options[:Port]}/") { |f| f.read }
74
- body.should.eql('success')
75
-
76
- Process.kill(:INT, $$)
77
- t.join
78
- open(pidfile) { |f| f.read.should.eql $$.to_s }
79
- end
80
-
81
- should "check pid file presence and running process" do
82
- pidfile = Tempfile.open('pidfile') { |f| f.write($$); break f }.path
83
- server = Rack::Server.new(:pid => pidfile)
84
- server.send(:pidfile_process_status).should.eql :running
85
- end
86
-
87
- should "check pid file presence and dead process" do
88
- dead_pid = `echo $$`.to_i
89
- pidfile = Tempfile.open('pidfile') { |f| f.write(dead_pid); break f }.path
90
- server = Rack::Server.new(:pid => pidfile)
91
- server.send(:pidfile_process_status).should.eql :dead
92
- end
93
-
94
- should "check pid file presence and exited process" do
95
- pidfile = Tempfile.open('pidfile') { |f| break f }.path
96
- ::File.delete(pidfile)
97
- server = Rack::Server.new(:pid => pidfile)
98
- server.send(:pidfile_process_status).should.eql :exited
99
- end
100
-
101
- should "check pid file presence and not owned process" do
102
- pidfile = Tempfile.open('pidfile') { |f| f.write(1); break f }.path
103
- server = Rack::Server.new(:pid => pidfile)
104
- server.send(:pidfile_process_status).should.eql :not_owned
105
- end
106
-
107
- should "inform the user about existing pidfiles with running processes" do
108
- pidfile = Tempfile.open('pidfile') { |f| f.write(1); break f }.path
109
- server = Rack::Server.new(:pid => pidfile)
110
- with_stderr do |err|
111
- should.raise(SystemExit) do
112
- server.start
113
- end
114
- err.rewind
115
- output = err.read
116
- output.should.match(/already running/)
117
- output.should.include? pidfile
118
- end
119
- end
120
-
121
- end