rack 1.6.13 → 2.0.9.3

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 (142) hide show
  1. checksums.yaml +4 -4
  2. data/COPYING +1 -1
  3. data/HISTORY.md +153 -8
  4. data/README.rdoc +35 -31
  5. data/Rakefile +6 -14
  6. data/SPEC +10 -11
  7. data/contrib/rack_logo.svg +164 -111
  8. data/example/protectedlobster.rb +1 -1
  9. data/example/protectedlobster.ru +1 -1
  10. data/lib/rack/auth/abstract/request.rb +5 -1
  11. data/lib/rack/auth/digest/params.rb +2 -3
  12. data/lib/rack/auth/digest/request.rb +1 -1
  13. data/lib/rack/body_proxy.rb +14 -9
  14. data/lib/rack/builder.rb +3 -3
  15. data/lib/rack/chunked.rb +5 -5
  16. data/lib/rack/{commonlogger.rb → common_logger.rb} +6 -3
  17. data/lib/rack/content_length.rb +2 -2
  18. data/lib/rack/deflater.rb +4 -39
  19. data/lib/rack/directory.rb +66 -54
  20. data/lib/rack/etag.rb +5 -4
  21. data/lib/rack/events.rb +154 -0
  22. data/lib/rack/file.rb +64 -40
  23. data/lib/rack/handler/cgi.rb +15 -16
  24. data/lib/rack/handler/fastcgi.rb +13 -14
  25. data/lib/rack/handler/lsws.rb +11 -11
  26. data/lib/rack/handler/scgi.rb +15 -15
  27. data/lib/rack/handler/thin.rb +3 -0
  28. data/lib/rack/handler/webrick.rb +24 -26
  29. data/lib/rack/handler.rb +3 -25
  30. data/lib/rack/head.rb +15 -17
  31. data/lib/rack/lint.rb +41 -41
  32. data/lib/rack/lobster.rb +1 -1
  33. data/lib/rack/lock.rb +15 -10
  34. data/lib/rack/logger.rb +2 -2
  35. data/lib/rack/media_type.rb +38 -0
  36. data/lib/rack/{methodoverride.rb → method_override.rb} +6 -6
  37. data/lib/rack/mime.rb +18 -5
  38. data/lib/rack/mock.rb +36 -54
  39. data/lib/rack/multipart/generator.rb +5 -5
  40. data/lib/rack/multipart/parser.rb +283 -157
  41. data/lib/rack/multipart/uploaded_file.rb +1 -2
  42. data/lib/rack/multipart.rb +36 -8
  43. data/lib/rack/{nulllogger.rb → null_logger.rb} +1 -1
  44. data/lib/rack/query_parser.rb +192 -0
  45. data/lib/rack/recursive.rb +8 -8
  46. data/lib/rack/request.rb +394 -305
  47. data/lib/rack/response.rb +130 -57
  48. data/lib/rack/rewindable_input.rb +1 -12
  49. data/lib/rack/runtime.rb +10 -18
  50. data/lib/rack/sendfile.rb +5 -7
  51. data/lib/rack/server.rb +30 -23
  52. data/lib/rack/session/abstract/id.rb +110 -75
  53. data/lib/rack/session/cookie.rb +24 -17
  54. data/lib/rack/session/memcache.rb +9 -9
  55. data/lib/rack/session/pool.rb +8 -8
  56. data/lib/rack/show_exceptions.rb +386 -0
  57. data/lib/rack/{showstatus.rb → show_status.rb} +3 -3
  58. data/lib/rack/static.rb +30 -5
  59. data/lib/rack/tempfile_reaper.rb +2 -2
  60. data/lib/rack/urlmap.rb +15 -14
  61. data/lib/rack/utils.rb +156 -217
  62. data/lib/rack.rb +70 -21
  63. data/rack.gemspec +10 -9
  64. data/test/builder/an_underscore_app.rb +5 -0
  65. data/test/builder/options.ru +1 -1
  66. data/test/cgi/test.fcgi +1 -0
  67. data/test/cgi/test.gz +0 -0
  68. data/test/helper.rb +34 -0
  69. data/test/multipart/filename_with_encoded_words +7 -0
  70. data/test/multipart/filename_with_escaped_quotes_and_modification_param +1 -1
  71. data/test/multipart/filename_with_single_quote +7 -0
  72. data/test/multipart/quoted +15 -0
  73. data/test/multipart/rack-logo.png +0 -0
  74. data/test/multipart/unity3d_wwwform +11 -0
  75. data/test/registering_handler/rack/handler/registering_myself.rb +1 -1
  76. data/test/spec_auth_basic.rb +27 -19
  77. data/test/spec_auth_digest.rb +47 -46
  78. data/test/spec_body_proxy.rb +27 -27
  79. data/test/spec_builder.rb +51 -41
  80. data/test/spec_cascade.rb +24 -22
  81. data/test/spec_cgi.rb +49 -67
  82. data/test/spec_chunked.rb +37 -35
  83. data/test/{spec_commonlogger.rb → spec_common_logger.rb} +35 -21
  84. data/test/{spec_conditionalget.rb → spec_conditional_get.rb} +29 -28
  85. data/test/spec_config.rb +3 -2
  86. data/test/spec_content_length.rb +18 -17
  87. data/test/spec_content_type.rb +13 -12
  88. data/test/spec_deflater.rb +85 -49
  89. data/test/spec_directory.rb +87 -27
  90. data/test/spec_etag.rb +32 -31
  91. data/test/spec_events.rb +133 -0
  92. data/test/spec_fastcgi.rb +50 -72
  93. data/test/spec_file.rb +120 -77
  94. data/test/spec_handler.rb +19 -34
  95. data/test/spec_head.rb +15 -14
  96. data/test/spec_lint.rb +169 -199
  97. data/test/spec_lobster.rb +24 -23
  98. data/test/spec_lock.rb +79 -39
  99. data/test/spec_logger.rb +4 -3
  100. data/test/spec_media_type.rb +42 -0
  101. data/test/{spec_methodoverride.rb → spec_method_override.rb} +34 -35
  102. data/test/spec_mime.rb +19 -19
  103. data/test/spec_mock.rb +206 -144
  104. data/test/spec_multipart.rb +329 -208
  105. data/test/{spec_nulllogger.rb → spec_null_logger.rb} +5 -4
  106. data/test/spec_recursive.rb +17 -14
  107. data/test/spec_request.rb +796 -605
  108. data/test/spec_response.rb +233 -112
  109. data/test/spec_rewindable_input.rb +50 -40
  110. data/test/spec_runtime.rb +11 -10
  111. data/test/spec_sendfile.rb +30 -35
  112. data/test/spec_server.rb +78 -52
  113. data/test/spec_session_abstract_id.rb +11 -33
  114. data/test/spec_session_abstract_session_hash.rb +45 -0
  115. data/test/spec_session_cookie.rb +99 -67
  116. data/test/spec_session_memcache.rb +67 -68
  117. data/test/spec_session_pool.rb +52 -51
  118. data/test/{spec_showexceptions.rb → spec_show_exceptions.rb} +23 -28
  119. data/test/{spec_showstatus.rb → spec_show_status.rb} +36 -35
  120. data/test/spec_static.rb +71 -32
  121. data/test/spec_tempfile_reaper.rb +11 -10
  122. data/test/spec_thin.rb +55 -50
  123. data/test/spec_urlmap.rb +79 -78
  124. data/test/spec_utils.rb +441 -346
  125. data/test/spec_version.rb +2 -8
  126. data/test/spec_webrick.rb +93 -71
  127. data/test/static/foo.html +1 -0
  128. data/test/testrequest.rb +1 -1
  129. data/test/unregistered_handler/rack/handler/unregistered.rb +1 -1
  130. data/test/unregistered_handler/rack/handler/unregistered_long_one.rb +1 -1
  131. metadata +95 -74
  132. data/KNOWN-ISSUES +0 -44
  133. data/lib/rack/backports/uri/common_18.rb +0 -56
  134. data/lib/rack/backports/uri/common_192.rb +0 -52
  135. data/lib/rack/backports/uri/common_193.rb +0 -29
  136. data/lib/rack/handler/evented_mongrel.rb +0 -8
  137. data/lib/rack/handler/mongrel.rb +0 -106
  138. data/lib/rack/handler/swiftiplied_mongrel.rb +0 -8
  139. data/lib/rack/showexceptions.rb +0 -387
  140. data/lib/rack/utils/okjson.rb +0 -600
  141. data/test/spec_mongrel.rb +0 -182
  142. /data/lib/rack/{conditionalget.rb → conditional_get.rb} +0 -0
