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
@@ -1,4 +1,5 @@
|
|
1
|
-
require '
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'rack/show_status'
|
2
3
|
require 'rack/lint'
|
3
4
|
require 'rack/mock'
|
4
5
|
require 'rack/utils'
|
@@ -7,23 +8,23 @@ describe Rack::ShowStatus do
|
|
7
8
|
def show_status(app)
|
8
9
|
Rack::Lint.new Rack::ShowStatus.new(app)
|
9
10
|
end
|
10
|
-
|
11
|
-
|
11
|
+
|
12
|
+
it "provide a default status message" do
|
12
13
|
req = Rack::MockRequest.new(
|
13
14
|
show_status(lambda{|env|
|
14
15
|
[404, {"Content-Type" => "text/plain", "Content-Length" => "0"}, []]
|
15
16
|
}))
|
16
17
|
|
17
18
|
res = req.get("/", :lint => true)
|
18
|
-
res.
|
19
|
-
res.
|
19
|
+
res.must_be :not_found?
|
20
|
+
res.wont_be_empty
|
20
21
|
|
21
|
-
res["Content-Type"].
|
22
|
-
res
|
23
|
-
res
|
22
|
+
res["Content-Type"].must_equal "text/html"
|
23
|
+
assert_match(res, /404/)
|
24
|
+
assert_match(res, /Not Found/)
|
24
25
|
end
|
25
26
|
|
26
|
-
|
27
|
+
it "let the app provide additional information" do
|
27
28
|
req = Rack::MockRequest.new(
|
28
29
|
show_status(
|
29
30
|
lambda{|env|
|
@@ -32,16 +33,16 @@ describe Rack::ShowStatus do
|
|
32
33
|
}))
|
33
34
|
|
34
35
|
res = req.get("/", :lint => true)
|
35
|
-
res.
|
36
|
-
res.
|
36
|
+
res.must_be :not_found?
|
37
|
+
res.wont_be_empty
|
37
38
|
|
38
|
-
res["Content-Type"].
|
39
|
-
res
|
40
|
-
res
|
41
|
-
res
|
39
|
+
res["Content-Type"].must_equal "text/html"
|
40
|
+
assert_match(res, /404/)
|
41
|
+
assert_match(res, /Not Found/)
|
42
|
+
assert_match(res, /too meta/)
|
42
43
|
end
|
43
44
|
|
44
|
-
|
45
|
+
it "escape error" do
|
45
46
|
detail = "<script>alert('hi \"')</script>"
|
46
47
|
req = Rack::MockRequest.new(
|
47
48
|
show_status(
|
@@ -51,15 +52,15 @@ describe Rack::ShowStatus do
|
|
51
52
|
}))
|
52
53
|
|
53
54
|
res = req.get("/", :lint => true)
|
54
|
-
res.
|
55
|
+
res.wont_be_empty
|
55
56
|
|
56
|
-
res["Content-Type"].
|
57
|
-
res
|
58
|
-
res.
|
59
|
-
res.body.
|
57
|
+
res["Content-Type"].must_equal "text/html"
|
58
|
+
assert_match(res, /500/)
|
59
|
+
res.wont_include detail
|
60
|
+
res.body.must_include Rack::Utils.escape_html(detail)
|
60
61
|
end
|
61
62
|
|
62
|
-
|
63
|
+
it "not replace existing messages" do
|
63
64
|
req = Rack::MockRequest.new(
|
64
65
|
show_status(
|
65
66
|
lambda{|env|
|
@@ -67,22 +68,22 @@ describe Rack::ShowStatus do
|
|
67
68
|
}))
|
68
69
|
|
69
70
|
res = req.get("/", :lint => true)
|
70
|
-
res.
|
71
|
+
res.must_be :not_found?
|
71
72
|
|
72
|
-
res.body.
|
73
|
+
res.body.must_equal "foo!"
|
73
74
|
end
|
74
75
|
|
75
|
-
|
76
|
+
it "pass on original headers" do
|
76
77
|
headers = {"WWW-Authenticate" => "Basic blah"}
|
77
78
|
|
78
79
|
req = Rack::MockRequest.new(
|
79
80
|
show_status(lambda{|env| [401, headers, []] }))
|
80
81
|
res = req.get("/", :lint => true)
|
81
82
|
|
82
|
-
res["WWW-Authenticate"].
|
83
|
+
res["WWW-Authenticate"].must_equal "Basic blah"
|
83
84
|
end
|
84
85
|
|
85
|
-
|
86
|
+
it "replace existing messages if there is detail" do
|
86
87
|
req = Rack::MockRequest.new(
|
87
88
|
show_status(
|
88
89
|
lambda{|env|
|
@@ -91,13 +92,13 @@ describe Rack::ShowStatus do
|
|
91
92
|
}))
|
92
93
|
|
93
94
|
res = req.get("/", :lint => true)
|
94
|
-
res.
|
95
|
-
res.
|
96
|
-
|
97
|
-
res["Content-Type"].
|
98
|
-
res["Content-Length"].
|
99
|
-
res
|
100
|
-
res
|
101
|
-
res.body.
|
95
|
+
res.must_be :not_found?
|
96
|
+
res.wont_be_empty
|
97
|
+
|
98
|
+
res["Content-Type"].must_equal "text/html"
|
99
|
+
res["Content-Length"].wont_equal "4"
|
100
|
+
assert_match(res, /404/)
|
101
|
+
assert_match(res, /too meta/)
|
102
|
+
res.body.wont_match(/foo/)
|
102
103
|
end
|
103
104
|
end
|
data/test/spec_static.rb
CHANGED
@@ -1,6 +1,9 @@
|
|
1
|
+
require 'minitest/autorun'
|
1
2
|
require 'rack/static'
|
2
3
|
require 'rack/lint'
|
3
4
|
require 'rack/mock'
|
5
|
+
require 'zlib'
|
6
|
+
require 'stringio'
|
4
7
|
|
5
8
|
class DummyApp
|
6
9
|
def call(env)
|
@@ -18,64 +21,101 @@ describe Rack::Static do
|
|
18
21
|
OPTIONS = {:urls => ["/cgi"], :root => root}
|
19
22
|
STATIC_OPTIONS = {:urls => [""], :root => "#{root}/static", :index => 'index.html'}
|
20
23
|
HASH_OPTIONS = {:urls => {"/cgi/sekret" => 'cgi/test'}, :root => root}
|
24
|
+
HASH_ROOT_OPTIONS = {:urls => {"/" => "static/foo.html"}, :root => root}
|
25
|
+
GZIP_OPTIONS = {:urls => ["/cgi"], :root => root, :gzip=>true}
|
21
26
|
|
27
|
+
before do
|
22
28
|
@request = Rack::MockRequest.new(static(DummyApp.new, OPTIONS))
|
23
29
|
@static_request = Rack::MockRequest.new(static(DummyApp.new, STATIC_OPTIONS))
|
24
30
|
@hash_request = Rack::MockRequest.new(static(DummyApp.new, HASH_OPTIONS))
|
31
|
+
@hash_root_request = Rack::MockRequest.new(static(DummyApp.new, HASH_ROOT_OPTIONS))
|
32
|
+
@gzip_request = Rack::MockRequest.new(static(DummyApp.new, GZIP_OPTIONS))
|
33
|
+
@header_request = Rack::MockRequest.new(static(DummyApp.new, HEADER_OPTIONS))
|
34
|
+
end
|
25
35
|
|
26
36
|
it "serves files" do
|
27
37
|
res = @request.get("/cgi/test")
|
28
|
-
res.
|
29
|
-
res.body.
|
38
|
+
res.must_be :ok?
|
39
|
+
res.body.must_match(/ruby/)
|
30
40
|
end
|
31
41
|
|
32
42
|
it "404s if url root is known but it can't find the file" do
|
33
43
|
res = @request.get("/cgi/foo")
|
34
|
-
res.
|
44
|
+
res.must_be :not_found?
|
35
45
|
end
|
36
46
|
|
37
47
|
it "calls down the chain if url root is not known" do
|
38
48
|
res = @request.get("/something/else")
|
39
|
-
res.
|
40
|
-
res.body.
|
49
|
+
res.must_be :ok?
|
50
|
+
res.body.must_equal "Hello World"
|
41
51
|
end
|
42
52
|
|
43
53
|
it "calls index file when requesting root in the given folder" do
|
44
54
|
res = @static_request.get("/")
|
45
|
-
res.
|
46
|
-
res.body.
|
55
|
+
res.must_be :ok?
|
56
|
+
res.body.must_match(/index!/)
|
47
57
|
|
48
58
|
res = @static_request.get("/other/")
|
49
|
-
res.
|
59
|
+
res.must_be :not_found?
|
50
60
|
|
51
61
|
res = @static_request.get("/another/")
|
52
|
-
res.
|
53
|
-
res.body.
|
62
|
+
res.must_be :ok?
|
63
|
+
res.body.must_match(/another index!/)
|
54
64
|
end
|
55
65
|
|
56
66
|
it "doesn't call index file if :index option was omitted" do
|
57
67
|
res = @request.get("/")
|
58
|
-
res.body.
|
68
|
+
res.body.must_equal "Hello World"
|
59
69
|
end
|
60
70
|
|
61
71
|
it "serves hidden files" do
|
62
72
|
res = @hash_request.get("/cgi/sekret")
|
63
|
-
res.
|
64
|
-
res.body.
|
73
|
+
res.must_be :ok?
|
74
|
+
res.body.must_match(/ruby/)
|
65
75
|
end
|
66
76
|
|
67
77
|
it "calls down the chain if the URI is not specified" do
|
68
78
|
res = @hash_request.get("/something/else")
|
69
|
-
res.
|
70
|
-
res.body.
|
79
|
+
res.must_be :ok?
|
80
|
+
res.body.must_equal "Hello World"
|
81
|
+
end
|
82
|
+
|
83
|
+
it "allows the root URI to be configured via hash options" do
|
84
|
+
res = @hash_root_request.get("/")
|
85
|
+
res.must_be :ok?
|
86
|
+
res.body.must_match(/foo.html!/)
|
87
|
+
end
|
88
|
+
|
89
|
+
it "serves gzipped files if client accepts gzip encoding and gzip files are present" do
|
90
|
+
res = @gzip_request.get("/cgi/test", 'HTTP_ACCEPT_ENCODING'=>'deflate, gzip')
|
91
|
+
res.must_be :ok?
|
92
|
+
res.headers['Content-Encoding'].must_equal 'gzip'
|
93
|
+
res.headers['Content-Type'].must_equal 'text/plain'
|
94
|
+
Zlib::GzipReader.wrap(StringIO.new(res.body), &:read).must_match(/ruby/)
|
95
|
+
end
|
96
|
+
|
97
|
+
it "serves regular files if client accepts gzip encoding and gzip files are not present" do
|
98
|
+
res = @gzip_request.get("/cgi/rackup_stub.rb", 'HTTP_ACCEPT_ENCODING'=>'deflate, gzip')
|
99
|
+
res.must_be :ok?
|
100
|
+
res.headers['Content-Encoding'].must_be_nil
|
101
|
+
res.headers['Content-Type'].must_equal 'text/x-script.ruby'
|
102
|
+
res.body.must_match(/ruby/)
|
103
|
+
end
|
104
|
+
|
105
|
+
it "serves regular files if client does not accept gzip encoding" do
|
106
|
+
res = @gzip_request.get("/cgi/test")
|
107
|
+
res.must_be :ok?
|
108
|
+
res.headers['Content-Encoding'].must_be_nil
|
109
|
+
res.headers['Content-Type'].must_equal 'text/plain'
|
110
|
+
res.body.must_match(/ruby/)
|
71
111
|
end
|
72
112
|
|
73
113
|
it "supports serving fixed cache-control (legacy option)" do
|
74
114
|
opts = OPTIONS.merge(:cache_control => 'public')
|
75
115
|
request = Rack::MockRequest.new(static(DummyApp.new, opts))
|
76
116
|
res = request.get("/cgi/test")
|
77
|
-
res.
|
78
|
-
res.headers['Cache-Control'].
|
117
|
+
res.must_be :ok?
|
118
|
+
res.headers['Cache-Control'].must_equal 'public'
|
79
119
|
end
|
80
120
|
|
81
121
|
HEADER_OPTIONS = {:urls => ["/cgi"], :root => root, :header_rules => [
|
@@ -86,47 +126,46 @@ describe Rack::Static do
|
|
86
126
|
['cgi/assets/javascripts', {'Cache-Control' => 'public, max-age=500'}],
|
87
127
|
[/\.(css|erb)\z/, {'Cache-Control' => 'public, max-age=600'}]
|
88
128
|
]}
|
89
|
-
@header_request = Rack::MockRequest.new(static(DummyApp.new, HEADER_OPTIONS))
|
90
129
|
|
91
130
|
it "supports header rule :all" do
|
92
131
|
# Headers for all files via :all shortcut
|
93
132
|
res = @header_request.get('/cgi/assets/index.html')
|
94
|
-
res.
|
95
|
-
res.headers['Cache-Control'].
|
133
|
+
res.must_be :ok?
|
134
|
+
res.headers['Cache-Control'].must_equal 'public, max-age=100'
|
96
135
|
end
|
97
136
|
|
98
137
|
it "supports header rule :fonts" do
|
99
138
|
# Headers for web fonts via :fonts shortcut
|
100
139
|
res = @header_request.get('/cgi/assets/fonts/font.eot')
|
101
|
-
res.
|
102
|
-
res.headers['Cache-Control'].
|
140
|
+
res.must_be :ok?
|
141
|
+
res.headers['Cache-Control'].must_equal 'public, max-age=200'
|
103
142
|
end
|
104
143
|
|
105
144
|
it "supports file extension header rules provided as an Array" do
|
106
145
|
# Headers for file extensions via array
|
107
146
|
res = @header_request.get('/cgi/assets/images/image.png')
|
108
|
-
res.
|
109
|
-
res.headers['Cache-Control'].
|
147
|
+
res.must_be :ok?
|
148
|
+
res.headers['Cache-Control'].must_equal 'public, max-age=300'
|
110
149
|
end
|
111
150
|
|
112
151
|
it "supports folder rules provided as a String" do
|
113
152
|
# Headers for files in folder via string
|
114
153
|
res = @header_request.get('/cgi/assets/folder/test.js')
|
115
|
-
res.
|
116
|
-
res.headers['Cache-Control'].
|
154
|
+
res.must_be :ok?
|
155
|
+
res.headers['Cache-Control'].must_equal 'public, max-age=400'
|
117
156
|
end
|
118
157
|
|
119
158
|
it "supports folder header rules provided as a String not starting with a slash" do
|
120
159
|
res = @header_request.get('/cgi/assets/javascripts/app.js')
|
121
|
-
res.
|
122
|
-
res.headers['Cache-Control'].
|
160
|
+
res.must_be :ok?
|
161
|
+
res.headers['Cache-Control'].must_equal 'public, max-age=500'
|
123
162
|
end
|
124
163
|
|
125
164
|
it "supports flexible header rules provided as Regexp" do
|
126
165
|
# Flexible Headers via Regexp
|
127
166
|
res = @header_request.get('/cgi/assets/stylesheets/app.css')
|
128
|
-
res.
|
129
|
-
res.headers['Cache-Control'].
|
167
|
+
res.must_be :ok?
|
168
|
+
res.headers['Cache-Control'].must_equal 'public, max-age=600'
|
130
169
|
end
|
131
170
|
|
132
171
|
it "prioritizes header rules over fixed cache-control setting (legacy option)" do
|
@@ -138,8 +177,8 @@ describe Rack::Static do
|
|
138
177
|
|
139
178
|
request = Rack::MockRequest.new(static(DummyApp.new, opts))
|
140
179
|
res = request.get("/cgi/test")
|
141
|
-
res.
|
142
|
-
res.headers['Cache-Control'].
|
180
|
+
res.must_be :ok?
|
181
|
+
res.headers['Cache-Control'].must_equal 'public, max-age=42'
|
143
182
|
end
|
144
183
|
|
145
184
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'minitest/autorun'
|
1
2
|
require 'rack/tempfile_reaper'
|
2
3
|
require 'rack/lint'
|
3
4
|
require 'rack/mock'
|
@@ -23,33 +24,33 @@ describe Rack::TempfileReaper do
|
|
23
24
|
Rack::Lint.new(Rack::TempfileReaper.new(app)).call(@env)
|
24
25
|
end
|
25
26
|
|
26
|
-
|
27
|
+
it 'do nothing (i.e. not bomb out) without env[rack.tempfiles]' do
|
27
28
|
app = lambda { |_| [200, {}, ['Hello, World!']] }
|
28
29
|
response = call(app)
|
29
30
|
response[2].close
|
30
|
-
response[0].
|
31
|
+
response[0].must_equal 200
|
31
32
|
end
|
32
33
|
|
33
|
-
|
34
|
+
it 'close env[rack.tempfiles] when body is closed' do
|
34
35
|
tempfile1, tempfile2 = MockTempfile.new, MockTempfile.new
|
35
36
|
@env['rack.tempfiles'] = [ tempfile1, tempfile2 ]
|
36
37
|
app = lambda { |_| [200, {}, ['Hello, World!']] }
|
37
38
|
call(app)[2].close
|
38
|
-
tempfile1.closed.
|
39
|
-
tempfile2.closed.
|
39
|
+
tempfile1.closed.must_equal true
|
40
|
+
tempfile2.closed.must_equal true
|
40
41
|
end
|
41
42
|
|
42
|
-
|
43
|
+
it 'initialize env[rack.tempfiles] when not already present' do
|
43
44
|
tempfile = MockTempfile.new
|
44
45
|
app = lambda do |env|
|
45
46
|
env['rack.tempfiles'] << tempfile
|
46
47
|
[200, {}, ['Hello, World!']]
|
47
48
|
end
|
48
49
|
call(app)[2].close
|
49
|
-
tempfile.closed.
|
50
|
+
tempfile.closed.must_equal true
|
50
51
|
end
|
51
52
|
|
52
|
-
|
53
|
+
it 'append env[rack.tempfiles] when already present' do
|
53
54
|
tempfile1, tempfile2 = MockTempfile.new, MockTempfile.new
|
54
55
|
@env['rack.tempfiles'] = [ tempfile1 ]
|
55
56
|
app = lambda do |env|
|
@@ -57,7 +58,7 @@ describe Rack::TempfileReaper do
|
|
57
58
|
[200, {}, ['Hello, World!']]
|
58
59
|
end
|
59
60
|
call(app)[2].close
|
60
|
-
tempfile1.closed.
|
61
|
-
tempfile2.closed.
|
61
|
+
tempfile1.closed.must_equal true
|
62
|
+
tempfile2.closed.must_equal true
|
62
63
|
end
|
63
64
|
end
|
data/test/spec_thin.rb
CHANGED
@@ -1,89 +1,94 @@
|
|
1
|
+
require 'minitest/autorun'
|
1
2
|
begin
|
2
3
|
require 'rack/handler/thin'
|
3
4
|
require File.expand_path('../testrequest', __FILE__)
|
4
5
|
require 'timeout'
|
5
6
|
|
6
7
|
describe Rack::Handler::Thin do
|
7
|
-
|
8
|
+
include TestRequest::Helpers
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
|
10
|
+
before do
|
11
|
+
@app = Rack::Lint.new(TestRequest.new)
|
12
|
+
@server = nil
|
13
|
+
Thin::Logging.silent = true
|
12
14
|
|
13
|
-
|
14
|
-
|
15
|
-
|
15
|
+
@thread = Thread.new do
|
16
|
+
Rack::Handler::Thin.run(@app, :Host => @host='127.0.0.1', :Port => @port=9204, :tag => "tag") do |server|
|
17
|
+
@server = server
|
18
|
+
end
|
16
19
|
end
|
20
|
+
|
21
|
+
Thread.pass until @server && @server.running?
|
22
|
+
end
|
23
|
+
|
24
|
+
after do
|
25
|
+
@server.stop!
|
26
|
+
@thread.join
|
17
27
|
end
|
18
28
|
|
19
|
-
Thread.pass until @server && @server.running?
|
20
29
|
|
21
|
-
|
30
|
+
it "respond" do
|
22
31
|
GET("/")
|
23
|
-
response.
|
32
|
+
response.wont_be :nil?
|
24
33
|
end
|
25
34
|
|
26
|
-
|
35
|
+
it "be a Thin" do
|
27
36
|
GET("/")
|
28
|
-
status.
|
29
|
-
response["SERVER_SOFTWARE"].
|
30
|
-
response["HTTP_VERSION"].
|
31
|
-
response["SERVER_PROTOCOL"].
|
32
|
-
response["SERVER_PORT"].
|
33
|
-
response["SERVER_NAME"].
|
37
|
+
status.must_equal 200
|
38
|
+
response["SERVER_SOFTWARE"].must_match(/thin/)
|
39
|
+
response["HTTP_VERSION"].must_equal "HTTP/1.1"
|
40
|
+
response["SERVER_PROTOCOL"].must_equal "HTTP/1.1"
|
41
|
+
response["SERVER_PORT"].must_equal "9204"
|
42
|
+
response["SERVER_NAME"].must_equal "127.0.0.1"
|
34
43
|
end
|
35
44
|
|
36
|
-
|
45
|
+
it "have rack headers" do
|
37
46
|
GET("/")
|
38
|
-
response["rack.version"].
|
39
|
-
response["rack.multithread"].
|
40
|
-
response["rack.multiprocess"].
|
41
|
-
response["rack.run_once"].
|
47
|
+
response["rack.version"].must_equal [1,0]
|
48
|
+
response["rack.multithread"].must_equal false
|
49
|
+
response["rack.multiprocess"].must_equal false
|
50
|
+
response["rack.run_once"].must_equal false
|
42
51
|
end
|
43
52
|
|
44
|
-
|
53
|
+
it "have CGI headers on GET" do
|
45
54
|
GET("/")
|
46
|
-
response["REQUEST_METHOD"].
|
47
|
-
response["REQUEST_PATH"].
|
48
|
-
response["PATH_INFO"].
|
49
|
-
response["QUERY_STRING"].
|
50
|
-
response["test.postdata"].
|
55
|
+
response["REQUEST_METHOD"].must_equal "GET"
|
56
|
+
response["REQUEST_PATH"].must_equal "/"
|
57
|
+
response["PATH_INFO"].must_equal "/"
|
58
|
+
response["QUERY_STRING"].must_equal ""
|
59
|
+
response["test.postdata"].must_equal ""
|
51
60
|
|
52
61
|
GET("/test/foo?quux=1")
|
53
|
-
response["REQUEST_METHOD"].
|
54
|
-
response["REQUEST_PATH"].
|
55
|
-
response["PATH_INFO"].
|
56
|
-
response["QUERY_STRING"].
|
62
|
+
response["REQUEST_METHOD"].must_equal "GET"
|
63
|
+
response["REQUEST_PATH"].must_equal "/test/foo"
|
64
|
+
response["PATH_INFO"].must_equal "/test/foo"
|
65
|
+
response["QUERY_STRING"].must_equal "quux=1"
|
57
66
|
end
|
58
67
|
|
59
|
-
|
68
|
+
it "have CGI headers on POST" do
|
60
69
|
POST("/", {"rack-form-data" => "23"}, {'X-test-header' => '42'})
|
61
|
-
status.
|
62
|
-
response["REQUEST_METHOD"].
|
63
|
-
response["REQUEST_PATH"].
|
64
|
-
response["QUERY_STRING"].
|
65
|
-
response["HTTP_X_TEST_HEADER"].
|
66
|
-
response["test.postdata"].
|
70
|
+
status.must_equal 200
|
71
|
+
response["REQUEST_METHOD"].must_equal "POST"
|
72
|
+
response["REQUEST_PATH"].must_equal "/"
|
73
|
+
response["QUERY_STRING"].must_equal ""
|
74
|
+
response["HTTP_X_TEST_HEADER"].must_equal "42"
|
75
|
+
response["test.postdata"].must_equal "rack-form-data=23"
|
67
76
|
end
|
68
77
|
|
69
|
-
|
78
|
+
it "support HTTP auth" do
|
70
79
|
GET("/test", {:user => "ruth", :passwd => "secret"})
|
71
|
-
response["HTTP_AUTHORIZATION"].
|
80
|
+
response["HTTP_AUTHORIZATION"].must_equal "Basic cnV0aDpzZWNyZXQ="
|
72
81
|
end
|
73
82
|
|
74
|
-
|
83
|
+
it "set status" do
|
75
84
|
GET("/test?secret")
|
76
|
-
status.
|
77
|
-
response["rack.url_scheme"].
|
85
|
+
status.must_equal 403
|
86
|
+
response["rack.url_scheme"].must_equal "http"
|
78
87
|
end
|
79
88
|
|
80
|
-
|
81
|
-
@server.tag.
|
89
|
+
it "set tag for server" do
|
90
|
+
@server.tag.must_equal 'tag'
|
82
91
|
end
|
83
|
-
|
84
|
-
@server.stop!
|
85
|
-
@thread.kill
|
86
|
-
|
87
92
|
end
|
88
93
|
|
89
94
|
rescue LoadError
|