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_methodoverride.rb
CHANGED
@@ -3,20 +3,24 @@ require 'rack/methodoverride'
|
|
3
3
|
require 'rack/mock'
|
4
4
|
|
5
5
|
describe Rack::MethodOverride do
|
6
|
+
def app
|
7
|
+
Rack::Lint.new(Rack::MethodOverride.new(lambda {|e|
|
8
|
+
[200, {"Content-Type" => "text/plain"}, []]
|
9
|
+
}))
|
10
|
+
end
|
11
|
+
|
6
12
|
should "not affect GET requests" do
|
7
13
|
env = Rack::MockRequest.env_for("/?_method=delete", :method => "GET")
|
8
|
-
app
|
9
|
-
req = app.call(env)
|
14
|
+
app.call env
|
10
15
|
|
11
|
-
|
16
|
+
env["REQUEST_METHOD"].should.equal "GET"
|
12
17
|
end
|
13
18
|
|
14
19
|
should "modify REQUEST_METHOD for POST requests when _method parameter is set" do
|
15
20
|
env = Rack::MockRequest.env_for("/", :method => "POST", :input => "_method=put")
|
16
|
-
app
|
17
|
-
req = app.call(env)
|
21
|
+
app.call env
|
18
22
|
|
19
|
-
|
23
|
+
env["REQUEST_METHOD"].should.equal "PUT"
|
20
24
|
end
|
21
25
|
|
22
26
|
should "modify REQUEST_METHOD for POST requests when X-HTTP-Method-Override is set" do
|
@@ -24,36 +28,32 @@ describe Rack::MethodOverride do
|
|
24
28
|
:method => "POST",
|
25
29
|
"HTTP_X_HTTP_METHOD_OVERRIDE" => "PATCH"
|
26
30
|
)
|
27
|
-
app
|
28
|
-
req = app.call(env)
|
31
|
+
app.call env
|
29
32
|
|
30
|
-
|
33
|
+
env["REQUEST_METHOD"].should.equal "PATCH"
|
31
34
|
end
|
32
35
|
|
33
36
|
should "not modify REQUEST_METHOD if the method is unknown" do
|
34
37
|
env = Rack::MockRequest.env_for("/", :method => "POST", :input => "_method=foo")
|
35
|
-
app
|
36
|
-
req = app.call(env)
|
38
|
+
app.call env
|
37
39
|
|
38
|
-
|
40
|
+
env["REQUEST_METHOD"].should.equal "POST"
|
39
41
|
end
|
40
42
|
|
41
43
|
should "not modify REQUEST_METHOD when _method is nil" do
|
42
44
|
env = Rack::MockRequest.env_for("/", :method => "POST", :input => "foo=bar")
|
43
|
-
app
|
44
|
-
req = app.call(env)
|
45
|
+
app.call env
|
45
46
|
|
46
|
-
|
47
|
+
env["REQUEST_METHOD"].should.equal "POST"
|
47
48
|
end
|
48
49
|
|
49
50
|
should "store the original REQUEST_METHOD prior to overriding" do
|
50
51
|
env = Rack::MockRequest.env_for("/",
|
51
52
|
:method => "POST",
|
52
53
|
:input => "_method=options")
|
53
|
-
app
|
54
|
-
req = app.call(env)
|
54
|
+
app.call env
|
55
55
|
|
56
|
-
|
56
|
+
env["rack.methodoverride.original_method"].should.equal "POST"
|
57
57
|
end
|
58
58
|
|
59
59
|
should "not modify REQUEST_METHOD when given invalid multipart form data" do
|
@@ -63,11 +63,10 @@ content-disposition: form-data; name="huge"; filename="huge"\r
|
|
63
63
|
EOF
|
64
64
|
env = Rack::MockRequest.env_for("/",
|
65
65
|
"CONTENT_TYPE" => "multipart/form-data, boundary=AaB03x",
|
66
|
-
"CONTENT_LENGTH" => input.size,
|
66
|
+
"CONTENT_LENGTH" => input.size.to_s,
|
67
67
|
:method => "POST", :input => input)
|
68
|
-
app
|
69
|
-
req = app.call(env)
|
68
|
+
app.call env
|
70
69
|
|
71
|
-
|
70
|
+
env["REQUEST_METHOD"].should.equal "POST"
|
72
71
|
end
|
73
72
|
end
|
data/test/spec_mock.rb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
require 'yaml'
|
2
|
+
require 'rack/lint'
|
2
3
|
require 'rack/mock'
|
3
4
|
require 'stringio'
|
4
5
|
|
5
|
-
app = lambda { |env|
|
6
|
+
app = Rack::Lint.new(lambda { |env|
|
6
7
|
req = Rack::Request.new(env)
|
7
8
|
|
8
9
|
env["mock.postdata"] = env["rack.input"].read
|
@@ -11,10 +12,11 @@ app = lambda { |env|
|
|
11
12
|
env["rack.errors"].flush
|
12
13
|
end
|
13
14
|
|
14
|
-
|
15
|
+
body = req.head? ? "" : env.to_yaml
|
16
|
+
Rack::Response.new(body,
|
15
17
|
req.GET["status"] || 200,
|
16
18
|
"Content-Type" => "text/yaml").finish
|
17
|
-
}
|
19
|
+
})
|
18
20
|
|
19
21
|
describe Rack::MockRequest do
|
20
22
|
should "return a MockResponse" do
|
@@ -55,13 +57,16 @@ describe Rack::MockRequest do
|
|
55
57
|
env = YAML.load(res.body)
|
56
58
|
env["REQUEST_METHOD"].should.equal "PUT"
|
57
59
|
|
58
|
-
res = Rack::MockRequest.new(app).
|
60
|
+
res = Rack::MockRequest.new(app).patch("", :input => "foo")
|
59
61
|
env = YAML.load(res.body)
|
60
|
-
env["REQUEST_METHOD"].should.equal "
|
62
|
+
env["REQUEST_METHOD"].should.equal "PATCH"
|
61
63
|
|
62
|
-
res = Rack::MockRequest.new(app).
|
64
|
+
res = Rack::MockRequest.new(app).delete("", :input => "foo")
|
63
65
|
env = YAML.load(res.body)
|
64
|
-
env["REQUEST_METHOD"].should.equal "
|
66
|
+
env["REQUEST_METHOD"].should.equal "DELETE"
|
67
|
+
|
68
|
+
Rack::MockRequest.env_for("/", :method => "HEAD")["REQUEST_METHOD"].
|
69
|
+
should.equal "HEAD"
|
65
70
|
|
66
71
|
Rack::MockRequest.env_for("/", :method => "OPTIONS")["REQUEST_METHOD"].
|
67
72
|
should.equal "OPTIONS"
|
data/test/spec_multipart.rb
CHANGED
@@ -360,4 +360,33 @@ EOF
|
|
360
360
|
params.should.equal({"description"=>"Very very blue"})
|
361
361
|
end
|
362
362
|
|
363
|
+
should "parse multipart upload with no content-length header" do
|
364
|
+
env = Rack::MockRequest.env_for '/', multipart_fixture(:webkit)
|
365
|
+
env['CONTENT_TYPE'] = "multipart/form-data; boundary=----WebKitFormBoundaryWLHCs9qmcJJoyjKR"
|
366
|
+
env.delete 'CONTENT_LENGTH'
|
367
|
+
params = Rack::Multipart.parse_multipart(env)
|
368
|
+
params['profile']['bio'].should.include 'hello'
|
369
|
+
end
|
370
|
+
|
371
|
+
should "parse very long unquoted multipart file names" do
|
372
|
+
data = <<-EOF
|
373
|
+
--AaB03x\r
|
374
|
+
Content-Type: text/plain\r
|
375
|
+
Content-Disposition: attachment; name=file; filename=#{'long' * 100}\r
|
376
|
+
\r
|
377
|
+
contents\r
|
378
|
+
--AaB03x--\r
|
379
|
+
EOF
|
380
|
+
|
381
|
+
options = {
|
382
|
+
"CONTENT_TYPE" => "multipart/form-data; boundary=AaB03x",
|
383
|
+
"CONTENT_LENGTH" => data.length.to_s,
|
384
|
+
:input => StringIO.new(data)
|
385
|
+
}
|
386
|
+
env = Rack::MockRequest.env_for("/", options)
|
387
|
+
params = Rack::Utils::Multipart.parse_multipart(env)
|
388
|
+
|
389
|
+
params["file"][:filename].should.equal('long' * 100)
|
390
|
+
end
|
391
|
+
|
363
392
|
end
|
data/test/spec_nulllogger.rb
CHANGED
@@ -1,12 +1,23 @@
|
|
1
|
+
require 'enumerator'
|
2
|
+
require 'rack/lint'
|
3
|
+
require 'rack/mock'
|
1
4
|
require 'rack/nulllogger'
|
2
5
|
|
3
6
|
describe Rack::NullLogger do
|
7
|
+
::Enumerator = ::Enumerable::Enumerator unless Object.const_defined?(:Enumerator)
|
8
|
+
|
4
9
|
should "act as a noop logger" do
|
5
10
|
app = lambda { |env|
|
6
11
|
env['rack.logger'].warn "b00m"
|
7
12
|
[200, {'Content-Type' => 'text/plain'}, ["Hello, World!"]]
|
8
13
|
}
|
9
|
-
|
10
|
-
|
14
|
+
|
15
|
+
logger = Rack::Lint.new(Rack::NullLogger.new(app))
|
16
|
+
|
17
|
+
res = logger.call(Rack::MockRequest.env_for)
|
18
|
+
res[0..1].should.equal [
|
19
|
+
200, {'Content-Type' => 'text/plain'}
|
20
|
+
]
|
21
|
+
Enumerator.new(res[2]).to_a.should.equal ["Hello, World!"]
|
11
22
|
end
|
12
23
|
end
|
data/test/spec_recursive.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'rack/lint'
|
1
2
|
require 'rack/recursive'
|
2
3
|
require 'rack/mock'
|
3
4
|
|
@@ -28,11 +29,14 @@ describe Rack::Recursive do
|
|
28
29
|
@app4 = lambda { |env|
|
29
30
|
raise Rack::ForwardRequest.new("http://example.org/app1/quux?meh")
|
30
31
|
}
|
32
|
+
|
33
|
+
def recursive(map)
|
34
|
+
Rack::Lint.new Rack::Recursive.new(Rack::URLMap.new(map))
|
35
|
+
end
|
31
36
|
|
32
37
|
should "allow for subrequests" do
|
33
|
-
res = Rack::MockRequest.new(
|
34
|
-
|
35
|
-
"/app2" => @app2))).
|
38
|
+
res = Rack::MockRequest.new(recursive("/app1" => @app1,
|
39
|
+
"/app2" => @app2)).
|
36
40
|
get("/app2")
|
37
41
|
|
38
42
|
res.should.be.ok
|
@@ -41,9 +45,8 @@ describe Rack::Recursive do
|
|
41
45
|
|
42
46
|
should "raise error on requests not below the app" do
|
43
47
|
app = Rack::URLMap.new("/app1" => @app1,
|
44
|
-
"/app" =>
|
45
|
-
|
46
|
-
"/2" => @app2)))
|
48
|
+
"/app" => recursive("/1" => @app1,
|
49
|
+
"/2" => @app2))
|
47
50
|
|
48
51
|
lambda {
|
49
52
|
Rack::MockRequest.new(app).get("/app/2")
|
@@ -52,9 +55,9 @@ describe Rack::Recursive do
|
|
52
55
|
end
|
53
56
|
|
54
57
|
should "support forwarding" do
|
55
|
-
app =
|
56
|
-
|
57
|
-
|
58
|
+
app = recursive("/app1" => @app1,
|
59
|
+
"/app3" => @app3,
|
60
|
+
"/app4" => @app4)
|
58
61
|
|
59
62
|
res = Rack::MockRequest.new(app).get("/app3")
|
60
63
|
res.should.be.ok
|
data/test/spec_request.rb
CHANGED
@@ -411,9 +411,9 @@ describe Rack::Request do
|
|
411
411
|
req.cookies.should.equal 'foo' => 'bar'
|
412
412
|
end
|
413
413
|
|
414
|
-
should "
|
414
|
+
should "pass through non-uri escaped cookies as-is" do
|
415
415
|
req = Rack::Request.new Rack::MockRequest.env_for("", "HTTP_COOKIE" => "foo=%")
|
416
|
-
|
416
|
+
req.cookies["foo"].should == "%"
|
417
417
|
end
|
418
418
|
|
419
419
|
should "parse cookies according to RFC 2109" do
|
data/test/spec_response.rb
CHANGED
@@ -280,4 +280,34 @@ describe Rack::Response do
|
|
280
280
|
res.close
|
281
281
|
res.body.should.be.closed
|
282
282
|
end
|
283
|
+
|
284
|
+
it "calls close on #body when 204, 205, or 304" do
|
285
|
+
res = Rack::Response.new
|
286
|
+
res.body = StringIO.new
|
287
|
+
res.finish
|
288
|
+
res.body.should.not.be.closed
|
289
|
+
|
290
|
+
res.status = 204
|
291
|
+
_, _, b = res.finish
|
292
|
+
res.body.should.be.closed
|
293
|
+
b.should.not == res.body
|
294
|
+
|
295
|
+
res.body = StringIO.new
|
296
|
+
res.status = 205
|
297
|
+
_, _, b = res.finish
|
298
|
+
res.body.should.be.closed
|
299
|
+
b.should.not == res.body
|
300
|
+
|
301
|
+
res.body = StringIO.new
|
302
|
+
res.status = 304
|
303
|
+
_, _, b = res.finish
|
304
|
+
res.body.should.be.closed
|
305
|
+
b.should.not == res.body
|
306
|
+
end
|
307
|
+
|
308
|
+
it "wraps the body from #to_ary to prevent infinite loops" do
|
309
|
+
res = Rack::Response.new
|
310
|
+
res.finish.last.should.not.respond_to?(:to_ary)
|
311
|
+
lambda { res.finish.last.to_ary }.should.raise(NoMethodError)
|
312
|
+
end
|
283
313
|
end
|
data/test/spec_runtime.rb
CHANGED
@@ -1,27 +1,37 @@
|
|
1
|
+
require 'rack/lint'
|
2
|
+
require 'rack/mock'
|
1
3
|
require 'rack/runtime'
|
2
4
|
|
3
5
|
describe Rack::Runtime do
|
6
|
+
def runtime_app(app, *args)
|
7
|
+
Rack::Lint.new Rack::Runtime.new(app, *args)
|
8
|
+
end
|
9
|
+
|
10
|
+
def request
|
11
|
+
Rack::MockRequest.env_for
|
12
|
+
end
|
13
|
+
|
4
14
|
it "sets X-Runtime is none is set" do
|
5
15
|
app = lambda { |env| [200, {'Content-Type' => 'text/plain'}, "Hello, World!"] }
|
6
|
-
response =
|
16
|
+
response = runtime_app(app).call(request)
|
7
17
|
response[1]['X-Runtime'].should =~ /[\d\.]+/
|
8
18
|
end
|
9
19
|
|
10
20
|
it "doesn't set the X-Runtime if it is already set" do
|
11
21
|
app = lambda { |env| [200, {'Content-Type' => 'text/plain', "X-Runtime" => "foobar"}, "Hello, World!"] }
|
12
|
-
response =
|
22
|
+
response = runtime_app(app).call(request)
|
13
23
|
response[1]['X-Runtime'].should == "foobar"
|
14
24
|
end
|
15
25
|
|
16
26
|
should "allow a suffix to be set" do
|
17
27
|
app = lambda { |env| [200, {'Content-Type' => 'text/plain'}, "Hello, World!"] }
|
18
|
-
response =
|
28
|
+
response = runtime_app(app, "Test").call(request)
|
19
29
|
response[1]['X-Runtime-Test'].should =~ /[\d\.]+/
|
20
30
|
end
|
21
31
|
|
22
32
|
should "allow multiple timers to be set" do
|
23
33
|
app = lambda { |env| sleep 0.1; [200, {'Content-Type' => 'text/plain'}, "Hello, World!"] }
|
24
|
-
runtime =
|
34
|
+
runtime = runtime_app(app, "App")
|
25
35
|
|
26
36
|
# wrap many times to guarantee a measurable difference
|
27
37
|
100.times do |i|
|
@@ -29,7 +39,7 @@ describe Rack::Runtime do
|
|
29
39
|
end
|
30
40
|
runtime = Rack::Runtime.new(runtime, "All")
|
31
41
|
|
32
|
-
response = runtime.call(
|
42
|
+
response = runtime.call(request)
|
33
43
|
|
34
44
|
response[1]['X-Runtime-App'].should =~ /[\d\.]+/
|
35
45
|
response[1]['X-Runtime-All'].should =~ /[\d\.]+/
|
data/test/spec_sendfile.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'rack/lint'
|
1
3
|
require 'rack/sendfile'
|
2
4
|
require 'rack/mock'
|
3
5
|
|
@@ -9,8 +11,9 @@ end
|
|
9
11
|
|
10
12
|
describe Rack::Sendfile do
|
11
13
|
def sendfile_body
|
14
|
+
FileUtils.touch "/tmp/rack_sendfile"
|
12
15
|
res = ['Hello World']
|
13
|
-
def res.to_path ; "/tmp/
|
16
|
+
def res.to_path ; "/tmp/rack_sendfile" ; end
|
14
17
|
res
|
15
18
|
end
|
16
19
|
|
@@ -19,7 +22,7 @@ describe Rack::Sendfile do
|
|
19
22
|
end
|
20
23
|
|
21
24
|
def sendfile_app(body=sendfile_body)
|
22
|
-
Rack::Sendfile.new(simple_app(body))
|
25
|
+
Rack::Lint.new Rack::Sendfile.new(simple_app(body))
|
23
26
|
end
|
24
27
|
|
25
28
|
@request = Rack::MockRequest.new(sendfile_app)
|
@@ -40,8 +43,8 @@ describe Rack::Sendfile do
|
|
40
43
|
request 'HTTP_X_SENDFILE_TYPE' => 'X-Sendfile' do |response|
|
41
44
|
response.should.be.ok
|
42
45
|
response.body.should.be.empty
|
43
|
-
response.headers['Content-Length'].should
|
44
|
-
response.headers['X-Sendfile'].should.equal '/tmp/
|
46
|
+
response.headers['Content-Length'].should.equal '0'
|
47
|
+
response.headers['X-Sendfile'].should.equal '/tmp/rack_sendfile'
|
45
48
|
end
|
46
49
|
end
|
47
50
|
|
@@ -49,8 +52,8 @@ describe Rack::Sendfile do
|
|
49
52
|
request 'HTTP_X_SENDFILE_TYPE' => 'X-Lighttpd-Send-File' do |response|
|
50
53
|
response.should.be.ok
|
51
54
|
response.body.should.be.empty
|
52
|
-
response.headers['Content-Length'].should
|
53
|
-
response.headers['X-Lighttpd-Send-File'].should.equal '/tmp/
|
55
|
+
response.headers['Content-Length'].should.equal '0'
|
56
|
+
response.headers['X-Lighttpd-Send-File'].should.equal '/tmp/rack_sendfile'
|
54
57
|
end
|
55
58
|
end
|
56
59
|
|
@@ -62,8 +65,8 @@ describe Rack::Sendfile do
|
|
62
65
|
request headers do |response|
|
63
66
|
response.should.be.ok
|
64
67
|
response.body.should.be.empty
|
65
|
-
response.headers['Content-Length'].should
|
66
|
-
response.headers['X-Accel-Redirect'].should.equal '/foo/bar/
|
68
|
+
response.headers['Content-Length'].should.equal '0'
|
69
|
+
response.headers['X-Accel-Redirect'].should.equal '/foo/bar/rack_sendfile'
|
67
70
|
end
|
68
71
|
end
|
69
72
|
|
data/test/spec_server.rb
CHANGED
@@ -10,6 +10,13 @@ describe Rack::Server do
|
|
10
10
|
lambda { |env| [200, {'Content-Type' => 'text/plain'}, ['success']] }
|
11
11
|
end
|
12
12
|
|
13
|
+
def with_stderr
|
14
|
+
old, $stderr = $stderr, StringIO.new
|
15
|
+
yield $stderr
|
16
|
+
ensure
|
17
|
+
$stderr = old
|
18
|
+
end
|
19
|
+
|
13
20
|
it "overrides :config if :app is passed in" do
|
14
21
|
server = Rack::Server.new(:app => "FOO")
|
15
22
|
server.app.should == "FOO"
|
@@ -71,4 +78,44 @@ describe Rack::Server do
|
|
71
78
|
open(pidfile) { |f| f.read.should.eql $$.to_s }
|
72
79
|
end
|
73
80
|
|
81
|
+
should "check pid file presence and running process" do
|
82
|
+
pidfile = Tempfile.open('pidfile') { |f| f.write($$); break f }.path
|
83
|
+
server = Rack::Server.new(:pid => pidfile)
|
84
|
+
server.send(:pidfile_process_status).should.eql :running
|
85
|
+
end
|
86
|
+
|
87
|
+
should "check pid file presence and dead process" do
|
88
|
+
dead_pid = `echo $$`.to_i
|
89
|
+
pidfile = Tempfile.open('pidfile') { |f| f.write(dead_pid); break f }.path
|
90
|
+
server = Rack::Server.new(:pid => pidfile)
|
91
|
+
server.send(:pidfile_process_status).should.eql :dead
|
92
|
+
end
|
93
|
+
|
94
|
+
should "check pid file presence and exited process" do
|
95
|
+
pidfile = Tempfile.open('pidfile') { |f| break f }.path
|
96
|
+
::File.delete(pidfile)
|
97
|
+
server = Rack::Server.new(:pid => pidfile)
|
98
|
+
server.send(:pidfile_process_status).should.eql :exited
|
99
|
+
end
|
100
|
+
|
101
|
+
should "check pid file presence and not owned process" do
|
102
|
+
pidfile = Tempfile.open('pidfile') { |f| f.write(1); break f }.path
|
103
|
+
server = Rack::Server.new(:pid => pidfile)
|
104
|
+
server.send(:pidfile_process_status).should.eql :not_owned
|
105
|
+
end
|
106
|
+
|
107
|
+
should "inform the user about existing pidfiles with running processes" do
|
108
|
+
pidfile = Tempfile.open('pidfile') { |f| f.write(1); break f }.path
|
109
|
+
server = Rack::Server.new(:pid => pidfile)
|
110
|
+
with_stderr do |err|
|
111
|
+
should.raise(SystemExit) do
|
112
|
+
server.start
|
113
|
+
end
|
114
|
+
err.rewind
|
115
|
+
output = err.read
|
116
|
+
output.should.match(/already running/)
|
117
|
+
output.should.include? pidfile
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
74
121
|
end
|