data/test/spec_lint.rb CHANGED
@@ -1,3 +1,4 @@
1
+ require 'minitest/autorun'
1
2
  require 'stringio'
2
3
  require 'tempfile'
3
4
  require 'rack/lint'
@@ -8,129 +9,132 @@ describe Rack::Lint do
8
9
  Rack::MockRequest.env_for("/", *args)
9
10
  end
10
11
 
11
- should "pass valid request" do
12
- lambda {
13
- Rack::Lint.new(lambda { |env|
14
- [200, {"Content-type" => "test/plain", "Content-length" => "3"}, ["foo"]]
15
- }).call(env({}))
16
- }.should.not.raise
12
+ it "pass valid request" do
13
+ Rack::Lint.new(lambda { |env|
14
+ [200, {"Content-type" => "test/plain", "Content-length" => "3"}, ["foo"]]
15
+ }).call(env({})).first.must_equal 200
17
16
  end
18
17
 
19
- should "notice fatal errors" do
20
- lambda { Rack::Lint.new(nil).call }.should.raise(Rack::Lint::LintError).
21
- message.should.match(/No env given/)
18
+ it "notice fatal errors" do
19
+ lambda { Rack::Lint.new(nil).call }.must_raise(Rack::Lint::LintError).
20
+ message.must_match(/No env given/)
22
21
  end
23
22
 
24
- should "notice environment errors" do
25
- lambda { Rack::Lint.new(nil).call 5 }.should.raise(Rack::Lint::LintError).
26
- message.should.match(/not a Hash/)
23
+ it "notice environment errors" do
24
+ lambda { Rack::Lint.new(nil).call 5 }.must_raise(Rack::Lint::LintError).
25
+ message.must_match(/not a Hash/)
27
26
 
