rack 1.6.11 → 2.1.4
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/CHANGELOG.md +77 -0
- data/{COPYING → MIT-LICENSE} +4 -2
- data/README.rdoc +89 -139
- data/Rakefile +27 -28
- data/SPEC +6 -7
- data/bin/rackup +1 -0
- data/contrib/rack_logo.svg +164 -111
- data/example/lobster.ru +2 -0
- data/example/protectedlobster.rb +4 -2
- data/example/protectedlobster.ru +3 -1
- data/lib/rack/auth/abstract/handler.rb +3 -1
- data/lib/rack/auth/abstract/request.rb +7 -1
- 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 +5 -4
- data/lib/rack/auth/digest/request.rb +3 -1
- data/lib/rack/body_proxy.rb +11 -9
- data/lib/rack/builder.rb +42 -18
- data/lib/rack/cascade.rb +6 -5
- data/lib/rack/chunked.rb +33 -10
- data/lib/rack/{commonlogger.rb → common_logger.rb} +11 -10
- data/lib/rack/{conditionalget.rb → conditional_get.rb} +3 -1
- data/lib/rack/config.rb +2 -0
- data/lib/rack/content_length.rb +5 -3
- data/lib/rack/content_type.rb +3 -1
- data/lib/rack/core_ext/regexp.rb +14 -0
- data/lib/rack/deflater.rb +33 -53
- data/lib/rack/directory.rb +75 -60
- data/lib/rack/etag.rb +8 -5
- data/lib/rack/events.rb +156 -0
- data/lib/rack/file.rb +4 -149
- data/lib/rack/files.rb +178 -0
- data/lib/rack/handler/cgi.rb +18 -17
- data/lib/rack/handler/fastcgi.rb +17 -16
- data/lib/rack/handler/lsws.rb +14 -12
- data/lib/rack/handler/scgi.rb +22 -19
- data/lib/rack/handler/thin.rb +6 -1
- data/lib/rack/handler/webrick.rb +28 -28
- data/lib/rack/handler.rb +9 -26
- data/lib/rack/head.rb +17 -17
- data/lib/rack/lint.rb +54 -51
- data/lib/rack/lobster.rb +8 -6
- data/lib/rack/lock.rb +17 -10
- data/lib/rack/logger.rb +4 -2
- data/lib/rack/media_type.rb +43 -0
- data/lib/rack/{methodoverride.rb → method_override.rb} +10 -8
- data/lib/rack/mime.rb +27 -6
- data/lib/rack/mock.rb +101 -60
- data/lib/rack/multipart/generator.rb +11 -12
- data/lib/rack/multipart/parser.rb +280 -161
- data/lib/rack/multipart/uploaded_file.rb +3 -2
- data/lib/rack/multipart.rb +39 -8
- data/lib/rack/{nulllogger.rb → null_logger.rb} +3 -1
- data/lib/rack/query_parser.rb +218 -0
- data/lib/rack/recursive.rb +11 -9
- data/lib/rack/reloader.rb +10 -4
- data/lib/rack/request.rb +447 -305
- data/lib/rack/response.rb +196 -83
- data/lib/rack/rewindable_input.rb +5 -14
- data/lib/rack/runtime.rb +12 -18
- data/lib/rack/sendfile.rb +19 -14
- data/lib/rack/server.rb +118 -41
- data/lib/rack/session/abstract/id.rb +215 -94
- data/lib/rack/session/cookie.rb +45 -28
- data/lib/rack/session/memcache.rb +4 -87
- data/lib/rack/session/pool.rb +25 -16
- data/lib/rack/show_exceptions.rb +392 -0
- data/lib/rack/{showstatus.rb → show_status.rb} +7 -5
- data/lib/rack/static.rb +41 -11
- data/lib/rack/tempfile_reaper.rb +4 -2
- data/lib/rack/urlmap.rb +25 -15
- data/lib/rack/utils.rb +186 -272
- data/lib/rack.rb +76 -24
- data/rack.gemspec +25 -14
- metadata +62 -182
- data/HISTORY.md +0 -375
- 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/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 -8
- data/test/cgi/test.ru +0 -5
- data/test/gemloader.rb +0 -10
- 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_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_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/semicolon +0 -6
- data/test/multipart/text +0 -15
- data/test/multipart/three_files_three_fields +0 -31
- 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 -81
- data/test/spec_auth_digest.rb +0 -259
- data/test/spec_body_proxy.rb +0 -85
- data/test/spec_builder.rb +0 -223
- data/test/spec_cascade.rb +0 -61
- data/test/spec_cgi.rb +0 -102
- data/test/spec_chunked.rb +0 -101
- data/test/spec_commonlogger.rb +0 -93
- data/test/spec_conditionalget.rb +0 -102
- data/test/spec_config.rb +0 -22
- data/test/spec_content_length.rb +0 -85
- data/test/spec_content_type.rb +0 -45
- data/test/spec_deflater.rb +0 -339
- data/test/spec_directory.rb +0 -88
- data/test/spec_etag.rb +0 -107
- data/test/spec_fastcgi.rb +0 -107
- data/test/spec_file.rb +0 -221
- data/test/spec_handler.rb +0 -72
- data/test/spec_head.rb +0 -45
- data/test/spec_lint.rb +0 -550
- data/test/spec_lobster.rb +0 -58
- data/test/spec_lock.rb +0 -164
- data/test/spec_logger.rb +0 -23
- data/test/spec_methodoverride.rb +0 -111
- data/test/spec_mime.rb +0 -51
- data/test/spec_mock.rb +0 -297
- data/test/spec_mongrel.rb +0 -182
- data/test/spec_multipart.rb +0 -600
- data/test/spec_nulllogger.rb +0 -20
- data/test/spec_recursive.rb +0 -72
- data/test/spec_request.rb +0 -1232
- data/test/spec_response.rb +0 -407
- data/test/spec_rewindable_input.rb +0 -118
- data/test/spec_runtime.rb +0 -49
- data/test/spec_sendfile.rb +0 -130
- data/test/spec_server.rb +0 -167
- data/test/spec_session_abstract_id.rb +0 -53
- data/test/spec_session_cookie.rb +0 -410
- data/test/spec_session_memcache.rb +0 -321
- data/test/spec_session_pool.rb +0 -209
- data/test/spec_showexceptions.rb +0 -98
- data/test/spec_showstatus.rb +0 -103
- data/test/spec_static.rb +0 -145
- data/test/spec_tempfile_reaper.rb +0 -63
- data/test/spec_thin.rb +0 -91
- data/test/spec_urlmap.rb +0 -236
- data/test/spec_utils.rb +0 -647
- data/test/spec_version.rb +0 -17
- data/test/spec_webrick.rb +0 -184
- data/test/static/another/index.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
data/test/spec_lock.rb
DELETED
@@ -1,164 +0,0 @@
|
|
1
|
-
require 'rack/lint'
|
2
|
-
require 'rack/lock'
|
3
|
-
require 'rack/mock'
|
4
|
-
|
5
|
-
class Lock
|
6
|
-
attr_reader :synchronized
|
7
|
-
|
8
|
-
def initialize
|
9
|
-
@synchronized = false
|
10
|
-
end
|
11
|
-
|
12
|
-
def synchronize
|
13
|
-
@synchronized = true
|
14
|
-
yield
|
15
|
-
end
|
16
|
-
|
17
|
-
def lock
|
18
|
-
@synchronized = true
|
19
|
-
end
|
20
|
-
|
21
|
-
def unlock
|
22
|
-
@synchronized = false
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
module LockHelpers
|
27
|
-
def lock_app(app, lock = Lock.new)
|
28
|
-
app = if lock
|
29
|
-
Rack::Lock.new app, lock
|
30
|
-
else
|
31
|
-
Rack::Lock.new app
|
32
|
-
end
|
33
|
-
Rack::Lint.new app
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
describe Rack::Lock do
|
38
|
-
extend LockHelpers
|
39
|
-
|
40
|
-
describe 'Proxy' do
|
41
|
-
extend LockHelpers
|
42
|
-
|
43
|
-
should 'delegate each' do
|
44
|
-
env = Rack::MockRequest.env_for("/")
|
45
|
-
response = Class.new {
|
46
|
-
attr_accessor :close_called
|
47
|
-
def initialize; @close_called = false; end
|
48
|
-
def each; %w{ hi mom }.each { |x| yield x }; end
|
49
|
-
}.new
|
50
|
-
|
51
|
-
app = lock_app(lambda { |inner_env| [200, {"Content-Type" => "text/plain"}, response] })
|
52
|
-
response = app.call(env)[2]
|
53
|
-
list = []
|
54
|
-
response.each { |x| list << x }
|
55
|
-
list.should.equal %w{ hi mom }
|
56
|
-
end
|
57
|
-
|
58
|
-
should 'delegate to_path' do
|
59
|
-
lock = Lock.new
|
60
|
-
env = Rack::MockRequest.env_for("/")
|
61
|
-
|
62
|
-
res = ['Hello World']
|
63
|
-
def res.to_path ; "/tmp/hello.txt" ; end
|
64
|
-
|
65
|
-
app = Rack::Lock.new(lambda { |inner_env| [200, {"Content-Type" => "text/plain"}, res] }, lock)
|
66
|
-
body = app.call(env)[2]
|
67
|
-
|
68
|
-
body.should.respond_to :to_path
|
69
|
-
body.to_path.should.equal "/tmp/hello.txt"
|
70
|
-
end
|
71
|
-
|
72
|
-
should 'not delegate to_path if body does not implement it' do
|
73
|
-
env = Rack::MockRequest.env_for("/")
|
74
|
-
|
75
|
-
res = ['Hello World']
|
76
|
-
|
77
|
-
app = lock_app(lambda { |inner_env| [200, {"Content-Type" => "text/plain"}, res] })
|
78
|
-
body = app.call(env)[2]
|
79
|
-
|
80
|
-
body.should.not.respond_to :to_path
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
should 'call super on close' do
|
85
|
-
env = Rack::MockRequest.env_for("/")
|
86
|
-
response = Class.new {
|
87
|
-
attr_accessor :close_called
|
88
|
-
def initialize; @close_called = false; end
|
89
|
-
def close; @close_called = true; end
|
90
|
-
}.new
|
91
|
-
|
92
|
-
app = lock_app(lambda { |inner_env| [200, {"Content-Type" => "text/plain"}, response] })
|
93
|
-
app.call(env)
|
94
|
-
response.close_called.should.equal false
|
95
|
-
response.close
|
96
|
-
response.close_called.should.equal true
|
97
|
-
end
|
98
|
-
|
99
|
-
should "not unlock until body is closed" do
|
100
|
-
lock = Lock.new
|
101
|
-
env = Rack::MockRequest.env_for("/")
|
102
|
-
response = Object.new
|
103
|
-
app = lock_app(lambda { |inner_env| [200, {"Content-Type" => "text/plain"}, response] }, lock)
|
104
|
-
lock.synchronized.should.equal false
|
105
|
-
response = app.call(env)[2]
|
106
|
-
lock.synchronized.should.equal true
|
107
|
-
response.close
|
108
|
-
lock.synchronized.should.equal false
|
109
|
-
end
|
110
|
-
|
111
|
-
should "return value from app" do
|
112
|
-
env = Rack::MockRequest.env_for("/")
|
113
|
-
body = [200, {"Content-Type" => "text/plain"}, %w{ hi mom }]
|
114
|
-
app = lock_app(lambda { |inner_env| body })
|
115
|
-
|
116
|
-
res = app.call(env)
|
117
|
-
res[0].should.equal body[0]
|
118
|
-
res[1].should.equal body[1]
|
119
|
-
res[2].to_enum.to_a.should.equal ["hi", "mom"]
|
120
|
-
end
|
121
|
-
|
122
|
-
should "call synchronize on lock" do
|
123
|
-
lock = Lock.new
|
124
|
-
env = Rack::MockRequest.env_for("/")
|
125
|
-
app = lock_app(lambda { |inner_env| [200, {"Content-Type" => "text/plain"}, %w{ a b c }] }, lock)
|
126
|
-
lock.synchronized.should.equal false
|
127
|
-
app.call(env)
|
128
|
-
lock.synchronized.should.equal true
|
129
|
-
end
|
130
|
-
|
131
|
-
should "unlock if the app raises" do
|
132
|
-
lock = Lock.new
|
133
|
-
env = Rack::MockRequest.env_for("/")
|
134
|
-
app = lock_app(lambda { raise Exception }, lock)
|
135
|
-
lambda { app.call(env) }.should.raise(Exception)
|
136
|
-
lock.synchronized.should.equal false
|
137
|
-
end
|
138
|
-
|
139
|
-
should "unlock if the app throws" do
|
140
|
-
lock = Lock.new
|
141
|
-
env = Rack::MockRequest.env_for("/")
|
142
|
-
app = lock_app(lambda {|_| throw :bacon }, lock)
|
143
|
-
lambda { app.call(env) }.should.throw(:bacon)
|
144
|
-
lock.synchronized.should.equal false
|
145
|
-
end
|
146
|
-
|
147
|
-
should "set multithread flag to false" do
|
148
|
-
app = lock_app(lambda { |env|
|
149
|
-
env['rack.multithread'].should.equal false
|
150
|
-
[200, {"Content-Type" => "text/plain"}, %w{ a b c }]
|
151
|
-
}, false)
|
152
|
-
app.call(Rack::MockRequest.env_for("/"))
|
153
|
-
end
|
154
|
-
|
155
|
-
should "reset original multithread flag when exiting lock" do
|
156
|
-
app = Class.new(Rack::Lock) {
|
157
|
-
def call(env)
|
158
|
-
env['rack.multithread'].should.equal true
|
159
|
-
super
|
160
|
-
end
|
161
|
-
}.new(lambda { |env| [200, {"Content-Type" => "text/plain"}, %w{ a b c }] })
|
162
|
-
Rack::Lint.new(app).call(Rack::MockRequest.env_for("/"))
|
163
|
-
end
|
164
|
-
end
|
data/test/spec_logger.rb
DELETED
@@ -1,23 +0,0 @@
|
|
1
|
-
require 'stringio'
|
2
|
-
require 'rack/lint'
|
3
|
-
require 'rack/logger'
|
4
|
-
require 'rack/mock'
|
5
|
-
|
6
|
-
describe Rack::Logger do
|
7
|
-
app = lambda { |env|
|
8
|
-
log = env['rack.logger']
|
9
|
-
log.debug("Created logger")
|
10
|
-
log.info("Program started")
|
11
|
-
log.warn("Nothing to do!")
|
12
|
-
|
13
|
-
[200, {'Content-Type' => 'text/plain'}, ["Hello, World!"]]
|
14
|
-
}
|
15
|
-
|
16
|
-
should "conform to Rack::Lint" do
|
17
|
-
errors = StringIO.new
|
18
|
-
a = Rack::Lint.new(Rack::Logger.new(app))
|
19
|
-
Rack::MockRequest.new(a).get('/', 'rack.errors' => errors)
|
20
|
-
errors.string.should.match(/INFO -- : Program started/)
|
21
|
-
errors.string.should.match(/WARN -- : Nothing to do/)
|
22
|
-
end
|
23
|
-
end
|
data/test/spec_methodoverride.rb
DELETED
@@ -1,111 +0,0 @@
|
|
1
|
-
require 'stringio'
|
2
|
-
require 'rack/methodoverride'
|
3
|
-
require 'rack/mock'
|
4
|
-
|
5
|
-
describe Rack::MethodOverride do
|
6
|
-
def app
|
7
|
-
Rack::Lint.new(Rack::MethodOverride.new(lambda {|e|
|
8
|
-
[200, {"Content-Type" => "text/plain"}, []]
|
9
|
-
}))
|
10
|
-
end
|
11
|
-
|
12
|
-
should "not affect GET requests" do
|
13
|
-
env = Rack::MockRequest.env_for("/?_method=delete", :method => "GET")
|
14
|
-
app.call env
|
15
|
-
|
16
|
-
env["REQUEST_METHOD"].should.equal "GET"
|
17
|
-
end
|
18
|
-
|
19
|
-
should "modify REQUEST_METHOD for POST requests when _method parameter is set" do
|
20
|
-
env = Rack::MockRequest.env_for("/", :method => "POST", :input => "_method=put")
|
21
|
-
app.call env
|
22
|
-
|
23
|
-
env["REQUEST_METHOD"].should.equal "PUT"
|
24
|
-
end
|
25
|
-
|
26
|
-
if RUBY_VERSION >= "1.9"
|
27
|
-
should "set rack.errors for invalid UTF8 _method values" do
|
28
|
-
errors = StringIO.new
|
29
|
-
env = Rack::MockRequest.env_for("/",
|
30
|
-
:method => "POST",
|
31
|
-
:input => "_method=\xBF".force_encoding("ASCII-8BIT"),
|
32
|
-
"rack.errors" => errors)
|
33
|
-
|
34
|
-
app.call env
|
35
|
-
|
36
|
-
errors.rewind
|
37
|
-
errors.read.should.equal "Invalid string for method\n"
|
38
|
-
env["REQUEST_METHOD"].should.equal "POST"
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
should "modify REQUEST_METHOD for POST requests when X-HTTP-Method-Override is set" do
|
43
|
-
env = Rack::MockRequest.env_for("/",
|
44
|
-
:method => "POST",
|
45
|
-
"HTTP_X_HTTP_METHOD_OVERRIDE" => "PATCH"
|
46
|
-
)
|
47
|
-
app.call env
|
48
|
-
|
49
|
-
env["REQUEST_METHOD"].should.equal "PATCH"
|
50
|
-
end
|
51
|
-
|
52
|
-
should "not modify REQUEST_METHOD if the method is unknown" do
|
53
|
-
env = Rack::MockRequest.env_for("/", :method => "POST", :input => "_method=foo")
|
54
|
-
app.call env
|
55
|
-
|
56
|
-
env["REQUEST_METHOD"].should.equal "POST"
|
57
|
-
end
|
58
|
-
|
59
|
-
should "not modify REQUEST_METHOD when _method is nil" do
|
60
|
-
env = Rack::MockRequest.env_for("/", :method => "POST", :input => "foo=bar")
|
61
|
-
app.call env
|
62
|
-
|
63
|
-
env["REQUEST_METHOD"].should.equal "POST"
|
64
|
-
end
|
65
|
-
|
66
|
-
should "store the original REQUEST_METHOD prior to overriding" do
|
67
|
-
env = Rack::MockRequest.env_for("/",
|
68
|
-
:method => "POST",
|
69
|
-
:input => "_method=options")
|
70
|
-
app.call env
|
71
|
-
|
72
|
-
env["rack.methodoverride.original_method"].should.equal "POST"
|
73
|
-
end
|
74
|
-
|
75
|
-
should "not modify REQUEST_METHOD when given invalid multipart form data" do
|
76
|
-
input = <<EOF
|
77
|
-
--AaB03x\r
|
78
|
-
content-disposition: form-data; name="huge"; filename="huge"\r
|
79
|
-
EOF
|
80
|
-
env = Rack::MockRequest.env_for("/",
|
81
|
-
"CONTENT_TYPE" => "multipart/form-data, boundary=AaB03x",
|
82
|
-
"CONTENT_LENGTH" => input.size.to_s,
|
83
|
-
:method => "POST", :input => input)
|
84
|
-
app.call env
|
85
|
-
|
86
|
-
env["REQUEST_METHOD"].should.equal "POST"
|
87
|
-
end
|
88
|
-
|
89
|
-
should "write error to RACK_ERRORS when given invalid multipart form data" do
|
90
|
-
input = <<EOF
|
91
|
-
--AaB03x\r
|
92
|
-
content-disposition: form-data; name="huge"; filename="huge"\r
|
93
|
-
EOF
|
94
|
-
env = Rack::MockRequest.env_for("/",
|
95
|
-
"CONTENT_TYPE" => "multipart/form-data, boundary=AaB03x",
|
96
|
-
"CONTENT_LENGTH" => input.size.to_s,
|
97
|
-
"rack.errors" => StringIO.new,
|
98
|
-
:method => "POST", :input => input)
|
99
|
-
Rack::MethodOverride.new(proc { [200, {"Content-Type" => "text/plain"}, []] }).call env
|
100
|
-
|
101
|
-
env["rack.errors"].rewind
|
102
|
-
env["rack.errors"].read.should =~ /Bad request content body/
|
103
|
-
end
|
104
|
-
|
105
|
-
should "not modify REQUEST_METHOD for POST requests when the params are unparseable" do
|
106
|
-
env = Rack::MockRequest.env_for("/", :method => "POST", :input => "(%bad-params%)")
|
107
|
-
app.call env
|
108
|
-
|
109
|
-
env["REQUEST_METHOD"].should.equal "POST"
|
110
|
-
end
|
111
|
-
end
|
data/test/spec_mime.rb
DELETED
@@ -1,51 +0,0 @@
|
|
1
|
-
require 'rack/mime'
|
2
|
-
|
3
|
-
describe Rack::Mime do
|
4
|
-
|
5
|
-
it "should return the fallback mime-type for files with no extension" do
|
6
|
-
fallback = 'image/jpg'
|
7
|
-
Rack::Mime.mime_type(File.extname('no_ext'), fallback).should.equal fallback
|
8
|
-
end
|
9
|
-
|
10
|
-
it "should always return 'application/octet-stream' for unknown file extensions" do
|
11
|
-
unknown_ext = File.extname('unknown_ext.abcdefg')
|
12
|
-
Rack::Mime.mime_type(unknown_ext).should.equal 'application/octet-stream'
|
13
|
-
end
|
14
|
-
|
15
|
-
it "should return the mime-type for a given extension" do
|
16
|
-
# sanity check. it would be infeasible test every single mime-type.
|
17
|
-
Rack::Mime.mime_type(File.extname('image.jpg')).should.equal 'image/jpeg'
|
18
|
-
end
|
19
|
-
|
20
|
-
it "should support null fallbacks" do
|
21
|
-
Rack::Mime.mime_type('.nothing', nil).should.equal nil
|
22
|
-
end
|
23
|
-
|
24
|
-
it "should match exact mimes" do
|
25
|
-
Rack::Mime.match?('text/html', 'text/html').should.equal true
|
26
|
-
Rack::Mime.match?('text/html', 'text/meme').should.equal false
|
27
|
-
Rack::Mime.match?('text', 'text').should.equal true
|
28
|
-
Rack::Mime.match?('text', 'binary').should.equal false
|
29
|
-
end
|
30
|
-
|
31
|
-
it "should match class wildcard mimes" do
|
32
|
-
Rack::Mime.match?('text/html', 'text/*').should.equal true
|
33
|
-
Rack::Mime.match?('text/plain', 'text/*').should.equal true
|
34
|
-
Rack::Mime.match?('application/json', 'text/*').should.equal false
|
35
|
-
Rack::Mime.match?('text/html', 'text').should.equal true
|
36
|
-
end
|
37
|
-
|
38
|
-
it "should match full wildcards" do
|
39
|
-
Rack::Mime.match?('text/html', '*').should.equal true
|
40
|
-
Rack::Mime.match?('text/plain', '*').should.equal true
|
41
|
-
Rack::Mime.match?('text/html', '*/*').should.equal true
|
42
|
-
Rack::Mime.match?('text/plain', '*/*').should.equal true
|
43
|
-
end
|
44
|
-
|
45
|
-
it "should match type wildcard mimes" do
|
46
|
-
Rack::Mime.match?('text/html', '*/html').should.equal true
|
47
|
-
Rack::Mime.match?('text/plain', '*/plain').should.equal true
|
48
|
-
end
|
49
|
-
|
50
|
-
end
|
51
|
-
|
data/test/spec_mock.rb
DELETED
@@ -1,297 +0,0 @@
|
|
1
|
-
require 'yaml'
|
2
|
-
require 'rack/lint'
|
3
|
-
require 'rack/mock'
|
4
|
-
require 'stringio'
|
5
|
-
|
6
|
-
app = Rack::Lint.new(lambda { |env|
|
7
|
-
req = Rack::Request.new(env)
|
8
|
-
|
9
|
-
env["mock.postdata"] = env["rack.input"].read
|
10
|
-
if req.GET["error"]
|
11
|
-
env["rack.errors"].puts req.GET["error"]
|
12
|
-
env["rack.errors"].flush
|
13
|
-
end
|
14
|
-
|
15
|
-
body = req.head? ? "" : env.to_yaml
|
16
|
-
Rack::Response.new(body,
|
17
|
-
req.GET["status"] || 200,
|
18
|
-
"Content-Type" => "text/yaml").finish
|
19
|
-
})
|
20
|
-
|
21
|
-
describe Rack::MockRequest do
|
22
|
-
should "return a MockResponse" do
|
23
|
-
res = Rack::MockRequest.new(app).get("")
|
24
|
-
res.should.be.kind_of Rack::MockResponse
|
25
|
-
end
|
26
|
-
|
27
|
-
should "be able to only return the environment" do
|
28
|
-
env = Rack::MockRequest.env_for("")
|
29
|
-
env.should.be.kind_of Hash
|
30
|
-
env.should.include "rack.version"
|
31
|
-
end
|
32
|
-
|
33
|
-
should "return an environment with a path" do
|
34
|
-
env = Rack::MockRequest.env_for("http://www.example.com/parse?location[]=1&location[]=2&age_group[]=2")
|
35
|
-
env["QUERY_STRING"].should.equal "location[]=1&location[]=2&age_group[]=2"
|
36
|
-
env["PATH_INFO"].should.equal "/parse"
|
37
|
-
env.should.be.kind_of Hash
|
38
|
-
env.should.include "rack.version"
|
39
|
-
end
|
40
|
-
|
41
|
-
should "provide sensible defaults" do
|
42
|
-
res = Rack::MockRequest.new(app).request
|
43
|
-
|
44
|
-
env = YAML.load(res.body)
|
45
|
-
env["REQUEST_METHOD"].should.equal "GET"
|
46
|
-
env["SERVER_NAME"].should.equal "example.org"
|
47
|
-
env["SERVER_PORT"].should.equal "80"
|
48
|
-
env["QUERY_STRING"].should.equal ""
|
49
|
-
env["PATH_INFO"].should.equal "/"
|
50
|
-
env["SCRIPT_NAME"].should.equal ""
|
51
|
-
env["rack.url_scheme"].should.equal "http"
|
52
|
-
env["mock.postdata"].should.be.empty
|
53
|
-
end
|
54
|
-
|
55
|
-
should "allow GET/POST/PUT/DELETE/HEAD" do
|
56
|
-
res = Rack::MockRequest.new(app).get("", :input => "foo")
|
57
|
-
env = YAML.load(res.body)
|
58
|
-
env["REQUEST_METHOD"].should.equal "GET"
|
59
|
-
|
60
|
-
res = Rack::MockRequest.new(app).post("", :input => "foo")
|
61
|
-
env = YAML.load(res.body)
|
62
|
-
env["REQUEST_METHOD"].should.equal "POST"
|
63
|
-
|
64
|
-
res = Rack::MockRequest.new(app).put("", :input => "foo")
|
65
|
-
env = YAML.load(res.body)
|
66
|
-
env["REQUEST_METHOD"].should.equal "PUT"
|
67
|
-
|
68
|
-
res = Rack::MockRequest.new(app).patch("", :input => "foo")
|
69
|
-
env = YAML.load(res.body)
|
70
|
-
env["REQUEST_METHOD"].should.equal "PATCH"
|
71
|
-
|
72
|
-
res = Rack::MockRequest.new(app).delete("", :input => "foo")
|
73
|
-
env = YAML.load(res.body)
|
74
|
-
env["REQUEST_METHOD"].should.equal "DELETE"
|
75
|
-
|
76
|
-
Rack::MockRequest.env_for("/", :method => "HEAD")["REQUEST_METHOD"].
|
77
|
-
should.equal "HEAD"
|
78
|
-
|
79
|
-
Rack::MockRequest.env_for("/", :method => "OPTIONS")["REQUEST_METHOD"].
|
80
|
-
should.equal "OPTIONS"
|
81
|
-
end
|
82
|
-
|
83
|
-
should "set content length" do
|
84
|
-
env = Rack::MockRequest.env_for("/", :input => "foo")
|
85
|
-
env["CONTENT_LENGTH"].should.equal "3"
|
86
|
-
end
|
87
|
-
|
88
|
-
should "allow posting" do
|
89
|
-
res = Rack::MockRequest.new(app).get("", :input => "foo")
|
90
|
-
env = YAML.load(res.body)
|
91
|
-
env["mock.postdata"].should.equal "foo"
|
92
|
-
|
93
|
-
res = Rack::MockRequest.new(app).post("", :input => StringIO.new("foo"))
|
94
|
-
env = YAML.load(res.body)
|
95
|
-
env["mock.postdata"].should.equal "foo"
|
96
|
-
end
|
97
|
-
|
98
|
-
should "use all parts of an URL" do
|
99
|
-
res = Rack::MockRequest.new(app).
|
100
|
-
get("https://bla.example.org:9292/meh/foo?bar")
|
101
|
-
res.should.be.kind_of Rack::MockResponse
|
102
|
-
|
103
|
-
env = YAML.load(res.body)
|
104
|
-
env["REQUEST_METHOD"].should.equal "GET"
|
105
|
-
env["SERVER_NAME"].should.equal "bla.example.org"
|
106
|
-
env["SERVER_PORT"].should.equal "9292"
|
107
|
-
env["QUERY_STRING"].should.equal "bar"
|
108
|
-
env["PATH_INFO"].should.equal "/meh/foo"
|
109
|
-
env["rack.url_scheme"].should.equal "https"
|
110
|
-
end
|
111
|
-
|
112
|
-
should "set SSL port and HTTP flag on when using https" do
|
113
|
-
res = Rack::MockRequest.new(app).
|
114
|
-
get("https://example.org/foo")
|
115
|
-
res.should.be.kind_of Rack::MockResponse
|
116
|
-
|
117
|
-
env = YAML.load(res.body)
|
118
|
-
env["REQUEST_METHOD"].should.equal "GET"
|
119
|
-
env["SERVER_NAME"].should.equal "example.org"
|
120
|
-
env["SERVER_PORT"].should.equal "443"
|
121
|
-
env["QUERY_STRING"].should.equal ""
|
122
|
-
env["PATH_INFO"].should.equal "/foo"
|
123
|
-
env["rack.url_scheme"].should.equal "https"
|
124
|
-
env["HTTPS"].should.equal "on"
|
125
|
-
end
|
126
|
-
|
127
|
-
should "prepend slash to uri path" do
|
128
|
-
res = Rack::MockRequest.new(app).
|
129
|
-
get("foo")
|
130
|
-
res.should.be.kind_of Rack::MockResponse
|
131
|
-
|
132
|
-
env = YAML.load(res.body)
|
133
|
-
env["REQUEST_METHOD"].should.equal "GET"
|
134
|
-
env["SERVER_NAME"].should.equal "example.org"
|
135
|
-
env["SERVER_PORT"].should.equal "80"
|
136
|
-
env["QUERY_STRING"].should.equal ""
|
137
|
-
env["PATH_INFO"].should.equal "/foo"
|
138
|
-
env["rack.url_scheme"].should.equal "http"
|
139
|
-
end
|
140
|
-
|
141
|
-
should "properly convert method name to an uppercase string" do
|
142
|
-
res = Rack::MockRequest.new(app).request(:get)
|
143
|
-
env = YAML.load(res.body)
|
144
|
-
env["REQUEST_METHOD"].should.equal "GET"
|
145
|
-
end
|
146
|
-
|
147
|
-
should "accept params and build query string for GET requests" do
|
148
|
-
res = Rack::MockRequest.new(app).get("/foo?baz=2", :params => {:foo => {:bar => "1"}})
|
149
|
-
env = YAML.load(res.body)
|
150
|
-
env["REQUEST_METHOD"].should.equal "GET"
|
151
|
-
env["QUERY_STRING"].should.include "baz=2"
|
152
|
-
env["QUERY_STRING"].should.include "foo[bar]=1"
|
153
|
-
env["PATH_INFO"].should.equal "/foo"
|
154
|
-
env["mock.postdata"].should.equal ""
|
155
|
-
end
|
156
|
-
|
157
|
-
should "accept raw input in params for GET requests" do
|
158
|
-
res = Rack::MockRequest.new(app).get("/foo?baz=2", :params => "foo[bar]=1")
|
159
|
-
env = YAML.load(res.body)
|
160
|
-
env["REQUEST_METHOD"].should.equal "GET"
|
161
|
-
env["QUERY_STRING"].should.include "baz=2"
|
162
|
-
env["QUERY_STRING"].should.include "foo[bar]=1"
|
163
|
-
env["PATH_INFO"].should.equal "/foo"
|
164
|
-
env["mock.postdata"].should.equal ""
|
165
|
-
end
|
166
|
-
|
167
|
-
should "accept params and build url encoded params for POST requests" do
|
168
|
-
res = Rack::MockRequest.new(app).post("/foo", :params => {:foo => {:bar => "1"}})
|
169
|
-
env = YAML.load(res.body)
|
170
|
-
env["REQUEST_METHOD"].should.equal "POST"
|
171
|
-
env["QUERY_STRING"].should.equal ""
|
172
|
-
env["PATH_INFO"].should.equal "/foo"
|
173
|
-
env["CONTENT_TYPE"].should.equal "application/x-www-form-urlencoded"
|
174
|
-
env["mock.postdata"].should.equal "foo[bar]=1"
|
175
|
-
end
|
176
|
-
|
177
|
-
should "accept raw input in params for POST requests" do
|
178
|
-
res = Rack::MockRequest.new(app).post("/foo", :params => "foo[bar]=1")
|
179
|
-
env = YAML.load(res.body)
|
180
|
-
env["REQUEST_METHOD"].should.equal "POST"
|
181
|
-
env["QUERY_STRING"].should.equal ""
|
182
|
-
env["PATH_INFO"].should.equal "/foo"
|
183
|
-
env["CONTENT_TYPE"].should.equal "application/x-www-form-urlencoded"
|
184
|
-
env["mock.postdata"].should.equal "foo[bar]=1"
|
185
|
-
end
|
186
|
-
|
187
|
-
should "accept params and build multipart encoded params for POST requests" do
|
188
|
-
files = Rack::Multipart::UploadedFile.new(File.join(File.dirname(__FILE__), "multipart", "file1.txt"))
|
189
|
-
res = Rack::MockRequest.new(app).post("/foo", :params => { "submit-name" => "Larry", "files" => files })
|
190
|
-
env = YAML.load(res.body)
|
191
|
-
env["REQUEST_METHOD"].should.equal "POST"
|
192
|
-
env["QUERY_STRING"].should.equal ""
|
193
|
-
env["PATH_INFO"].should.equal "/foo"
|
194
|
-
env["CONTENT_TYPE"].should.equal "multipart/form-data; boundary=AaB03x"
|
195
|
-
# The gsub accounts for differences in YAMLs affect on the data.
|
196
|
-
env["mock.postdata"].gsub("\r", "").length.should.equal 206
|
197
|
-
end
|
198
|
-
|
199
|
-
should "behave valid according to the Rack spec" do
|
200
|
-
lambda {
|
201
|
-
Rack::MockRequest.new(app).
|
202
|
-
get("https://bla.example.org:9292/meh/foo?bar", :lint => true)
|
203
|
-
}.should.not.raise(Rack::Lint::LintError)
|
204
|
-
end
|
205
|
-
|
206
|
-
should "call close on the original body object" do
|
207
|
-
called = false
|
208
|
-
body = Rack::BodyProxy.new(['hi']) { called = true }
|
209
|
-
capp = proc { |e| [200, {'Content-Type' => 'text/plain'}, body] }
|
210
|
-
called.should.equal false
|
211
|
-
Rack::MockRequest.new(capp).get('/', :lint => true)
|
212
|
-
called.should.equal true
|
213
|
-
end
|
214
|
-
|
215
|
-
if "<3".respond_to? :b
|
216
|
-
should "defaults encoding to ASCII 8BIT" do
|
217
|
-
req = Rack::MockRequest.env_for("/foo")
|
218
|
-
|
219
|
-
keys = [
|
220
|
-
Rack::REQUEST_METHOD,
|
221
|
-
"SERVER_NAME",
|
222
|
-
"SERVER_PORT",
|
223
|
-
Rack::QUERY_STRING,
|
224
|
-
Rack::PATH_INFO,
|
225
|
-
"rack.url_scheme",
|
226
|
-
"HTTPS"
|
227
|
-
]
|
228
|
-
|
229
|
-
keys.each do |k|
|
230
|
-
req[k].encoding.should.equal Encoding::ASCII_8BIT
|
231
|
-
end
|
232
|
-
end
|
233
|
-
end
|
234
|
-
end
|
235
|
-
|
236
|
-
describe Rack::MockResponse do
|
237
|
-
should "provide access to the HTTP status" do
|
238
|
-
res = Rack::MockRequest.new(app).get("")
|
239
|
-
res.should.be.successful
|
240
|
-
res.should.be.ok
|
241
|
-
|
242
|
-
res = Rack::MockRequest.new(app).get("/?status=404")
|
243
|
-
res.should.not.be.successful
|
244
|
-
res.should.be.client_error
|
245
|
-
res.should.be.not_found
|
246
|
-
|
247
|
-
res = Rack::MockRequest.new(app).get("/?status=501")
|
248
|
-
res.should.not.be.successful
|
249
|
-
res.should.be.server_error
|
250
|
-
|
251
|
-
res = Rack::MockRequest.new(app).get("/?status=307")
|
252
|
-
res.should.be.redirect
|
253
|
-
|
254
|
-
res = Rack::MockRequest.new(app).get("/?status=201", :lint => true)
|
255
|
-
res.should.be.empty
|
256
|
-
end
|
257
|
-
|
258
|
-
should "provide access to the HTTP headers" do
|
259
|
-
res = Rack::MockRequest.new(app).get("")
|
260
|
-
res.should.include "Content-Type"
|
261
|
-
res.headers["Content-Type"].should.equal "text/yaml"
|
262
|
-
res.original_headers["Content-Type"].should.equal "text/yaml"
|
263
|
-
res["Content-Type"].should.equal "text/yaml"
|
264
|
-
res.content_type.should.equal "text/yaml"
|
265
|
-
res.content_length.should.not.equal 0
|
266
|
-
res.location.should.be.nil
|
267
|
-
end
|
268
|
-
|
269
|
-
should "provide access to the HTTP body" do
|
270
|
-
res = Rack::MockRequest.new(app).get("")
|
271
|
-
res.body.should =~ /rack/
|
272
|
-
res.should =~ /rack/
|
273
|
-
res.should.match(/rack/)
|
274
|
-
res.should.satisfy { |r| r.match(/rack/) }
|
275
|
-
end
|
276
|
-
|
277
|
-
should "provide access to the Rack errors" do
|
278
|
-
res = Rack::MockRequest.new(app).get("/?error=foo", :lint => true)
|
279
|
-
res.should.be.ok
|
280
|
-
res.errors.should.not.be.empty
|
281
|
-
res.errors.should.include "foo"
|
282
|
-
end
|
283
|
-
|
284
|
-
should "allow calling body.close afterwards" do
|
285
|
-
# this is exactly what rack-test does
|
286
|
-
body = StringIO.new("hi")
|
287
|
-
res = Rack::MockResponse.new(200, {}, body)
|
288
|
-
body.close if body.respond_to?(:close)
|
289
|
-
res.body.should == 'hi'
|
290
|
-
end
|
291
|
-
|
292
|
-
should "optionally make Rack errors fatal" do
|
293
|
-
lambda {
|
294
|
-
Rack::MockRequest.new(app).get("/?error=foo", :fatal => true)
|
295
|
-
}.should.raise(Rack::MockRequest::FatalWarning)
|
296
|
-
end
|
297
|
-
end
|