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