28
27
  lambda {
29
28
  e = env
30
29
  e.delete("REQUEST_METHOD")
31
30
  Rack::Lint.new(nil).call(e)
32
- }.should.raise(Rack::Lint::LintError).
33
- message.should.match(/missing required key REQUEST_METHOD/)
31
+ }.must_raise(Rack::Lint::LintError).
32
+ message.must_match(/missing required key REQUEST_METHOD/)
34
33
 
35
34
  lambda {
36
35
  e = env
37
36
  e.delete("SERVER_NAME")
38
37
  Rack::Lint.new(nil).call(e)
39
- }.should.raise(Rack::Lint::LintError).
40
- message.should.match(/missing required key SERVER_NAME/)
38
+ }.must_raise(Rack::Lint::LintError).
39
+ message.must_match(/missing required key SERVER_NAME/)
41
40
 
42
41
 
43
42
  lambda {
44
43
  Rack::Lint.new(nil).call(env("HTTP_CONTENT_TYPE" => "text/plain"))
45
- }.should.raise(Rack::Lint::LintError).
46
- message.should.match(/contains HTTP_CONTENT_TYPE/)
44
+ }.must_raise(Rack::Lint::LintError).
45
+ message.must_match(/contains HTTP_CONTENT_TYPE/)
47
46
 
48
47
  lambda {
49
48
  Rack::Lint.new(nil).call(env("HTTP_CONTENT_LENGTH" => "42"))
50
- }.should.raise(Rack::Lint::LintError).
51
- message.should.match(/contains HTTP_CONTENT_LENGTH/)
49
+ }.must_raise(Rack::Lint::LintError).
50
+ message.must_match(/contains HTTP_CONTENT_LENGTH/)
52
51
 
53
52
  lambda {
54
53
  Rack::Lint.new(nil).call(env("FOO" => Object.new))
55
- }.should.raise(Rack::Lint::LintError).
56
- message.should.match(/non-string value/)
54
+ }.must_raise(Rack::Lint::LintError).
55
+ message.must_match(/non-string value/)
57
56
 
58
57
  lambda {
59
58
  Rack::Lint.new(nil).call(env("rack.version" => "0.2"))
60
- }.should.raise(Rack::Lint::LintError).
61
- message.should.match(/must be an Array/)
59
+ }.must_raise(Rack::Lint::LintError).
60
+ message.must_match(/must be an Array/)
62
61
 
63
62
  lambda {
64
63
  Rack::Lint.new(nil).call(env("rack.url_scheme" => "gopher"))
65
- }.should.raise(Rack::Lint::LintError).
66
- message.should.match(/url_scheme unknown/)
64
+ }.must_raise(Rack::Lint::LintError).
65
+ message.must_match(/url_scheme unknown/)
67
66
 
68
67
  lambda {
69
68
  Rack::Lint.new(nil).call(env("rack.session" => []))
70
- }.should.raise(Rack::Lint::LintError).
71
- message.should.equal("session [] must respond to store and []=")
69
+ }.must_raise(Rack::Lint::LintError).
70
+ message.must_equal "session [] must respond to store and []="
72
71
 
73
72
  lambda {
74
73
  Rack::Lint.new(nil).call(env("rack.logger" => []))
75
- }.should.raise(Rack::Lint::LintError).
76
- message.should.equal("logger [] must respond to info")
74
+ }.must_raise(Rack::Lint::LintError).
75
+ message.must_equal "logger [] must respond to info"
77
76
 
78
77
  lambda {
79
78
  Rack::Lint.new(nil).call(env("rack.multipart.buffer_size" => 0))
80
- }.should.raise(Rack::Lint::LintError).
81
- message.should.equal("rack.multipart.buffer_size must be an Integer > 0 if specified")
79
+ }.must_raise(Rack::Lint::LintError).
80
+ message.must_equal "rack.multipart.buffer_size must be an Integer > 0 if specified"
82
81
 
83
82
  lambda {
84
83
  Rack::Lint.new(nil).call(env("rack.multipart.tempfile_factory" => Tempfile))
85
- }.should.raise(Rack::Lint::LintError).
86
- message.should.equal("rack.multipart.tempfile_factory must respond to #call")
84
+ }.must_raise(Rack::Lint::LintError).
85
+ message.must_equal "rack.multipart.tempfile_factory must respond to #call"
87
86
 
88
87
  lambda {
89
88
  Rack::Lint.new(lambda { |env|
90
89
  env['rack.multipart.tempfile_factory'].call("testfile", "text/plain")
91
90
  }).call(env("rack.multipart.tempfile_factory" => lambda { |filename, content_type| Object.new }))
92
- }.should.raise(Rack::Lint::LintError).
93
- message.should.equal("rack.multipart.tempfile_factory return value must respond to #<<")
91
+ }.must_raise(Rack::Lint::LintError).
92
+ message.must_equal "rack.multipart.tempfile_factory return value must respond to #<<"
94
93
 
95
94
  lambda {
96
95
  Rack::Lint.new(nil).call(env("REQUEST_METHOD" => "FUCKUP?"))
97
- }.should.raise(Rack::Lint::LintError).
98
- message.should.match(/REQUEST_METHOD/)
96
+ }.must_raise(Rack::Lint::LintError).
97
+ message.must_match(/REQUEST_METHOD/)
98
+
99
+ lambda {
100
+ Rack::Lint.new(nil).call(env("REQUEST_METHOD" => "OOPS?\b!"))
101
+ }.must_raise(Rack::Lint::LintError).
102
+ message.must_match(/OOPS\?\\/)
99
103
 
