rack 1.4.1 → 1.4.2
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.
- data/COPYING +1 -1
- data/KNOWN-ISSUES +9 -0
- data/README.rdoc +72 -7
- data/Rakefile +18 -11
- data/SPEC +3 -1
- data/contrib/rack.png +0 -0
- data/contrib/rack.svg +150 -0
- data/contrib/rdoc.css +412 -0
- data/lib/rack/auth/basic.rb +1 -1
- data/lib/rack/auth/digest/nonce.rb +1 -1
- data/lib/rack/backports/uri/common_18.rb +14 -28
- data/lib/rack/backports/uri/common_192.rb +14 -17
- data/lib/rack/backports/uri/common_193.rb +29 -0
- data/lib/rack/body_proxy.rb +10 -0
- data/lib/rack/builder.rb +1 -1
- data/lib/rack/cascade.rb +11 -0
- data/lib/rack/commonlogger.rb +18 -5
- data/lib/rack/deflater.rb +5 -1
- data/lib/rack/directory.rb +1 -1
- data/lib/rack/etag.rb +6 -3
- data/lib/rack/file.rb +13 -4
- data/lib/rack/head.rb +1 -0
- data/lib/rack/lint.rb +3 -1
- data/lib/rack/lock.rb +3 -4
- data/lib/rack/mime.rb +1 -1
- data/lib/rack/mock.rb +3 -2
- data/lib/rack/multipart.rb +2 -2
- data/lib/rack/multipart/parser.rb +6 -4
- data/lib/rack/reloader.rb +1 -1
- data/lib/rack/request.rb +2 -4
- data/lib/rack/response.rb +2 -1
- data/lib/rack/server.rb +28 -2
- data/lib/rack/session/abstract/id.rb +5 -0
- data/lib/rack/session/cookie.rb +9 -0
- data/lib/rack/static.rb +90 -8
- data/lib/rack/utils.rb +17 -10
- data/rack.gemspec +3 -3
- data/test/builder/line.ru +1 -0
- data/test/cgi/assets/folder/test.js +1 -0
- data/test/cgi/assets/fonts/font.eot +1 -0
- data/test/cgi/assets/images/image.png +1 -0
- data/test/cgi/assets/index.html +1 -0
- data/test/cgi/assets/javascripts/app.js +1 -0
- data/test/cgi/assets/stylesheets/app.css +1 -0
- data/test/spec_auth_basic.rb +8 -0
- data/test/spec_auth_digest.rb +14 -0
- data/test/spec_body_proxy.rb +4 -0
- data/test/spec_builder.rb +7 -1
- data/test/spec_cascade.rb +8 -0
- data/test/spec_chunked.rb +6 -6
- data/test/spec_config.rb +0 -1
- data/test/spec_content_length.rb +26 -13
- data/test/spec_content_type.rb +15 -5
- data/test/spec_deflater.rb +35 -17
- data/test/spec_directory.rb +20 -1
- data/test/spec_etag.rb +29 -13
- data/test/spec_file.rb +42 -25
- data/test/spec_head.rb +25 -7
- data/test/spec_lobster.rb +20 -5
- data/test/spec_lock.rb +46 -21
- data/test/spec_logger.rb +2 -7
- data/test/spec_methodoverride.rb +21 -22
- data/test/spec_mock.rb +12 -7
- data/test/spec_multipart.rb +29 -0
- data/test/spec_nulllogger.rb +13 -2
- data/test/spec_recursive.rb +12 -9
- data/test/spec_request.rb +2 -2
- data/test/spec_response.rb +30 -0
- data/test/spec_runtime.rb +15 -5
- data/test/spec_sendfile.rb +11 -8
- data/test/spec_server.rb +47 -0
- data/test/spec_session_cookie.rb +68 -1
- data/test/spec_session_memcache.rb +10 -8
- data/test/spec_session_pool.rb +13 -10
- data/test/spec_showexceptions.rb +9 -4
- data/test/spec_showstatus.rb +10 -5
- data/test/spec_static.rb +85 -9
- data/test/spec_urlmap.rb +10 -10
- data/test/spec_utils.rb +14 -1
- data/test/static/another/index.html +1 -0
- metadata +21 -8
data/test/spec_file.rb
CHANGED
@@ -1,20 +1,23 @@
|
|
1
1
|
require 'rack/file'
|
2
|
+
require 'rack/lint'
|
2
3
|
require 'rack/mock'
|
3
4
|
|
4
5
|
describe Rack::File do
|
5
6
|
DOCROOT = File.expand_path(File.dirname(__FILE__)) unless defined? DOCROOT
|
6
7
|
|
8
|
+
def file(*args)
|
9
|
+
Rack::Lint.new Rack::File.new(*args)
|
10
|
+
end
|
11
|
+
|
7
12
|
should "serve files" do
|
8
|
-
res = Rack::MockRequest.new(
|
9
|
-
get("/cgi/test")
|
13
|
+
res = Rack::MockRequest.new(file(DOCROOT)).get("/cgi/test")
|
10
14
|
|
11
15
|
res.should.be.ok
|
12
16
|
res.should =~ /ruby/
|
13
17
|
end
|
14
18
|
|
15
19
|
should "set Last-Modified header" do
|
16
|
-
res = Rack::MockRequest.new(
|
17
|
-
get("/cgi/test")
|
20
|
+
res = Rack::MockRequest.new(file(DOCROOT)).get("/cgi/test")
|
18
21
|
|
19
22
|
path = File.join(DOCROOT, "/cgi/test")
|
20
23
|
|
@@ -24,7 +27,7 @@ describe Rack::File do
|
|
24
27
|
|
25
28
|
should "return 304 if file isn't modified since last serve" do
|
26
29
|
path = File.join(DOCROOT, "/cgi/test")
|
27
|
-
res = Rack::MockRequest.new(
|
30
|
+
res = Rack::MockRequest.new(file(DOCROOT)).
|
28
31
|
get("/cgi/test", 'HTTP_IF_MODIFIED_SINCE' => File.mtime(path).httpdate)
|
29
32
|
|
30
33
|
res.status.should.equal 304
|
@@ -33,22 +36,21 @@ describe Rack::File do
|
|
33
36
|
|
34
37
|
should "return the file if it's modified since last serve" do
|
35
38
|
path = File.join(DOCROOT, "/cgi/test")
|
36
|
-
res = Rack::MockRequest.new(
|
39
|
+
res = Rack::MockRequest.new(file(DOCROOT)).
|
37
40
|
get("/cgi/test", 'HTTP_IF_MODIFIED_SINCE' => (File.mtime(path) - 100).httpdate)
|
38
41
|
|
39
42
|
res.should.be.ok
|
40
43
|
end
|
41
44
|
|
42
45
|
should "serve files with URL encoded filenames" do
|
43
|
-
res = Rack::MockRequest.new(
|
44
|
-
get("/cgi/%74%65%73%74") # "/cgi/test"
|
46
|
+
res = Rack::MockRequest.new(file(DOCROOT)).get("/cgi/%74%65%73%74") # "/cgi/test"
|
45
47
|
|
46
48
|
res.should.be.ok
|
47
49
|
res.should =~ /ruby/
|
48
50
|
end
|
49
51
|
|
50
52
|
should "allow safe directory traversal" do
|
51
|
-
req = Rack::MockRequest.new(
|
53
|
+
req = Rack::MockRequest.new(file(DOCROOT))
|
52
54
|
|
53
55
|
res = req.get('/cgi/../cgi/test')
|
54
56
|
res.should.be.successful
|
@@ -61,7 +63,7 @@ describe Rack::File do
|
|
61
63
|
end
|
62
64
|
|
63
65
|
should "not allow unsafe directory traversal" do
|
64
|
-
req = Rack::MockRequest.new(
|
66
|
+
req = Rack::MockRequest.new(file(DOCROOT))
|
65
67
|
|
66
68
|
res = req.get("/../README")
|
67
69
|
res.should.be.client_error
|
@@ -76,7 +78,7 @@ describe Rack::File do
|
|
76
78
|
end
|
77
79
|
|
78
80
|
should "allow files with .. in their name" do
|
79
|
-
req = Rack::MockRequest.new(
|
81
|
+
req = Rack::MockRequest.new(file(DOCROOT))
|
80
82
|
res = req.get("/cgi/..test")
|
81
83
|
res.should.be.not_found
|
82
84
|
|
@@ -88,30 +90,26 @@ describe Rack::File do
|
|
88
90
|
end
|
89
91
|
|
90
92
|
should "not allow unsafe directory traversal with encoded periods" do
|
91
|
-
res = Rack::MockRequest.new(
|
92
|
-
get("/%2E%2E/README")
|
93
|
+
res = Rack::MockRequest.new(file(DOCROOT)).get("/%2E%2E/README")
|
93
94
|
|
94
95
|
res.should.be.client_error?
|
95
96
|
res.should.be.not_found
|
96
97
|
end
|
97
98
|
|
98
99
|
should "allow safe directory traversal with encoded periods" do
|
99
|
-
res = Rack::MockRequest.new(
|
100
|
-
get("/cgi/%2E%2E/cgi/test")
|
100
|
+
res = Rack::MockRequest.new(file(DOCROOT)).get("/cgi/%2E%2E/cgi/test")
|
101
101
|
|
102
102
|
res.should.be.successful
|
103
103
|
end
|
104
104
|
|
105
105
|
should "404 if it can't find the file" do
|
106
|
-
res = Rack::MockRequest.new(
|
107
|
-
get("/cgi/blubb")
|
106
|
+
res = Rack::MockRequest.new(file(DOCROOT)).get("/cgi/blubb")
|
108
107
|
|
109
108
|
res.should.be.not_found
|
110
109
|
end
|
111
110
|
|
112
111
|
should "detect SystemCallErrors" do
|
113
|
-
res = Rack::MockRequest.new(
|
114
|
-
get("/cgi")
|
112
|
+
res = Rack::MockRequest.new(file(DOCROOT)).get("/cgi")
|
115
113
|
|
116
114
|
res.should.be.not_found
|
117
115
|
end
|
@@ -130,7 +128,7 @@ describe Rack::File do
|
|
130
128
|
should "return correct byte range in body" do
|
131
129
|
env = Rack::MockRequest.env_for("/cgi/test")
|
132
130
|
env["HTTP_RANGE"] = "bytes=22-33"
|
133
|
-
res = Rack::MockResponse.new(*
|
131
|
+
res = Rack::MockResponse.new(*file(DOCROOT).call(env))
|
134
132
|
|
135
133
|
res.status.should.equal 206
|
136
134
|
res["Content-Length"].should.equal "12"
|
@@ -141,24 +139,43 @@ describe Rack::File do
|
|
141
139
|
should "return error for unsatisfiable byte range" do
|
142
140
|
env = Rack::MockRequest.env_for("/cgi/test")
|
143
141
|
env["HTTP_RANGE"] = "bytes=1234-5678"
|
144
|
-
res = Rack::MockResponse.new(*
|
142
|
+
res = Rack::MockResponse.new(*file(DOCROOT).call(env))
|
145
143
|
|
146
144
|
res.status.should.equal 416
|
147
145
|
res["Content-Range"].should.equal "bytes */193"
|
148
146
|
end
|
149
147
|
|
150
|
-
should "support cache control options" do
|
148
|
+
should "support legacy cache control options provided as string" do
|
151
149
|
env = Rack::MockRequest.env_for("/cgi/test")
|
152
|
-
status, heads, _ =
|
150
|
+
status, heads, _ = file(DOCROOT, 'public, max-age=38').call(env)
|
153
151
|
|
154
152
|
status.should.equal 200
|
155
153
|
heads['Cache-Control'].should.equal 'public, max-age=38'
|
156
154
|
end
|
157
155
|
|
156
|
+
should "support custom http headers" do
|
157
|
+
env = Rack::MockRequest.env_for("/cgi/test")
|
158
|
+
status, heads, _ = file(DOCROOT, 'Cache-Control' => 'public, max-age=38',
|
159
|
+
'Access-Control-Allow-Origin' => '*').call(env)
|
160
|
+
|
161
|
+
status.should.equal 200
|
162
|
+
heads['Cache-Control'].should.equal 'public, max-age=38'
|
163
|
+
heads['Access-Control-Allow-Origin'].should.equal '*'
|
164
|
+
end
|
165
|
+
|
166
|
+
should "support not add custom http headers if none are supplied" do
|
167
|
+
env = Rack::MockRequest.env_for("/cgi/test")
|
168
|
+
status, heads, _ = file(DOCROOT).call(env)
|
169
|
+
|
170
|
+
status.should.equal 200
|
171
|
+
heads['Cache-Control'].should.equal nil
|
172
|
+
heads['Access-Control-Allow-Origin'].should.equal nil
|
173
|
+
end
|
174
|
+
|
158
175
|
should "only support GET and HEAD requests" do
|
159
|
-
req = Rack::MockRequest.new(
|
176
|
+
req = Rack::MockRequest.new(file(DOCROOT))
|
160
177
|
|
161
|
-
forbidden = %w[post put delete]
|
178
|
+
forbidden = %w[post put patch delete]
|
162
179
|
forbidden.each do |method|
|
163
180
|
|
164
181
|
res = req.send(method, "/cgi/test")
|
data/test/spec_head.rb
CHANGED
@@ -1,30 +1,48 @@
|
|
1
|
+
require 'enumerator'
|
1
2
|
require 'rack/head'
|
3
|
+
require 'rack/lint'
|
2
4
|
require 'rack/mock'
|
3
5
|
|
4
6
|
describe Rack::Head do
|
7
|
+
|
5
8
|
def test_response(headers = {})
|
6
|
-
|
9
|
+
body = StringIO.new "foo"
|
10
|
+
app = lambda do |env|
|
11
|
+
[200, {"Content-type" => "test/plain", "Content-length" => "3"}, body]
|
12
|
+
end
|
7
13
|
request = Rack::MockRequest.env_for("/", headers)
|
8
|
-
response = Rack::Head.new(app).call(request)
|
14
|
+
response = Rack::Lint.new(Rack::Head.new(app)).call(request)
|
15
|
+
|
16
|
+
return response, body
|
17
|
+
end
|
9
18
|
|
10
|
-
|
19
|
+
def enum
|
20
|
+
defined?(Enumerator) ? Enumerator : Enumerable::Enumerator
|
11
21
|
end
|
12
22
|
|
13
23
|
should "pass GET, POST, PUT, DELETE, OPTIONS, TRACE requests" do
|
14
24
|
%w[GET POST PUT DELETE OPTIONS TRACE].each do |type|
|
15
|
-
resp = test_response("REQUEST_METHOD" => type)
|
25
|
+
resp, _ = test_response("REQUEST_METHOD" => type)
|
16
26
|
|
17
27
|
resp[0].should.equal(200)
|
18
28
|
resp[1].should.equal({"Content-type" => "test/plain", "Content-length" => "3"})
|
19
|
-
resp[2].should.equal(["foo"])
|
29
|
+
enum.new(resp[2]).to_a.should.equal(["foo"])
|
20
30
|
end
|
21
31
|
end
|
22
32
|
|
23
33
|
should "remove body from HEAD requests" do
|
24
|
-
resp = test_response("REQUEST_METHOD" => "HEAD")
|
34
|
+
resp, _ = test_response("REQUEST_METHOD" => "HEAD")
|
35
|
+
|
36
|
+
resp[0].should.equal(200)
|
37
|
+
resp[1].should.equal({"Content-type" => "test/plain", "Content-length" => "3"})
|
38
|
+
enum.new(resp[2]).to_a.should.equal([])
|
39
|
+
end
|
25
40
|
|
41
|
+
should "close the body when it is removed" do
|
42
|
+
resp, body = test_response("REQUEST_METHOD" => "HEAD")
|
26
43
|
resp[0].should.equal(200)
|
27
44
|
resp[1].should.equal({"Content-type" => "test/plain", "Content-length" => "3"})
|
28
|
-
resp[2].should.equal([])
|
45
|
+
enum.new(resp[2]).to_a.should.equal([])
|
46
|
+
body.should.be.closed
|
29
47
|
end
|
30
48
|
end
|
data/test/spec_lobster.rb
CHANGED
@@ -1,28 +1,43 @@
|
|
1
1
|
require 'rack/lobster'
|
2
|
+
require 'rack/lint'
|
2
3
|
require 'rack/mock'
|
3
4
|
|
5
|
+
module LobsterHelpers
|
6
|
+
def lobster
|
7
|
+
Rack::MockRequest.new Rack::Lint.new(Rack::Lobster.new)
|
8
|
+
end
|
9
|
+
|
10
|
+
def lambda_lobster
|
11
|
+
Rack::MockRequest.new Rack::Lint.new(Rack::Lobster::LambdaLobster)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
4
15
|
describe Rack::Lobster::LambdaLobster do
|
16
|
+
extend LobsterHelpers
|
17
|
+
|
5
18
|
should "be a single lambda" do
|
6
19
|
Rack::Lobster::LambdaLobster.should.be.kind_of Proc
|
7
20
|
end
|
8
21
|
|
9
22
|
should "look like a lobster" do
|
10
|
-
res =
|
23
|
+
res = lambda_lobster.get("/")
|
11
24
|
res.should.be.ok
|
12
25
|
res.body.should.include "(,(,,(,,,("
|
13
26
|
res.body.should.include "?flip"
|
14
27
|
end
|
15
28
|
|
16
29
|
should "be flippable" do
|
17
|
-
res =
|
30
|
+
res = lambda_lobster.get("/?flip")
|
18
31
|
res.should.be.ok
|
19
32
|
res.body.should.include "(,,,(,,(,("
|
20
33
|
end
|
21
34
|
end
|
22
35
|
|
23
36
|
describe Rack::Lobster do
|
37
|
+
extend LobsterHelpers
|
38
|
+
|
24
39
|
should "look like a lobster" do
|
25
|
-
res =
|
40
|
+
res = lobster.get("/")
|
26
41
|
res.should.be.ok
|
27
42
|
res.body.should.include "(,(,,(,,,("
|
28
43
|
res.body.should.include "?flip"
|
@@ -30,14 +45,14 @@ describe Rack::Lobster do
|
|
30
45
|
end
|
31
46
|
|
32
47
|
should "be flippable" do
|
33
|
-
res =
|
48
|
+
res = lobster.get("/?flip=left")
|
34
49
|
res.should.be.ok
|
35
50
|
res.body.should.include "(,,,(,,(,("
|
36
51
|
end
|
37
52
|
|
38
53
|
should "provide crashing for testing purposes" do
|
39
54
|
lambda {
|
40
|
-
|
55
|
+
lobster.get("/?flip=crash")
|
41
56
|
}.should.raise
|
42
57
|
end
|
43
58
|
end
|
data/test/spec_lock.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'enumerator'
|
2
|
+
require 'rack/lint'
|
1
3
|
require 'rack/lock'
|
2
4
|
require 'rack/mock'
|
3
5
|
|
@@ -22,10 +24,26 @@ class Lock
|
|
22
24
|
end
|
23
25
|
end
|
24
26
|
|
27
|
+
module LockHelpers
|
28
|
+
def lock_app(app, lock = Lock.new)
|
29
|
+
app = if lock
|
30
|
+
Rack::Lock.new app, lock
|
31
|
+
else
|
32
|
+
Rack::Lock.new app
|
33
|
+
end
|
34
|
+
Rack::Lint.new app
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
25
38
|
describe Rack::Lock do
|
39
|
+
::Enumerator = ::Enumerable::Enumerator unless Object.const_defined?(:Enumerator)
|
40
|
+
|
41
|
+
extend LockHelpers
|
42
|
+
|
26
43
|
describe 'Proxy' do
|
44
|
+
extend LockHelpers
|
45
|
+
|
27
46
|
should 'delegate each' do
|
28
|
-
lock = Lock.new
|
29
47
|
env = Rack::MockRequest.env_for("/")
|
30
48
|
response = Class.new {
|
31
49
|
attr_accessor :close_called
|
@@ -33,7 +51,7 @@ describe Rack::Lock do
|
|
33
51
|
def each; %w{ hi mom }.each { |x| yield x }; end
|
34
52
|
}.new
|
35
53
|
|
36
|
-
app =
|
54
|
+
app = lock_app(lambda { |inner_env| [200, {"Content-Type" => "text/plain"}, response] })
|
37
55
|
response = app.call(env)[2]
|
38
56
|
list = []
|
39
57
|
response.each { |x| list << x }
|
@@ -47,7 +65,7 @@ describe Rack::Lock do
|
|
47
65
|
res = ['Hello World']
|
48
66
|
def res.to_path ; "/tmp/hello.txt" ; end
|
49
67
|
|
50
|
-
app = Rack::Lock.new(lambda { |inner_env| [200, {}, res] }, lock)
|
68
|
+
app = Rack::Lock.new(lambda { |inner_env| [200, {"Content-Type" => "text/plain"}, res] }, lock)
|
51
69
|
body = app.call(env)[2]
|
52
70
|
|
53
71
|
body.should.respond_to :to_path
|
@@ -55,12 +73,11 @@ describe Rack::Lock do
|
|
55
73
|
end
|
56
74
|
|
57
75
|
should 'not delegate to_path if body does not implement it' do
|
58
|
-
lock = Lock.new
|
59
76
|
env = Rack::MockRequest.env_for("/")
|
60
77
|
|
61
78
|
res = ['Hello World']
|
62
79
|
|
63
|
-
app =
|
80
|
+
app = lock_app(lambda { |inner_env| [200, {"Content-Type" => "text/plain"}, res] })
|
64
81
|
body = app.call(env)[2]
|
65
82
|
|
66
83
|
body.should.not.respond_to :to_path
|
@@ -68,7 +85,6 @@ describe Rack::Lock do
|
|
68
85
|
end
|
69
86
|
|
70
87
|
should 'call super on close' do
|
71
|
-
lock = Lock.new
|
72
88
|
env = Rack::MockRequest.env_for("/")
|
73
89
|
response = Class.new {
|
74
90
|
attr_accessor :close_called
|
@@ -76,7 +92,7 @@ describe Rack::Lock do
|
|
76
92
|
def close; @close_called = true; end
|
77
93
|
}.new
|
78
94
|
|
79
|
-
app =
|
95
|
+
app = lock_app(lambda { |inner_env| [200, {"Content-Type" => "text/plain"}, response] })
|
80
96
|
app.call(env)
|
81
97
|
response.close_called.should.equal false
|
82
98
|
response.close
|
@@ -87,7 +103,7 @@ describe Rack::Lock do
|
|
87
103
|
lock = Lock.new
|
88
104
|
env = Rack::MockRequest.env_for("/")
|
89
105
|
response = Object.new
|
90
|
-
app =
|
106
|
+
app = lock_app(lambda { |inner_env| [200, {"Content-Type" => "text/plain"}, response] }, lock)
|
91
107
|
lock.synchronized.should.equal false
|
92
108
|
response = app.call(env)[2]
|
93
109
|
lock.synchronized.should.equal true
|
@@ -96,19 +112,20 @@ describe Rack::Lock do
|
|
96
112
|
end
|
97
113
|
|
98
114
|
should "return value from app" do
|
99
|
-
lock = Lock.new
|
100
115
|
env = Rack::MockRequest.env_for("/")
|
101
|
-
body = [200, {}, %w{ hi mom }]
|
102
|
-
app =
|
103
|
-
|
116
|
+
body = [200, {"Content-Type" => "text/plain"}, %w{ hi mom }]
|
117
|
+
app = lock_app(lambda { |inner_env| body })
|
118
|
+
|
119
|
+
res = app.call(env)
|
120
|
+
res[0].should.equal body[0]
|
121
|
+
res[1].should.equal body[1]
|
122
|
+
Enumerator.new(res[2]).to_a.should.equal ["hi", "mom"]
|
104
123
|
end
|
105
124
|
|
106
125
|
should "call synchronize on lock" do
|
107
126
|
lock = Lock.new
|
108
127
|
env = Rack::MockRequest.env_for("/")
|
109
|
-
app =
|
110
|
-
[200, {}, %w{ a b c }]
|
111
|
-
}, lock)
|
128
|
+
app = lock_app(lambda { |inner_env| [200, {"Content-Type" => "text/plain"}, %w{ a b c }] }, lock)
|
112
129
|
lock.synchronized.should.equal false
|
113
130
|
app.call(env)
|
114
131
|
lock.synchronized.should.equal true
|
@@ -117,16 +134,24 @@ describe Rack::Lock do
|
|
117
134
|
should "unlock if the app raises" do
|
118
135
|
lock = Lock.new
|
119
136
|
env = Rack::MockRequest.env_for("/")
|
120
|
-
app =
|
137
|
+
app = lock_app(lambda { raise Exception }, lock)
|
121
138
|
lambda { app.call(env) }.should.raise(Exception)
|
122
139
|
lock.synchronized.should.equal false
|
123
140
|
end
|
124
141
|
|
142
|
+
should "unlock if the app throws" do
|
143
|
+
lock = Lock.new
|
144
|
+
env = Rack::MockRequest.env_for("/")
|
145
|
+
app = lock_app(lambda {|env| throw :bacon }, lock)
|
146
|
+
lambda { app.call(env) }.should.throw(:bacon)
|
147
|
+
lock.synchronized.should.equal false
|
148
|
+
end
|
149
|
+
|
125
150
|
should "set multithread flag to false" do
|
126
|
-
app =
|
151
|
+
app = lock_app(lambda { |env|
|
127
152
|
env['rack.multithread'].should.equal false
|
128
|
-
[200, {}, %w{ a b c }]
|
129
|
-
})
|
153
|
+
[200, {"Content-Type" => "text/plain"}, %w{ a b c }]
|
154
|
+
}, false)
|
130
155
|
app.call(Rack::MockRequest.env_for("/"))
|
131
156
|
end
|
132
157
|
|
@@ -136,7 +161,7 @@ describe Rack::Lock do
|
|
136
161
|
env['rack.multithread'].should.equal true
|
137
162
|
super
|
138
163
|
end
|
139
|
-
}.new(lambda { |env| [200, {}, %w{ a b c }] })
|
140
|
-
app.call(Rack::MockRequest.env_for("/"))
|
164
|
+
}.new(lambda { |env| [200, {"Content-Type" => "text/plain"}, %w{ a b c }] })
|
165
|
+
Rack::Lint.new(app).call(Rack::MockRequest.env_for("/"))
|
141
166
|
end
|
142
167
|
end
|
data/test/spec_logger.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
require 'stringio'
|
2
|
+
require 'rack/lint'
|
2
3
|
require 'rack/logger'
|
4
|
+
require 'rack/mock'
|
3
5
|
|
4
6
|
describe Rack::Logger do
|
5
7
|
app = lambda { |env|
|
@@ -11,13 +13,6 @@ describe Rack::Logger do
|
|
11
13
|
[200, {'Content-Type' => 'text/plain'}, ["Hello, World!"]]
|
12
14
|
}
|
13
15
|
|
14
|
-
should "log to rack.errors" do
|
15
|
-
errors = StringIO.new
|
16
|
-
Rack::Logger.new(app).call('rack.errors' => errors)
|
17
|
-
errors.string.should.match(/INFO -- : Program started/)
|
18
|
-
errors.string.should.match(/WARN -- : Nothing to do/)
|
19
|
-
end
|
20
|
-
|
21
16
|
should "conform to Rack::Lint" do
|
22
17
|
errors = StringIO.new
|
23
18
|
a = Rack::Lint.new(Rack::Logger.new(app))
|