rack 1.4.7 → 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.

Files changed (183) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +77 -0
  3. data/{COPYING → MIT-LICENSE} +4 -2
  4. data/README.rdoc +122 -456
  5. data/Rakefile +32 -31
  6. data/SPEC +119 -29
  7. data/bin/rackup +1 -0
  8. data/contrib/rack_logo.svg +164 -111
  9. data/example/lobster.ru +2 -0
  10. data/example/protectedlobster.rb +4 -2
  11. data/example/protectedlobster.ru +3 -1
  12. data/lib/rack/auth/abstract/handler.rb +7 -5
  13. data/lib/rack/auth/abstract/request.rb +8 -6
  14. data/lib/rack/auth/basic.rb +5 -2
  15. data/lib/rack/auth/digest/md5.rb +10 -8
  16. data/lib/rack/auth/digest/nonce.rb +6 -3
  17. data/lib/rack/auth/digest/params.rb +5 -4
  18. data/lib/rack/auth/digest/request.rb +4 -2
  19. data/lib/rack/body_proxy.rb +11 -9
  20. data/lib/rack/builder.rb +63 -20
  21. data/lib/rack/cascade.rb +10 -9
  22. data/lib/rack/chunked.rb +45 -11
  23. data/lib/rack/{commonlogger.rb → common_logger.rb} +24 -15
  24. data/lib/rack/{conditionalget.rb → conditional_get.rb} +20 -6
  25. data/lib/rack/config.rb +7 -0
  26. data/lib/rack/content_length.rb +12 -6
  27. data/lib/rack/content_type.rb +4 -2
  28. data/lib/rack/core_ext/regexp.rb +14 -0
  29. data/lib/rack/deflater.rb +73 -42
  30. data/lib/rack/directory.rb +77 -56
  31. data/lib/rack/etag.rb +25 -13
  32. data/lib/rack/events.rb +156 -0
  33. data/lib/rack/file.rb +4 -143
  34. data/lib/rack/files.rb +178 -0
  35. data/lib/rack/handler/cgi.rb +18 -17
  36. data/lib/rack/handler/fastcgi.rb +21 -17
  37. data/lib/rack/handler/lsws.rb +14 -12
  38. data/lib/rack/handler/scgi.rb +27 -21
  39. data/lib/rack/handler/thin.rb +19 -5
  40. data/lib/rack/handler/webrick.rb +66 -24
  41. data/lib/rack/handler.rb +29 -19
  42. data/lib/rack/head.rb +21 -14
  43. data/lib/rack/lint.rb +259 -65
  44. data/lib/rack/lobster.rb +17 -10
  45. data/lib/rack/lock.rb +19 -10
  46. data/lib/rack/logger.rb +4 -2
  47. data/lib/rack/media_type.rb +43 -0
  48. data/lib/rack/method_override.rb +52 -0
  49. data/lib/rack/mime.rb +43 -6
  50. data/lib/rack/mock.rb +109 -44
  51. data/lib/rack/multipart/generator.rb +11 -12
  52. data/lib/rack/multipart/parser.rb +302 -115
  53. data/lib/rack/multipart/uploaded_file.rb +4 -3
  54. data/lib/rack/multipart.rb +40 -9
  55. data/lib/rack/null_logger.rb +39 -0
  56. data/lib/rack/query_parser.rb +218 -0
  57. data/lib/rack/recursive.rb +14 -11
  58. data/lib/rack/reloader.rb +12 -5
  59. data/lib/rack/request.rb +484 -270
  60. data/lib/rack/response.rb +196 -77
  61. data/lib/rack/rewindable_input.rb +5 -14
  62. data/lib/rack/runtime.rb +13 -6
  63. data/lib/rack/sendfile.rb +44 -20
  64. data/lib/rack/server.rb +175 -61
  65. data/lib/rack/session/abstract/id.rb +276 -133
  66. data/lib/rack/session/cookie.rb +75 -40
  67. data/lib/rack/session/memcache.rb +4 -87
  68. data/lib/rack/session/pool.rb +24 -18
  69. data/lib/rack/show_exceptions.rb +392 -0
  70. data/lib/rack/{showstatus.rb → show_status.rb} +11 -9
  71. data/lib/rack/static.rb +65 -38
  72. data/lib/rack/tempfile_reaper.rb +24 -0
  73. data/lib/rack/urlmap.rb +40 -15
  74. data/lib/rack/utils.rb +316 -285
  75. data/lib/rack.rb +78 -23
  76. data/rack.gemspec +26 -19
  77. metadata +44 -209
  78. data/KNOWN-ISSUES +0 -30
  79. data/lib/rack/backports/uri/common_18.rb +0 -56
  80. data/lib/rack/backports/uri/common_192.rb +0 -52
  81. data/lib/rack/backports/uri/common_193.rb +0 -29
  82. data/lib/rack/handler/evented_mongrel.rb +0 -8
  83. data/lib/rack/handler/mongrel.rb +0 -100
  84. data/lib/rack/handler/swiftiplied_mongrel.rb +0 -8
  85. data/lib/rack/methodoverride.rb +0 -33
  86. data/lib/rack/nulllogger.rb +0 -18
  87. data/lib/rack/showexceptions.rb +0 -378
  88. data/test/builder/anything.rb +0 -5
  89. data/test/builder/comment.ru +0 -4
  90. data/test/builder/end.ru +0 -5
  91. data/test/builder/line.ru +0 -1
  92. data/test/builder/options.ru +0 -2
  93. data/test/cgi/assets/folder/test.js +0 -1
  94. data/test/cgi/assets/fonts/font.eot +0 -1
  95. data/test/cgi/assets/images/image.png +0 -1
  96. data/test/cgi/assets/index.html +0 -1
  97. data/test/cgi/assets/javascripts/app.js +0 -1
  98. data/test/cgi/assets/stylesheets/app.css +0 -1
  99. data/test/cgi/lighttpd.conf +0 -26
  100. data/test/cgi/lighttpd.errors +0 -1
  101. data/test/cgi/rackup_stub.rb +0 -6
  102. data/test/cgi/sample_rackup.ru +0 -5
  103. data/test/cgi/test +0 -9
  104. data/test/cgi/test+directory/test+file +0 -1
  105. data/test/cgi/test.fcgi +0 -8
  106. data/test/cgi/test.ru +0 -5
  107. data/test/gemloader.rb +0 -10
  108. data/test/multipart/bad_robots +0 -259
  109. data/test/multipart/binary +0 -0
  110. data/test/multipart/content_type_and_no_filename +0 -6
  111. data/test/multipart/empty +0 -10
  112. data/test/multipart/fail_16384_nofile +0 -814
  113. data/test/multipart/file1.txt +0 -1
  114. data/test/multipart/filename_and_modification_param +0 -7
  115. data/test/multipart/filename_with_escaped_quotes +0 -6
  116. data/test/multipart/filename_with_escaped_quotes_and_modification_param +0 -7
  117. data/test/multipart/filename_with_percent_escaped_quotes +0 -6
  118. data/test/multipart/filename_with_unescaped_percentages +0 -6
  119. data/test/multipart/filename_with_unescaped_percentages2 +0 -6
  120. data/test/multipart/filename_with_unescaped_percentages3 +0 -6
  121. data/test/multipart/filename_with_unescaped_quotes +0 -6
  122. data/test/multipart/ie +0 -6
  123. data/test/multipart/mixed_files +0 -21
  124. data/test/multipart/nested +0 -10
  125. data/test/multipart/none +0 -9
  126. data/test/multipart/semicolon +0 -6
  127. data/test/multipart/text +0 -15
  128. data/test/multipart/three_files_three_fields +0 -31
  129. data/test/multipart/webkit +0 -32
  130. data/test/rackup/config.ru +0 -31
  131. data/test/registering_handler/rack/handler/registering_myself.rb +0 -8
  132. data/test/spec_auth.rb +0 -57
  133. data/test/spec_auth_basic.rb +0 -81
  134. data/test/spec_auth_digest.rb +0 -259
  135. data/test/spec_body_proxy.rb +0 -69
  136. data/test/spec_builder.rb +0 -207
  137. data/test/spec_cascade.rb +0 -61
  138. data/test/spec_cgi.rb +0 -102
  139. data/test/spec_chunked.rb +0 -87
  140. data/test/spec_commonlogger.rb +0 -57
  141. data/test/spec_conditionalget.rb +0 -102
  142. data/test/spec_config.rb +0 -22
  143. data/test/spec_content_length.rb +0 -86
  144. data/test/spec_content_type.rb +0 -45
  145. data/test/spec_deflater.rb +0 -187
  146. data/test/spec_directory.rb +0 -88
  147. data/test/spec_etag.rb +0 -98
  148. data/test/spec_fastcgi.rb +0 -107
  149. data/test/spec_file.rb +0 -200
  150. data/test/spec_handler.rb +0 -59
  151. data/test/spec_head.rb +0 -48
  152. data/test/spec_lint.rb +0 -515
  153. data/test/spec_lobster.rb +0 -58
  154. data/test/spec_lock.rb +0 -167
  155. data/test/spec_logger.rb +0 -23
  156. data/test/spec_methodoverride.rb +0 -72
  157. data/test/spec_mock.rb +0 -269
  158. data/test/spec_mongrel.rb +0 -182
  159. data/test/spec_multipart.rb +0 -479
  160. data/test/spec_nulllogger.rb +0 -23
  161. data/test/spec_recursive.rb +0 -72
  162. data/test/spec_request.rb +0 -955
  163. data/test/spec_response.rb +0 -313
  164. data/test/spec_rewindable_input.rb +0 -118
  165. data/test/spec_runtime.rb +0 -49
  166. data/test/spec_sendfile.rb +0 -90
  167. data/test/spec_server.rb +0 -121
  168. data/test/spec_session_abstract_id.rb +0 -43
  169. data/test/spec_session_cookie.rb +0 -361
  170. data/test/spec_session_memcache.rb +0 -321
  171. data/test/spec_session_pool.rb +0 -209
  172. data/test/spec_showexceptions.rb +0 -92
  173. data/test/spec_showstatus.rb +0 -84
  174. data/test/spec_static.rb +0 -145
  175. data/test/spec_thin.rb +0 -86
  176. data/test/spec_urlmap.rb +0 -213
  177. data/test/spec_utils.rb +0 -554
  178. data/test/spec_webrick.rb +0 -143
  179. data/test/static/another/index.html +0 -1
  180. data/test/static/index.html +0 -1
  181. data/test/testrequest.rb +0 -78
  182. data/test/unregistered_handler/rack/handler/unregistered.rb +0 -7
  183. data/test/unregistered_handler/rack/handler/unregistered_long_one.rb +0 -7