100
104
  lambda {
101
105
  Rack::Lint.new(nil).call(env("SCRIPT_NAME" => "howdy"))
102
- }.should.raise(Rack::Lint::LintError).
103
- message.should.match(/must start with/)
106
+ }.must_raise(Rack::Lint::LintError).
107
+ message.must_match(/must start with/)
104
108
 
105
109
  lambda {
106
110
  Rack::Lint.new(nil).call(env("PATH_INFO" => "../foo"))
107
- }.should.raise(Rack::Lint::LintError).
108
- message.should.match(/must start with/)
111
+ }.must_raise(Rack::Lint::LintError).
112
+ message.must_match(/must start with/)
109
113
 
110
114
  lambda {
111
115
  Rack::Lint.new(nil).call(env("CONTENT_LENGTH" => "xcii"))
112
- }.should.raise(Rack::Lint::LintError).
113
- message.should.match(/Invalid CONTENT_LENGTH/)
116
+ }.must_raise(Rack::Lint::LintError).
117
+ message.must_match(/Invalid CONTENT_LENGTH/)
114
118
 
115
119
  lambda {
116
120
  e = env
117
121
  e.delete("PATH_INFO")
118
122
  e.delete("SCRIPT_NAME")
119
123
  Rack::Lint.new(nil).call(e)
120
- }.should.raise(Rack::Lint::LintError).
121
- message.should.match(/One of .* must be set/)
124
+ }.must_raise(Rack::Lint::LintError).
125
+ message.must_match(/One of .* must be set/)
122
126
 
123
127
  lambda {
124
128
  Rack::Lint.new(nil).call(env("SCRIPT_NAME" => "/"))
125
- }.should.raise(Rack::Lint::LintError).
126
- message.should.match(/cannot be .* make it ''/)
129
+ }.must_raise(Rack::Lint::LintError).
130
+ message.must_match(/cannot be .* make it ''/)
127
131
  end
128
132
 
129
- should "notice input errors" do
133
+ it "notice input errors" do
130
134
  lambda {
131
135
  Rack::Lint.new(nil).call(env("rack.input" => ""))
132
- }.should.raise(Rack::Lint::LintError).
133
- message.should.match(/does not respond to #gets/)
136
+ }.must_raise(Rack::Lint::LintError).
137
+ message.must_match(/does not respond to #gets/)
134
138
 
135
139
  lambda {
136
140
  input = Object.new
@@ -138,8 +142,8 @@ describe Rack::Lint do
138
142
  false
139
143
  end
140
144
  Rack::Lint.new(nil).call(env("rack.input" => input))
141
- }.should.raise(Rack::Lint::LintError).
142
- message.should.match(/is not opened in binary mode/)
145
+ }.must_raise(Rack::Lint::LintError).
146
+ message.must_match(/is not opened in binary mode/)
143
147
 
144
148
  lambda {
145
149
  input = Object.new
@@ -151,54 +155,54 @@ describe Rack::Lint do
151
155
  result
152
156
  end
153
157
  Rack::Lint.new(nil).call(env("rack.input" => input))
154
- }.should.raise(Rack::Lint::LintError).
155
- message.should.match(/does not have ASCII-8BIT as its external encoding/)
158
+ }.must_raise(Rack::Lint::LintError).
159
+ message.must_match(/does not have ASCII-8BIT as its external encoding/)
156
160
  end
157
161
 
158
- should "notice error errors" do
162
+ it "notice error errors" do
159
163
  lambda {
160
164
  Rack::Lint.new(nil).call(env("rack.errors" => ""))
161
- }.should.raise(Rack::Lint::LintError).
162
- message.should.match(/does not respond to #puts/)
165
+ }.must_raise(Rack::Lint::LintError).
166
+ message.must_match(/does not respond to #puts/)
163
167
  end
164
168
 
165
- should "notice status errors" do
169
+ it "notice status errors" do
166
170
  lambda {
167
171
  Rack::Lint.new(lambda { |env|
168
172
  ["cc", {}, ""]
169
173
  }).call(env({}))
170
- }.should.raise(Rack::Lint::LintError).
171
- message.should.match(/must be >=100 seen as integer/)
174
+ }.must_raise(Rack::Lint::LintError).
175
+ message.must_match(/must be >=100 seen as integer/)
172
176
 
173
177
  lambda {
174
178
  Rack::Lint.new(lambda { |env|
175
179
  [42, {}, ""]
176
180
  }).call(env({}))
177
- }.should.raise(Rack::Lint::LintError).
178
- message.should.match(/must be >=100 seen as integer/)
181
+ }.must_raise(Rack::Lint::LintError).
182
+ message.must_match(/must be >=100 seen as integer/)
179
183
  end
180
184
 
181
- should "notice header errors" do
185
+ it "notice header errors" do
182
186
  lambda {
183
187
  Rack::Lint.new(lambda { |env|
184
188
  [200, Object.new, []]
185
189
  }).call(env({}))
186
- }.should.raise(Rack::Lint::LintError).
187
- message.should.equal("headers object should respond to #each, but doesn't (got Object as headers)")
190
+ }.must_raise(Rack::Lint::LintError).
191
+ message.must_equal "headers object should respond to #each, but doesn't (got Object as headers)"
188
192
 
