rack 2.0.9.4 → 2.1.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.
- checksums.yaml +4 -4
- data/{HISTORY.md → CHANGELOG.md} +214 -164
- data/{COPYING → MIT-LICENSE} +4 -2
- data/README.rdoc +79 -133
- data/Rakefile +25 -18
- data/SPEC +9 -9
- data/bin/rackup +1 -0
- data/example/lobster.ru +2 -0
- data/example/protectedlobster.rb +3 -1
- data/example/protectedlobster.ru +2 -0
- data/lib/rack/auth/abstract/handler.rb +3 -1
- data/lib/rack/auth/abstract/request.rb +2 -0
- data/lib/rack/auth/basic.rb +4 -1
- data/lib/rack/auth/digest/md5.rb +9 -7
- data/lib/rack/auth/digest/nonce.rb +6 -3
- data/lib/rack/auth/digest/params.rb +4 -2
- data/lib/rack/auth/digest/request.rb +2 -0
- data/lib/rack/body_proxy.rb +3 -6
- data/lib/rack/builder.rb +38 -15
- data/lib/rack/cascade.rb +6 -5
- data/lib/rack/chunked.rb +29 -6
- data/lib/rack/common_logger.rb +9 -11
- data/lib/rack/conditional_get.rb +3 -1
- data/lib/rack/config.rb +2 -0
- data/lib/rack/content_length.rb +3 -1
- data/lib/rack/content_type.rb +3 -1
- data/lib/rack/core_ext/regexp.rb +14 -0
- data/lib/rack/deflater.rb +28 -17
- data/lib/rack/directory.rb +17 -14
- data/lib/rack/etag.rb +3 -1
- data/lib/rack/events.rb +5 -3
- data/lib/rack/file.rb +5 -173
- data/lib/rack/files.rb +178 -0
- data/lib/rack/handler/cgi.rb +3 -1
- data/lib/rack/handler/fastcgi.rb +4 -2
- data/lib/rack/handler/lsws.rb +3 -1
- data/lib/rack/handler/scgi.rb +9 -6
- data/lib/rack/handler/thin.rb +3 -1
- data/lib/rack/handler/webrick.rb +4 -2
- data/lib/rack/handler.rb +7 -2
- data/lib/rack/head.rb +2 -0
- data/lib/rack/lint.rb +15 -12
- data/lib/rack/lobster.rb +7 -5
- data/lib/rack/lock.rb +2 -0
- data/lib/rack/logger.rb +2 -0
- data/lib/rack/media_type.rb +10 -5
- data/lib/rack/method_override.rb +4 -2
- data/lib/rack/mime.rb +9 -1
- data/lib/rack/mock.rb +74 -15
- data/lib/rack/multipart/generator.rb +6 -7
- data/lib/rack/multipart/parser.rb +55 -62
- data/lib/rack/multipart/uploaded_file.rb +2 -0
- data/lib/rack/multipart.rb +6 -3
- data/lib/rack/null_logger.rb +2 -0
- data/lib/rack/query_parser.rb +51 -25
- data/lib/rack/recursive.rb +7 -5
- data/lib/rack/reloader.rb +10 -4
- data/lib/rack/request.rb +79 -26
- data/lib/rack/response.rb +71 -31
- data/lib/rack/rewindable_input.rb +4 -2
- data/lib/rack/runtime.rb +4 -2
- data/lib/rack/sendfile.rb +15 -8
- data/lib/rack/server.rb +88 -16
- data/lib/rack/session/abstract/id.rb +40 -22
- data/lib/rack/session/cookie.rb +10 -9
- data/lib/rack/session/memcache.rb +4 -93
- data/lib/rack/session/pool.rb +4 -2
- data/lib/rack/show_exceptions.rb +15 -9
- data/lib/rack/show_status.rb +4 -2
- data/lib/rack/static.rb +15 -10
- data/lib/rack/tempfile_reaper.rb +2 -0
- data/lib/rack/urlmap.rb +11 -2
- data/lib/rack/utils.rb +64 -93
- data/lib/rack.rb +63 -60
- data/rack.gemspec +17 -7
- metadata +33 -175
- data/test/builder/an_underscore_app.rb +0 -5
- data/test/builder/anything.rb +0 -5
- data/test/builder/comment.ru +0 -4
- data/test/builder/end.ru +0 -5
- data/test/builder/line.ru +0 -1
- data/test/builder/options.ru +0 -2
- data/test/cgi/assets/folder/test.js +0 -1
- data/test/cgi/assets/fonts/font.eot +0 -1
- data/test/cgi/assets/images/image.png +0 -1
- data/test/cgi/assets/index.html +0 -1
- data/test/cgi/assets/javascripts/app.js +0 -1
- data/test/cgi/assets/stylesheets/app.css +0 -1
- data/test/cgi/lighttpd.conf +0 -26
- data/test/cgi/rackup_stub.rb +0 -6
- data/test/cgi/sample_rackup.ru +0 -5
- data/test/cgi/test +0 -9
- data/test/cgi/test+directory/test+file +0 -1
- data/test/cgi/test.fcgi +0 -9
- data/test/cgi/test.gz +0 -0
- data/test/cgi/test.ru +0 -5
- data/test/gemloader.rb +0 -10
- data/test/helper.rb +0 -34
- data/test/multipart/bad_robots +0 -259
- data/test/multipart/binary +0 -0
- data/test/multipart/content_type_and_no_filename +0 -6
- data/test/multipart/empty +0 -10
- data/test/multipart/fail_16384_nofile +0 -814
- data/test/multipart/file1.txt +0 -1
- data/test/multipart/filename_and_modification_param +0 -7
- data/test/multipart/filename_and_no_name +0 -6
- data/test/multipart/filename_with_encoded_words +0 -7
- data/test/multipart/filename_with_escaped_quotes +0 -6
- data/test/multipart/filename_with_escaped_quotes_and_modification_param +0 -7
- data/test/multipart/filename_with_null_byte +0 -7
- data/test/multipart/filename_with_percent_escaped_quotes +0 -6
- data/test/multipart/filename_with_single_quote +0 -7
- data/test/multipart/filename_with_unescaped_percentages +0 -6
- data/test/multipart/filename_with_unescaped_percentages2 +0 -6
- data/test/multipart/filename_with_unescaped_percentages3 +0 -6
- data/test/multipart/filename_with_unescaped_quotes +0 -6
- data/test/multipart/ie +0 -6
- data/test/multipart/invalid_character +0 -6
- data/test/multipart/mixed_files +0 -21
- data/test/multipart/nested +0 -10
- data/test/multipart/none +0 -9
- data/test/multipart/quoted +0 -15
- data/test/multipart/rack-logo.png +0 -0
- data/test/multipart/semicolon +0 -6
- data/test/multipart/text +0 -15
- data/test/multipart/three_files_three_fields +0 -31
- data/test/multipart/unity3d_wwwform +0 -11
- data/test/multipart/webkit +0 -32
- data/test/rackup/config.ru +0 -31
- data/test/registering_handler/rack/handler/registering_myself.rb +0 -8
- data/test/spec_auth_basic.rb +0 -89
- data/test/spec_auth_digest.rb +0 -260
- data/test/spec_body_proxy.rb +0 -85
- data/test/spec_builder.rb +0 -233
- data/test/spec_cascade.rb +0 -63
- data/test/spec_cgi.rb +0 -84
- data/test/spec_chunked.rb +0 -103
- data/test/spec_common_logger.rb +0 -107
- data/test/spec_conditional_get.rb +0 -103
- data/test/spec_config.rb +0 -23
- data/test/spec_content_length.rb +0 -86
- data/test/spec_content_type.rb +0 -46
- data/test/spec_deflater.rb +0 -375
- data/test/spec_directory.rb +0 -148
- data/test/spec_etag.rb +0 -108
- data/test/spec_events.rb +0 -133
- data/test/spec_fastcgi.rb +0 -85
- data/test/spec_file.rb +0 -264
- data/test/spec_handler.rb +0 -57
- data/test/spec_head.rb +0 -46
- data/test/spec_lint.rb +0 -520
- data/test/spec_lobster.rb +0 -59
- data/test/spec_lock.rb +0 -204
- data/test/spec_logger.rb +0 -24
- data/test/spec_media_type.rb +0 -42
- data/test/spec_method_override.rb +0 -110
- data/test/spec_mime.rb +0 -51
- data/test/spec_mock.rb +0 -359
- data/test/spec_multipart.rb +0 -721
- data/test/spec_null_logger.rb +0 -21
- data/test/spec_recursive.rb +0 -75
- data/test/spec_request.rb +0 -1423
- data/test/spec_response.rb +0 -528
- data/test/spec_rewindable_input.rb +0 -128
- data/test/spec_runtime.rb +0 -50
- data/test/spec_sendfile.rb +0 -125
- data/test/spec_server.rb +0 -193
- data/test/spec_session_abstract_id.rb +0 -31
- data/test/spec_session_abstract_session_hash.rb +0 -45
- data/test/spec_session_cookie.rb +0 -442
- data/test/spec_session_memcache.rb +0 -357
- data/test/spec_session_persisted_secure_secure_session_hash.rb +0 -73
- data/test/spec_session_pool.rb +0 -247
- data/test/spec_show_exceptions.rb +0 -93
- data/test/spec_show_status.rb +0 -104
- data/test/spec_static.rb +0 -184
- data/test/spec_tempfile_reaper.rb +0 -64
- data/test/spec_thin.rb +0 -96
- data/test/spec_urlmap.rb +0 -237
- data/test/spec_utils.rb +0 -742
- data/test/spec_version.rb +0 -11
- data/test/spec_webrick.rb +0 -206
- data/test/static/another/index.html +0 -1
- data/test/static/foo.html +0 -1
- data/test/static/index.html +0 -1
- data/test/testrequest.rb +0 -78
- data/test/unregistered_handler/rack/handler/unregistered.rb +0 -7
- data/test/unregistered_handler/rack/handler/unregistered_long_one.rb +0 -7
@@ -1,93 +0,0 @@
|
|
1
|
-
require 'minitest/autorun'
|
2
|
-
require 'rack/show_exceptions'
|
3
|
-
require 'rack/lint'
|
4
|
-
require 'rack/mock'
|
5
|
-
|
6
|
-
describe Rack::ShowExceptions do
|
7
|
-
def show_exceptions(app)
|
8
|
-
Rack::Lint.new Rack::ShowExceptions.new(app)
|
9
|
-
end
|
10
|
-
|
11
|
-
it "catches exceptions" do
|
12
|
-
res = nil
|
13
|
-
|
14
|
-
req = Rack::MockRequest.new(
|
15
|
-
show_exceptions(
|
16
|
-
lambda{|env| raise RuntimeError }
|
17
|
-
))
|
18
|
-
|
19
|
-
res = req.get("/", "HTTP_ACCEPT" => "text/html")
|
20
|
-
|
21
|
-
res.must_be :server_error?
|
22
|
-
res.status.must_equal 500
|
23
|
-
|
24
|
-
assert_match(res, /RuntimeError/)
|
25
|
-
assert_match(res, /ShowExceptions/)
|
26
|
-
end
|
27
|
-
|
28
|
-
it "responds with HTML only to requests accepting HTML" do
|
29
|
-
res = nil
|
30
|
-
|
31
|
-
req = Rack::MockRequest.new(
|
32
|
-
show_exceptions(
|
33
|
-
lambda{|env| raise RuntimeError, "It was never supposed to work" }
|
34
|
-
))
|
35
|
-
|
36
|
-
[
|
37
|
-
# Serve text/html when the client accepts text/html
|
38
|
-
["text/html", ["/", {"HTTP_ACCEPT" => "text/html"}]],
|
39
|
-
["text/html", ["/", {"HTTP_ACCEPT" => "*/*"}]],
|
40
|
-
# Serve text/plain when the client does not accept text/html
|
41
|
-
["text/plain", ["/"]],
|
42
|
-
["text/plain", ["/", {"HTTP_ACCEPT" => "application/json"}]]
|
43
|
-
].each do |exmime, rargs|
|
44
|
-
res = req.get(*rargs)
|
45
|
-
|
46
|
-
res.must_be :server_error?
|
47
|
-
res.status.must_equal 500
|
48
|
-
|
49
|
-
res.content_type.must_equal exmime
|
50
|
-
|
51
|
-
res.body.must_include "RuntimeError"
|
52
|
-
res.body.must_include "It was never supposed to work"
|
53
|
-
|
54
|
-
if exmime == "text/html"
|
55
|
-
res.body.must_include '</html>'
|
56
|
-
else
|
57
|
-
res.body.wont_include '</html>'
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
it "handles exceptions without a backtrace" do
|
63
|
-
res = nil
|
64
|
-
|
65
|
-
req = Rack::MockRequest.new(
|
66
|
-
show_exceptions(
|
67
|
-
lambda{|env| raise RuntimeError, "", [] }
|
68
|
-
)
|
69
|
-
)
|
70
|
-
|
71
|
-
res = req.get("/", "HTTP_ACCEPT" => "text/html")
|
72
|
-
|
73
|
-
res.must_be :server_error?
|
74
|
-
res.status.must_equal 500
|
75
|
-
|
76
|
-
assert_match(res, /RuntimeError/)
|
77
|
-
assert_match(res, /ShowExceptions/)
|
78
|
-
assert_match(res, /unknown location/)
|
79
|
-
end
|
80
|
-
|
81
|
-
it "knows to prefer plaintext for non-html" do
|
82
|
-
# We don't need an app for this
|
83
|
-
exc = Rack::ShowExceptions.new(nil)
|
84
|
-
|
85
|
-
[
|
86
|
-
[{ "HTTP_ACCEPT" => "text/plain" }, true],
|
87
|
-
[{ "HTTP_ACCEPT" => "text/foo" }, true],
|
88
|
-
[{ "HTTP_ACCEPT" => "text/html" }, false]
|
89
|
-
].each do |env, expected|
|
90
|
-
assert_equal(expected, exc.prefers_plaintext?(env))
|
91
|
-
end
|
92
|
-
end
|
93
|
-
end
|
data/test/spec_show_status.rb
DELETED
@@ -1,104 +0,0 @@
|
|
1
|
-
require 'minitest/autorun'
|
2
|
-
require 'rack/show_status'
|
3
|
-
require 'rack/lint'
|
4
|
-
require 'rack/mock'
|
5
|
-
require 'rack/utils'
|
6
|
-
|
7
|
-
describe Rack::ShowStatus do
|
8
|
-
def show_status(app)
|
9
|
-
Rack::Lint.new Rack::ShowStatus.new(app)
|
10
|
-
end
|
11
|
-
|
12
|
-
it "provide a default status message" do
|
13
|
-
req = Rack::MockRequest.new(
|
14
|
-
show_status(lambda{|env|
|
15
|
-
[404, {"Content-Type" => "text/plain", "Content-Length" => "0"}, []]
|
16
|
-
}))
|
17
|
-
|
18
|
-
res = req.get("/", :lint => true)
|
19
|
-
res.must_be :not_found?
|
20
|
-
res.wont_be_empty
|
21
|
-
|
22
|
-
res["Content-Type"].must_equal "text/html"
|
23
|
-
assert_match(res, /404/)
|
24
|
-
assert_match(res, /Not Found/)
|
25
|
-
end
|
26
|
-
|
27
|
-
it "let the app provide additional information" do
|
28
|
-
req = Rack::MockRequest.new(
|
29
|
-
show_status(
|
30
|
-
lambda{|env|
|
31
|
-
env["rack.showstatus.detail"] = "gone too meta."
|
32
|
-
[404, {"Content-Type" => "text/plain", "Content-Length" => "0"}, []]
|
33
|
-
}))
|
34
|
-
|
35
|
-
res = req.get("/", :lint => true)
|
36
|
-
res.must_be :not_found?
|
37
|
-
res.wont_be_empty
|
38
|
-
|
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/)
|
43
|
-
end
|
44
|
-
|
45
|
-
it "escape error" do
|
46
|
-
detail = "<script>alert('hi \"')</script>"
|
47
|
-
req = Rack::MockRequest.new(
|
48
|
-
show_status(
|
49
|
-
lambda{|env|
|
50
|
-
env["rack.showstatus.detail"] = detail
|
51
|
-
[500, {"Content-Type" => "text/plain", "Content-Length" => "0"}, []]
|
52
|
-
}))
|
53
|
-
|
54
|
-
res = req.get("/", :lint => true)
|
55
|
-
res.wont_be_empty
|
56
|
-
|
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)
|
61
|
-
end
|
62
|
-
|
63
|
-
it "not replace existing messages" do
|
64
|
-
req = Rack::MockRequest.new(
|
65
|
-
show_status(
|
66
|
-
lambda{|env|
|
67
|
-
[404, {"Content-Type" => "text/plain", "Content-Length" => "4"}, ["foo!"]]
|
68
|
-
}))
|
69
|
-
|
70
|
-
res = req.get("/", :lint => true)
|
71
|
-
res.must_be :not_found?
|
72
|
-
|
73
|
-
res.body.must_equal "foo!"
|
74
|
-
end
|
75
|
-
|
76
|
-
it "pass on original headers" do
|
77
|
-
headers = {"WWW-Authenticate" => "Basic blah"}
|
78
|
-
|
79
|
-
req = Rack::MockRequest.new(
|
80
|
-
show_status(lambda{|env| [401, headers, []] }))
|
81
|
-
res = req.get("/", :lint => true)
|
82
|
-
|
83
|
-
res["WWW-Authenticate"].must_equal "Basic blah"
|
84
|
-
end
|
85
|
-
|
86
|
-
it "replace existing messages if there is detail" do
|
87
|
-
req = Rack::MockRequest.new(
|
88
|
-
show_status(
|
89
|
-
lambda{|env|
|
90
|
-
env["rack.showstatus.detail"] = "gone too meta."
|
91
|
-
[404, {"Content-Type" => "text/plain", "Content-Length" => "4"}, ["foo!"]]
|
92
|
-
}))
|
93
|
-
|
94
|
-
res = req.get("/", :lint => true)
|
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/)
|
103
|
-
end
|
104
|
-
end
|
data/test/spec_static.rb
DELETED
@@ -1,184 +0,0 @@
|
|
1
|
-
require 'minitest/autorun'
|
2
|
-
require 'rack/static'
|
3
|
-
require 'rack/lint'
|
4
|
-
require 'rack/mock'
|
5
|
-
require 'zlib'
|
6
|
-
require 'stringio'
|
7
|
-
|
8
|
-
class DummyApp
|
9
|
-
def call(env)
|
10
|
-
[200, {"Content-Type" => "text/plain"}, ["Hello World"]]
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
describe Rack::Static do
|
15
|
-
def static(app, *args)
|
16
|
-
Rack::Lint.new Rack::Static.new(app, *args)
|
17
|
-
end
|
18
|
-
|
19
|
-
root = File.expand_path(File.dirname(__FILE__))
|
20
|
-
|
21
|
-
OPTIONS = {:urls => ["/cgi"], :root => root}
|
22
|
-
STATIC_OPTIONS = {:urls => [""], :root => "#{root}/static", :index => 'index.html'}
|
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}
|
26
|
-
|
27
|
-
before do
|
28
|
-
@request = Rack::MockRequest.new(static(DummyApp.new, OPTIONS))
|
29
|
-
@static_request = Rack::MockRequest.new(static(DummyApp.new, STATIC_OPTIONS))
|
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
|
35
|
-
|
36
|
-
it "serves files" do
|
37
|
-
res = @request.get("/cgi/test")
|
38
|
-
res.must_be :ok?
|
39
|
-
res.body.must_match(/ruby/)
|
40
|
-
end
|
41
|
-
|
42
|
-
it "404s if url root is known but it can't find the file" do
|
43
|
-
res = @request.get("/cgi/foo")
|
44
|
-
res.must_be :not_found?
|
45
|
-
end
|
46
|
-
|
47
|
-
it "calls down the chain if url root is not known" do
|
48
|
-
res = @request.get("/something/else")
|
49
|
-
res.must_be :ok?
|
50
|
-
res.body.must_equal "Hello World"
|
51
|
-
end
|
52
|
-
|
53
|
-
it "calls index file when requesting root in the given folder" do
|
54
|
-
res = @static_request.get("/")
|
55
|
-
res.must_be :ok?
|
56
|
-
res.body.must_match(/index!/)
|
57
|
-
|
58
|
-
res = @static_request.get("/other/")
|
59
|
-
res.must_be :not_found?
|
60
|
-
|
61
|
-
res = @static_request.get("/another/")
|
62
|
-
res.must_be :ok?
|
63
|
-
res.body.must_match(/another index!/)
|
64
|
-
end
|
65
|
-
|
66
|
-
it "doesn't call index file if :index option was omitted" do
|
67
|
-
res = @request.get("/")
|
68
|
-
res.body.must_equal "Hello World"
|
69
|
-
end
|
70
|
-
|
71
|
-
it "serves hidden files" do
|
72
|
-
res = @hash_request.get("/cgi/sekret")
|
73
|
-
res.must_be :ok?
|
74
|
-
res.body.must_match(/ruby/)
|
75
|
-
end
|
76
|
-
|
77
|
-
it "calls down the chain if the URI is not specified" do
|
78
|
-
res = @hash_request.get("/something/else")
|
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/)
|
111
|
-
end
|
112
|
-
|
113
|
-
it "supports serving fixed cache-control (legacy option)" do
|
114
|
-
opts = OPTIONS.merge(:cache_control => 'public')
|
115
|
-
request = Rack::MockRequest.new(static(DummyApp.new, opts))
|
116
|
-
res = request.get("/cgi/test")
|
117
|
-
res.must_be :ok?
|
118
|
-
res.headers['Cache-Control'].must_equal 'public'
|
119
|
-
end
|
120
|
-
|
121
|
-
HEADER_OPTIONS = {:urls => ["/cgi"], :root => root, :header_rules => [
|
122
|
-
[:all, {'Cache-Control' => 'public, max-age=100'}],
|
123
|
-
[:fonts, {'Cache-Control' => 'public, max-age=200'}],
|
124
|
-
[%w(png jpg), {'Cache-Control' => 'public, max-age=300'}],
|
125
|
-
['/cgi/assets/folder/', {'Cache-Control' => 'public, max-age=400'}],
|
126
|
-
['cgi/assets/javascripts', {'Cache-Control' => 'public, max-age=500'}],
|
127
|
-
[/\.(css|erb)\z/, {'Cache-Control' => 'public, max-age=600'}]
|
128
|
-
]}
|
129
|
-
|
130
|
-
it "supports header rule :all" do
|
131
|
-
# Headers for all files via :all shortcut
|
132
|
-
res = @header_request.get('/cgi/assets/index.html')
|
133
|
-
res.must_be :ok?
|
134
|
-
res.headers['Cache-Control'].must_equal 'public, max-age=100'
|
135
|
-
end
|
136
|
-
|
137
|
-
it "supports header rule :fonts" do
|
138
|
-
# Headers for web fonts via :fonts shortcut
|
139
|
-
res = @header_request.get('/cgi/assets/fonts/font.eot')
|
140
|
-
res.must_be :ok?
|
141
|
-
res.headers['Cache-Control'].must_equal 'public, max-age=200'
|
142
|
-
end
|
143
|
-
|
144
|
-
it "supports file extension header rules provided as an Array" do
|
145
|
-
# Headers for file extensions via array
|
146
|
-
res = @header_request.get('/cgi/assets/images/image.png')
|
147
|
-
res.must_be :ok?
|
148
|
-
res.headers['Cache-Control'].must_equal 'public, max-age=300'
|
149
|
-
end
|
150
|
-
|
151
|
-
it "supports folder rules provided as a String" do
|
152
|
-
# Headers for files in folder via string
|
153
|
-
res = @header_request.get('/cgi/assets/folder/test.js')
|
154
|
-
res.must_be :ok?
|
155
|
-
res.headers['Cache-Control'].must_equal 'public, max-age=400'
|
156
|
-
end
|
157
|
-
|
158
|
-
it "supports folder header rules provided as a String not starting with a slash" do
|
159
|
-
res = @header_request.get('/cgi/assets/javascripts/app.js')
|
160
|
-
res.must_be :ok?
|
161
|
-
res.headers['Cache-Control'].must_equal 'public, max-age=500'
|
162
|
-
end
|
163
|
-
|
164
|
-
it "supports flexible header rules provided as Regexp" do
|
165
|
-
# Flexible Headers via Regexp
|
166
|
-
res = @header_request.get('/cgi/assets/stylesheets/app.css')
|
167
|
-
res.must_be :ok?
|
168
|
-
res.headers['Cache-Control'].must_equal 'public, max-age=600'
|
169
|
-
end
|
170
|
-
|
171
|
-
it "prioritizes header rules over fixed cache-control setting (legacy option)" do
|
172
|
-
opts = OPTIONS.merge(
|
173
|
-
:cache_control => 'public, max-age=24',
|
174
|
-
:header_rules => [
|
175
|
-
[:all, {'Cache-Control' => 'public, max-age=42'}]
|
176
|
-
])
|
177
|
-
|
178
|
-
request = Rack::MockRequest.new(static(DummyApp.new, opts))
|
179
|
-
res = request.get("/cgi/test")
|
180
|
-
res.must_be :ok?
|
181
|
-
res.headers['Cache-Control'].must_equal 'public, max-age=42'
|
182
|
-
end
|
183
|
-
|
184
|
-
end
|
@@ -1,64 +0,0 @@
|
|
1
|
-
require 'minitest/autorun'
|
2
|
-
require 'rack/tempfile_reaper'
|
3
|
-
require 'rack/lint'
|
4
|
-
require 'rack/mock'
|
5
|
-
|
6
|
-
describe Rack::TempfileReaper do
|
7
|
-
class MockTempfile
|
8
|
-
attr_reader :closed
|
9
|
-
|
10
|
-
def initialize
|
11
|
-
@closed = false
|
12
|
-
end
|
13
|
-
|
14
|
-
def close!
|
15
|
-
@closed = true
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
before do
|
20
|
-
@env = Rack::MockRequest.env_for
|
21
|
-
end
|
22
|
-
|
23
|
-
def call(app)
|
24
|
-
Rack::Lint.new(Rack::TempfileReaper.new(app)).call(@env)
|
25
|
-
end
|
26
|
-
|
27
|
-
it 'do nothing (i.e. not bomb out) without env[rack.tempfiles]' do
|
28
|
-
app = lambda { |_| [200, {}, ['Hello, World!']] }
|
29
|
-
response = call(app)
|
30
|
-
response[2].close
|
31
|
-
response[0].must_equal 200
|
32
|
-
end
|
33
|
-
|
34
|
-
it 'close env[rack.tempfiles] when body is closed' do
|
35
|
-
tempfile1, tempfile2 = MockTempfile.new, MockTempfile.new
|
36
|
-
@env['rack.tempfiles'] = [ tempfile1, tempfile2 ]
|
37
|
-
app = lambda { |_| [200, {}, ['Hello, World!']] }
|
38
|
-
call(app)[2].close
|
39
|
-
tempfile1.closed.must_equal true
|
40
|
-
tempfile2.closed.must_equal true
|
41
|
-
end
|
42
|
-
|
43
|
-
it 'initialize env[rack.tempfiles] when not already present' do
|
44
|
-
tempfile = MockTempfile.new
|
45
|
-
app = lambda do |env|
|
46
|
-
env['rack.tempfiles'] << tempfile
|
47
|
-
[200, {}, ['Hello, World!']]
|
48
|
-
end
|
49
|
-
call(app)[2].close
|
50
|
-
tempfile.closed.must_equal true
|
51
|
-
end
|
52
|
-
|
53
|
-
it 'append env[rack.tempfiles] when already present' do
|
54
|
-
tempfile1, tempfile2 = MockTempfile.new, MockTempfile.new
|
55
|
-
@env['rack.tempfiles'] = [ tempfile1 ]
|
56
|
-
app = lambda do |env|
|
57
|
-
env['rack.tempfiles'] << tempfile2
|
58
|
-
[200, {}, ['Hello, World!']]
|
59
|
-
end
|
60
|
-
call(app)[2].close
|
61
|
-
tempfile1.closed.must_equal true
|
62
|
-
tempfile2.closed.must_equal true
|
63
|
-
end
|
64
|
-
end
|
data/test/spec_thin.rb
DELETED
@@ -1,96 +0,0 @@
|
|
1
|
-
require 'minitest/autorun'
|
2
|
-
begin
|
3
|
-
require 'rack/handler/thin'
|
4
|
-
require File.expand_path('../testrequest', __FILE__)
|
5
|
-
require 'timeout'
|
6
|
-
|
7
|
-
describe Rack::Handler::Thin do
|
8
|
-
include TestRequest::Helpers
|
9
|
-
|
10
|
-
before do
|
11
|
-
@app = Rack::Lint.new(TestRequest.new)
|
12
|
-
@server = nil
|
13
|
-
Thin::Logging.silent = true
|
14
|
-
|
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
|
19
|
-
end
|
20
|
-
|
21
|
-
Thread.pass until @server && @server.running?
|
22
|
-
end
|
23
|
-
|
24
|
-
after do
|
25
|
-
@server.stop!
|
26
|
-
@thread.join
|
27
|
-
end
|
28
|
-
|
29
|
-
|
30
|
-
it "respond" do
|
31
|
-
GET("/")
|
32
|
-
response.wont_be :nil?
|
33
|
-
end
|
34
|
-
|
35
|
-
it "be a Thin" do
|
36
|
-
GET("/")
|
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"
|
43
|
-
end
|
44
|
-
|
45
|
-
it "have rack headers" do
|
46
|
-
GET("/")
|
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
|
51
|
-
end
|
52
|
-
|
53
|
-
it "have CGI headers on GET" do
|
54
|
-
GET("/")
|
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 ""
|
60
|
-
|
61
|
-
GET("/test/foo?quux=1")
|
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"
|
66
|
-
end
|
67
|
-
|
68
|
-
it "have CGI headers on POST" do
|
69
|
-
POST("/", {"rack-form-data" => "23"}, {'X-test-header' => '42'})
|
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"
|
76
|
-
end
|
77
|
-
|
78
|
-
it "support HTTP auth" do
|
79
|
-
GET("/test", {:user => "ruth", :passwd => "secret"})
|
80
|
-
response["HTTP_AUTHORIZATION"].must_equal "Basic cnV0aDpzZWNyZXQ="
|
81
|
-
end
|
82
|
-
|
83
|
-
it "set status" do
|
84
|
-
GET("/test?secret")
|
85
|
-
status.must_equal 403
|
86
|
-
response["rack.url_scheme"].must_equal "http"
|
87
|
-
end
|
88
|
-
|
89
|
-
it "set tag for server" do
|
90
|
-
@server.tag.must_equal 'tag'
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
rescue LoadError
|
95
|
-
$stderr.puts "Skipping Rack::Handler::Thin tests (Thin is required). `gem install thin` and try again."
|
96
|
-
end
|