rack 1.1.6 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README +9 -205
- data/SPEC +3 -3
- data/lib/rack.rb +1 -24
- data/lib/rack/auth/abstract/request.rb +1 -5
- data/lib/rack/auth/digest/md5.rb +1 -2
- data/lib/rack/auth/digest/params.rb +1 -1
- data/lib/rack/content_length.rb +1 -1
- data/lib/rack/etag.rb +15 -6
- data/lib/rack/file.rb +3 -1
- data/lib/rack/handler/cgi.rb +8 -7
- data/lib/rack/handler/fastcgi.rb +1 -1
- data/lib/rack/handler/lsws.rb +1 -1
- data/lib/rack/handler/mongrel.rb +1 -1
- data/lib/rack/handler/scgi.rb +1 -4
- data/lib/rack/handler/webrick.rb +10 -6
- data/lib/rack/lint.rb +29 -37
- data/lib/rack/mime.rb +2 -0
- data/lib/rack/mock.rb +2 -1
- data/lib/rack/recursive.rb +4 -0
- data/lib/rack/request.rb +8 -6
- data/lib/rack/response.rb +1 -0
- data/lib/rack/rewindable_input.rb +13 -10
- data/lib/rack/sendfile.rb +8 -6
- data/lib/rack/server.rb +68 -9
- data/lib/rack/session/cookie.rb +1 -10
- data/lib/rack/session/memcache.rb +1 -1
- data/lib/rack/urlmap.rb +6 -7
- data/lib/rack/utils.rb +40 -71
- data/rack.gemspec +7 -11
- data/spec/cgi/lighttpd.conf +25 -0
- data/spec/cgi/rackup_stub.rb +6 -0
- data/spec/cgi/sample_rackup.ru +5 -0
- data/spec/cgi/test +9 -0
- data/spec/cgi/test.fcgi +8 -0
- data/spec/cgi/test.ru +5 -0
- data/spec/multipart/bad_robots +259 -0
- data/spec/multipart/binary +0 -0
- data/spec/multipart/empty +10 -0
- data/spec/multipart/fail_16384_nofile +814 -0
- data/spec/multipart/file1.txt +1 -0
- data/spec/multipart/filename_and_modification_param +7 -0
- data/spec/multipart/filename_with_escaped_quotes +6 -0
- data/spec/multipart/filename_with_escaped_quotes_and_modification_param +7 -0
- data/spec/multipart/filename_with_percent_escaped_quotes +6 -0
- data/spec/multipart/filename_with_unescaped_quotes +6 -0
- data/spec/multipart/ie +6 -0
- data/spec/multipart/nested +10 -0
- data/spec/multipart/none +9 -0
- data/spec/multipart/semicolon +6 -0
- data/spec/multipart/text +10 -0
- data/spec/rackup/config.ru +31 -0
- data/{test/spec_rack_auth_basic.rb → spec/spec_auth_basic.rb} +11 -14
- data/{test/spec_rack_auth_digest.rb → spec/spec_auth_digest.rb} +18 -27
- data/{test/spec_rack_builder.rb → spec/spec_builder.rb} +49 -10
- data/{test/spec_rack_cascade.rb → spec/spec_cascade.rb} +7 -10
- data/{test/spec_rack_cgi.rb → spec/spec_cgi.rb} +34 -32
- data/{test/spec_rack_chunked.rb → spec/spec_chunked.rb} +8 -10
- data/{test/spec_rack_commonlogger.rb → spec/spec_commonlogger.rb} +10 -15
- data/{test/spec_rack_conditionalget.rb → spec/spec_conditionalget.rb} +5 -7
- data/{test/spec_rack_config.rb → spec/spec_config.rb} +6 -7
- data/{test/spec_rack_content_length.rb → spec/spec_content_length.rb} +7 -8
- data/{test/spec_rack_content_type.rb → spec/spec_content_type.rb} +5 -6
- data/{test/spec_rack_deflater.rb → spec/spec_deflater.rb} +11 -13
- data/{test/spec_rack_directory.rb → spec/spec_directory.rb} +6 -10
- data/{test/spec_rack_etag.rb → spec/spec_etag.rb} +3 -5
- data/{test/spec_rack_fastcgi.rb → spec/spec_fastcgi.rb} +36 -29
- data/{test/spec_rack_file.rb → spec/spec_file.rb} +9 -13
- data/{test/spec_rack_handler.rb → spec/spec_handler.rb} +10 -12
- data/{test/spec_rack_head.rb → spec/spec_head.rb} +3 -3
- data/{test/spec_rack_lint.rb → spec/spec_lint.rb} +19 -32
- data/{test/spec_rack_lobster.rb → spec/spec_lobster.rb} +9 -11
- data/{test/spec_rack_lock.rb → spec/spec_lock.rb} +15 -17
- data/{test/spec_rack_logger.rb → spec/spec_logger.rb} +6 -7
- data/{test/spec_rack_methodoverride.rb → spec/spec_methodoverride.rb} +15 -17
- data/{test/spec_rack_mock.rb → spec/spec_mock.rb} +30 -32
- data/{test/spec_rack_mongrel.rb → spec/spec_mongrel.rb} +40 -46
- data/{test/spec_rack_nulllogger.rb → spec/spec_nulllogger.rb} +4 -5
- data/{test/spec_rack_recursive.rb → spec/spec_recursive.rb} +28 -36
- data/{test/spec_rack_request.rb → spec/spec_request.rb} +84 -98
- data/{test/spec_rack_response.rb → spec/spec_response.rb} +46 -27
- data/spec/spec_rewindable_input.rb +118 -0
- data/{test/spec_rack_runtime.rb → spec/spec_runtime.rb} +15 -11
- data/{test/spec_rack_sendfile.rb → spec/spec_sendfile.rb} +11 -14
- data/{test/spec_rack_session_cookie.rb → spec/spec_session_cookie.rb} +14 -36
- data/{test/spec_rack_session_memcache.rb → spec/spec_session_memcache.rb} +32 -26
- data/{test/spec_rack_session_pool.rb → spec/spec_session_pool.rb} +36 -31
- data/spec/spec_showexceptions.rb +23 -0
- data/spec/spec_showstatus.rb +79 -0
- data/{test/spec_rack_static.rb → spec/spec_static.rb} +5 -9
- data/{test/spec_rack_thin.rb → spec/spec_thin.rb} +30 -35
- data/{test/spec_rack_urlmap.rb → spec/spec_urlmap.rb} +6 -8
- data/{test/spec_rack_utils.rb → spec/spec_utils.rb} +134 -74
- data/{test/spec_rack_webrick.rb → spec/spec_webrick.rb} +28 -36
- data/spec/testrequest.rb +77 -0
- data/spec/unregistered_handler/rack/handler/unregistered.rb +7 -0
- data/spec/unregistered_handler/rack/handler/unregistered_long_one.rb +7 -0
- metadata +176 -191
- data/RDOX +0 -0
- data/lib/rack/adapter/camping.rb +0 -22
- data/test/spec_auth.rb +0 -57
- data/test/spec_rack_camping.rb +0 -55
- data/test/spec_rack_rewindable_input.rb +0 -118
- data/test/spec_rack_showexceptions.rb +0 -21
- data/test/spec_rack_showstatus.rb +0 -72
- data/test/spec_rackup.rb +0 -164
|
@@ -1,16 +1,12 @@
|
|
|
1
|
-
require 'test/spec'
|
|
2
|
-
|
|
3
1
|
require 'rack/directory'
|
|
4
|
-
require 'rack/lint'
|
|
5
|
-
|
|
6
2
|
require 'rack/mock'
|
|
7
3
|
|
|
8
|
-
|
|
4
|
+
describe Rack::Directory do
|
|
9
5
|
DOCROOT = File.expand_path(File.dirname(__FILE__)) unless defined? DOCROOT
|
|
10
6
|
FILE_CATCH = proc{|env| [200, {'Content-Type'=>'text/plain', "Content-Length" => "7"}, ['passed!']] }
|
|
11
7
|
app = Rack::Directory.new DOCROOT, FILE_CATCH
|
|
12
8
|
|
|
13
|
-
|
|
9
|
+
should "serve directory indices" do
|
|
14
10
|
res = Rack::MockRequest.new(Rack::Lint.new(app)).
|
|
15
11
|
get("/cgi/")
|
|
16
12
|
|
|
@@ -18,7 +14,7 @@ context "Rack::Directory" do
|
|
|
18
14
|
res.should =~ /<html><head>/
|
|
19
15
|
end
|
|
20
16
|
|
|
21
|
-
|
|
17
|
+
should "pass to app if file found" do
|
|
22
18
|
res = Rack::MockRequest.new(Rack::Lint.new(app)).
|
|
23
19
|
get("/cgi/test")
|
|
24
20
|
|
|
@@ -26,7 +22,7 @@ context "Rack::Directory" do
|
|
|
26
22
|
res.should =~ /passed!/
|
|
27
23
|
end
|
|
28
24
|
|
|
29
|
-
|
|
25
|
+
should "serve uri with URL encoded filenames" do
|
|
30
26
|
res = Rack::MockRequest.new(Rack::Lint.new(app)).
|
|
31
27
|
get("/%63%67%69/") # "/cgi/test"
|
|
32
28
|
|
|
@@ -40,7 +36,7 @@ context "Rack::Directory" do
|
|
|
40
36
|
res.should =~ /passed!/
|
|
41
37
|
end
|
|
42
38
|
|
|
43
|
-
|
|
39
|
+
should "not allow directory traversal" do
|
|
44
40
|
res = Rack::MockRequest.new(Rack::Lint.new(app)).
|
|
45
41
|
get("/cgi/../test")
|
|
46
42
|
|
|
@@ -52,7 +48,7 @@ context "Rack::Directory" do
|
|
|
52
48
|
res.should.be.forbidden
|
|
53
49
|
end
|
|
54
50
|
|
|
55
|
-
|
|
51
|
+
should "404 if it can't find the file" do
|
|
56
52
|
res = Rack::MockRequest.new(Rack::Lint.new(app)).
|
|
57
53
|
get("/cgi/blubb")
|
|
58
54
|
|
|
@@ -1,15 +1,13 @@
|
|
|
1
|
-
require 'test/spec'
|
|
2
|
-
require 'rack/mock'
|
|
3
1
|
require 'rack/etag'
|
|
4
2
|
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
describe Rack::ETag do
|
|
4
|
+
should "set ETag if none is set" do
|
|
7
5
|
app = lambda { |env| [200, {'Content-Type' => 'text/plain'}, ["Hello, World!"]] }
|
|
8
6
|
response = Rack::ETag.new(app).call({})
|
|
9
7
|
response[1]['ETag'].should.equal "\"65a8e27d8879283831b664bd8b7f0ad4\""
|
|
10
8
|
end
|
|
11
9
|
|
|
12
|
-
|
|
10
|
+
should "not change ETag if it is already set" do
|
|
13
11
|
app = lambda { |env| [200, {'Content-Type' => 'text/plain', 'ETag' => '"abc"'}, ["Hello, World!"]] }
|
|
14
12
|
response = Rack::ETag.new(app).call({})
|
|
15
13
|
response[1]['ETag'].should.equal "\"abc\""
|
|
@@ -1,48 +1,55 @@
|
|
|
1
|
-
require '
|
|
2
|
-
require '
|
|
1
|
+
require File.expand_path('../testrequest', __FILE__)
|
|
2
|
+
require 'rack/handler/fastcgi'
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
describe Rack::Handler::FastCGI do
|
|
5
|
+
extend TestRequest::Helpers
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
@port = 9203
|
|
10
|
-
end
|
|
7
|
+
@host = '0.0.0.0'
|
|
8
|
+
@port = 9203
|
|
11
9
|
|
|
12
10
|
# Keep this first.
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
$pid = fork {
|
|
12
|
+
ENV['RACK_ENV'] = 'deployment'
|
|
13
|
+
ENV['RUBYLIB'] = [
|
|
14
|
+
File.expand_path('../../lib', __FILE__),
|
|
15
|
+
ENV['RUBYLIB'],
|
|
16
|
+
].compact.join(':')
|
|
17
|
+
|
|
18
|
+
Dir.chdir(File.expand_path("../cgi", __FILE__)) do
|
|
16
19
|
exec "lighttpd -D -f lighttpd.conf"
|
|
17
|
-
|
|
18
|
-
|
|
20
|
+
end
|
|
21
|
+
}
|
|
19
22
|
|
|
20
|
-
|
|
23
|
+
should "respond" do
|
|
21
24
|
sleep 1
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}.should.not.raise
|
|
25
|
+
GET("/test")
|
|
26
|
+
response.should.not.be.nil
|
|
25
27
|
end
|
|
26
28
|
|
|
27
|
-
|
|
29
|
+
should "respond via rackup server" do
|
|
30
|
+
GET("/sample_rackup.ru")
|
|
31
|
+
status.should.equal 200
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
should "be a lighttpd" do
|
|
28
35
|
GET("/test.fcgi")
|
|
29
|
-
status.should.
|
|
36
|
+
status.should.equal 200
|
|
30
37
|
response["SERVER_SOFTWARE"].should =~ /lighttpd/
|
|
31
38
|
response["HTTP_VERSION"].should.equal "HTTP/1.1"
|
|
32
39
|
response["SERVER_PROTOCOL"].should.equal "HTTP/1.1"
|
|
33
40
|
response["SERVER_PORT"].should.equal @port.to_s
|
|
34
|
-
response["SERVER_NAME"].should
|
|
41
|
+
response["SERVER_NAME"].should.equal @host
|
|
35
42
|
end
|
|
36
43
|
|
|
37
|
-
|
|
44
|
+
should "have rack headers" do
|
|
38
45
|
GET("/test.fcgi")
|
|
39
46
|
response["rack.version"].should.equal [1,1]
|
|
40
|
-
response["rack.multithread"].should.be
|
|
41
|
-
response["rack.multiprocess"].should.be
|
|
42
|
-
response["rack.run_once"].should.be
|
|
47
|
+
response["rack.multithread"].should.be.false
|
|
48
|
+
response["rack.multiprocess"].should.be.true
|
|
49
|
+
response["rack.run_once"].should.be.false
|
|
43
50
|
end
|
|
44
51
|
|
|
45
|
-
|
|
52
|
+
should "have CGI headers on GET" do
|
|
46
53
|
GET("/test.fcgi")
|
|
47
54
|
response["REQUEST_METHOD"].should.equal "GET"
|
|
48
55
|
response["SCRIPT_NAME"].should.equal "/test.fcgi"
|
|
@@ -59,7 +66,7 @@ context "Rack::Handler::FastCGI" do
|
|
|
59
66
|
response["QUERY_STRING"].should.equal "quux=1"
|
|
60
67
|
end
|
|
61
68
|
|
|
62
|
-
|
|
69
|
+
should "have CGI headers on POST" do
|
|
63
70
|
POST("/test.fcgi", {"rack-form-data" => "23"}, {'X-test-header' => '42'})
|
|
64
71
|
status.should.equal 200
|
|
65
72
|
response["REQUEST_METHOD"].should.equal "POST"
|
|
@@ -70,19 +77,19 @@ context "Rack::Handler::FastCGI" do
|
|
|
70
77
|
response["test.postdata"].should.equal "rack-form-data=23"
|
|
71
78
|
end
|
|
72
79
|
|
|
73
|
-
|
|
80
|
+
should "support HTTP auth" do
|
|
74
81
|
GET("/test.fcgi", {:user => "ruth", :passwd => "secret"})
|
|
75
82
|
response["HTTP_AUTHORIZATION"].should.equal "Basic cnV0aDpzZWNyZXQ="
|
|
76
83
|
end
|
|
77
84
|
|
|
78
|
-
|
|
85
|
+
should "set status" do
|
|
79
86
|
GET("/test.fcgi?secret")
|
|
80
87
|
status.should.equal 403
|
|
81
88
|
response["rack.url_scheme"].should.equal "http"
|
|
82
89
|
end
|
|
83
90
|
|
|
84
91
|
# Keep this last.
|
|
85
|
-
|
|
92
|
+
should "shutdown" do
|
|
86
93
|
Process.kill 15, $pid
|
|
87
94
|
Process.wait($pid).should.equal $pid
|
|
88
95
|
end
|
|
@@ -1,14 +1,10 @@
|
|
|
1
|
-
require 'test/spec'
|
|
2
|
-
|
|
3
1
|
require 'rack/file'
|
|
4
|
-
require 'rack/lint'
|
|
5
|
-
|
|
6
2
|
require 'rack/mock'
|
|
7
3
|
|
|
8
|
-
|
|
4
|
+
describe Rack::File do
|
|
9
5
|
DOCROOT = File.expand_path(File.dirname(__FILE__)) unless defined? DOCROOT
|
|
10
6
|
|
|
11
|
-
|
|
7
|
+
should "serve files" do
|
|
12
8
|
res = Rack::MockRequest.new(Rack::Lint.new(Rack::File.new(DOCROOT))).
|
|
13
9
|
get("/cgi/test")
|
|
14
10
|
|
|
@@ -16,7 +12,7 @@ context "Rack::File" do
|
|
|
16
12
|
res.should =~ /ruby/
|
|
17
13
|
end
|
|
18
14
|
|
|
19
|
-
|
|
15
|
+
should "set Last-Modified header" do
|
|
20
16
|
res = Rack::MockRequest.new(Rack::Lint.new(Rack::File.new(DOCROOT))).
|
|
21
17
|
get("/cgi/test")
|
|
22
18
|
|
|
@@ -26,7 +22,7 @@ context "Rack::File" do
|
|
|
26
22
|
res["Last-Modified"].should.equal File.mtime(path).httpdate
|
|
27
23
|
end
|
|
28
24
|
|
|
29
|
-
|
|
25
|
+
should "serve files with URL encoded filenames" do
|
|
30
26
|
res = Rack::MockRequest.new(Rack::Lint.new(Rack::File.new(DOCROOT))).
|
|
31
27
|
get("/cgi/%74%65%73%74") # "/cgi/test"
|
|
32
28
|
|
|
@@ -34,35 +30,35 @@ context "Rack::File" do
|
|
|
34
30
|
res.should =~ /ruby/
|
|
35
31
|
end
|
|
36
32
|
|
|
37
|
-
|
|
33
|
+
should "not allow directory traversal" do
|
|
38
34
|
res = Rack::MockRequest.new(Rack::Lint.new(Rack::File.new(DOCROOT))).
|
|
39
35
|
get("/cgi/../test")
|
|
40
36
|
|
|
41
37
|
res.should.be.forbidden
|
|
42
38
|
end
|
|
43
39
|
|
|
44
|
-
|
|
40
|
+
should "not allow directory traversal with encoded periods" do
|
|
45
41
|
res = Rack::MockRequest.new(Rack::Lint.new(Rack::File.new(DOCROOT))).
|
|
46
42
|
get("/%2E%2E/README")
|
|
47
43
|
|
|
48
44
|
res.should.be.forbidden
|
|
49
45
|
end
|
|
50
46
|
|
|
51
|
-
|
|
47
|
+
should "404 if it can't find the file" do
|
|
52
48
|
res = Rack::MockRequest.new(Rack::Lint.new(Rack::File.new(DOCROOT))).
|
|
53
49
|
get("/cgi/blubb")
|
|
54
50
|
|
|
55
51
|
res.should.be.not_found
|
|
56
52
|
end
|
|
57
53
|
|
|
58
|
-
|
|
54
|
+
should "detect SystemCallErrors" do
|
|
59
55
|
res = Rack::MockRequest.new(Rack::Lint.new(Rack::File.new(DOCROOT))).
|
|
60
56
|
get("/cgi")
|
|
61
57
|
|
|
62
58
|
res.should.be.not_found
|
|
63
59
|
end
|
|
64
60
|
|
|
65
|
-
|
|
61
|
+
should "return bodies that respond to #to_path" do
|
|
66
62
|
env = Rack::MockRequest.env_for("/cgi/test")
|
|
67
63
|
status, headers, body = Rack::File.new(DOCROOT).call(env)
|
|
68
64
|
|
|
@@ -1,43 +1,41 @@
|
|
|
1
|
-
require 'test/spec'
|
|
2
|
-
|
|
3
1
|
require 'rack/handler'
|
|
4
2
|
|
|
5
3
|
class Rack::Handler::Lobster; end
|
|
6
4
|
class RockLobster; end
|
|
7
5
|
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
describe Rack::Handler do
|
|
7
|
+
it "has registered default handlers" do
|
|
10
8
|
Rack::Handler.get('cgi').should.equal Rack::Handler::CGI
|
|
11
9
|
Rack::Handler.get('fastcgi').should.equal Rack::Handler::FastCGI
|
|
12
10
|
Rack::Handler.get('mongrel').should.equal Rack::Handler::Mongrel
|
|
13
11
|
Rack::Handler.get('webrick').should.equal Rack::Handler::WEBrick
|
|
14
12
|
end
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
|
|
14
|
+
should "raise NameError if handler doesn't exist" do
|
|
17
15
|
lambda {
|
|
18
16
|
Rack::Handler.get('boom')
|
|
19
17
|
}.should.raise(NameError)
|
|
20
18
|
end
|
|
21
19
|
|
|
22
|
-
|
|
20
|
+
should "get unregistered, but already required, handler by name" do
|
|
23
21
|
Rack::Handler.get('Lobster').should.equal Rack::Handler::Lobster
|
|
24
22
|
end
|
|
25
23
|
|
|
26
|
-
|
|
24
|
+
should "register custom handler" do
|
|
27
25
|
Rack::Handler.register('rock_lobster', 'RockLobster')
|
|
28
26
|
Rack::Handler.get('rock_lobster').should.equal RockLobster
|
|
29
27
|
end
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
|
|
29
|
+
should "not need registration for properly coded handlers even if not already required" do
|
|
32
30
|
begin
|
|
33
|
-
|
|
31
|
+
$LOAD_PATH.push File.expand_path('../unregistered_handler', __FILE__)
|
|
34
32
|
Rack::Handler.get('Unregistered').should.equal Rack::Handler::Unregistered
|
|
35
33
|
lambda {
|
|
36
34
|
Rack::Handler.get('UnRegistered')
|
|
37
35
|
}.should.raise(NameError)
|
|
38
36
|
Rack::Handler.get('UnregisteredLongOne').should.equal Rack::Handler::UnregisteredLongOne
|
|
39
37
|
ensure
|
|
40
|
-
|
|
38
|
+
$LOAD_PATH.delete File.expand_path('../unregistered_handler', __FILE__)
|
|
41
39
|
end
|
|
42
40
|
end
|
|
43
41
|
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
require 'rack/head'
|
|
2
2
|
require 'rack/mock'
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
describe Rack::Head do
|
|
5
5
|
def test_response(headers = {})
|
|
6
6
|
app = lambda { |env| [200, {"Content-type" => "test/plain", "Content-length" => "3"}, ["foo"]] }
|
|
7
7
|
request = Rack::MockRequest.env_for("/", headers)
|
|
@@ -10,7 +10,7 @@ context "Rack::Head" do
|
|
|
10
10
|
return response
|
|
11
11
|
end
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
should "pass GET, POST, PUT, DELETE, OPTIONS, TRACE requests" do
|
|
14
14
|
%w[GET POST PUT DELETE OPTIONS TRACE].each do |type|
|
|
15
15
|
resp = test_response("REQUEST_METHOD" => type)
|
|
16
16
|
|
|
@@ -20,7 +20,7 @@ context "Rack::Head" do
|
|
|
20
20
|
end
|
|
21
21
|
end
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
should "remove body from HEAD requests" do
|
|
24
24
|
resp = test_response("REQUEST_METHOD" => "HEAD")
|
|
25
25
|
|
|
26
26
|
resp[0].should.equal(200)
|
|
@@ -1,15 +1,13 @@
|
|
|
1
|
-
require 'test/spec'
|
|
2
1
|
require 'stringio'
|
|
3
|
-
|
|
4
2
|
require 'rack/lint'
|
|
5
3
|
require 'rack/mock'
|
|
6
4
|
|
|
7
|
-
|
|
5
|
+
describe Rack::Lint do
|
|
8
6
|
def env(*args)
|
|
9
7
|
Rack::MockRequest.env_for("/", *args)
|
|
10
8
|
end
|
|
11
9
|
|
|
12
|
-
|
|
10
|
+
should "pass valid request" do
|
|
13
11
|
lambda {
|
|
14
12
|
Rack::Lint.new(lambda { |env|
|
|
15
13
|
[200, {"Content-type" => "test/plain", "Content-length" => "3"}, ["foo"]]
|
|
@@ -17,12 +15,12 @@ context "Rack::Lint" do
|
|
|
17
15
|
}.should.not.raise
|
|
18
16
|
end
|
|
19
17
|
|
|
20
|
-
|
|
18
|
+
should "notice fatal errors" do
|
|
21
19
|
lambda { Rack::Lint.new(nil).call }.should.raise(Rack::Lint::LintError).
|
|
22
20
|
message.should.match(/No env given/)
|
|
23
21
|
end
|
|
24
22
|
|
|
25
|
-
|
|
23
|
+
should "notice environment errors" do
|
|
26
24
|
lambda { Rack::Lint.new(nil).call 5 }.should.raise(Rack::Lint::LintError).
|
|
27
25
|
message.should.match(/not a Hash/)
|
|
28
26
|
|
|
@@ -110,7 +108,7 @@ context "Rack::Lint" do
|
|
|
110
108
|
message.should.match(/cannot be .* make it ''/)
|
|
111
109
|
end
|
|
112
110
|
|
|
113
|
-
|
|
111
|
+
should "notice input errors" do
|
|
114
112
|
lambda {
|
|
115
113
|
Rack::Lint.new(nil).call(env("rack.input" => ""))
|
|
116
114
|
}.should.raise(Rack::Lint::LintError).
|
|
@@ -139,14 +137,14 @@ context "Rack::Lint" do
|
|
|
139
137
|
message.should.match(/does not have ASCII-8BIT as its external encoding/)
|
|
140
138
|
end
|
|
141
139
|
|
|
142
|
-
|
|
140
|
+
should "notice error errors" do
|
|
143
141
|
lambda {
|
|
144
142
|
Rack::Lint.new(nil).call(env("rack.errors" => ""))
|
|
145
143
|
}.should.raise(Rack::Lint::LintError).
|
|
146
144
|
message.should.match(/does not respond to #puts/)
|
|
147
145
|
end
|
|
148
146
|
|
|
149
|
-
|
|
147
|
+
should "notice status errors" do
|
|
150
148
|
lambda {
|
|
151
149
|
Rack::Lint.new(lambda { |env|
|
|
152
150
|
["cc", {}, ""]
|
|
@@ -162,7 +160,7 @@ context "Rack::Lint" do
|
|
|
162
160
|
message.should.match(/must be >=100 seen as integer/)
|
|
163
161
|
end
|
|
164
162
|
|
|
165
|
-
|
|
163
|
+
should "notice header errors" do
|
|
166
164
|
lambda {
|
|
167
165
|
Rack::Lint.new(lambda { |env|
|
|
168
166
|
[200, Object.new, []]
|
|
@@ -235,7 +233,7 @@ context "Rack::Lint" do
|
|
|
235
233
|
}.should.not.raise(Rack::Lint::LintError)
|
|
236
234
|
end
|
|
237
235
|
|
|
238
|
-
|
|
236
|
+
should "notice content-type errors" do
|
|
239
237
|
lambda {
|
|
240
238
|
Rack::Lint.new(lambda { |env|
|
|
241
239
|
[200, {"Content-length" => "0"}, []]
|
|
@@ -253,7 +251,7 @@ context "Rack::Lint" do
|
|
|
253
251
|
end
|
|
254
252
|
end
|
|
255
253
|
|
|
256
|
-
|
|
254
|
+
should "notice content-length errors" do
|
|
257
255
|
[100, 101, 204, 304].each do |status|
|
|
258
256
|
lambda {
|
|
259
257
|
Rack::Lint.new(lambda { |env|
|
|
@@ -266,12 +264,12 @@ context "Rack::Lint" do
|
|
|
266
264
|
lambda {
|
|
267
265
|
Rack::Lint.new(lambda { |env|
|
|
268
266
|
[200, {"Content-type" => "text/plain", "Content-Length" => "1"}, []]
|
|
269
|
-
}).call(env({}))
|
|
267
|
+
}).call(env({}))[2].each { }
|
|
270
268
|
}.should.raise(Rack::Lint::LintError).
|
|
271
269
|
message.should.match(/Content-Length header was 1, but should be 0/)
|
|
272
270
|
end
|
|
273
271
|
|
|
274
|
-
|
|
272
|
+
should "notice body errors" do
|
|
275
273
|
lambda {
|
|
276
274
|
status, header, body = Rack::Lint.new(lambda { |env|
|
|
277
275
|
[200, {"Content-type" => "text/plain","Content-length" => "3"}, [1,2,3]]
|
|
@@ -281,7 +279,7 @@ context "Rack::Lint" do
|
|
|
281
279
|
message.should.match(/yielded non-string/)
|
|
282
280
|
end
|
|
283
281
|
|
|
284
|
-
|
|
282
|
+
should "notice input handling errors" do
|
|
285
283
|
lambda {
|
|
286
284
|
Rack::Lint.new(lambda { |env|
|
|
287
285
|
env["rack.input"].gets("\r\n")
|
|
@@ -425,7 +423,7 @@ context "Rack::Lint" do
|
|
|
425
423
|
message.should.match(/close must not be called/)
|
|
426
424
|
end
|
|
427
425
|
|
|
428
|
-
|
|
426
|
+
should "notice error handling errors" do
|
|
429
427
|
lambda {
|
|
430
428
|
Rack::Lint.new(lambda { |env|
|
|
431
429
|
env["rack.errors"].write(42)
|
|
@@ -443,7 +441,7 @@ context "Rack::Lint" do
|
|
|
443
441
|
message.should.match(/close must not be called/)
|
|
444
442
|
end
|
|
445
443
|
|
|
446
|
-
|
|
444
|
+
should "notice HEAD errors" do
|
|
447
445
|
lambda {
|
|
448
446
|
Rack::Lint.new(lambda { |env|
|
|
449
447
|
[200, {"Content-type" => "test/plain", "Content-length" => "3"}, []]
|
|
@@ -453,12 +451,12 @@ context "Rack::Lint" do
|
|
|
453
451
|
lambda {
|
|
454
452
|
Rack::Lint.new(lambda { |env|
|
|
455
453
|
[200, {"Content-type" => "test/plain", "Content-length" => "3"}, ["foo"]]
|
|
456
|
-
}).call(env({"REQUEST_METHOD" => "HEAD"}))
|
|
454
|
+
}).call(env({"REQUEST_METHOD" => "HEAD"}))[2].each { }
|
|
457
455
|
}.should.raise(Rack::Lint::LintError).
|
|
458
456
|
message.should.match(/body was given for HEAD/)
|
|
459
457
|
end
|
|
460
458
|
|
|
461
|
-
|
|
459
|
+
should "pass valid read calls" do
|
|
462
460
|
hello_str = "hello world"
|
|
463
461
|
hello_str.force_encoding("ASCII-8BIT") if hello_str.respond_to? :force_encoding
|
|
464
462
|
lambda {
|
|
@@ -505,19 +503,8 @@ context "Rack::Lint" do
|
|
|
505
503
|
end
|
|
506
504
|
end
|
|
507
505
|
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
class IOMock
|
|
511
|
-
def size
|
|
512
|
-
101
|
|
513
|
-
end
|
|
514
|
-
end
|
|
515
|
-
|
|
516
|
-
wrapper = Rack::Lint::InputWrapper.new(IOMock.new)
|
|
517
|
-
wrapper.size.should == 101
|
|
518
|
-
end
|
|
519
|
-
|
|
520
|
-
specify "delegates :rewind to underlying IO object" do
|
|
506
|
+
describe "Rack::Lint::InputWrapper" do
|
|
507
|
+
should "delegate :rewind to underlying IO object" do
|
|
521
508
|
io = StringIO.new("123")
|
|
522
509
|
wrapper = Rack::Lint::InputWrapper.new(io)
|
|
523
510
|
wrapper.read.should.equal "123"
|