189
193
  lambda {
190
194
  Rack::Lint.new(lambda { |env|
191
195
  [200, {true=>false}, []]
192
196
  }).call(env({}))
193
- }.should.raise(Rack::Lint::LintError).
194
- message.should.equal("header key must be a string, was TrueClass")
197
+ }.must_raise(Rack::Lint::LintError).
198
+ message.must_equal "header key must be a string, was TrueClass"
195
199
 
196
200
  lambda {
197
201
  Rack::Lint.new(lambda { |env|
198
202
  [200, {"Status" => "404"}, []]
199
203
  }).call(env({}))
200
- }.should.raise(Rack::Lint::LintError).
201
- message.should.match(/must not contain Status/)
204
+ }.must_raise(Rack::Lint::LintError).
205
+ message.must_match(/must not contain Status/)
202
206
 
203
207
  # From RFC 7230:<F24><F25>
204
208
  # Most HTTP header field values are defined using common syntax
@@ -206,9 +210,9 @@ describe Rack::Lint do
206
210
  # whitespace or specific delimiting characters. Delimiters are chosen
207
211
  # from the set of US-ASCII visual characters not allowed in a token
208
212
  # (DQUOTE and "(),/:;<=>?@[\]{}").
209
- #
213
+ #
210
214
  # token = 1*tchar
211
- #
215
+ #
212
216
  # tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*"
213
217
  # / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~"
214
218
  # / DIGIT / ALPHA
@@ -219,157 +223,151 @@ describe Rack::Lint do
219
223
  Rack::Lint.new(lambda { |env|
220
224
  [200, {invalid_header => "text/plain"}, []]
221
225
  }).call(env({}))
222
- }.should.raise(Rack::Lint::LintError, "on invalid header: #{invalid_header}").
223
- message.should.equal("invalid header name: #{invalid_header}")
226
+ }.must_raise(Rack::Lint::LintError, "on invalid header: #{invalid_header}").
227
+ message.must_equal("invalid header name: #{invalid_header}")
224
228
  end
225
229
  valid_headers = 0.upto(127).map(&:chr) - invalid_headers
226
230
  valid_headers.each do |valid_header|
227
- lambda {
228
- Rack::Lint.new(lambda { |env|
229
- [200, {valid_header => "text/plain"}, []]
230
- }).call(env({}))
231
- }.should.not.raise(Rack::Lint::LintError, "on valid header: #{valid_header}")
231
+ Rack::Lint.new(lambda { |env|
232
+ [200, {valid_header => "text/plain"}, []]
233
+ }).call(env({})).first.must_equal 200
232
234
  end
233
235
 
234
236
  lambda {
235
237
  Rack::Lint.new(lambda { |env|
236
238
  [200, {"Foo" => Object.new}, []]
237
239
  }).call(env({}))
238
- }.should.raise(Rack::Lint::LintError).
239
- message.should.equal("a header value must be a String, but the value of 'Foo' is a Object")
240
+ }.must_raise(Rack::Lint::LintError).
241
+ message.must_equal "a header value must be a String, but the value of 'Foo' is a Object"
240
242
 
241
243
  lambda {
242
244
  Rack::Lint.new(lambda { |env|
243
245
  [200, {"Foo" => [1, 2, 3]}, []]
244
246
  }).call(env({}))
245
- }.should.raise(Rack::Lint::LintError).
246
- message.should.equal("a header value must be a String, but the value of 'Foo' is a Array")
247
+ }.must_raise(Rack::Lint::LintError).
248
+ message.must_equal "a header value must be a String, but the value of 'Foo' is a Array"
247
249
 
248
250
 
249
251
  lambda {
250
252
  Rack::Lint.new(lambda { |env|
251
253
  [200, {"Foo-Bar" => "text\000plain"}, []]
252
254
  }).call(env({}))
253
- }.should.raise(Rack::Lint::LintError).
254
- message.should.match(/invalid header/)
255
-
256
- # line ends (010) should be allowed in header values.
257
- lambda {
258
- Rack::Lint.new(lambda { |env|
259
- [200, {"Foo-Bar" => "one\ntwo\nthree", "Content-Length" => "0", "Content-Type" => "text/plain" }, []]
260
- }).call(env({}))
261
- }.should.not.raise(Rack::Lint::LintError)
262
-
263
- # non-Hash header responses should be allowed
264
- lambda {
265
- Rack::Lint.new(lambda { |env|
266
- [200, [%w(Content-Type text/plain), %w(Content-Length 0)], []]
267
- }).call(env({}))
268
- }.should.not.raise(TypeError)
255
+ }.must_raise(Rack::Lint::LintError).
256
+ message.must_match(/invalid header/)
257
+
258
+ # line ends (010).must_be :allowed in header values.?
259
+ Rack::Lint.new(lambda { |env|
260
+ [200, {"Foo-Bar" => "one\ntwo\nthree", "Content-Length" => "0", "Content-Type" => "text/plain" }, []]
261
+ }).call(env({})).first.must_equal 200
262
+
263
+ # non-Hash header responses.must_be :allowed?
264
+ Rack::Lint.new(lambda { |env|
265
+ [200, [%w(Content-Type text/plain), %w(Content-Length 0)], []]
266
+ }).call(env({})).first.must_equal 200
269
267
  end
