rack 0.3.0 → 0.4.0
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/AUTHORS +1 -0
- data/RDOX +61 -3
- data/README +94 -9
- data/Rakefile +36 -32
- data/SPEC +1 -7
- data/bin/rackup +31 -13
- data/lib/rack.rb +8 -19
- data/lib/rack/auth/digest/params.rb +2 -2
- data/lib/rack/auth/openid.rb +406 -80
- data/lib/rack/builder.rb +1 -1
- data/lib/rack/cascade.rb +10 -0
- data/lib/rack/commonlogger.rb +6 -1
- data/lib/rack/deflater.rb +63 -0
- data/lib/rack/directory.rb +158 -0
- data/lib/rack/file.rb +11 -5
- data/lib/rack/handler.rb +44 -0
- data/lib/rack/handler/evented_mongrel.rb +8 -0
- data/lib/rack/handler/fastcgi.rb +1 -0
- data/lib/rack/handler/mongrel.rb +21 -1
- data/lib/rack/lint.rb +20 -13
- data/lib/rack/mock.rb +1 -0
- data/lib/rack/request.rb +69 -2
- data/lib/rack/session/abstract/id.rb +140 -0
- data/lib/rack/session/memcache.rb +97 -0
- data/lib/rack/session/pool.rb +50 -59
- data/lib/rack/showstatus.rb +3 -1
- data/lib/rack/urlmap.rb +12 -12
- data/lib/rack/utils.rb +88 -9
- data/test/cgi/lighttpd.conf +1 -1
- data/test/cgi/test.fcgi +1 -2
- data/test/cgi/test.ru +2 -2
- data/test/spec_rack_auth_openid.rb +137 -0
- data/test/spec_rack_camping.rb +37 -33
- data/test/spec_rack_cascade.rb +15 -0
- data/test/spec_rack_cgi.rb +4 -3
- data/test/spec_rack_deflater.rb +70 -0
- data/test/spec_rack_directory.rb +56 -0
- data/test/spec_rack_fastcgi.rb +4 -3
- data/test/spec_rack_file.rb +11 -1
- data/test/spec_rack_handler.rb +24 -0
- data/test/spec_rack_lint.rb +19 -33
- data/test/spec_rack_mongrel.rb +71 -0
- data/test/spec_rack_request.rb +91 -1
- data/test/spec_rack_session_memcache.rb +132 -0
- data/test/spec_rack_session_pool.rb +48 -1
- data/test/spec_rack_showstatus.rb +5 -4
- data/test/spec_rack_urlmap.rb +60 -25
- data/test/spec_rack_utils.rb +118 -1
- data/test/testrequest.rb +3 -1
- metadata +67 -44
data/test/spec_rack_cgi.rb
CHANGED
@@ -12,12 +12,13 @@ context "Rack::Handler::CGI" do
|
|
12
12
|
# Keep this first.
|
13
13
|
specify "startup" do
|
14
14
|
$pid = fork {
|
15
|
-
Dir.chdir
|
15
|
+
Dir.chdir(File.join(File.dirname(__FILE__), "..", "test", "cgi"))
|
16
16
|
exec "lighttpd -D -f lighttpd.conf"
|
17
17
|
}
|
18
18
|
end
|
19
19
|
|
20
20
|
specify "should respond" do
|
21
|
+
sleep 1
|
21
22
|
lambda {
|
22
23
|
GET("/test")
|
23
24
|
}.should.not.raise
|
@@ -29,8 +30,8 @@ context "Rack::Handler::CGI" do
|
|
29
30
|
response["SERVER_SOFTWARE"].should =~ /lighttpd/
|
30
31
|
response["HTTP_VERSION"].should.equal "HTTP/1.1"
|
31
32
|
response["SERVER_PROTOCOL"].should.equal "HTTP/1.1"
|
32
|
-
response["SERVER_PORT"].should.equal
|
33
|
-
response["SERVER_NAME"].should =~
|
33
|
+
response["SERVER_PORT"].should.equal @port.to_s
|
34
|
+
response["SERVER_NAME"].should =~ @host
|
34
35
|
end
|
35
36
|
|
36
37
|
specify "should have rack headers" do
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'test/spec'
|
2
|
+
|
3
|
+
require 'rack/mock'
|
4
|
+
require 'rack/deflater'
|
5
|
+
require 'stringio'
|
6
|
+
|
7
|
+
context "Rack::Deflater" do
|
8
|
+
def build_response(body, accept_encoding, headers = {})
|
9
|
+
app = lambda { |env| [200, {}, body] }
|
10
|
+
request = Rack::MockRequest.env_for("", headers.merge("HTTP_ACCEPT_ENCODING" => accept_encoding))
|
11
|
+
response = Rack::Deflater.new(app).call(request)
|
12
|
+
|
13
|
+
return response
|
14
|
+
end
|
15
|
+
|
16
|
+
specify "should be able to deflate bodies that respond to each" do
|
17
|
+
body = Object.new
|
18
|
+
class << body; def each; yield("foo"); yield("bar"); end; end
|
19
|
+
|
20
|
+
response = build_response(body, "deflate")
|
21
|
+
|
22
|
+
response[0].should.equal(200)
|
23
|
+
response[1].should.equal({ "Content-Encoding" => "deflate" })
|
24
|
+
response[2].to_s.should.equal("K\313\317OJ,\002\000")
|
25
|
+
end
|
26
|
+
|
27
|
+
# TODO: This is really just a special case of the above...
|
28
|
+
specify "should be able to deflate String bodies" do
|
29
|
+
response = build_response("Hello world!", "deflate")
|
30
|
+
|
31
|
+
response[0].should.equal(200)
|
32
|
+
response[1].should.equal({ "Content-Encoding" => "deflate" })
|
33
|
+
response[2].to_s.should.equal("\363H\315\311\311W(\317/\312IQ\004\000")
|
34
|
+
end
|
35
|
+
|
36
|
+
specify "should be able to gzip bodies that respond to each" do
|
37
|
+
body = Object.new
|
38
|
+
class << body; def each; yield("foo"); yield("bar"); end; end
|
39
|
+
|
40
|
+
response = build_response(body, "gzip")
|
41
|
+
|
42
|
+
response[0].should.equal(200)
|
43
|
+
response[1].should.equal({ "Content-Encoding" => "gzip" })
|
44
|
+
|
45
|
+
io = StringIO.new(response[2].to_s)
|
46
|
+
gz = Zlib::GzipReader.new(io)
|
47
|
+
gz.read.should.equal("foobar")
|
48
|
+
gz.close
|
49
|
+
end
|
50
|
+
|
51
|
+
specify "should be able to fallback to no deflation" do
|
52
|
+
response = build_response("Hello world!", "superzip")
|
53
|
+
|
54
|
+
response[0].should.equal(200)
|
55
|
+
response[1].should.equal({})
|
56
|
+
response[2].should.equal("Hello world!")
|
57
|
+
end
|
58
|
+
|
59
|
+
specify "should handle the lack of an acceptable encoding" do
|
60
|
+
response1 = build_response("Hello world!", "identity;q=0", "PATH_INFO" => "/")
|
61
|
+
response1[0].should.equal(406)
|
62
|
+
response1[1].should.equal({"Content-Type" => "text/plain"})
|
63
|
+
response1[2].should.equal("An acceptable encoding for the requested resource / could not be found.")
|
64
|
+
|
65
|
+
response2 = build_response("Hello world!", "identity;q=0", "SCRIPT_NAME" => "/foo", "PATH_INFO" => "/bar")
|
66
|
+
response2[0].should.equal(406)
|
67
|
+
response2[1].should.equal({"Content-Type" => "text/plain"})
|
68
|
+
response2[2].should.equal("An acceptable encoding for the requested resource /foo/bar could not be found.")
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'test/spec'
|
2
|
+
|
3
|
+
require 'rack/directory'
|
4
|
+
require 'rack/lint'
|
5
|
+
|
6
|
+
require 'rack/mock'
|
7
|
+
|
8
|
+
context "Rack::Directory" do
|
9
|
+
DOCROOT = File.expand_path(File.dirname(__FILE__))
|
10
|
+
FILE_CATCH = proc{|env| [200, {'Content-Type'=>'text/plain', "Content-Length" => "7"}, 'passed!'] }
|
11
|
+
app = Rack::Directory.new DOCROOT, FILE_CATCH
|
12
|
+
|
13
|
+
specify "serves directory indices" do
|
14
|
+
res = Rack::MockRequest.new(Rack::Lint.new(app)).
|
15
|
+
get("/cgi/")
|
16
|
+
|
17
|
+
res.should.be.ok
|
18
|
+
res.should =~ /<html><head>/
|
19
|
+
end
|
20
|
+
|
21
|
+
specify "passes to app if file found" do
|
22
|
+
res = Rack::MockRequest.new(Rack::Lint.new(app)).
|
23
|
+
get("/cgi/test")
|
24
|
+
|
25
|
+
res.should.be.ok
|
26
|
+
res.should =~ /passed!/
|
27
|
+
end
|
28
|
+
|
29
|
+
specify "serves uri with URL encoded filenames" do
|
30
|
+
res = Rack::MockRequest.new(Rack::Lint.new(app)).
|
31
|
+
get("/%63%67%69/") # "/cgi/test"
|
32
|
+
|
33
|
+
res.should.be.ok
|
34
|
+
res.should =~ /<html><head>/
|
35
|
+
|
36
|
+
res = Rack::MockRequest.new(Rack::Lint.new(app)).
|
37
|
+
get("/cgi/%74%65%73%74") # "/cgi/test"
|
38
|
+
|
39
|
+
res.should.be.ok
|
40
|
+
res.should =~ /passed!/
|
41
|
+
end
|
42
|
+
|
43
|
+
specify "does not allow directory traversal" do
|
44
|
+
res = Rack::MockRequest.new(Rack::Lint.new(app)).
|
45
|
+
get("/cgi/../test")
|
46
|
+
|
47
|
+
res.should.be.forbidden
|
48
|
+
end
|
49
|
+
|
50
|
+
specify "404s if it can't find the file" do
|
51
|
+
res = Rack::MockRequest.new(Rack::Lint.new(app)).
|
52
|
+
get("/cgi/blubb")
|
53
|
+
|
54
|
+
res.should.be.not_found
|
55
|
+
end
|
56
|
+
end
|
data/test/spec_rack_fastcgi.rb
CHANGED
@@ -12,12 +12,13 @@ context "Rack::Handler::FastCGI" do
|
|
12
12
|
# Keep this first.
|
13
13
|
specify "startup" do
|
14
14
|
$pid = fork {
|
15
|
-
Dir.chdir
|
15
|
+
Dir.chdir(File.join(File.dirname(__FILE__), "..", "test", "cgi"))
|
16
16
|
exec "lighttpd -D -f lighttpd.conf"
|
17
17
|
}
|
18
18
|
end
|
19
19
|
|
20
20
|
specify "should respond" do
|
21
|
+
sleep 1
|
21
22
|
lambda {
|
22
23
|
GET("/test.fcgi")
|
23
24
|
}.should.not.raise
|
@@ -29,8 +30,8 @@ context "Rack::Handler::FastCGI" do
|
|
29
30
|
response["SERVER_SOFTWARE"].should =~ /lighttpd/
|
30
31
|
response["HTTP_VERSION"].should.equal "HTTP/1.1"
|
31
32
|
response["SERVER_PROTOCOL"].should.equal "HTTP/1.1"
|
32
|
-
response["SERVER_PORT"].should.equal
|
33
|
-
response["SERVER_NAME"].should =~
|
33
|
+
response["SERVER_PORT"].should.equal @port.to_s
|
34
|
+
response["SERVER_NAME"].should =~ @host
|
34
35
|
end
|
35
36
|
|
36
37
|
specify "should have rack headers" do
|
data/test/spec_rack_file.rb
CHANGED
@@ -15,7 +15,17 @@ context "Rack::File" do
|
|
15
15
|
res.should.be.ok
|
16
16
|
res.should =~ /ruby/
|
17
17
|
end
|
18
|
-
|
18
|
+
|
19
|
+
specify "sets Last-Modified header" do
|
20
|
+
res = Rack::MockRequest.new(Rack::Lint.new(Rack::File.new(DOCROOT))).
|
21
|
+
get("/cgi/test")
|
22
|
+
|
23
|
+
path = File.join(DOCROOT, "/cgi/test")
|
24
|
+
|
25
|
+
res.should.be.ok
|
26
|
+
res["Last-Modified"].should.equal File.mtime(path).httpdate
|
27
|
+
end
|
28
|
+
|
19
29
|
specify "serves files with URL encoded filenames" do
|
20
30
|
res = Rack::MockRequest.new(Rack::Lint.new(Rack::File.new(DOCROOT))).
|
21
31
|
get("/cgi/%74%65%73%74") # "/cgi/test"
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'test/spec'
|
2
|
+
|
3
|
+
require 'rack/handler'
|
4
|
+
|
5
|
+
context "Rack::Handler" do
|
6
|
+
class Rack::Handler::Lobster; end
|
7
|
+
class RockLobster; end
|
8
|
+
|
9
|
+
specify "has registered default handlers" do
|
10
|
+
Rack::Handler.get('cgi').should.equal Rack::Handler::CGI
|
11
|
+
Rack::Handler.get('fastcgi').should.equal Rack::Handler::FastCGI
|
12
|
+
Rack::Handler.get('mongrel').should.equal Rack::Handler::Mongrel
|
13
|
+
Rack::Handler.get('webrick').should.equal Rack::Handler::WEBrick
|
14
|
+
end
|
15
|
+
|
16
|
+
specify "should get unregistered handler by name" do
|
17
|
+
Rack::Handler.get('lobster').should.equal Rack::Handler::Lobster
|
18
|
+
end
|
19
|
+
|
20
|
+
specify "should register custom handler" do
|
21
|
+
Rack::Handler.register('rock_lobster', 'RockLobster')
|
22
|
+
Rack::Handler.get('rock_lobster').should.equal RockLobster
|
23
|
+
end
|
24
|
+
end
|
data/test/spec_rack_lint.rb
CHANGED
@@ -8,11 +8,11 @@ context "Rack::Lint" do
|
|
8
8
|
def env(*args)
|
9
9
|
Rack::MockRequest.env_for("/", *args)
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
12
|
specify "passes valid request" do
|
13
13
|
lambda {
|
14
14
|
Rack::Lint.new(lambda { |env|
|
15
|
-
[200, {"Content-type" => "test/plain"}, "foo"]
|
15
|
+
[200, {"Content-type" => "test/plain", "Content-length" => "3"}, "foo"]
|
16
16
|
}).call(env({}))
|
17
17
|
}.should.not.raise
|
18
18
|
end
|
@@ -120,14 +120,14 @@ context "Rack::Lint" do
|
|
120
120
|
["cc", {}, ""]
|
121
121
|
}).call(env({}))
|
122
122
|
}.should.raise(Rack::Lint::LintError).
|
123
|
-
message.should.match(/must be
|
123
|
+
message.should.match(/must be >=100 seen as integer/)
|
124
124
|
|
125
125
|
lambda {
|
126
126
|
Rack::Lint.new(lambda { |env|
|
127
127
|
[42, {}, ""]
|
128
128
|
}).call(env({}))
|
129
129
|
}.should.raise(Rack::Lint::LintError).
|
130
|
-
message.should.match(/must be
|
130
|
+
message.should.match(/must be >=100 seen as integer/)
|
131
131
|
end
|
132
132
|
|
133
133
|
specify "notices header errors" do
|
@@ -136,14 +136,14 @@ context "Rack::Lint" do
|
|
136
136
|
[200, Object.new, ""]
|
137
137
|
}).call(env({}))
|
138
138
|
}.should.raise(Rack::Lint::LintError).
|
139
|
-
message.should.
|
139
|
+
message.should.equal("headers object should respond to #each, but doesn't (got Object as headers)")
|
140
140
|
|
141
141
|
lambda {
|
142
142
|
Rack::Lint.new(lambda { |env|
|
143
143
|
[200, {true=>false}, ""]
|
144
144
|
}).call(env({}))
|
145
145
|
}.should.raise(Rack::Lint::LintError).
|
146
|
-
message.should.
|
146
|
+
message.should.equal("header key must be a string, was TrueClass")
|
147
147
|
|
148
148
|
lambda {
|
149
149
|
Rack::Lint.new(lambda { |env|
|
@@ -171,21 +171,21 @@ context "Rack::Lint" do
|
|
171
171
|
[200, {"..%%quark%%.." => "text/plain"}, ""]
|
172
172
|
}).call(env({}))
|
173
173
|
}.should.raise(Rack::Lint::LintError).
|
174
|
-
message.should.
|
174
|
+
message.should.equal("invalid header name: ..%%quark%%..")
|
175
175
|
|
176
176
|
lambda {
|
177
177
|
Rack::Lint.new(lambda { |env|
|
178
178
|
[200, {"Foo" => Object.new}, ""]
|
179
179
|
}).call(env({}))
|
180
180
|
}.should.raise(Rack::Lint::LintError).
|
181
|
-
message.should.
|
181
|
+
message.should.equal("header values must respond to #each, but the value of 'Foo' doesn't (is Object)")
|
182
182
|
|
183
183
|
lambda {
|
184
184
|
Rack::Lint.new(lambda { |env|
|
185
185
|
[200, {"Foo" => [1,2,3]}, ""]
|
186
186
|
}).call(env({}))
|
187
187
|
}.should.raise(Rack::Lint::LintError).
|
188
|
-
message.should.
|
188
|
+
message.should.equal("header values must consist of Strings, but 'Foo' also contains a Fixnum")
|
189
189
|
|
190
190
|
|
191
191
|
lambda {
|
@@ -199,30 +199,16 @@ context "Rack::Lint" do
|
|
199
199
|
specify "notices content-type errors" do
|
200
200
|
lambda {
|
201
201
|
Rack::Lint.new(lambda { |env|
|
202
|
-
[200, {}, ""]
|
202
|
+
[200, {"Content-length" => "0"}, ""]
|
203
203
|
}).call(env({}))
|
204
204
|
}.should.raise(Rack::Lint::LintError).
|
205
205
|
message.should.match(/No Content-Type/)
|
206
|
-
|
207
|
-
lambda {
|
208
|
-
Rack::Lint.new(lambda { |env|
|
209
|
-
[204, {"Content-Type" => "text/plain"}, ""]
|
210
|
-
}).call(env({}))
|
211
|
-
}.should.raise(Rack::Lint::LintError).
|
212
|
-
message.should.match(/Content-Type header found/)
|
213
|
-
|
214
|
-
lambda {
|
215
|
-
Rack::Lint.new(lambda { |env|
|
216
|
-
[204, {"Content-type" => "text/plain"}, ""]
|
217
|
-
}).call(env({}))
|
218
|
-
}.should.raise(Rack::Lint::LintError).
|
219
|
-
message.should.match(/Content-Type header found/)
|
220
206
|
end
|
221
207
|
|
222
208
|
specify "notices body errors" do
|
223
209
|
lambda {
|
224
210
|
status, header, body = Rack::Lint.new(lambda { |env|
|
225
|
-
[200, {"Content-type" => "text/plain"}, [1,2,3]]
|
211
|
+
[200, {"Content-type" => "text/plain","Content-length" => "3"}, [1,2,3]]
|
226
212
|
}).call(env({}))
|
227
213
|
body.each { |part| }
|
228
214
|
}.should.raise(Rack::Lint::LintError).
|
@@ -233,7 +219,7 @@ context "Rack::Lint" do
|
|
233
219
|
lambda {
|
234
220
|
Rack::Lint.new(lambda { |env|
|
235
221
|
env["rack.input"].gets("\r\n")
|
236
|
-
[201, {"Content-type" => "text/plain"}, ""]
|
222
|
+
[201, {"Content-type" => "text/plain", "Content-length" => "0"}, ""]
|
237
223
|
}).call(env({}))
|
238
224
|
}.should.raise(Rack::Lint::LintError).
|
239
225
|
message.should.match(/gets called with arguments/)
|
@@ -241,7 +227,7 @@ context "Rack::Lint" do
|
|
241
227
|
lambda {
|
242
228
|
Rack::Lint.new(lambda { |env|
|
243
229
|
env["rack.input"].read("foo")
|
244
|
-
[201, {"Content-type" => "text/plain"}, ""]
|
230
|
+
[201, {"Content-type" => "text/plain", "Content-length" => "0"}, ""]
|
245
231
|
}).call(env({}))
|
246
232
|
}.should.raise(Rack::Lint::LintError).
|
247
233
|
message.should.match(/read called with non-integer argument/)
|
@@ -265,7 +251,7 @@ context "Rack::Lint" do
|
|
265
251
|
lambda {
|
266
252
|
Rack::Lint.new(lambda { |env|
|
267
253
|
env["rack.input"].gets
|
268
|
-
[201, {"Content-type" => "text/plain"}, ""]
|
254
|
+
[201, {"Content-type" => "text/plain", "Content-length" => "0"}, ""]
|
269
255
|
}).call(env("rack.input" => weirdio))
|
270
256
|
}.should.raise(Rack::Lint::LintError).
|
271
257
|
message.should.match(/gets didn't return a String/)
|
@@ -273,7 +259,7 @@ context "Rack::Lint" do
|
|
273
259
|
lambda {
|
274
260
|
Rack::Lint.new(lambda { |env|
|
275
261
|
env["rack.input"].each { |x| }
|
276
|
-
[201, {"Content-type" => "text/plain"}, ""]
|
262
|
+
[201, {"Content-type" => "text/plain", "Content-length" => "0"}, ""]
|
277
263
|
}).call(env("rack.input" => weirdio))
|
278
264
|
}.should.raise(Rack::Lint::LintError).
|
279
265
|
message.should.match(/each didn't yield a String/)
|
@@ -281,7 +267,7 @@ context "Rack::Lint" do
|
|
281
267
|
lambda {
|
282
268
|
Rack::Lint.new(lambda { |env|
|
283
269
|
env["rack.input"].read
|
284
|
-
[201, {"Content-type" => "text/plain"}, ""]
|
270
|
+
[201, {"Content-type" => "text/plain", "Content-length" => "0"}, ""]
|
285
271
|
}).call(env("rack.input" => weirdio))
|
286
272
|
}.should.raise(Rack::Lint::LintError).
|
287
273
|
message.should.match(/read didn't return a String/)
|
@@ -290,7 +276,7 @@ context "Rack::Lint" do
|
|
290
276
|
lambda {
|
291
277
|
Rack::Lint.new(lambda { |env|
|
292
278
|
env["rack.input"].close
|
293
|
-
[201, {"Content-type" => "text/plain"}, ""]
|
279
|
+
[201, {"Content-type" => "text/plain", "Content-length" => "0"}, ""]
|
294
280
|
}).call(env({}))
|
295
281
|
}.should.raise(Rack::Lint::LintError).
|
296
282
|
message.should.match(/close must not be called/)
|
@@ -300,7 +286,7 @@ context "Rack::Lint" do
|
|
300
286
|
lambda {
|
301
287
|
Rack::Lint.new(lambda { |env|
|
302
288
|
env["rack.errors"].write(42)
|
303
|
-
[201, {"Content-type" => "text/plain"}, ""]
|
289
|
+
[201, {"Content-type" => "text/plain", "Content-length" => "0"}, ""]
|
304
290
|
}).call(env({}))
|
305
291
|
}.should.raise(Rack::Lint::LintError).
|
306
292
|
message.should.match(/write not called with a String/)
|
@@ -308,7 +294,7 @@ context "Rack::Lint" do
|
|
308
294
|
lambda {
|
309
295
|
Rack::Lint.new(lambda { |env|
|
310
296
|
env["rack.errors"].close
|
311
|
-
[201, {"Content-type" => "text/plain"}, ""]
|
297
|
+
[201, {"Content-type" => "text/plain", "Content-length" => "0"}, ""]
|
312
298
|
}).call(env({}))
|
313
299
|
}.should.raise(Rack::Lint::LintError).
|
314
300
|
message.should.match(/close must not be called/)
|
data/test/spec_rack_mongrel.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'test/spec'
|
2
2
|
|
3
|
+
begin
|
3
4
|
require 'rack/handler/mongrel'
|
5
|
+
require 'rack/urlmap'
|
4
6
|
require 'rack/lint'
|
5
7
|
require 'testrequest'
|
6
8
|
|
@@ -93,7 +95,76 @@ context "Rack::Handler::Mongrel" do
|
|
93
95
|
block_ran.should.be true
|
94
96
|
end
|
95
97
|
|
98
|
+
specify "should provide a .run that maps a hash" do
|
99
|
+
block_ran = false
|
100
|
+
Thread.new {
|
101
|
+
map = {'/'=>lambda{},'/foo'=>lambda{}}
|
102
|
+
Rack::Handler::Mongrel.run(map, :map => true, :Port => 9221) { |server|
|
103
|
+
server.should.be.kind_of Mongrel::HttpServer
|
104
|
+
server.classifier.uris.size.should.be 2
|
105
|
+
server.classifier.uris.should.not.include '/arf'
|
106
|
+
server.classifier.uris.should.include '/'
|
107
|
+
server.classifier.uris.should.include '/foo'
|
108
|
+
block_ran = true
|
109
|
+
}
|
110
|
+
}
|
111
|
+
sleep 1
|
112
|
+
block_ran.should.be true
|
113
|
+
end
|
114
|
+
|
115
|
+
specify "should provide a .run that maps a urlmap" do
|
116
|
+
block_ran = false
|
117
|
+
Thread.new {
|
118
|
+
map = Rack::URLMap.new({'/'=>lambda{},'/bar'=>lambda{}})
|
119
|
+
Rack::Handler::Mongrel.run(map, {:map => true, :Port => 9231}) { |server|
|
120
|
+
server.should.be.kind_of Mongrel::HttpServer
|
121
|
+
server.classifier.uris.size.should.be 2
|
122
|
+
server.classifier.uris.should.not.include '/arf'
|
123
|
+
server.classifier.uris.should.include '/'
|
124
|
+
server.classifier.uris.should.include '/bar'
|
125
|
+
block_ran = true
|
126
|
+
}
|
127
|
+
}
|
128
|
+
sleep 1
|
129
|
+
block_ran.should.be true
|
130
|
+
end
|
131
|
+
|
132
|
+
specify "should provide a .run that maps a urlmap restricting by host" do
|
133
|
+
block_ran = false
|
134
|
+
Thread.new {
|
135
|
+
map = Rack::URLMap.new({
|
136
|
+
'/' => lambda{},
|
137
|
+
'/foo' => lambda{},
|
138
|
+
'/bar' => lambda{},
|
139
|
+
'http://localhost/' => lambda{},
|
140
|
+
'http://localhost/bar' => lambda{},
|
141
|
+
'http://falsehost/arf' => lambda{},
|
142
|
+
'http://falsehost/qux' => lambda{}
|
143
|
+
})
|
144
|
+
opt = {:map => true, :Port => 9241, :Host => 'localhost'}
|
145
|
+
Rack::Handler::Mongrel.run(map, opt) { |server|
|
146
|
+
server.should.be.kind_of Mongrel::HttpServer
|
147
|
+
server.classifier.uris.should.include '/'
|
148
|
+
server.classifier.handler_map['/'].size.should.be 2
|
149
|
+
server.classifier.uris.should.include '/foo'
|
150
|
+
server.classifier.handler_map['/foo'].size.should.be 1
|
151
|
+
server.classifier.uris.should.include '/bar'
|
152
|
+
server.classifier.handler_map['/bar'].size.should.be 2
|
153
|
+
server.classifier.uris.should.not.include '/qux'
|
154
|
+
server.classifier.uris.should.not.include '/arf'
|
155
|
+
server.classifier.uris.size.should.be 3
|
156
|
+
block_ran = true
|
157
|
+
}
|
158
|
+
}
|
159
|
+
sleep 1
|
160
|
+
block_ran.should.be true
|
161
|
+
end
|
162
|
+
|
96
163
|
teardown do
|
97
164
|
@acc.raise Mongrel::StopServer
|
98
165
|
end
|
99
166
|
end
|
167
|
+
|
168
|
+
rescue LoadError
|
169
|
+
$stderr.puts "Skipping Rack::Handler::Mongrel tests (Mongrel is required). `gem install mongrel` and try again."
|
170
|
+
end
|