rack 1.6.13 → 2.0.9
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.
- checksums.yaml +4 -4
- data/COPYING +1 -1
- data/HISTORY.md +138 -8
- data/README.rdoc +18 -28
- data/Rakefile +6 -14
- data/SPEC +3 -3
- data/contrib/rack_logo.svg +164 -111
- data/example/protectedlobster.rb +1 -1
- data/example/protectedlobster.ru +1 -1
- data/lib/rack/auth/abstract/request.rb +5 -1
- data/lib/rack/auth/digest/params.rb +2 -3
- data/lib/rack/auth/digest/request.rb +1 -1
- data/lib/rack/body_proxy.rb +14 -9
- data/lib/rack/builder.rb +3 -3
- data/lib/rack/chunked.rb +5 -5
- data/lib/rack/{commonlogger.rb → common_logger.rb} +3 -3
- data/lib/rack/content_length.rb +2 -2
- data/lib/rack/deflater.rb +4 -39
- data/lib/rack/directory.rb +66 -54
- data/lib/rack/etag.rb +5 -4
- data/lib/rack/events.rb +154 -0
- data/lib/rack/file.rb +64 -40
- data/lib/rack/handler/cgi.rb +15 -16
- data/lib/rack/handler/fastcgi.rb +13 -14
- data/lib/rack/handler/lsws.rb +11 -11
- data/lib/rack/handler/scgi.rb +15 -15
- data/lib/rack/handler/thin.rb +3 -0
- data/lib/rack/handler/webrick.rb +24 -26
- data/lib/rack/handler.rb +3 -25
- data/lib/rack/head.rb +15 -17
- data/lib/rack/lint.rb +40 -40
- data/lib/rack/lobster.rb +1 -1
- data/lib/rack/lock.rb +15 -10
- data/lib/rack/logger.rb +2 -2
- data/lib/rack/media_type.rb +38 -0
- data/lib/rack/{methodoverride.rb → method_override.rb} +6 -6
- data/lib/rack/mime.rb +18 -5
- data/lib/rack/mock.rb +36 -54
- data/lib/rack/multipart/generator.rb +5 -5
- data/lib/rack/multipart/parser.rb +270 -157
- data/lib/rack/multipart/uploaded_file.rb +1 -2
- data/lib/rack/multipart.rb +35 -6
- data/lib/rack/{nulllogger.rb → null_logger.rb} +1 -1
- data/lib/rack/query_parser.rb +192 -0
- data/lib/rack/recursive.rb +8 -8
- data/lib/rack/request.rb +394 -305
- data/lib/rack/response.rb +130 -57
- data/lib/rack/rewindable_input.rb +1 -12
- data/lib/rack/runtime.rb +10 -18
- data/lib/rack/sendfile.rb +5 -7
- data/lib/rack/server.rb +30 -23
- data/lib/rack/session/abstract/id.rb +110 -75
- data/lib/rack/session/cookie.rb +24 -17
- data/lib/rack/session/memcache.rb +9 -9
- data/lib/rack/session/pool.rb +8 -8
- data/lib/rack/show_exceptions.rb +386 -0
- data/lib/rack/{showstatus.rb → show_status.rb} +3 -3
- data/lib/rack/static.rb +30 -5
- data/lib/rack/tempfile_reaper.rb +2 -2
- data/lib/rack/urlmap.rb +15 -14
- data/lib/rack/utils.rb +138 -211
- data/lib/rack.rb +70 -21
- data/rack.gemspec +10 -9
- data/test/builder/an_underscore_app.rb +5 -0
- data/test/builder/options.ru +1 -1
- data/test/cgi/test.fcgi +1 -0
- data/test/cgi/test.gz +0 -0
- data/test/helper.rb +34 -0
- data/test/multipart/filename_with_encoded_words +7 -0
- data/test/multipart/filename_with_single_quote +7 -0
- data/test/multipart/quoted +15 -0
- data/test/multipart/rack-logo.png +0 -0
- data/test/multipart/unity3d_wwwform +11 -0
- data/test/registering_handler/rack/handler/registering_myself.rb +1 -1
- data/test/spec_auth_basic.rb +27 -19
- data/test/spec_auth_digest.rb +47 -46
- data/test/spec_body_proxy.rb +27 -27
- data/test/spec_builder.rb +51 -41
- data/test/spec_cascade.rb +24 -22
- data/test/spec_cgi.rb +49 -67
- data/test/spec_chunked.rb +37 -35
- data/test/{spec_commonlogger.rb → spec_common_logger.rb} +23 -21
- data/test/{spec_conditionalget.rb → spec_conditional_get.rb} +29 -28
- data/test/spec_config.rb +3 -2
- data/test/spec_content_length.rb +18 -17
- data/test/spec_content_type.rb +13 -12
- data/test/spec_deflater.rb +85 -49
- data/test/spec_directory.rb +87 -27
- data/test/spec_etag.rb +32 -31
- data/test/spec_events.rb +133 -0
- data/test/spec_fastcgi.rb +50 -72
- data/test/spec_file.rb +120 -77
- data/test/spec_handler.rb +19 -34
- data/test/spec_head.rb +15 -14
- data/test/spec_lint.rb +164 -199
- data/test/spec_lobster.rb +24 -23
- data/test/spec_lock.rb +79 -39
- data/test/spec_logger.rb +4 -3
- data/test/spec_media_type.rb +42 -0
- data/test/{spec_methodoverride.rb → spec_method_override.rb} +34 -35
- data/test/spec_mime.rb +19 -19
- data/test/spec_mock.rb +206 -144
- data/test/spec_multipart.rb +322 -200
- data/test/{spec_nulllogger.rb → spec_null_logger.rb} +5 -4
- data/test/spec_recursive.rb +17 -14
- data/test/spec_request.rb +780 -605
- data/test/spec_response.rb +233 -112
- data/test/spec_rewindable_input.rb +50 -40
- data/test/spec_runtime.rb +11 -10
- data/test/spec_sendfile.rb +30 -35
- data/test/spec_server.rb +78 -52
- data/test/spec_session_abstract_id.rb +11 -33
- data/test/spec_session_abstract_session_hash.rb +45 -0
- data/test/spec_session_cookie.rb +99 -67
- data/test/spec_session_memcache.rb +67 -68
- data/test/spec_session_pool.rb +52 -51
- data/test/{spec_showexceptions.rb → spec_show_exceptions.rb} +23 -28
- data/test/{spec_showstatus.rb → spec_show_status.rb} +36 -35
- data/test/spec_static.rb +71 -32
- data/test/spec_tempfile_reaper.rb +11 -10
- data/test/spec_thin.rb +55 -50
- data/test/spec_urlmap.rb +79 -78
- data/test/spec_utils.rb +441 -346
- data/test/spec_version.rb +2 -8
- data/test/spec_webrick.rb +93 -71
- data/test/static/foo.html +1 -0
- data/test/testrequest.rb +1 -1
- data/test/unregistered_handler/rack/handler/unregistered.rb +1 -1
- data/test/unregistered_handler/rack/handler/unregistered_long_one.rb +1 -1
- metadata +57 -36
- data/KNOWN-ISSUES +0 -44
- data/lib/rack/backports/uri/common_18.rb +0 -56
- data/lib/rack/backports/uri/common_192.rb +0 -52
- data/lib/rack/backports/uri/common_193.rb +0 -29
- data/lib/rack/handler/evented_mongrel.rb +0 -8
- data/lib/rack/handler/mongrel.rb +0 -106
- data/lib/rack/handler/swiftiplied_mongrel.rb +0 -8
- data/lib/rack/showexceptions.rb +0 -387
- data/lib/rack/utils/okjson.rb +0 -600
- data/test/spec_mongrel.rb +0 -182
- /data/lib/rack/{conditionalget.rb → conditional_get.rb} +0 -0
data/test/spec_lobster.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'minitest/autorun'
|
1
2
|
require 'rack/lobster'
|
2
3
|
require 'rack/lint'
|
3
4
|
require 'rack/mock'
|
@@ -13,46 +14,46 @@ module LobsterHelpers
|
|
13
14
|
end
|
14
15
|
|
15
16
|
describe Rack::Lobster::LambdaLobster do
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
Rack::Lobster::LambdaLobster.
|
17
|
+
include LobsterHelpers
|
18
|
+
|
19
|
+
it "be a single lambda" do
|
20
|
+
Rack::Lobster::LambdaLobster.must_be_kind_of Proc
|
20
21
|
end
|
21
22
|
|
22
|
-
|
23
|
+
it "look like a lobster" do
|
23
24
|
res = lambda_lobster.get("/")
|
24
|
-
res.
|
25
|
-
res.body.
|
26
|
-
res.body.
|
25
|
+
res.must_be :ok?
|
26
|
+
res.body.must_include "(,(,,(,,,("
|
27
|
+
res.body.must_include "?flip"
|
27
28
|
end
|
28
29
|
|
29
|
-
|
30
|
+
it "be flippable" do
|
30
31
|
res = lambda_lobster.get("/?flip")
|
31
|
-
res.
|
32
|
-
res.body.
|
32
|
+
res.must_be :ok?
|
33
|
+
res.body.must_include "(,,,(,,(,("
|
33
34
|
end
|
34
35
|
end
|
35
36
|
|
36
37
|
describe Rack::Lobster do
|
37
|
-
|
38
|
-
|
39
|
-
|
38
|
+
include LobsterHelpers
|
39
|
+
|
40
|
+
it "look like a lobster" do
|
40
41
|
res = lobster.get("/")
|
41
|
-
res.
|
42
|
-
res.body.
|
43
|
-
res.body.
|
44
|
-
res.body.
|
42
|
+
res.must_be :ok?
|
43
|
+
res.body.must_include "(,(,,(,,,("
|
44
|
+
res.body.must_include "?flip"
|
45
|
+
res.body.must_include "crash"
|
45
46
|
end
|
46
47
|
|
47
|
-
|
48
|
+
it "be flippable" do
|
48
49
|
res = lobster.get("/?flip=left")
|
49
|
-
res.
|
50
|
-
res.body.
|
50
|
+
res.must_be :ok?
|
51
|
+
res.body.must_include "),,,),,),)"
|
51
52
|
end
|
52
53
|
|
53
|
-
|
54
|
+
it "provide crashing for testing purposes" do
|
54
55
|
lambda {
|
55
56
|
lobster.get("/?flip=crash")
|
56
|
-
}.
|
57
|
+
}.must_raise RuntimeError
|
57
58
|
end
|
58
59
|
end
|
data/test/spec_lock.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'minitest/autorun'
|
1
2
|
require 'rack/lint'
|
2
3
|
require 'rack/lock'
|
3
4
|
require 'rack/mock'
|
@@ -9,11 +10,6 @@ class Lock
|
|
9
10
|
@synchronized = false
|
10
11
|
end
|
11
12
|
|
12
|
-
def synchronize
|
13
|
-
@synchronized = true
|
14
|
-
yield
|
15
|
-
end
|
16
|
-
|
17
13
|
def lock
|
18
14
|
@synchronized = true
|
19
15
|
end
|
@@ -35,12 +31,12 @@ module LockHelpers
|
|
35
31
|
end
|
36
32
|
|
37
33
|
describe Rack::Lock do
|
38
|
-
|
34
|
+
include LockHelpers
|
39
35
|
|
40
36
|
describe 'Proxy' do
|
41
|
-
|
37
|
+
include LockHelpers
|
42
38
|
|
43
|
-
|
39
|
+
it 'delegate each' do
|
44
40
|
env = Rack::MockRequest.env_for("/")
|
45
41
|
response = Class.new {
|
46
42
|
attr_accessor :close_called
|
@@ -52,10 +48,10 @@ describe Rack::Lock do
|
|
52
48
|
response = app.call(env)[2]
|
53
49
|
list = []
|
54
50
|
response.each { |x| list << x }
|
55
|
-
list.
|
51
|
+
list.must_equal %w{ hi mom }
|
56
52
|
end
|
57
53
|
|
58
|
-
|
54
|
+
it 'delegate to_path' do
|
59
55
|
lock = Lock.new
|
60
56
|
env = Rack::MockRequest.env_for("/")
|
61
57
|
|
@@ -65,11 +61,11 @@ describe Rack::Lock do
|
|
65
61
|
app = Rack::Lock.new(lambda { |inner_env| [200, {"Content-Type" => "text/plain"}, res] }, lock)
|
66
62
|
body = app.call(env)[2]
|
67
63
|
|
68
|
-
body.
|
69
|
-
body.to_path.
|
64
|
+
body.must_respond_to :to_path
|
65
|
+
body.to_path.must_equal "/tmp/hello.txt"
|
70
66
|
end
|
71
67
|
|
72
|
-
|
68
|
+
it 'not delegate to_path if body does not implement it' do
|
73
69
|
env = Rack::MockRequest.env_for("/")
|
74
70
|
|
75
71
|
res = ['Hello World']
|
@@ -77,11 +73,11 @@ describe Rack::Lock do
|
|
77
73
|
app = lock_app(lambda { |inner_env| [200, {"Content-Type" => "text/plain"}, res] })
|
78
74
|
body = app.call(env)[2]
|
79
75
|
|
80
|
-
body.
|
76
|
+
body.wont_respond_to :to_path
|
81
77
|
end
|
82
78
|
end
|
83
79
|
|
84
|
-
|
80
|
+
it 'call super on close' do
|
85
81
|
env = Rack::MockRequest.env_for("/")
|
86
82
|
response = Class.new {
|
87
83
|
attr_accessor :close_called
|
@@ -91,74 +87,118 @@ describe Rack::Lock do
|
|
91
87
|
|
92
88
|
app = lock_app(lambda { |inner_env| [200, {"Content-Type" => "text/plain"}, response] })
|
93
89
|
app.call(env)
|
94
|
-
response.close_called.
|
90
|
+
response.close_called.must_equal false
|
95
91
|
response.close
|
96
|
-
response.close_called.
|
92
|
+
response.close_called.must_equal true
|
97
93
|
end
|
98
94
|
|
99
|
-
|
95
|
+
it "not unlock until body is closed" do
|
100
96
|
lock = Lock.new
|
101
97
|
env = Rack::MockRequest.env_for("/")
|
102
98
|
response = Object.new
|
103
99
|
app = lock_app(lambda { |inner_env| [200, {"Content-Type" => "text/plain"}, response] }, lock)
|
104
|
-
lock.synchronized.
|
100
|
+
lock.synchronized.must_equal false
|
105
101
|
response = app.call(env)[2]
|
106
|
-
lock.synchronized.
|
102
|
+
lock.synchronized.must_equal true
|
107
103
|
response.close
|
108
|
-
lock.synchronized.
|
104
|
+
lock.synchronized.must_equal false
|
109
105
|
end
|
110
106
|
|
111
|
-
|
107
|
+
it "return value from app" do
|
112
108
|
env = Rack::MockRequest.env_for("/")
|
113
109
|
body = [200, {"Content-Type" => "text/plain"}, %w{ hi mom }]
|
114
110
|
app = lock_app(lambda { |inner_env| body })
|
115
111
|
|
116
112
|
res = app.call(env)
|
117
|
-
res[0].
|
118
|
-
res[1].
|
119
|
-
res[2].to_enum.to_a.
|
113
|
+
res[0].must_equal body[0]
|
114
|
+
res[1].must_equal body[1]
|
115
|
+
res[2].to_enum.to_a.must_equal ["hi", "mom"]
|
120
116
|
end
|
121
117
|
|
122
|
-
|
118
|
+
it "call synchronize on lock" do
|
123
119
|
lock = Lock.new
|
124
120
|
env = Rack::MockRequest.env_for("/")
|
125
121
|
app = lock_app(lambda { |inner_env| [200, {"Content-Type" => "text/plain"}, %w{ a b c }] }, lock)
|
126
|
-
lock.synchronized.
|
122
|
+
lock.synchronized.must_equal false
|
127
123
|
app.call(env)
|
128
|
-
lock.synchronized.
|
124
|
+
lock.synchronized.must_equal true
|
129
125
|
end
|
130
126
|
|
131
|
-
|
127
|
+
it "unlock if the app raises" do
|
132
128
|
lock = Lock.new
|
133
129
|
env = Rack::MockRequest.env_for("/")
|
134
130
|
app = lock_app(lambda { raise Exception }, lock)
|
135
|
-
lambda { app.call(env) }.
|
136
|
-
lock.synchronized.
|
131
|
+
lambda { app.call(env) }.must_raise Exception
|
132
|
+
lock.synchronized.must_equal false
|
137
133
|
end
|
138
134
|
|
139
|
-
|
135
|
+
it "unlock if the app throws" do
|
140
136
|
lock = Lock.new
|
141
137
|
env = Rack::MockRequest.env_for("/")
|
142
138
|
app = lock_app(lambda {|_| throw :bacon }, lock)
|
143
|
-
lambda { app.call(env) }.
|
144
|
-
lock.synchronized.
|
139
|
+
lambda { app.call(env) }.must_throw :bacon
|
140
|
+
lock.synchronized.must_equal false
|
145
141
|
end
|
146
142
|
|
147
|
-
|
143
|
+
it "set multithread flag to false" do
|
148
144
|
app = lock_app(lambda { |env|
|
149
|
-
env['rack.multithread'].
|
145
|
+
env['rack.multithread'].must_equal false
|
150
146
|
[200, {"Content-Type" => "text/plain"}, %w{ a b c }]
|
151
147
|
}, false)
|
152
|
-
|
148
|
+
env = Rack::MockRequest.env_for("/")
|
149
|
+
env['rack.multithread'].must_equal true
|
150
|
+
_, _, body = app.call(env)
|
151
|
+
body.close
|
152
|
+
env['rack.multithread'].must_equal true
|
153
153
|
end
|
154
154
|
|
155
|
-
|
155
|
+
it "reset original multithread flag when exiting lock" do
|
156
156
|
app = Class.new(Rack::Lock) {
|
157
157
|
def call(env)
|
158
|
-
env['rack.multithread'].
|
158
|
+
env['rack.multithread'].must_equal true
|
159
159
|
super
|
160
160
|
end
|
161
161
|
}.new(lambda { |env| [200, {"Content-Type" => "text/plain"}, %w{ a b c }] })
|
162
162
|
Rack::Lint.new(app).call(Rack::MockRequest.env_for("/"))
|
163
163
|
end
|
164
|
+
|
165
|
+
it 'not unlock if an error is raised before the mutex is locked' do
|
166
|
+
lock = Class.new do
|
167
|
+
def initialize() @unlocked = false end
|
168
|
+
def unlocked?() @unlocked end
|
169
|
+
def lock() raise Exception end
|
170
|
+
def unlock() @unlocked = true end
|
171
|
+
end.new
|
172
|
+
env = Rack::MockRequest.env_for("/")
|
173
|
+
app = lock_app(proc { [200, {"Content-Type" => "text/plain"}, []] }, lock)
|
174
|
+
lambda { app.call(env) }.must_raise Exception
|
175
|
+
lock.unlocked?.must_equal false
|
176
|
+
end
|
177
|
+
|
178
|
+
it "not reset the environment while the body is proxied" do
|
179
|
+
proxy = Class.new do
|
180
|
+
attr_reader :env
|
181
|
+
def initialize(env) @env = env end
|
182
|
+
end
|
183
|
+
app = Rack::Lock.new lambda { |env| [200, {"Content-Type" => "text/plain"}, proxy.new(env)] }
|
184
|
+
response = app.call(Rack::MockRequest.env_for("/"))[2]
|
185
|
+
response.env['rack.multithread'].must_equal false
|
186
|
+
end
|
187
|
+
|
188
|
+
it "unlock if an exception occurs before returning" do
|
189
|
+
lock = Lock.new
|
190
|
+
env = Rack::MockRequest.env_for("/")
|
191
|
+
app = lock_app(proc { [].freeze }, lock)
|
192
|
+
lambda { app.call(env) }.must_raise Exception
|
193
|
+
lock.synchronized.must_equal false
|
194
|
+
end
|
195
|
+
|
196
|
+
it "not replace the environment" do
|
197
|
+
env = Rack::MockRequest.env_for("/")
|
198
|
+
app = lock_app(lambda { |inner_env| [200, {"Content-Type" => "text/plain"}, [inner_env.object_id.to_s]] })
|
199
|
+
|
200
|
+
_, _, body = app.call(env)
|
201
|
+
|
202
|
+
body.to_enum.to_a.must_equal [env.object_id.to_s]
|
203
|
+
end
|
164
204
|
end
|
data/test/spec_logger.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'minitest/autorun'
|
1
2
|
require 'stringio'
|
2
3
|
require 'rack/lint'
|
3
4
|
require 'rack/logger'
|
@@ -13,11 +14,11 @@ describe Rack::Logger do
|
|
13
14
|
[200, {'Content-Type' => 'text/plain'}, ["Hello, World!"]]
|
14
15
|
}
|
15
16
|
|
16
|
-
|
17
|
+
it "conform to Rack::Lint" do
|
17
18
|
errors = StringIO.new
|
18
19
|
a = Rack::Lint.new(Rack::Logger.new(app))
|
19
20
|
Rack::MockRequest.new(a).get('/', 'rack.errors' => errors)
|
20
|
-
errors.string.
|
21
|
-
errors.string.
|
21
|
+
errors.string.must_match(/INFO -- : Program started/)
|
22
|
+
errors.string.must_match(/WARN -- : Nothing to do/)
|
22
23
|
end
|
23
24
|
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'rack/media_type'
|
3
|
+
|
4
|
+
describe Rack::MediaType do
|
5
|
+
before { @empty_hash = {} }
|
6
|
+
|
7
|
+
describe 'when content_type nil' do
|
8
|
+
before { @content_type = nil }
|
9
|
+
|
10
|
+
it '#type is nil' do
|
11
|
+
Rack::MediaType.type(@content_type).must_be_nil
|
12
|
+
end
|
13
|
+
|
14
|
+
it '#params is empty' do
|
15
|
+
Rack::MediaType.params(@content_type).must_equal @empty_hash
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe 'when content_type contains only media_type' do
|
20
|
+
before { @content_type = 'application/text' }
|
21
|
+
|
22
|
+
it '#type is application/text' do
|
23
|
+
Rack::MediaType.type(@content_type).must_equal 'application/text'
|
24
|
+
end
|
25
|
+
|
26
|
+
it '#params is empty' do
|
27
|
+
Rack::MediaType.params(@content_type).must_equal @empty_hash
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe 'when content_type contains media_type and params' do
|
32
|
+
before { @content_type = 'application/text;CHARSET="utf-8"' }
|
33
|
+
|
34
|
+
it '#type is application/text' do
|
35
|
+
Rack::MediaType.type(@content_type).must_equal 'application/text'
|
36
|
+
end
|
37
|
+
|
38
|
+
it '#params has key "charset" with value "utf-8"' do
|
39
|
+
Rack::MediaType.params(@content_type)['charset'].must_equal 'utf-8'
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -1,5 +1,6 @@
|
|
1
|
+
require 'minitest/autorun'
|
1
2
|
require 'stringio'
|
2
|
-
require 'rack/
|
3
|
+
require 'rack/method_override'
|
3
4
|
require 'rack/mock'
|
4
5
|
|
5
6
|
describe Rack::MethodOverride do
|
@@ -9,70 +10,68 @@ describe Rack::MethodOverride do
|
|
9
10
|
}))
|
10
11
|
end
|
11
12
|
|
12
|
-
|
13
|
+
it "not affect GET requests" do
|
13
14
|
env = Rack::MockRequest.env_for("/?_method=delete", :method => "GET")
|
14
15
|
app.call env
|
15
16
|
|
16
|
-
env["REQUEST_METHOD"].
|
17
|
+
env["REQUEST_METHOD"].must_equal "GET"
|
17
18
|
end
|
18
19
|
|
19
|
-
|
20
|
-
|
20
|
+
it "sets rack.errors for invalid UTF8 _method values" do
|
21
|
+
errors = StringIO.new
|
22
|
+
env = Rack::MockRequest.env_for("/",
|
23
|
+
:method => "POST",
|
24
|
+
:input => "_method=\xBF".b,
|
25
|
+
Rack::RACK_ERRORS => errors)
|
26
|
+
|
21
27
|
app.call env
|
22
28
|
|
23
|
-
|
29
|
+
errors.rewind
|
30
|
+
errors.read.must_equal "Invalid string for method\n"
|
31
|
+
env["REQUEST_METHOD"].must_equal "POST"
|
24
32
|
end
|
25
33
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
env = Rack::MockRequest.env_for("/",
|
30
|
-
:method => "POST",
|
31
|
-
:input => "_method=\xBF".force_encoding("ASCII-8BIT"),
|
32
|
-
"rack.errors" => errors)
|
33
|
-
|
34
|
-
app.call env
|
34
|
+
it "modify REQUEST_METHOD for POST requests when _method parameter is set" do
|
35
|
+
env = Rack::MockRequest.env_for("/", :method => "POST", :input => "_method=put")
|
36
|
+
app.call env
|
35
37
|
|
36
|
-
|
37
|
-
errors.read.should.equal "Invalid string for method\n"
|
38
|
-
env["REQUEST_METHOD"].should.equal "POST"
|
39
|
-
end
|
38
|
+
env["REQUEST_METHOD"].must_equal "PUT"
|
40
39
|
end
|
41
40
|
|
42
|
-
|
41
|
+
it "modify REQUEST_METHOD for POST requests when X-HTTP-Method-Override is set" do
|
43
42
|
env = Rack::MockRequest.env_for("/",
|
44
43
|
:method => "POST",
|
45
44
|
"HTTP_X_HTTP_METHOD_OVERRIDE" => "PATCH"
|
46
45
|
)
|
47
46
|
app.call env
|
48
47
|
|
49
|
-
env["REQUEST_METHOD"].
|
48
|
+
env["REQUEST_METHOD"].must_equal "PATCH"
|
50
49
|
end
|
51
50
|
|
52
|
-
|
51
|
+
it "not modify REQUEST_METHOD if the method is unknown" do
|
53
52
|
env = Rack::MockRequest.env_for("/", :method => "POST", :input => "_method=foo")
|
54
53
|
app.call env
|
55
54
|
|
56
|
-
env["REQUEST_METHOD"].
|
55
|
+
env["REQUEST_METHOD"].must_equal "POST"
|
57
56
|
end
|
58
57
|
|
59
|
-
|
58
|
+
it "not modify REQUEST_METHOD when _method is nil" do
|
60
59
|
env = Rack::MockRequest.env_for("/", :method => "POST", :input => "foo=bar")
|
61
60
|
app.call env
|
62
61
|
|
63
|
-
env["REQUEST_METHOD"].
|
62
|
+
env["REQUEST_METHOD"].must_equal "POST"
|
64
63
|
end
|
65
64
|
|
66
|
-
|
65
|
+
it "store the original REQUEST_METHOD prior to overriding" do
|
67
66
|
env = Rack::MockRequest.env_for("/",
|
68
67
|
:method => "POST",
|
69
68
|
:input => "_method=options")
|
70
69
|
app.call env
|
71
70
|
|
72
|
-
env["rack.methodoverride.original_method"].
|
71
|
+
env["rack.methodoverride.original_method"].must_equal "POST"
|
73
72
|
end
|
74
73
|
|
75
|
-
|
74
|
+
it "not modify REQUEST_METHOD when given invalid multipart form data" do
|
76
75
|
input = <<EOF
|
77
76
|
--AaB03x\r
|
78
77
|
content-disposition: form-data; name="huge"; filename="huge"\r
|
@@ -83,10 +82,10 @@ EOF
|
|
83
82
|
:method => "POST", :input => input)
|
84
83
|
app.call env
|
85
84
|
|
86
|
-
env["REQUEST_METHOD"].
|
85
|
+
env["REQUEST_METHOD"].must_equal "POST"
|
87
86
|
end
|
88
87
|
|
89
|
-
|
88
|
+
it "writes error to RACK_ERRORS when given invalid multipart form data" do
|
90
89
|
input = <<EOF
|
91
90
|
--AaB03x\r
|
92
91
|
content-disposition: form-data; name="huge"; filename="huge"\r
|
@@ -94,18 +93,18 @@ EOF
|
|
94
93
|
env = Rack::MockRequest.env_for("/",
|
95
94
|
"CONTENT_TYPE" => "multipart/form-data, boundary=AaB03x",
|
96
95
|
"CONTENT_LENGTH" => input.size.to_s,
|
97
|
-
|
96
|
+
Rack::RACK_ERRORS => StringIO.new,
|
98
97
|
:method => "POST", :input => input)
|
99
98
|
Rack::MethodOverride.new(proc { [200, {"Content-Type" => "text/plain"}, []] }).call env
|
100
99
|
|
101
|
-
env[
|
102
|
-
env[
|
100
|
+
env[Rack::RACK_ERRORS].rewind
|
101
|
+
env[Rack::RACK_ERRORS].read.must_match /Bad request content body/
|
103
102
|
end
|
104
103
|
|
105
|
-
|
104
|
+
it "not modify REQUEST_METHOD for POST requests when the params are unparseable" do
|
106
105
|
env = Rack::MockRequest.env_for("/", :method => "POST", :input => "(%bad-params%)")
|
107
106
|
app.call env
|
108
107
|
|
109
|
-
env["REQUEST_METHOD"].
|
108
|
+
env["REQUEST_METHOD"].must_equal "POST"
|
110
109
|
end
|
111
110
|
end
|
data/test/spec_mime.rb
CHANGED
@@ -1,51 +1,51 @@
|
|
1
|
+
require 'minitest/autorun'
|
1
2
|
require 'rack/mime'
|
2
3
|
|
3
4
|
describe Rack::Mime do
|
4
5
|
|
5
6
|
it "should return the fallback mime-type for files with no extension" do
|
6
7
|
fallback = 'image/jpg'
|
7
|
-
Rack::Mime.mime_type(File.extname('no_ext'), fallback).
|
8
|
+
Rack::Mime.mime_type(File.extname('no_ext'), fallback).must_equal fallback
|
8
9
|
end
|
9
10
|
|
10
11
|
it "should always return 'application/octet-stream' for unknown file extensions" do
|
11
12
|
unknown_ext = File.extname('unknown_ext.abcdefg')
|
12
|
-
Rack::Mime.mime_type(unknown_ext).
|
13
|
+
Rack::Mime.mime_type(unknown_ext).must_equal 'application/octet-stream'
|
13
14
|
end
|
14
15
|
|
15
16
|
it "should return the mime-type for a given extension" do
|
16
17
|
# sanity check. it would be infeasible test every single mime-type.
|
17
|
-
Rack::Mime.mime_type(File.extname('image.jpg')).
|
18
|
+
Rack::Mime.mime_type(File.extname('image.jpg')).must_equal 'image/jpeg'
|
18
19
|
end
|
19
20
|
|
20
21
|
it "should support null fallbacks" do
|
21
|
-
Rack::Mime.mime_type('.nothing', nil).
|
22
|
+
Rack::Mime.mime_type('.nothing', nil).must_be_nil
|
22
23
|
end
|
23
24
|
|
24
25
|
it "should match exact mimes" do
|
25
|
-
Rack::Mime.match?('text/html', 'text/html').
|
26
|
-
Rack::Mime.match?('text/html', 'text/meme').
|
27
|
-
Rack::Mime.match?('text', 'text').
|
28
|
-
Rack::Mime.match?('text', 'binary').
|
26
|
+
Rack::Mime.match?('text/html', 'text/html').must_equal true
|
27
|
+
Rack::Mime.match?('text/html', 'text/meme').must_equal false
|
28
|
+
Rack::Mime.match?('text', 'text').must_equal true
|
29
|
+
Rack::Mime.match?('text', 'binary').must_equal false
|
29
30
|
end
|
30
31
|
|
31
32
|
it "should match class wildcard mimes" do
|
32
|
-
Rack::Mime.match?('text/html', 'text/*').
|
33
|
-
Rack::Mime.match?('text/plain', 'text/*').
|
34
|
-
Rack::Mime.match?('application/json', 'text/*').
|
35
|
-
Rack::Mime.match?('text/html', 'text').
|
33
|
+
Rack::Mime.match?('text/html', 'text/*').must_equal true
|
34
|
+
Rack::Mime.match?('text/plain', 'text/*').must_equal true
|
35
|
+
Rack::Mime.match?('application/json', 'text/*').must_equal false
|
36
|
+
Rack::Mime.match?('text/html', 'text').must_equal true
|
36
37
|
end
|
37
38
|
|
38
39
|
it "should match full wildcards" do
|
39
|
-
Rack::Mime.match?('text/html', '*').
|
40
|
-
Rack::Mime.match?('text/plain', '*').
|
41
|
-
Rack::Mime.match?('text/html', '*/*').
|
42
|
-
Rack::Mime.match?('text/plain', '*/*').
|
40
|
+
Rack::Mime.match?('text/html', '*').must_equal true
|
41
|
+
Rack::Mime.match?('text/plain', '*').must_equal true
|
42
|
+
Rack::Mime.match?('text/html', '*/*').must_equal true
|
43
|
+
Rack::Mime.match?('text/plain', '*/*').must_equal true
|
43
44
|
end
|
44
45
|
|
45
46
|
it "should match type wildcard mimes" do
|
46
|
-
Rack::Mime.match?('text/html', '*/html').
|
47
|
-
Rack::Mime.match?('text/plain', '*/plain').
|
47
|
+
Rack::Mime.match?('text/html', '*/html').must_equal true
|
48
|
+
Rack::Mime.match?('text/plain', '*/plain').must_equal true
|
48
49
|
end
|
49
50
|
|
50
51
|
end
|
51
|
-
|