270
268
 
271
- should "notice content-type errors" do
269
+ it "notice content-type errors" do
272
270
  # lambda {
273
271
  # Rack::Lint.new(lambda { |env|
274
272
  # [200, {"Content-length" => "0"}, []]
275
273
  # }).call(env({}))
276
- # }.should.raise(Rack::Lint::LintError).
277
- # message.should.match(/No Content-Type/)
274
+ # }.must_raise(Rack::Lint::LintError).
275
+ # message.must_match(/No Content-Type/)
278
276
 
279
- [100, 101, 204, 205, 304].each do |status|
277
+ [100, 101, 204, 304].each do |status|
280
278
  lambda {
281
279
  Rack::Lint.new(lambda { |env|
282
280
  [status, {"Content-type" => "text/plain", "Content-length" => "0"}, []]
283
281
  }).call(env({}))
284
- }.should.raise(Rack::Lint::LintError).
285
- message.should.match(/Content-Type header found/)
282
+ }.must_raise(Rack::Lint::LintError).
283
+ message.must_match(/Content-Type header found/)
286
284
  end
287
285
  end
288
286
 
289
- should "notice content-length errors" do
290
- [100, 101, 204, 205, 304].each do |status|
287
+ it "notice content-length errors" do
288
+ [100, 101, 204, 304].each do |status|
291
289
  lambda {
292
290
  Rack::Lint.new(lambda { |env|
293
291
  [status, {"Content-length" => "0"}, []]
294
292
  }).call(env({}))
295
- }.should.raise(Rack::Lint::LintError).
296
- message.should.match(/Content-Length header found/)
293
+ }.must_raise(Rack::Lint::LintError).
294
+ message.must_match(/Content-Length header found/)
297
295
  end
298
296
 
299
297
  lambda {
300
298
  Rack::Lint.new(lambda { |env|
301
299
  [200, {"Content-type" => "text/plain", "Content-Length" => "1"}, []]
302
300
  }).call(env({}))[2].each { }
303
- }.should.raise(Rack::Lint::LintError).
304
- message.should.match(/Content-Length header was 1, but should be 0/)
301
+ }.must_raise(Rack::Lint::LintError).
302
+ message.must_match(/Content-Length header was 1, but should be 0/)
305
303
  end
306
304
 
307
- should "notice body errors" do
305
+ it "notice body errors" do
308
306
  lambda {
309
307
  body = Rack::Lint.new(lambda { |env|
310
308
  [200, {"Content-type" => "text/plain","Content-length" => "3"}, [1,2,3]]
311
309
  }).call(env({}))[2]
312
310
  body.each { |part| }
313
- }.should.raise(Rack::Lint::LintError).
314
- message.should.match(/yielded non-string/)
311
+ }.must_raise(Rack::Lint::LintError).
312
+ message.must_match(/yielded non-string/)
315
313
  end
316
314
 
317
- should "notice input handling errors" do
315
+ it "notice input handling errors" do
318
316
  lambda {
319
317
  Rack::Lint.new(lambda { |env|
320
318
  env["rack.input"].gets("\r\n")
321
319
  [201, {"Content-type" => "text/plain", "Content-length" => "0"}, []]
322
320
  }).call(env({}))
323
- }.should.raise(Rack::Lint::LintError).
324
- message.should.match(/gets called with arguments/)
321
+ }.must_raise(Rack::Lint::LintError).
322
+ message.must_match(/gets called with arguments/)
325
323
 
326
324
  lambda {
327
325
  Rack::Lint.new(lambda { |env|
328
326
  env["rack.input"].read(1, 2, 3)
329
327
  [201, {"Content-type" => "text/plain", "Content-length" => "0"}, []]
330
328
  }).call(env({}))
331
- }.should.raise(Rack::Lint::LintError).
332
- message.should.match(/read called with too many arguments/)
329
+ }.must_raise(Rack::Lint::LintError).
330
+ message.must_match(/read called with too many arguments/)
333
331
 
334
332
  lambda {
335
333
  Rack::Lint.new(lambda { |env|
336
334
  env["rack.input"].read("foo")
337
335
  [201, {"Content-type" => "text/plain", "Content-length" => "0"}, []]
338
336
  }).call(env({}))
339
- }.should.raise(Rack::Lint::LintError).
340
- message.should.match(/read called with non-integer and non-nil length/)
337
+ }.must_raise(Rack::Lint::LintError).
338
+ message.must_match(/read called with non-integer and non-nil length/)
341
339
 
342
340
  lambda {
343
341
  Rack::Lint.new(lambda { |env|
344
342
  env["rack.input"].read(-1)
345
343
  [201, {"Content-type" => "text/plain", "Content-length" => "0"}, []]
346
344
  }).call(env({}))
347
- }.should.raise(Rack::Lint::LintError).
348
- message.should.match(/read called with a negative length/)
345
+ }.must_raise(Rack::Lint::LintError).
346
+ message.must_match(/read called with a negative length/)
349
347
 
