rack 1.1.6 → 1.6.9
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.
- checksums.yaml +7 -0
- data/COPYING +1 -1
- data/HISTORY.md +375 -0
- data/KNOWN-ISSUES +23 -0
- data/README.rdoc +312 -0
- data/Rakefile +124 -0
- data/SPEC +125 -32
- data/contrib/rack.png +0 -0
- data/contrib/rack.svg +150 -0
- data/contrib/rack_logo.svg +1 -1
- data/contrib/rdoc.css +412 -0
- data/example/protectedlobster.rb +1 -1
- data/lib/rack/auth/abstract/handler.rb +4 -4
- data/lib/rack/auth/abstract/request.rb +7 -5
- data/lib/rack/auth/basic.rb +1 -1
- data/lib/rack/auth/digest/md5.rb +7 -3
- data/lib/rack/auth/digest/nonce.rb +1 -1
- data/lib/rack/auth/digest/params.rb +7 -9
- data/lib/rack/auth/digest/request.rb +10 -9
- data/lib/rack/backports/uri/common_18.rb +56 -0
- data/lib/rack/backports/uri/common_192.rb +52 -0
- data/lib/rack/backports/uri/common_193.rb +29 -0
- data/lib/rack/body_proxy.rb +39 -0
- data/lib/rack/builder.rb +106 -22
- data/lib/rack/cascade.rb +17 -6
- data/lib/rack/chunked.rb +44 -24
- data/lib/rack/commonlogger.rb +36 -13
- data/lib/rack/conditionalget.rb +49 -17
- data/lib/rack/config.rb +5 -0
- data/lib/rack/content_length.rb +14 -6
- data/lib/rack/content_type.rb +7 -1
- data/lib/rack/deflater.rb +73 -15
- data/lib/rack/directory.rb +18 -8
- data/lib/rack/etag.rb +59 -9
- data/lib/rack/file.rb +106 -44
- data/lib/rack/handler/cgi.rb +11 -11
- data/lib/rack/handler/fastcgi.rb +18 -6
- data/lib/rack/handler/lsws.rb +2 -4
- data/lib/rack/handler/mongrel.rb +22 -6
- data/lib/rack/handler/scgi.rb +16 -8
- data/lib/rack/handler/thin.rb +19 -4
- data/lib/rack/handler/webrick.rb +72 -19
- data/lib/rack/handler.rb +47 -14
- data/lib/rack/head.rb +10 -2
- data/lib/rack/lint.rb +260 -75
- data/lib/rack/lobster.rb +13 -8
- data/lib/rack/lock.rb +13 -3
- data/lib/rack/logger.rb +0 -2
- data/lib/rack/methodoverride.rb +27 -8
- data/lib/rack/mime.rb +625 -167
- data/lib/rack/mock.rb +78 -53
- data/lib/rack/multipart/generator.rb +93 -0
- data/lib/rack/multipart/parser.rb +253 -0
- data/lib/rack/multipart/uploaded_file.rb +34 -0
- data/lib/rack/multipart.rb +34 -0
- data/lib/rack/nulllogger.rb +21 -2
- data/lib/rack/recursive.rb +10 -5
- data/lib/rack/reloader.rb +3 -2
- data/lib/rack/request.rb +201 -74
- data/lib/rack/response.rb +41 -28
- data/lib/rack/rewindable_input.rb +15 -11
- data/lib/rack/runtime.rb +16 -3
- data/lib/rack/sendfile.rb +47 -29
- data/lib/rack/server.rb +223 -47
- data/lib/rack/session/abstract/id.rb +289 -30
- data/lib/rack/session/cookie.rb +133 -44
- data/lib/rack/session/memcache.rb +30 -56
- data/lib/rack/session/pool.rb +19 -43
- data/lib/rack/showexceptions.rb +53 -15
- data/lib/rack/showstatus.rb +14 -7
- data/lib/rack/static.rb +124 -12
- data/lib/rack/tempfile_reaper.rb +22 -0
- data/lib/rack/urlmap.rb +49 -15
- data/lib/rack/utils/okjson.rb +600 -0
- data/lib/rack/utils.rb +363 -361
- data/lib/rack.rb +17 -23
- data/rack.gemspec +11 -20
- data/test/builder/anything.rb +5 -0
- data/test/builder/comment.ru +4 -0
- data/test/builder/end.ru +5 -0
- data/test/builder/line.ru +1 -0
- data/test/builder/options.ru +2 -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/cgi/lighttpd.conf +26 -0
- data/test/cgi/rackup_stub.rb +6 -0
- data/test/cgi/sample_rackup.ru +5 -0
- data/test/cgi/test +9 -0
- data/test/cgi/test+directory/test+file +1 -0
- data/test/cgi/test.fcgi +8 -0
- data/test/cgi/test.ru +5 -0
- data/test/gemloader.rb +10 -0
- data/test/multipart/bad_robots +259 -0
- data/test/multipart/binary +0 -0
- data/test/multipart/content_type_and_no_filename +6 -0
- data/test/multipart/empty +10 -0
- data/test/multipart/fail_16384_nofile +814 -0
- data/test/multipart/file1.txt +1 -0
- data/test/multipart/filename_and_modification_param +7 -0
- data/test/multipart/filename_and_no_name +6 -0
- data/test/multipart/filename_with_escaped_quotes +6 -0
- data/test/multipart/filename_with_escaped_quotes_and_modification_param +7 -0
- data/test/multipart/filename_with_null_byte +7 -0
- data/test/multipart/filename_with_percent_escaped_quotes +6 -0
- data/test/multipart/filename_with_unescaped_percentages +6 -0
- data/test/multipart/filename_with_unescaped_percentages2 +6 -0
- data/test/multipart/filename_with_unescaped_percentages3 +6 -0
- data/test/multipart/filename_with_unescaped_quotes +6 -0
- data/test/multipart/ie +6 -0
- data/test/multipart/invalid_character +6 -0
- data/test/multipart/mixed_files +21 -0
- data/test/multipart/nested +10 -0
- data/test/multipart/none +9 -0
- data/test/multipart/semicolon +6 -0
- data/test/multipart/text +15 -0
- data/test/multipart/three_files_three_fields +31 -0
- data/test/multipart/webkit +32 -0
- data/test/rackup/config.ru +31 -0
- data/test/registering_handler/rack/handler/registering_myself.rb +8 -0
- data/test/{spec_rack_auth_basic.rb → spec_auth_basic.rb} +23 -15
- data/test/{spec_rack_auth_digest.rb → spec_auth_digest.rb} +56 -29
- data/test/spec_body_proxy.rb +85 -0
- data/test/spec_builder.rb +223 -0
- data/test/{spec_rack_cascade.rb → spec_cascade.rb} +28 -15
- data/test/{spec_rack_cgi.rb → spec_cgi.rb} +44 -31
- data/test/spec_chunked.rb +101 -0
- data/test/spec_commonlogger.rb +93 -0
- data/test/spec_conditionalget.rb +102 -0
- data/test/{spec_rack_config.rb → spec_config.rb} +6 -8
- data/test/spec_content_length.rb +85 -0
- data/test/spec_content_type.rb +45 -0
- data/test/spec_deflater.rb +339 -0
- data/test/{spec_rack_directory.rb → spec_directory.rb} +37 -10
- data/test/spec_etag.rb +107 -0
- data/test/{spec_rack_fastcgi.rb → spec_fastcgi.rb} +47 -29
- data/test/spec_file.rb +221 -0
- data/test/spec_handler.rb +72 -0
- data/test/spec_head.rb +45 -0
- data/test/{spec_rack_lint.rb → spec_lint.rb} +82 -60
- data/test/spec_lobster.rb +58 -0
- data/test/spec_lock.rb +164 -0
- data/test/spec_logger.rb +23 -0
- data/test/spec_methodoverride.rb +95 -0
- data/test/spec_mime.rb +51 -0
- data/test/{spec_rack_mock.rb → spec_mock.rb} +92 -38
- data/test/{spec_rack_mongrel.rb → spec_mongrel.rb} +46 -53
- data/test/spec_multipart.rb +600 -0
- data/test/spec_nulllogger.rb +20 -0
- data/test/spec_recursive.rb +72 -0
- data/test/spec_request.rb +1227 -0
- data/test/spec_response.rb +407 -0
- data/test/spec_rewindable_input.rb +118 -0
- data/test/spec_runtime.rb +49 -0
- data/test/spec_sendfile.rb +130 -0
- data/test/spec_server.rb +167 -0
- data/test/spec_session_abstract_id.rb +53 -0
- data/test/spec_session_cookie.rb +410 -0
- data/test/{spec_rack_session_memcache.rb → spec_session_memcache.rb} +119 -71
- data/test/{spec_rack_session_pool.rb → spec_session_pool.rb} +106 -69
- data/test/spec_showexceptions.rb +85 -0
- data/test/spec_showstatus.rb +103 -0
- data/test/spec_static.rb +145 -0
- data/test/spec_tempfile_reaper.rb +63 -0
- data/test/{spec_rack_thin.rb → spec_thin.rb} +35 -35
- data/test/{spec_rack_urlmap.rb → spec_urlmap.rb} +40 -19
- data/test/spec_utils.rb +647 -0
- data/test/spec_version.rb +17 -0
- data/test/spec_webrick.rb +184 -0
- data/test/static/another/index.html +1 -0
- data/test/static/index.html +1 -0
- data/test/testrequest.rb +78 -0
- data/test/unregistered_handler/rack/handler/unregistered.rb +7 -0
- data/test/unregistered_handler/rack/handler/unregistered_long_one.rb +7 -0
- metadata +220 -239
- data/RDOX +0 -0
- data/README +0 -592
- data/lib/rack/adapter/camping.rb +0 -22
- data/test/spec_auth.rb +0 -57
- data/test/spec_rack_builder.rb +0 -84
- data/test/spec_rack_camping.rb +0 -55
- data/test/spec_rack_chunked.rb +0 -62
- data/test/spec_rack_commonlogger.rb +0 -61
- data/test/spec_rack_conditionalget.rb +0 -41
- data/test/spec_rack_content_length.rb +0 -43
- data/test/spec_rack_content_type.rb +0 -30
- data/test/spec_rack_deflater.rb +0 -127
- data/test/spec_rack_etag.rb +0 -17
- data/test/spec_rack_file.rb +0 -75
- data/test/spec_rack_handler.rb +0 -43
- data/test/spec_rack_head.rb +0 -30
- data/test/spec_rack_lobster.rb +0 -45
- data/test/spec_rack_lock.rb +0 -38
- data/test/spec_rack_logger.rb +0 -21
- data/test/spec_rack_methodoverride.rb +0 -60
- data/test/spec_rack_nulllogger.rb +0 -13
- data/test/spec_rack_recursive.rb +0 -77
- data/test/spec_rack_request.rb +0 -594
- data/test/spec_rack_response.rb +0 -221
- data/test/spec_rack_rewindable_input.rb +0 -118
- data/test/spec_rack_runtime.rb +0 -35
- data/test/spec_rack_sendfile.rb +0 -86
- data/test/spec_rack_session_cookie.rb +0 -92
- data/test/spec_rack_showexceptions.rb +0 -21
- data/test/spec_rack_showstatus.rb +0 -72
- data/test/spec_rack_static.rb +0 -37
- data/test/spec_rack_utils.rb +0 -557
- data/test/spec_rack_webrick.rb +0 -130
- data/test/spec_rackup.rb +0 -164
|
@@ -0,0 +1 @@
|
|
|
1
|
+
contents
|
data/test/multipart/ie
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
--AaB03x
|
|
2
|
+
Content-Disposition: form-data; name="foo"
|
|
3
|
+
|
|
4
|
+
bar
|
|
5
|
+
--AaB03x
|
|
6
|
+
Content-Disposition: form-data; name="files"
|
|
7
|
+
Content-Type: multipart/mixed, boundary=BbC04y
|
|
8
|
+
|
|
9
|
+
--BbC04y
|
|
10
|
+
Content-Disposition: attachment; filename="file.txt"
|
|
11
|
+
Content-Type: text/plain
|
|
12
|
+
|
|
13
|
+
contents
|
|
14
|
+
--BbC04y
|
|
15
|
+
Content-Disposition: attachment; filename="flowers.jpg"
|
|
16
|
+
Content-Type: image/jpeg
|
|
17
|
+
Content-Transfer-Encoding: binary
|
|
18
|
+
|
|
19
|
+
contents
|
|
20
|
+
--BbC04y--
|
|
21
|
+
--AaB03x--
|
data/test/multipart/none
ADDED
data/test/multipart/text
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
--AaB03x
|
|
2
|
+
Content-Disposition: form-data; name="submit-name"
|
|
3
|
+
|
|
4
|
+
Larry
|
|
5
|
+
--AaB03x
|
|
6
|
+
Content-Disposition: form-data; name="submit-name-with-content"
|
|
7
|
+
Content-Type: text/plain
|
|
8
|
+
|
|
9
|
+
Berry
|
|
10
|
+
--AaB03x
|
|
11
|
+
Content-Disposition: form-data; name="files"; filename="file1.txt"
|
|
12
|
+
Content-Type: text/plain
|
|
13
|
+
|
|
14
|
+
contents
|
|
15
|
+
--AaB03x--
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
--AaB03x
|
|
2
|
+
content-disposition: form-data; name="reply"
|
|
3
|
+
|
|
4
|
+
yes
|
|
5
|
+
--AaB03x
|
|
6
|
+
content-disposition: form-data; name="to"
|
|
7
|
+
|
|
8
|
+
people
|
|
9
|
+
--AaB03x
|
|
10
|
+
content-disposition: form-data; name="from"
|
|
11
|
+
|
|
12
|
+
others
|
|
13
|
+
--AaB03x
|
|
14
|
+
content-disposition: form-data; name="fileupload1"; filename="file1.jpg"
|
|
15
|
+
Content-Type: image/jpeg
|
|
16
|
+
Content-Transfer-Encoding: base64
|
|
17
|
+
|
|
18
|
+
/9j/4AAQSkZJRgABAQAAAQABAAD//gA+Q1JFQVRPUjogZ2QtanBlZyB2MS4wICh1c2luZyBJSkcg
|
|
19
|
+
--AaB03x
|
|
20
|
+
content-disposition: form-data; name="fileupload2"; filename="file2.jpg"
|
|
21
|
+
Content-Type: image/jpeg
|
|
22
|
+
Content-Transfer-Encoding: base64
|
|
23
|
+
|
|
24
|
+
/9j/4AAQSkZJRgABAQAAAQABAAD//gA+Q1JFQVRPUjogZ2QtanBlZyB2MS4wICh1c2luZyBJSkcg
|
|
25
|
+
--AaB03x
|
|
26
|
+
content-disposition: form-data; name="fileupload3"; filename="file3.jpg"
|
|
27
|
+
Content-Type: image/jpeg
|
|
28
|
+
Content-Transfer-Encoding: base64
|
|
29
|
+
|
|
30
|
+
/9j/4AAQSkZJRgABAQAAAQABAAD//gA+Q1JFQVRPUjogZ2QtanBlZyB2MS4wICh1c2luZyBJSkcg
|
|
31
|
+
--AaB03x--
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
------WebKitFormBoundaryWLHCs9qmcJJoyjKR
|
|
2
|
+
Content-Disposition: form-data; name="_method"
|
|
3
|
+
|
|
4
|
+
put
|
|
5
|
+
------WebKitFormBoundaryWLHCs9qmcJJoyjKR
|
|
6
|
+
Content-Disposition: form-data; name="profile[blog]"
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
------WebKitFormBoundaryWLHCs9qmcJJoyjKR
|
|
10
|
+
Content-Disposition: form-data; name="profile[public_email]"
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
------WebKitFormBoundaryWLHCs9qmcJJoyjKR
|
|
14
|
+
Content-Disposition: form-data; name="profile[interests]"
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
------WebKitFormBoundaryWLHCs9qmcJJoyjKR
|
|
18
|
+
Content-Disposition: form-data; name="profile[bio]"
|
|
19
|
+
|
|
20
|
+
hello
|
|
21
|
+
|
|
22
|
+
"quote"
|
|
23
|
+
------WebKitFormBoundaryWLHCs9qmcJJoyjKR
|
|
24
|
+
Content-Disposition: form-data; name="media"; filename=""
|
|
25
|
+
Content-Type: application/octet-stream
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
------WebKitFormBoundaryWLHCs9qmcJJoyjKR
|
|
29
|
+
Content-Disposition: form-data; name="commit"
|
|
30
|
+
|
|
31
|
+
Save
|
|
32
|
+
------WebKitFormBoundaryWLHCs9qmcJJoyjKR--
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
require "#{File.dirname(__FILE__)}/../testrequest"
|
|
2
|
+
|
|
3
|
+
$stderr = File.open("#{File.dirname(__FILE__)}/log_output", "w")
|
|
4
|
+
|
|
5
|
+
class EnvMiddleware
|
|
6
|
+
def initialize(app)
|
|
7
|
+
@app = app
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def call(env)
|
|
11
|
+
# provides a way to test that lint is present
|
|
12
|
+
if env["PATH_INFO"] == "/broken_lint"
|
|
13
|
+
return [200, {}, ["Broken Lint"]]
|
|
14
|
+
# provides a way to kill the process without knowing the pid
|
|
15
|
+
elsif env["PATH_INFO"] == "/die"
|
|
16
|
+
exit!
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
env["test.$DEBUG"] = $DEBUG
|
|
20
|
+
env["test.$EVAL"] = BUKKIT if defined?(BUKKIT)
|
|
21
|
+
env["test.$VERBOSE"] = $VERBOSE
|
|
22
|
+
env["test.$LOAD_PATH"] = $LOAD_PATH
|
|
23
|
+
env["test.stderr"] = File.expand_path($stderr.path)
|
|
24
|
+
env["test.Ping"] = defined?(Ping)
|
|
25
|
+
env["test.pid"] = Process.pid
|
|
26
|
+
@app.call(env)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
use EnvMiddleware
|
|
31
|
+
run TestRequest.new
|
|
@@ -1,25 +1,25 @@
|
|
|
1
|
-
require 'test/spec'
|
|
2
|
-
|
|
3
1
|
require 'rack/auth/basic'
|
|
2
|
+
require 'rack/lint'
|
|
4
3
|
require 'rack/mock'
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
describe Rack::Auth::Basic do
|
|
8
6
|
def realm
|
|
9
7
|
'WallysWorld'
|
|
10
8
|
end
|
|
11
|
-
|
|
9
|
+
|
|
12
10
|
def unprotected_app
|
|
13
|
-
lambda { |env|
|
|
11
|
+
Rack::Lint.new lambda { |env|
|
|
12
|
+
[ 200, {'Content-Type' => 'text/plain'}, ["Hi #{env['REMOTE_USER']}"] ]
|
|
13
|
+
}
|
|
14
14
|
end
|
|
15
|
-
|
|
15
|
+
|
|
16
16
|
def protected_app
|
|
17
17
|
app = Rack::Auth::Basic.new(unprotected_app) { |username, password| 'Boss' == username }
|
|
18
18
|
app.realm = realm
|
|
19
19
|
app
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
before do
|
|
23
23
|
@request = Rack::MockRequest.new(protected_app)
|
|
24
24
|
end
|
|
25
25
|
|
|
@@ -39,26 +39,26 @@ context 'Rack::Auth::Basic' do
|
|
|
39
39
|
response.body.should.be.empty
|
|
40
40
|
end
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
should 'challenge correctly when no credentials are specified' do
|
|
43
43
|
request do |response|
|
|
44
44
|
assert_basic_auth_challenge response
|
|
45
45
|
end
|
|
46
46
|
end
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
should 'rechallenge if incorrect credentials are specified' do
|
|
49
49
|
request_with_basic_auth 'joe', 'password' do |response|
|
|
50
50
|
assert_basic_auth_challenge response
|
|
51
51
|
end
|
|
52
52
|
end
|
|
53
53
|
|
|
54
|
-
|
|
54
|
+
should 'return application output if correct credentials are specified' do
|
|
55
55
|
request_with_basic_auth 'Boss', 'password' do |response|
|
|
56
56
|
response.status.should.equal 200
|
|
57
57
|
response.body.to_s.should.equal 'Hi Boss'
|
|
58
58
|
end
|
|
59
59
|
end
|
|
60
|
-
|
|
61
|
-
|
|
60
|
+
|
|
61
|
+
should 'return 400 Bad Request if different auth scheme used' do
|
|
62
62
|
request 'HTTP_AUTHORIZATION' => 'Digest params' do |response|
|
|
63
63
|
response.should.be.a.client_error
|
|
64
64
|
response.status.should.equal 400
|
|
@@ -66,8 +66,16 @@ context 'Rack::Auth::Basic' do
|
|
|
66
66
|
end
|
|
67
67
|
end
|
|
68
68
|
|
|
69
|
-
|
|
69
|
+
should 'return 400 Bad Request for a malformed authorization header' do
|
|
70
|
+
request 'HTTP_AUTHORIZATION' => '' do |response|
|
|
71
|
+
response.should.be.a.client_error
|
|
72
|
+
response.status.should.equal 400
|
|
73
|
+
response.should.not.include 'WWW-Authenticate'
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
it 'takes realm as optional constructor arg' do
|
|
70
78
|
app = Rack::Auth::Basic.new(unprotected_app, realm) { true }
|
|
71
|
-
|
|
79
|
+
realm.should == app.realm
|
|
72
80
|
end
|
|
73
81
|
end
|
|
@@ -1,27 +1,23 @@
|
|
|
1
|
-
require 'test/spec'
|
|
2
|
-
|
|
3
1
|
require 'rack/auth/digest/md5'
|
|
2
|
+
require 'rack/lint'
|
|
4
3
|
require 'rack/mock'
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
describe Rack::Auth::Digest::MD5 do
|
|
8
6
|
def realm
|
|
9
7
|
'WallysWorld'
|
|
10
8
|
end
|
|
11
9
|
|
|
12
10
|
def unprotected_app
|
|
13
|
-
lambda
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
Rack::Lint.new lambda { |env|
|
|
12
|
+
friend = Rack::Utils.parse_query(env["QUERY_STRING"])["friend"]
|
|
13
|
+
[ 200, {'Content-Type' => 'text/plain'}, ["Hi #{env['REMOTE_USER']}#{friend ? " and #{friend}" : ''}"] ]
|
|
14
|
+
}
|
|
16
15
|
end
|
|
17
16
|
|
|
18
17
|
def protected_app
|
|
19
|
-
|
|
18
|
+
Rack::Auth::Digest::MD5.new(unprotected_app, :realm => realm, :opaque => 'this-should-be-secret') do |username|
|
|
20
19
|
{ 'Alice' => 'correct-password' }[username]
|
|
21
20
|
end
|
|
22
|
-
app.realm = realm
|
|
23
|
-
app.opaque = 'this-should-be-secret'
|
|
24
|
-
app
|
|
25
21
|
end
|
|
26
22
|
|
|
27
23
|
def protected_app_with_hashed_passwords
|
|
@@ -45,7 +41,7 @@ context 'Rack::Auth::Digest::MD5' do
|
|
|
45
41
|
Rack::MethodOverride.new(protected_app)
|
|
46
42
|
end
|
|
47
43
|
|
|
48
|
-
|
|
44
|
+
before do
|
|
49
45
|
@request = Rack::MockRequest.new(protected_app)
|
|
50
46
|
end
|
|
51
47
|
|
|
@@ -117,20 +113,20 @@ context 'Rack::Auth::Digest::MD5' do
|
|
|
117
113
|
response.should.not.include 'WWW-Authenticate'
|
|
118
114
|
end
|
|
119
115
|
|
|
120
|
-
|
|
116
|
+
should 'challenge when no credentials are specified' do
|
|
121
117
|
request 'GET', '/' do |response|
|
|
122
118
|
assert_digest_auth_challenge response
|
|
123
119
|
end
|
|
124
120
|
end
|
|
125
121
|
|
|
126
|
-
|
|
122
|
+
should 'return application output if correct credentials given' do
|
|
127
123
|
request_with_digest_auth 'GET', '/', 'Alice', 'correct-password' do |response|
|
|
128
124
|
response.status.should.equal 200
|
|
129
125
|
response.body.to_s.should.equal 'Hi Alice'
|
|
130
126
|
end
|
|
131
127
|
end
|
|
132
128
|
|
|
133
|
-
|
|
129
|
+
should 'return application output if correct credentials given (hashed passwords)' do
|
|
134
130
|
@request = Rack::MockRequest.new(protected_app_with_hashed_passwords)
|
|
135
131
|
|
|
136
132
|
request_with_digest_auth 'GET', '/', 'Alice', 'correct-password' do |response|
|
|
@@ -139,25 +135,39 @@ context 'Rack::Auth::Digest::MD5' do
|
|
|
139
135
|
end
|
|
140
136
|
end
|
|
141
137
|
|
|
142
|
-
|
|
138
|
+
should 'rechallenge if incorrect username given' do
|
|
143
139
|
request_with_digest_auth 'GET', '/', 'Bob', 'correct-password' do |response|
|
|
144
140
|
assert_digest_auth_challenge response
|
|
145
141
|
end
|
|
146
142
|
end
|
|
147
143
|
|
|
148
|
-
|
|
144
|
+
should 'rechallenge if incorrect password given' do
|
|
149
145
|
request_with_digest_auth 'GET', '/', 'Alice', 'wrong-password' do |response|
|
|
150
146
|
assert_digest_auth_challenge response
|
|
151
147
|
end
|
|
152
148
|
end
|
|
153
149
|
|
|
154
|
-
|
|
150
|
+
should 'rechallenge if incorrect user and blank password given' do
|
|
155
151
|
request_with_digest_auth 'GET', '/', 'Bob', '' do |response|
|
|
156
152
|
assert_digest_auth_challenge response
|
|
157
153
|
end
|
|
158
154
|
end
|
|
159
155
|
|
|
160
|
-
|
|
156
|
+
should 'not rechallenge if nonce is not stale' do
|
|
157
|
+
begin
|
|
158
|
+
Rack::Auth::Digest::Nonce.time_limit = 10
|
|
159
|
+
|
|
160
|
+
request_with_digest_auth 'GET', '/', 'Alice', 'correct-password', :wait => 1 do |response|
|
|
161
|
+
response.status.should.equal 200
|
|
162
|
+
response.body.to_s.should.equal 'Hi Alice'
|
|
163
|
+
response.headers['WWW-Authenticate'].should.not =~ /\bstale=true\b/
|
|
164
|
+
end
|
|
165
|
+
ensure
|
|
166
|
+
Rack::Auth::Digest::Nonce.time_limit = nil
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
should 'rechallenge with stale parameter if nonce is stale' do
|
|
161
171
|
begin
|
|
162
172
|
Rack::Auth::Digest::Nonce.time_limit = 1
|
|
163
173
|
|
|
@@ -170,39 +180,39 @@ context 'Rack::Auth::Digest::MD5' do
|
|
|
170
180
|
end
|
|
171
181
|
end
|
|
172
182
|
|
|
173
|
-
|
|
183
|
+
should 'return 400 Bad Request if incorrect qop given' do
|
|
174
184
|
request_with_digest_auth 'GET', '/', 'Alice', 'correct-password', 'qop' => 'auth-int' do |response|
|
|
175
185
|
assert_bad_request response
|
|
176
186
|
end
|
|
177
187
|
end
|
|
178
188
|
|
|
179
|
-
|
|
189
|
+
should 'return 400 Bad Request if incorrect uri given' do
|
|
180
190
|
request_with_digest_auth 'GET', '/', 'Alice', 'correct-password', 'uri' => '/foo' do |response|
|
|
181
191
|
assert_bad_request response
|
|
182
192
|
end
|
|
183
193
|
end
|
|
184
194
|
|
|
185
|
-
|
|
195
|
+
should 'return 400 Bad Request if different auth scheme used' do
|
|
186
196
|
request 'GET', '/', 'HTTP_AUTHORIZATION' => 'Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==' do |response|
|
|
187
197
|
assert_bad_request response
|
|
188
198
|
end
|
|
189
199
|
end
|
|
190
200
|
|
|
191
|
-
|
|
201
|
+
should 'not require credentials for unprotected path' do
|
|
192
202
|
@request = Rack::MockRequest.new(partially_protected_app)
|
|
193
203
|
request 'GET', '/' do |response|
|
|
194
204
|
response.should.be.ok
|
|
195
205
|
end
|
|
196
206
|
end
|
|
197
207
|
|
|
198
|
-
|
|
208
|
+
should 'challenge when no credentials are specified for protected path' do
|
|
199
209
|
@request = Rack::MockRequest.new(partially_protected_app)
|
|
200
210
|
request 'GET', '/protected' do |response|
|
|
201
211
|
assert_digest_auth_challenge response
|
|
202
212
|
end
|
|
203
213
|
end
|
|
204
214
|
|
|
205
|
-
|
|
215
|
+
should 'return application output if correct credentials given for protected path' do
|
|
206
216
|
@request = Rack::MockRequest.new(partially_protected_app)
|
|
207
217
|
request_with_digest_auth 'GET', '/protected', 'Alice', 'correct-password' do |response|
|
|
208
218
|
response.status.should.equal 200
|
|
@@ -210,14 +220,31 @@ context 'Rack::Auth::Digest::MD5' do
|
|
|
210
220
|
end
|
|
211
221
|
end
|
|
212
222
|
|
|
213
|
-
|
|
223
|
+
should 'return application output when used with a query string and path as uri' do
|
|
224
|
+
@request = Rack::MockRequest.new(partially_protected_app)
|
|
225
|
+
request_with_digest_auth 'GET', '/protected?friend=Mike', 'Alice', 'correct-password' do |response|
|
|
226
|
+
response.status.should.equal 200
|
|
227
|
+
response.body.to_s.should.equal 'Hi Alice and Mike'
|
|
228
|
+
end
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
should 'return application output when used with a query string and fullpath as uri' do
|
|
232
|
+
@request = Rack::MockRequest.new(partially_protected_app)
|
|
233
|
+
qs_uri = '/protected?friend=Mike'
|
|
234
|
+
request_with_digest_auth 'GET', qs_uri, 'Alice', 'correct-password', 'uri' => qs_uri do |response|
|
|
235
|
+
response.status.should.equal 200
|
|
236
|
+
response.body.to_s.should.equal 'Hi Alice and Mike'
|
|
237
|
+
end
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
should 'return application output if correct credentials given for POST' do
|
|
214
241
|
request_with_digest_auth 'POST', '/', 'Alice', 'correct-password' do |response|
|
|
215
242
|
response.status.should.equal 200
|
|
216
243
|
response.body.to_s.should.equal 'Hi Alice'
|
|
217
244
|
end
|
|
218
245
|
end
|
|
219
246
|
|
|
220
|
-
|
|
247
|
+
should 'return application output if correct credentials given for PUT (using method override of POST)' do
|
|
221
248
|
@request = Rack::MockRequest.new(protected_app_with_method_override)
|
|
222
249
|
request_with_digest_auth 'POST', '/', 'Alice', 'correct-password', :input => "_method=put" do |response|
|
|
223
250
|
response.status.should.equal 200
|
|
@@ -225,8 +252,8 @@ context 'Rack::Auth::Digest::MD5' do
|
|
|
225
252
|
end
|
|
226
253
|
end
|
|
227
254
|
|
|
228
|
-
|
|
255
|
+
it 'takes realm as optional constructor arg' do
|
|
229
256
|
app = Rack::Auth::Digest::MD5.new(unprotected_app, realm) { true }
|
|
230
|
-
|
|
257
|
+
realm.should == app.realm
|
|
231
258
|
end
|
|
232
259
|
end
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
require 'rack/body_proxy'
|
|
2
|
+
require 'stringio'
|
|
3
|
+
require 'ostruct'
|
|
4
|
+
|
|
5
|
+
describe Rack::BodyProxy do
|
|
6
|
+
should 'call each on the wrapped body' do
|
|
7
|
+
called = false
|
|
8
|
+
proxy = Rack::BodyProxy.new(['foo']) { }
|
|
9
|
+
proxy.each do |str|
|
|
10
|
+
called = true
|
|
11
|
+
str.should.equal 'foo'
|
|
12
|
+
end
|
|
13
|
+
called.should.equal true
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
should 'call close on the wrapped body' do
|
|
17
|
+
body = StringIO.new
|
|
18
|
+
proxy = Rack::BodyProxy.new(body) { }
|
|
19
|
+
proxy.close
|
|
20
|
+
body.should.be.closed
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
should 'only call close on the wrapped body if it responds to close' do
|
|
24
|
+
body = []
|
|
25
|
+
proxy = Rack::BodyProxy.new(body) { }
|
|
26
|
+
proc { proxy.close }.should.not.raise
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
should 'call the passed block on close' do
|
|
30
|
+
called = false
|
|
31
|
+
proxy = Rack::BodyProxy.new([]) { called = true }
|
|
32
|
+
called.should.equal false
|
|
33
|
+
proxy.close
|
|
34
|
+
called.should.equal true
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
should 'call the passed block on close even if there is an exception' do
|
|
38
|
+
object = Object.new
|
|
39
|
+
def object.close() raise "No!" end
|
|
40
|
+
called = false
|
|
41
|
+
|
|
42
|
+
begin
|
|
43
|
+
proxy = Rack::BodyProxy.new(object) { called = true }
|
|
44
|
+
called.should.equal false
|
|
45
|
+
proxy.close
|
|
46
|
+
rescue RuntimeError => e
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
raise "Expected exception to have been raised" unless e
|
|
50
|
+
called.should.equal true
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
should 'allow multiple arguments in respond_to?' do
|
|
54
|
+
body = []
|
|
55
|
+
proxy = Rack::BodyProxy.new(body) { }
|
|
56
|
+
proc { proxy.respond_to?(:foo, false) }.should.not.raise
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
should 'not respond to :to_ary' do
|
|
60
|
+
body = OpenStruct.new(:to_ary => true)
|
|
61
|
+
body.respond_to?(:to_ary).should.equal true
|
|
62
|
+
|
|
63
|
+
proxy = Rack::BodyProxy.new(body) { }
|
|
64
|
+
proxy.respond_to?(:to_ary).should.equal false
|
|
65
|
+
proxy.respond_to?("to_ary").should.equal false
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
should 'not close more than one time' do
|
|
69
|
+
count = 0
|
|
70
|
+
proxy = Rack::BodyProxy.new([]) { count += 1; raise "Block invoked more than 1 time!" if count > 1 }
|
|
71
|
+
2.times { proxy.close }
|
|
72
|
+
count.should.equal 1
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
should 'be closed when the callback is triggered' do
|
|
76
|
+
closed = false
|
|
77
|
+
proxy = Rack::BodyProxy.new([]) { closed = proxy.closed? }
|
|
78
|
+
proxy.close
|
|
79
|
+
closed.should.equal true
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
should 'provide an #each method' do
|
|
83
|
+
Rack::BodyProxy.method_defined?(:each).should.equal true
|
|
84
|
+
end
|
|
85
|
+
end
|