rack 1.6.11 → 2.2.3

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 (190) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +694 -0
  3. data/CONTRIBUTING.md +136 -0
  4. data/{COPYING → MIT-LICENSE} +4 -2
  5. data/README.rdoc +157 -163
  6. data/Rakefile +38 -32
  7. data/{SPEC → SPEC.rdoc} +41 -13
  8. data/bin/rackup +1 -0
  9. data/contrib/rack_logo.svg +164 -111
  10. data/example/lobster.ru +2 -0
  11. data/example/protectedlobster.rb +4 -2
  12. data/example/protectedlobster.ru +3 -1
  13. data/lib/rack/auth/abstract/handler.rb +3 -1
  14. data/lib/rack/auth/abstract/request.rb +6 -2
  15. data/lib/rack/auth/basic.rb +7 -4
  16. data/lib/rack/auth/digest/md5.rb +13 -11
  17. data/lib/rack/auth/digest/nonce.rb +6 -3
  18. data/lib/rack/auth/digest/params.rb +5 -4
  19. data/lib/rack/auth/digest/request.rb +6 -4
  20. data/lib/rack/body_proxy.rb +21 -15
  21. data/lib/rack/builder.rb +119 -26
  22. data/lib/rack/cascade.rb +28 -12
  23. data/lib/rack/chunked.rb +70 -22
  24. data/lib/rack/common_logger.rb +80 -0
  25. data/lib/rack/{conditionalget.rb → conditional_get.rb} +20 -16
  26. data/lib/rack/config.rb +2 -0
  27. data/lib/rack/content_length.rb +9 -8
  28. data/lib/rack/content_type.rb +5 -4
  29. data/lib/rack/core_ext/regexp.rb +14 -0
  30. data/lib/rack/deflater.rb +60 -70
  31. data/lib/rack/directory.rb +117 -85
  32. data/lib/rack/etag.rb +9 -7
  33. data/lib/rack/events.rb +153 -0
  34. data/lib/rack/file.rb +4 -149
  35. data/lib/rack/files.rb +218 -0
  36. data/lib/rack/handler/cgi.rb +17 -19
  37. data/lib/rack/handler/fastcgi.rb +17 -18
  38. data/lib/rack/handler/lsws.rb +14 -14
  39. data/lib/rack/handler/scgi.rb +22 -21
  40. data/lib/rack/handler/thin.rb +6 -3
  41. data/lib/rack/handler/webrick.rb +39 -32
  42. data/lib/rack/handler.rb +9 -26
  43. data/lib/rack/head.rb +16 -18
  44. data/lib/rack/lint.rb +110 -64
  45. data/lib/rack/lobster.rb +10 -10
  46. data/lib/rack/lock.rb +17 -11
  47. data/lib/rack/logger.rb +4 -2
  48. data/lib/rack/media_type.rb +43 -0
  49. data/lib/rack/{methodoverride.rb → method_override.rb} +10 -8
  50. data/lib/rack/mime.rb +27 -6
  51. data/lib/rack/mock.rb +124 -65
  52. data/lib/rack/multipart/generator.rb +20 -16
  53. data/lib/rack/multipart/parser.rb +273 -162
  54. data/lib/rack/multipart/uploaded_file.rb +15 -8
  55. data/lib/rack/multipart.rb +39 -8
  56. data/lib/rack/{nulllogger.rb → null_logger.rb} +3 -1
  57. data/lib/rack/query_parser.rb +217 -0
  58. data/lib/rack/recursive.rb +11 -9
  59. data/lib/rack/reloader.rb +8 -4
  60. data/lib/rack/request.rb +553 -305
  61. data/lib/rack/response.rb +244 -88
  62. data/lib/rack/rewindable_input.rb +5 -15
  63. data/lib/rack/runtime.rb +12 -18
  64. data/lib/rack/sendfile.rb +17 -15
  65. data/lib/rack/server.rb +125 -47
  66. data/lib/rack/session/abstract/id.rb +217 -93
  67. data/lib/rack/session/cookie.rb +46 -31
  68. data/lib/rack/session/memcache.rb +4 -87
  69. data/lib/rack/session/pool.rb +26 -17
  70. data/lib/rack/show_exceptions.rb +390 -0
  71. data/lib/rack/{showstatus.rb → show_status.rb} +12 -12
  72. data/lib/rack/static.rb +48 -11
  73. data/lib/rack/tempfile_reaper.rb +3 -3
  74. data/lib/rack/urlmap.rb +26 -19
  75. data/lib/rack/utils.rb +212 -294
  76. data/lib/rack/version.rb +29 -0
  77. data/lib/rack.rb +76 -33
  78. data/rack.gemspec +43 -30
  79. metadata +65 -186
  80. data/HISTORY.md +0 -375
  81. data/KNOWN-ISSUES +0 -44
  82. data/lib/rack/backports/uri/common_18.rb +0 -56
  83. data/lib/rack/backports/uri/common_192.rb +0 -52
  84. data/lib/rack/backports/uri/common_193.rb +0 -29
  85. data/lib/rack/commonlogger.rb +0 -72
  86. data/lib/rack/handler/evented_mongrel.rb +0 -8
  87. data/lib/rack/handler/mongrel.rb +0 -106
  88. data/lib/rack/handler/swiftiplied_mongrel.rb +0 -8
  89. data/lib/rack/showexceptions.rb +0 -387
  90. data/lib/rack/utils/okjson.rb +0 -600
  91. data/test/builder/anything.rb +0 -5
  92. data/test/builder/comment.ru +0 -4
  93. data/test/builder/end.ru +0 -5
  94. data/test/builder/line.ru +0 -1
  95. data/test/builder/options.ru +0 -2
  96. data/test/cgi/assets/folder/test.js +0 -1
  97. data/test/cgi/assets/fonts/font.eot +0 -1
  98. data/test/cgi/assets/images/image.png +0 -1
  99. data/test/cgi/assets/index.html +0 -1
  100. data/test/cgi/assets/javascripts/app.js +0 -1
  101. data/test/cgi/assets/stylesheets/app.css +0 -1
  102. data/test/cgi/lighttpd.conf +0 -26
  103. data/test/cgi/rackup_stub.rb +0 -6
  104. data/test/cgi/sample_rackup.ru +0 -5
  105. data/test/cgi/test +0 -9
  106. data/test/cgi/test+directory/test+file +0 -1
  107. data/test/cgi/test.fcgi +0 -8
  108. data/test/cgi/test.ru +0 -5
  109. data/test/gemloader.rb +0 -10
  110. data/test/multipart/bad_robots +0 -259
  111. data/test/multipart/binary +0 -0
  112. data/test/multipart/content_type_and_no_filename +0 -6
  113. data/test/multipart/empty +0 -10
  114. data/test/multipart/fail_16384_nofile +0 -814
  115. data/test/multipart/file1.txt +0 -1
  116. data/test/multipart/filename_and_modification_param +0 -7
  117. data/test/multipart/filename_and_no_name +0 -6
  118. data/test/multipart/filename_with_escaped_quotes +0 -6
  119. data/test/multipart/filename_with_escaped_quotes_and_modification_param +0 -7
  120. data/test/multipart/filename_with_null_byte +0 -7
  121. data/test/multipart/filename_with_percent_escaped_quotes +0 -6
  122. data/test/multipart/filename_with_unescaped_percentages +0 -6
  123. data/test/multipart/filename_with_unescaped_percentages2 +0 -6
  124. data/test/multipart/filename_with_unescaped_percentages3 +0 -6
  125. data/test/multipart/filename_with_unescaped_quotes +0 -6
  126. data/test/multipart/ie +0 -6
  127. data/test/multipart/invalid_character +0 -6
  128. data/test/multipart/mixed_files +0 -21
  129. data/test/multipart/nested +0 -10
  130. data/test/multipart/none +0 -9
  131. data/test/multipart/semicolon +0 -6
  132. data/test/multipart/text +0 -15
  133. data/test/multipart/three_files_three_fields +0 -31
  134. data/test/multipart/webkit +0 -32
  135. data/test/rackup/config.ru +0 -31
  136. data/test/registering_handler/rack/handler/registering_myself.rb +0 -8
  137. data/test/spec_auth_basic.rb +0 -81
  138. data/test/spec_auth_digest.rb +0 -259
  139. data/test/spec_body_proxy.rb +0 -85
  140. data/test/spec_builder.rb +0 -223
  141. data/test/spec_cascade.rb +0 -61
  142. data/test/spec_cgi.rb +0 -102
  143. data/test/spec_chunked.rb +0 -101
  144. data/test/spec_commonlogger.rb +0 -93
  145. data/test/spec_conditionalget.rb +0 -102
  146. data/test/spec_config.rb +0 -22
  147. data/test/spec_content_length.rb +0 -85
  148. data/test/spec_content_type.rb +0 -45
  149. data/test/spec_deflater.rb +0 -339
  150. data/test/spec_directory.rb +0 -88
  151. data/test/spec_etag.rb +0 -107
  152. data/test/spec_fastcgi.rb +0 -107
  153. data/test/spec_file.rb +0 -221
  154. data/test/spec_handler.rb +0 -72
  155. data/test/spec_head.rb +0 -45
  156. data/test/spec_lint.rb +0 -550
  157. data/test/spec_lobster.rb +0 -58
  158. data/test/spec_lock.rb +0 -164
  159. data/test/spec_logger.rb +0 -23
  160. data/test/spec_methodoverride.rb +0 -111
  161. data/test/spec_mime.rb +0 -51
  162. data/test/spec_mock.rb +0 -297
  163. data/test/spec_mongrel.rb +0 -182
  164. data/test/spec_multipart.rb +0 -600
  165. data/test/spec_nulllogger.rb +0 -20
  166. data/test/spec_recursive.rb +0 -72
  167. data/test/spec_request.rb +0 -1232
  168. data/test/spec_response.rb +0 -407
  169. data/test/spec_rewindable_input.rb +0 -118
  170. data/test/spec_runtime.rb +0 -49
  171. data/test/spec_sendfile.rb +0 -130
  172. data/test/spec_server.rb +0 -167
  173. data/test/spec_session_abstract_id.rb +0 -53
  174. data/test/spec_session_cookie.rb +0 -410
  175. data/test/spec_session_memcache.rb +0 -321
  176. data/test/spec_session_pool.rb +0 -209
  177. data/test/spec_showexceptions.rb +0 -98
  178. data/test/spec_showstatus.rb +0 -103
  179. data/test/spec_static.rb +0 -145
  180. data/test/spec_tempfile_reaper.rb +0 -63
  181. data/test/spec_thin.rb +0 -91
  182. data/test/spec_urlmap.rb +0 -236
  183. data/test/spec_utils.rb +0 -647
  184. data/test/spec_version.rb +0 -17
  185. data/test/spec_webrick.rb +0 -184
  186. data/test/static/another/index.html +0 -1
  187. data/test/static/index.html +0 -1
  188. data/test/testrequest.rb +0 -78
  189. data/test/unregistered_handler/rack/handler/unregistered.rb +0 -7
  190. 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
@@ -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