350
348
  lambda {
351
349
  Rack::Lint.new(lambda { |env|
352
350
  env["rack.input"].read(nil, nil)
353
351
  [201, {"Content-type" => "text/plain", "Content-length" => "0"}, []]
354
352
  }).call(env({}))
355
- }.should.raise(Rack::Lint::LintError).
356
- message.should.match(/read called with non-String buffer/)
353
+ }.must_raise(Rack::Lint::LintError).
354
+ message.must_match(/read called with non-String buffer/)
357
355
 
358
356
  lambda {
359
357
  Rack::Lint.new(lambda { |env|
360
358
  env["rack.input"].read(nil, 1)
361
359
  [201, {"Content-type" => "text/plain", "Content-length" => "0"}, []]
362
360
  }).call(env({}))
363
- }.should.raise(Rack::Lint::LintError).
364
- message.should.match(/read called with non-String buffer/)
361
+ }.must_raise(Rack::Lint::LintError).
362
+ message.must_match(/read called with non-String buffer/)
365
363
 
366
364
  lambda {
367
365
  Rack::Lint.new(lambda { |env|
368
366
  env["rack.input"].rewind(0)
369
367
  [201, {"Content-type" => "text/plain", "Content-length" => "0"}, []]
370
368
  }).call(env({}))
371
- }.should.raise(Rack::Lint::LintError).
372
- message.should.match(/rewind called with arguments/)
369
+ }.must_raise(Rack::Lint::LintError).
370
+ message.must_match(/rewind called with arguments/)
373
371
 
374
372
  weirdio = Object.new
375
373
  class << weirdio
@@ -413,40 +411,40 @@ describe Rack::Lint do
413
411
  env["rack.input"].gets
414
412
  [201, {"Content-type" => "text/plain", "Content-length" => "0"}, []]
415
413
  }).call(env("rack.input" => weirdio))
416
- }.should.raise(Rack::Lint::LintError).
417
- message.should.match(/gets didn't return a String/)
414
+ }.must_raise(Rack::Lint::LintError).
415
+ message.must_match(/gets didn't return a String/)
418
416
 
419
417
  lambda {
420
418
  Rack::Lint.new(lambda { |env|
421
419
  env["rack.input"].each { |x| }
422
420
  [201, {"Content-type" => "text/plain", "Content-length" => "0"}, []]
423
421
  }).call(env("rack.input" => weirdio))
424
- }.should.raise(Rack::Lint::LintError).
425
- message.should.match(/each didn't yield a String/)
422
+ }.must_raise(Rack::Lint::LintError).
423
+ message.must_match(/each didn't yield a String/)
426
424
 
427
425
  lambda {
428
426
  Rack::Lint.new(lambda { |env|
429
427
  env["rack.input"].read
430
428
  [201, {"Content-type" => "text/plain", "Content-length" => "0"}, []]
431
429
  }).call(env("rack.input" => weirdio))
432
- }.should.raise(Rack::Lint::LintError).
433
- message.should.match(/read didn't return nil or a String/)
430
+ }.must_raise(Rack::Lint::LintError).
431
+ message.must_match(/read didn't return nil or a String/)
434
432
 
435
433
  lambda {
436
434
  Rack::Lint.new(lambda { |env|
437
435
  env["rack.input"].read
438
436
  [201, {"Content-type" => "text/plain", "Content-length" => "0"}, []]
439
437
  }).call(env("rack.input" => eof_weirdio))
440
- }.should.raise(Rack::Lint::LintError).
441
- message.should.match(/read\(nil\) returned nil on EOF/)
438
+ }.must_raise(Rack::Lint::LintError).
439
+ message.must_match(/read\(nil\) returned nil on EOF/)
442
440
 
443
441
  lambda {
444
442
  Rack::Lint.new(lambda { |env|
445
443
  env["rack.input"].rewind
446
444
  [201, {"Content-type" => "text/plain", "Content-length" => "0"}, []]
447
445
  }).call(env("rack.input" => weirdio))
448
- }.should.raise(Rack::Lint::LintError).
449
- message.should.match(/rewind raised Errno::ESPIPE/)
446
+ }.must_raise(Rack::Lint::LintError).
447
+ message.must_match(/rewind raised Errno::ESPIPE/)
450
448
 
451
449
 
452
450
  lambda {
@@ -454,97 +452,69 @@ describe Rack::Lint do
454
452
  env["rack.input"].close
455
453
  [201, {"Content-type" => "text/plain", "Content-length" => "0"}, []]
456
454
  }).call(env({}))
457
- }.should.raise(Rack::Lint::LintError).
458
- message.should.match(/close must not be called/)
455
+ }.must_raise(Rack::Lint::LintError).
456
+ message.must_match(/close must not be called/)
459
457
  end
460
458
 
461
- should "notice error handling errors" do
459
+ it "notice error handling errors" do
462
460
  lambda {
463
461
  Rack::Lint.new(lambda { |env|
464
462
  env["rack.errors"].write(42)
465
463
  [201, {"Content-type" => "text/plain", "Content-length" => "0"}, []]
466
464
  }).call(env({}))
467
- }.should.raise(Rack::Lint::LintError).
468
- message.should.match(/write not called with a String/)
465
+ }.must_raise(Rack::Lint::LintError).
466
+ message.must_match(/write not called with a String/)
469
467
 