data/test/spec_lock.rb DELETED
@@ -1,167 +0,0 @@
1
- require 'enumerator'
2
- require 'rack/lint'
3
- require 'rack/lock'
4
- require 'rack/mock'
5
-
6
- class Lock
7
- attr_reader :synchronized
8
-
9
- def initialize
10
- @synchronized = false
11
- end
12
-
13
- def synchronize
14
- @synchronized = true
15
- yield
16
- end
17
-
18
- def lock
19
- @synchronized = true
20
- end
21
-
22
- def unlock
23
- @synchronized = false
24
- end
25
- end
26
-
27
- module LockHelpers
28
- def lock_app(app, lock = Lock.new)
29
- app = if lock
30
- Rack::Lock.new app, lock
31
- else
32
- Rack::Lock.new app
33
- end
34
- Rack::Lint.new app
35
- end
36
- end
37
-
38
- describe Rack::Lock do
39
- ::Enumerator = ::Enumerable::Enumerator unless Object.const_defined?(:Enumerator)
40
-
41
- extend LockHelpers
42
-
43
- describe 'Proxy' do
44
- extend LockHelpers
45
-
46
- should 'delegate each' do
47
- env = Rack::MockRequest.env_for("/")
48
- response = Class.new {
49
- attr_accessor :close_called
50
- def initialize; @close_called = false; end
51
- def each; %w{ hi mom }.each { |x| yield x }; end
52
- }.new
53
-
54
- app = lock_app(lambda { |inner_env| [200, {"Content-Type" => "text/plain"}, response] })
55
- response = app.call(env)[2]
56
- list = []
57
- response.each { |x| list << x }
58
- list.should.equal %w{ hi mom }
59
- end
60
-
61
- should 'delegate to_path' do
62
- lock = Lock.new
63
- env = Rack::MockRequest.env_for("/")
64
-
65
- res = ['Hello World']
66
- def res.to_path ; "/tmp/hello.txt" ; end
67
-
68
- app = Rack::Lock.new(lambda { |inner_env| [200, {"Content-Type" => "text/plain"}, res] }, lock)
69
- body = app.call(env)[2]
70
-
71
- body.should.respond_to :to_path
72
- body.to_path.should.equal "/tmp/hello.txt"
73
- end
74
-
75
- should 'not delegate to_path if body does not implement it' do
76
- env = Rack::MockRequest.env_for("/")
77
-
78
- res = ['Hello World']
79
-
80
- app = lock_app(lambda { |inner_env| [200, {"Content-Type" => "text/plain"}, res] })
81
- body = app.call(env)[2]
82
-
83
- body.should.not.respond_to :to_path
84
- end
85
- end
86
-
87
- should 'call super on close' do
88
- env = Rack::MockRequest.env_for("/")
89
- response = Class.new {
90
- attr_accessor :close_called
91
- def initialize; @close_called = false; end
92
- def close; @close_called = true; end
93
- }.new
94
-
95
- app = lock_app(lambda { |inner_env| [200, {"Content-Type" => "text/plain"}, response] })
96
- app.call(env)
97
- response.close_called.should.equal false
98
- response.close
99
- response.close_called.should.equal true
100
- end
101
-
102
- should "not unlock until body is closed" do
103
- lock = Lock.new
104
- env = Rack::MockRequest.env_for("/")
105
- response = Object.new
106
- app = lock_app(lambda { |inner_env| [200, {"Content-Type" => "text/plain"}, response] }, lock)
107
- lock.synchronized.should.equal false
108
- response = app.call(env)[2]
109
- lock.synchronized.should.equal true
110
- response.close
111
- lock.synchronized.should.equal false
112
- end
113
-
114
- should "return value from app" do
115
- env = Rack::MockRequest.env_for("/")
116
- body = [200, {"Content-Type" => "text/plain"}, %w{ hi mom }]
117
- app = lock_app(lambda { |inner_env| body })
118
-
119
- res = app.call(env)
120
- res[0].should.equal body[0]
121
- res[1].should.equal body[1]
122
- Enumerator.new(res[2]).to_a.should.equal ["hi", "mom"]
123
- end
124
-
125
- should "call synchronize on lock" do
126
- lock = Lock.new
127
- env = Rack::MockRequest.env_for("/")
128
- app = lock_app(lambda { |inner_env| [200, {"Content-Type" => "text/plain"}, %w{ a b c }] }, lock)
129
- lock.synchronized.should.equal false
130
- app.call(env)
131
- lock.synchronized.should.equal true
132
- end
133
-
134
- should "unlock if the app raises" do
135
- lock = Lock.new
136
- env = Rack::MockRequest.env_for("/")
137
- app = lock_app(lambda { raise Exception }, lock)
138
- lambda { app.call(env) }.should.raise(Exception)
139
- lock.synchronized.should.equal false
140
- end
141
-
142
- should "unlock if the app throws" do
143
- lock = Lock.new
144
- env = Rack::MockRequest.env_for("/")
145
- app = lock_app(lambda {|_| throw :bacon }, lock)
146
- lambda { app.call(env) }.should.throw(:bacon)
147
- lock.synchronized.should.equal false
148
- end
149
-
150
- should "set multithread flag to false" do
151
- app = lock_app(lambda { |env|
152
- env['rack.multithread'].should.equal false
153
- [200, {"Content-Type" => "text/plain"}, %w{ a b c }]
154
- }, false)
155
- app.call(Rack::MockRequest.env_for("/"))
156
- end
157
-
158
- should "reset original multithread flag when exiting lock" do
159
- app = Class.new(Rack::Lock) {
160
- def call(env)
161
- env['rack.multithread'].should.equal true
162
- super
163
- end
164
- }.new(lambda { |env| [200, {"Content-Type" => "text/plain"}, %w{ a b c }] })
165
- Rack::Lint.new(app).call(Rack::MockRequest.env_for("/"))
166
- end
167
- 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
@@ -1,72 +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
- should "modify REQUEST_METHOD for POST requests when X-HTTP-Method-Override is set" do
27
- env = Rack::MockRequest.env_for("/",
28
- :method => "POST",
29
- "HTTP_X_HTTP_METHOD_OVERRIDE" => "PATCH"
30
- )
31
- app.call env
32
-
33
- env["REQUEST_METHOD"].should.equal "PATCH"
34
- end
35
-
36
- should "not modify REQUEST_METHOD if the method is unknown" do
37
- env = Rack::MockRequest.env_for("/", :method => "POST", :input => "_method=foo")
38
- app.call env
39
-
40
- env["REQUEST_METHOD"].should.equal "POST"
41
- end
42
-
43
- should "not modify REQUEST_METHOD when _method is nil" do
44
- env = Rack::MockRequest.env_for("/", :method => "POST", :input => "foo=bar")
45
- app.call env
46
-
47
- env["REQUEST_METHOD"].should.equal "POST"
48
- end
49
-
50
- should "store the original REQUEST_METHOD prior to overriding" do
51
- env = Rack::MockRequest.env_for("/",
52
- :method => "POST",
53
- :input => "_method=options")
54
- app.call env
55
-
56
- env["rack.methodoverride.original_method"].should.equal "POST"
57
- end
58
-
59
- should "not modify REQUEST_METHOD when given invalid multipart form data" do
60
- input = <<EOF
61
- --AaB03x\r
62
- content-disposition: form-data; name="huge"; filename="huge"\r
63
- EOF
64
- env = Rack::MockRequest.env_for("/",
65
- "CONTENT_TYPE" => "multipart/form-data, boundary=AaB03x",
66
- "CONTENT_LENGTH" => input.size.to_s,
67
- :method => "POST", :input => input)
68
- app.call env
69
-
70
- env["REQUEST_METHOD"].should.equal "POST"
71
- end
72
- end
data/test/spec_mock.rb DELETED
@@ -1,269 +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 "provide sensible defaults" do
34
- res = Rack::MockRequest.new(app).request
35
-
36
- env = YAML.load(res.body)
37
- env["REQUEST_METHOD"].should.equal "GET"
38
- env["SERVER_NAME"].should.equal "example.org"
39
- env["SERVER_PORT"].should.equal "80"
40
- env["QUERY_STRING"].should.equal ""
41
- env["PATH_INFO"].should.equal "/"
42
- env["SCRIPT_NAME"].should.equal ""
43
- env["rack.url_scheme"].should.equal "http"
44
- env["mock.postdata"].should.be.empty
45
- end
46
-
47
- should "allow GET/POST/PUT/DELETE/HEAD" do
48
- res = Rack::MockRequest.new(app).get("", :input => "foo")
49
- env = YAML.load(res.body)
50
- env["REQUEST_METHOD"].should.equal "GET"
51
-
52
- res = Rack::MockRequest.new(app).post("", :input => "foo")
53
- env = YAML.load(res.body)
54
- env["REQUEST_METHOD"].should.equal "POST"
55
-
56
- res = Rack::MockRequest.new(app).put("", :input => "foo")
57
- env = YAML.load(res.body)
58
- env["REQUEST_METHOD"].should.equal "PUT"
59
-
60
- res = Rack::MockRequest.new(app).patch("", :input => "foo")
61
- env = YAML.load(res.body)
62
- env["REQUEST_METHOD"].should.equal "PATCH"
63
-
64
- res = Rack::MockRequest.new(app).delete("", :input => "foo")
65
- env = YAML.load(res.body)
66
- env["REQUEST_METHOD"].should.equal "DELETE"
67
-
68
- Rack::MockRequest.env_for("/", :method => "HEAD")["REQUEST_METHOD"].
69
- should.equal "HEAD"
70
-
71
- Rack::MockRequest.env_for("/", :method => "OPTIONS")["REQUEST_METHOD"].
72
- should.equal "OPTIONS"
73
- end
74
-
75
- should "set content length" do
76
- env = Rack::MockRequest.env_for("/", :input => "foo")
77
- env["CONTENT_LENGTH"].should.equal "3"
78
- end
79
-
80
- should "allow posting" do
81
- res = Rack::MockRequest.new(app).get("", :input => "foo")
82
- env = YAML.load(res.body)
83
- env["mock.postdata"].should.equal "foo"
84
-
85
- res = Rack::MockRequest.new(app).post("", :input => StringIO.new("foo"))
86
- env = YAML.load(res.body)
87
- env["mock.postdata"].should.equal "foo"
88
- end
89
-
90
- should "use all parts of an URL" do
91
- res = Rack::MockRequest.new(app).
92
- get("https://bla.example.org:9292/meh/foo?bar")
93
- res.should.be.kind_of Rack::MockResponse
94
-
95
- env = YAML.load(res.body)
96
- env["REQUEST_METHOD"].should.equal "GET"
97
- env["SERVER_NAME"].should.equal "bla.example.org"
98
- env["SERVER_PORT"].should.equal "9292"
99
- env["QUERY_STRING"].should.equal "bar"
100
- env["PATH_INFO"].should.equal "/meh/foo"
101
- env["rack.url_scheme"].should.equal "https"
102
- end
103
-
104
- should "set SSL port and HTTP flag on when using https" do
105
- res = Rack::MockRequest.new(app).
106
- get("https://example.org/foo")
107
- res.should.be.kind_of Rack::MockResponse
108
-
109
- env = YAML.load(res.body)
110
- env["REQUEST_METHOD"].should.equal "GET"
111
- env["SERVER_NAME"].should.equal "example.org"
112
- env["SERVER_PORT"].should.equal "443"
113
- env["QUERY_STRING"].should.equal ""
114
- env["PATH_INFO"].should.equal "/foo"
115
- env["rack.url_scheme"].should.equal "https"
116
- env["HTTPS"].should.equal "on"
117
- end
118
-
119
- should "prepend slash to uri path" do
120
- res = Rack::MockRequest.new(app).
121
- get("foo")
122
- res.should.be.kind_of Rack::MockResponse
123
-
124
- env = YAML.load(res.body)
125
- env["REQUEST_METHOD"].should.equal "GET"
126
- env["SERVER_NAME"].should.equal "example.org"
127
- env["SERVER_PORT"].should.equal "80"
128
- env["QUERY_STRING"].should.equal ""
129
- env["PATH_INFO"].should.equal "/foo"
130
- env["rack.url_scheme"].should.equal "http"
131
- end
132
-
133
- should "properly convert method name to an uppercase string" do
134
- res = Rack::MockRequest.new(app).request(:get)
135
- env = YAML.load(res.body)
136
- env["REQUEST_METHOD"].should.equal "GET"
137
- end
138
-
139
- should "accept params and build query string for GET requests" do
140
- res = Rack::MockRequest.new(app).get("/foo?baz=2", :params => {:foo => {:bar => "1"}})
141
- env = YAML.load(res.body)
142
- env["REQUEST_METHOD"].should.equal "GET"
143
- env["QUERY_STRING"].should.include "baz=2"
144
- env["QUERY_STRING"].should.include "foo[bar]=1"
145
- env["PATH_INFO"].should.equal "/foo"
146
- env["mock.postdata"].should.equal ""
147
- end
148
-
149
- should "accept raw input in params for GET requests" do
150
- res = Rack::MockRequest.new(app).get("/foo?baz=2", :params => "foo[bar]=1")
151
- env = YAML.load(res.body)
152
- env["REQUEST_METHOD"].should.equal "GET"
153
- env["QUERY_STRING"].should.include "baz=2"
154
- env["QUERY_STRING"].should.include "foo[bar]=1"
155
- env["PATH_INFO"].should.equal "/foo"
156
- env["mock.postdata"].should.equal ""
157
- end
158
-
159
- should "accept params and build url encoded params for POST requests" do
160
- res = Rack::MockRequest.new(app).post("/foo", :params => {:foo => {:bar => "1"}})
161
- env = YAML.load(res.body)
162
- env["REQUEST_METHOD"].should.equal "POST"
163
- env["QUERY_STRING"].should.equal ""
164
- env["PATH_INFO"].should.equal "/foo"
165
- env["CONTENT_TYPE"].should.equal "application/x-www-form-urlencoded"
166
- env["mock.postdata"].should.equal "foo[bar]=1"
167
- end
168
-
169
- should "accept raw input in params for POST requests" do
170
- res = Rack::MockRequest.new(app).post("/foo", :params => "foo[bar]=1")
171
- env = YAML.load(res.body)
172
- env["REQUEST_METHOD"].should.equal "POST"
173
- env["QUERY_STRING"].should.equal ""
174
- env["PATH_INFO"].should.equal "/foo"
175
- env["CONTENT_TYPE"].should.equal "application/x-www-form-urlencoded"
176
- env["mock.postdata"].should.equal "foo[bar]=1"
177
- end
178
-
179
- should "accept params and build multipart encoded params for POST requests" do
180
- files = Rack::Multipart::UploadedFile.new(File.join(File.dirname(__FILE__), "multipart", "file1.txt"))
181
- res = Rack::MockRequest.new(app).post("/foo", :params => { "submit-name" => "Larry", "files" => files })
182
- env = YAML.load(res.body)
183
- env["REQUEST_METHOD"].should.equal "POST"
184
- env["QUERY_STRING"].should.equal ""
185
- env["PATH_INFO"].should.equal "/foo"
186
- env["CONTENT_TYPE"].should.equal "multipart/form-data; boundary=AaB03x"
187
- # The gsub accounts for differences in YAMLs affect on the data.
188
- env["mock.postdata"].gsub("\r", "").length.should.equal 206
189
- end
190
-
191
- should "behave valid according to the Rack spec" do
192
- lambda {
193
- Rack::MockRequest.new(app).
194
- get("https://bla.example.org:9292/meh/foo?bar", :lint => true)
195
- }.should.not.raise(Rack::Lint::LintError)
196
- end
197
-
198
- should "call close on the original body object" do
199
- called = false
200
- body = Rack::BodyProxy.new(['hi']) { called = true }
201
- capp = proc { |e| [200, {'Content-Type' => 'text/plain'}, body] }
202
- called.should.equal false
203
- Rack::MockRequest.new(capp).get('/', :lint => true)
204
- called.should.equal true
205
- end
206
- end
207
-
208
- describe Rack::MockResponse do
209
- should "provide access to the HTTP status" do
210
- res = Rack::MockRequest.new(app).get("")
211
- res.should.be.successful
212
- res.should.be.ok
213
-
214
- res = Rack::MockRequest.new(app).get("/?status=404")
215
- res.should.not.be.successful
216
- res.should.be.client_error
217
- res.should.be.not_found
218
-
219
- res = Rack::MockRequest.new(app).get("/?status=501")
220
- res.should.not.be.successful
221
- res.should.be.server_error
222
-
223
- res = Rack::MockRequest.new(app).get("/?status=307")
224
- res.should.be.redirect
225
-
226
- res = Rack::MockRequest.new(app).get("/?status=201", :lint => true)
227
- res.should.be.empty
228
- end
229
-
230
- should "provide access to the HTTP headers" do
231
- res = Rack::MockRequest.new(app).get("")
232
- res.should.include "Content-Type"
233
- res.headers["Content-Type"].should.equal "text/yaml"
234
- res.original_headers["Content-Type"].should.equal "text/yaml"
235
- res["Content-Type"].should.equal "text/yaml"
236
- res.content_type.should.equal "text/yaml"
237
- res.content_length.should.not.equal 0
238
- res.location.should.be.nil
239
- end
240
-
241
- should "provide access to the HTTP body" do
242
- res = Rack::MockRequest.new(app).get("")
243
- res.body.should =~ /rack/
244
- res.should =~ /rack/
245
- res.should.match(/rack/)
246
- res.should.satisfy { |r| r.match(/rack/) }
247
- end
248
-
249
- should "provide access to the Rack errors" do
250
- res = Rack::MockRequest.new(app).get("/?error=foo", :lint => true)
251
- res.should.be.ok
252
- res.errors.should.not.be.empty
253
- res.errors.should.include "foo"
254
- end
255
-
256
- should "allow calling body.close afterwards" do
257
- # this is exactly what rack-test does
258
- body = StringIO.new("hi")
259
- res = Rack::MockResponse.new(200, {}, body)
260
- body.close if body.respond_to?(:close)
261
- res.body.should == 'hi'
262
- end
263
-
264
- should "optionally make Rack errors fatal" do
265
- lambda {
266
- Rack::MockRequest.new(app).get("/?error=foo", :fatal => true)
267
- }.should.raise(Rack::MockRequest::FatalWarning)
268
- end
269
- end