470
468
  lambda {
471
469
  Rack::Lint.new(lambda { |env|
472
470
  env["rack.errors"].close
473
471
  [201, {"Content-type" => "text/plain", "Content-length" => "0"}, []]
474
472
  }).call(env({}))
475
- }.should.raise(Rack::Lint::LintError).
476
- message.should.match(/close must not be called/)
473
+ }.must_raise(Rack::Lint::LintError).
474
+ message.must_match(/close must not be called/)
477
475
  end
478
476
 
479
- should "notice HEAD errors" do
480
- lambda {
481
- Rack::Lint.new(lambda { |env|
482
- [200, {"Content-type" => "test/plain", "Content-length" => "3"}, []]
483
- }).call(env({"REQUEST_METHOD" => "HEAD"}))
484
- }.should.not.raise
477
+ it "notice HEAD errors" do
478
+ Rack::Lint.new(lambda { |env|
479
+ [200, {"Content-type" => "test/plain", "Content-length" => "3"}, []]
480
+ }).call(env({"REQUEST_METHOD" => "HEAD"})).first.must_equal 200
485
481
 
486
482
  lambda {
487
483
  Rack::Lint.new(lambda { |env|
488
484
  [200, {"Content-type" => "test/plain", "Content-length" => "3"}, ["foo"]]
489
485
  }).call(env({"REQUEST_METHOD" => "HEAD"}))[2].each { }
490
- }.should.raise(Rack::Lint::LintError).
491
- message.should.match(/body was given for HEAD/)
486
+ }.must_raise(Rack::Lint::LintError).
487
+ message.must_match(/body was given for HEAD/)
492
488
  end
493
489
 
494
- should "pass valid read calls" do
490
+ def assert_lint(*args)
495
491
  hello_str = "hello world"
496
- hello_str.force_encoding("ASCII-8BIT") if hello_str.respond_to? :force_encoding
497
- lambda {
498
- Rack::Lint.new(lambda { |env|
499
- env["rack.input"].read
500
- [201, {"Content-type" => "text/plain", "Content-length" => "0"}, []]
501
- }).call(env({"rack.input" => StringIO.new(hello_str)}))
502
- }.should.not.raise(Rack::Lint::LintError)
503
-
504
- lambda {
505
- Rack::Lint.new(lambda { |env|
506
- env["rack.input"].read(0)
507
- [201, {"Content-type" => "text/plain", "Content-length" => "0"}, []]
508
- }).call(env({"rack.input" => StringIO.new(hello_str)}))
509
- }.should.not.raise(Rack::Lint::LintError)
492
+ hello_str.force_encoding(Encoding::ASCII_8BIT)
510
493
 
511
- lambda {
512
- Rack::Lint.new(lambda { |env|
513
- env["rack.input"].read(1)
514
- [201, {"Content-type" => "text/plain", "Content-length" => "0"}, []]
515
- }).call(env({"rack.input" => StringIO.new(hello_str)}))
516
- }.should.not.raise(Rack::Lint::LintError)
517
-
518
- lambda {
519
- Rack::Lint.new(lambda { |env|
520
- env["rack.input"].read(nil)
521
- [201, {"Content-type" => "text/plain", "Content-length" => "0"}, []]
522
- }).call(env({"rack.input" => StringIO.new(hello_str)}))
523
- }.should.not.raise(Rack::Lint::LintError)
524
-
525
- lambda {
526
- Rack::Lint.new(lambda { |env|
527
- env["rack.input"].read(nil, '')
528
- [201, {"Content-type" => "text/plain", "Content-length" => "0"}, []]
529
- }).call(env({"rack.input" => StringIO.new(hello_str)}))
530
- }.should.not.raise(Rack::Lint::LintError)
494
+ Rack::Lint.new(lambda { |env|
495
+ env["rack.input"].send(:read, *args)
496
+ [201, {"Content-type" => "text/plain", "Content-length" => "0"}, []]
497
+ }).call(env({"rack.input" => StringIO.new(hello_str)})).
498
+ first.must_equal 201
499
+ end
531
500
 
532
- lambda {
533
- Rack::Lint.new(lambda { |env|
534
- env["rack.input"].read(1, '')
535
- [201, {"Content-type" => "text/plain", "Content-length" => "0"}, []]
536
- }).call(env({"rack.input" => StringIO.new(hello_str)}))
537
- }.should.not.raise(Rack::Lint::LintError)
501
+ it "pass valid read calls" do
502
+ assert_lint
503
+ assert_lint 0
504
+ assert_lint 1
505
+ assert_lint nil
506
+ assert_lint nil, ''
507
+ assert_lint 1, ''
538
508
  end
539
509
  end
540
510
 
541
511
  describe "Rack::Lint::InputWrapper" do
542
- should "delegate :rewind to underlying IO object" do
512
+ it "delegate :rewind to underlying IO object" do
543
513
  io = StringIO.new("123")
544
514
  wrapper = Rack::Lint::InputWrapper.new(io)
545
- wrapper.read.should.equal "123"
546
- wrapper.read.should.equal ""
515
+ wrapper.read.must_equal "123"
516
+ wrapper.read.must_equal ""
547
517
  wrapper.rewind
548
- wrapper.read.should.equal "123"
518
+ wrapper.read.must_equal "123"
549
519
  end
550
520
  end