rack 1.6.13 → 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 (191) 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 +141 -93
  67. data/lib/rack/session/cookie.rb +35 -29
  68. data/lib/rack/session/memcache.rb +4 -93
  69. data/lib/rack/session/pool.rb +13 -11
  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 -187
  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 -358
  176. data/test/spec_session_persisted_secure_secure_session_hash.rb +0 -73
  177. data/test/spec_session_pool.rb +0 -246
  178. data/test/spec_showexceptions.rb +0 -98
  179. data/test/spec_showstatus.rb +0 -103
  180. data/test/spec_static.rb +0 -145
  181. data/test/spec_tempfile_reaper.rb +0 -63
  182. data/test/spec_thin.rb +0 -91
  183. data/test/spec_urlmap.rb +0 -236
  184. data/test/spec_utils.rb +0 -647
  185. data/test/spec_version.rb +0 -17
  186. data/test/spec_webrick.rb +0 -184
  187. data/test/static/another/index.html +0 -1
  188. data/test/static/index.html +0 -1
  189. data/test/testrequest.rb +0 -78
  190. data/test/unregistered_handler/rack/handler/unregistered.rb +0 -7
  191. data/test/unregistered_handler/rack/handler/unregistered_long_one.rb +0 -7
data/test/spec_etag.rb DELETED
@@ -1,107 +0,0 @@
1
- require 'rack/etag'
2
- require 'rack/lint'
3
- require 'rack/mock'
4
- require 'time'
5
-
6
- describe Rack::ETag do
7
- def etag(app, *args)
8
- Rack::Lint.new Rack::ETag.new(app, *args)
9
- end
10
-
11
- def request
12
- Rack::MockRequest.env_for
13
- end
14
-
15
- def sendfile_body
16
- res = ['Hello World']
17
- def res.to_path ; "/tmp/hello.txt" ; end
18
- res
19
- end
20
-
21
- should "set ETag if none is set if status is 200" do
22
- app = lambda { |env| [200, {'Content-Type' => 'text/plain'}, ["Hello, World!"]] }
23
- response = etag(app).call(request)
24
- response[1]['ETag'].should.equal "W/\"65a8e27d8879283831b664bd8b7f0ad4\""
25
- end
26
-
27
- should "set ETag if none is set if status is 201" do
28
- app = lambda { |env| [201, {'Content-Type' => 'text/plain'}, ["Hello, World!"]] }
29
- response = etag(app).call(request)
30
- response[1]['ETag'].should.equal "W/\"65a8e27d8879283831b664bd8b7f0ad4\""
31
- end
32
-
33
- should "set Cache-Control to 'max-age=0, private, must-revalidate' (default) if none is set" do
34
- app = lambda { |env| [201, {'Content-Type' => 'text/plain'}, ["Hello, World!"]] }
35
- response = etag(app).call(request)
36
- response[1]['Cache-Control'].should.equal 'max-age=0, private, must-revalidate'
37
- end
38
-
39
- should "set Cache-Control to chosen one if none is set" do
40
- app = lambda { |env| [201, {'Content-Type' => 'text/plain'}, ["Hello, World!"]] }
41
- response = etag(app, nil, 'public').call(request)
42
- response[1]['Cache-Control'].should.equal 'public'
43
- end
44
-
45
- should "set a given Cache-Control even if digest could not be calculated" do
46
- app = lambda { |env| [200, {'Content-Type' => 'text/plain'}, []] }
47
- response = etag(app, 'no-cache').call(request)
48
- response[1]['Cache-Control'].should.equal 'no-cache'
49
- end
50
-
51
- should "not set Cache-Control if it is already set" do
52
- app = lambda { |env| [201, {'Content-Type' => 'text/plain', 'Cache-Control' => 'public'}, ["Hello, World!"]] }
53
- response = etag(app).call(request)
54
- response[1]['Cache-Control'].should.equal 'public'
55
- end
56
-
57
- should "not set Cache-Control if directive isn't present" do
58
- app = lambda { |env| [200, {'Content-Type' => 'text/plain'}, ["Hello, World!"]] }
59
- response = etag(app, nil, nil).call(request)
60
- response[1]['Cache-Control'].should.equal nil
61
- end
62
-
63
- should "not change ETag if it is already set" do
64
- app = lambda { |env| [200, {'Content-Type' => 'text/plain', 'ETag' => '"abc"'}, ["Hello, World!"]] }
65
- response = etag(app).call(request)
66
- response[1]['ETag'].should.equal "\"abc\""
67
- end
68
-
69
- should "not set ETag if body is empty" do
70
- app = lambda { |env| [200, {'Content-Type' => 'text/plain', 'Last-Modified' => Time.now.httpdate}, []] }
71
- response = etag(app).call(request)
72
- response[1]['ETag'].should.be.nil
73
- end
74
-
75
- should "not set ETag if Last-Modified is set" do
76
- app = lambda { |env| [200, {'Content-Type' => 'text/plain', 'Last-Modified' => Time.now.httpdate}, ["Hello, World!"]] }
77
- response = etag(app).call(request)
78
- response[1]['ETag'].should.be.nil
79
- end
80
-
81
- should "not set ETag if a sendfile_body is given" do
82
- app = lambda { |env| [200, {'Content-Type' => 'text/plain'}, sendfile_body] }
83
- response = etag(app).call(request)
84
- response[1]['ETag'].should.be.nil
85
- end
86
-
87
- should "not set ETag if a status is not 200 or 201" do
88
- app = lambda { |env| [401, {'Content-Type' => 'text/plain'}, ['Access denied.']] }
89
- response = etag(app).call(request)
90
- response[1]['ETag'].should.be.nil
91
- end
92
-
93
- should "not set ETag if no-cache is given" do
94
- app = lambda { |env| [200, {'Content-Type' => 'text/plain', 'Cache-Control' => 'no-cache, must-revalidate'}, ['Hello, World!']] }
95
- response = etag(app).call(request)
96
- response[1]['ETag'].should.be.nil
97
- end
98
-
99
- should "close the original body" do
100
- body = StringIO.new
101
- app = lambda { |env| [200, {}, body] }
102
- response = etag(app).call(request)
103
- body.should.not.be.closed
104
- response[2].close
105
- body.should.be.closed
106
- end
107
- end
data/test/spec_fastcgi.rb DELETED
@@ -1,107 +0,0 @@
1
- begin
2
- require File.expand_path('../testrequest', __FILE__)
3
- require 'rack/handler/fastcgi'
4
-
5
- describe Rack::Handler::FastCGI do
6
- extend TestRequest::Helpers
7
-
8
- @host = '127.0.0.1'
9
- @port = 9203
10
-
11
- if `which lighttpd` && !$?.success?
12
- raise "lighttpd not found"
13
- end
14
-
15
- # Keep this first.
16
- $pid = fork {
17
- ENV['RACK_ENV'] = 'deployment'
18
- ENV['RUBYLIB'] = [
19
- File.expand_path('../../lib', __FILE__),
20
- ENV['RUBYLIB'],
21
- ].compact.join(':')
22
-
23
- Dir.chdir(File.expand_path("../cgi", __FILE__)) do
24
- exec "lighttpd -D -f lighttpd.conf"
25
- end
26
- }
27
-
28
- should "respond" do
29
- sleep 1
30
- GET("/test")
31
- response.should.not.be.nil
32
- end
33
-
34
- should "respond via rackup server" do
35
- GET("/sample_rackup.ru")
36
- status.should.equal 200
37
- end
38
-
39
- should "be a lighttpd" do
40
- GET("/test.fcgi")
41
- status.should.equal 200
42
- response["SERVER_SOFTWARE"].should =~ /lighttpd/
43
- response["HTTP_VERSION"].should.equal "HTTP/1.1"
44
- response["SERVER_PROTOCOL"].should.equal "HTTP/1.1"
45
- response["SERVER_PORT"].should.equal @port.to_s
46
- response["SERVER_NAME"].should.equal @host
47
- end
48
-
49
- should "have rack headers" do
50
- GET("/test.fcgi")
51
- response["rack.version"].should.equal [1,3]
52
- response["rack.multithread"].should.be.false
53
- response["rack.multiprocess"].should.be.true
54
- response["rack.run_once"].should.be.false
55
- end
56
-
57
- should "have CGI headers on GET" do
58
- GET("/test.fcgi")
59
- response["REQUEST_METHOD"].should.equal "GET"
60
- response["SCRIPT_NAME"].should.equal "/test.fcgi"
61
- response["REQUEST_PATH"].should.equal "/"
62
- response["PATH_INFO"].should.equal ""
63
- response["QUERY_STRING"].should.equal ""
64
- response["test.postdata"].should.equal ""
65
-
66
- GET("/test.fcgi/foo?quux=1")
67
- response["REQUEST_METHOD"].should.equal "GET"
68
- response["SCRIPT_NAME"].should.equal "/test.fcgi"
69
- response["REQUEST_PATH"].should.equal "/"
70
- response["PATH_INFO"].should.equal "/foo"
71
- response["QUERY_STRING"].should.equal "quux=1"
72
- end
73
-
74
- should "have CGI headers on POST" do
75
- POST("/test.fcgi", {"rack-form-data" => "23"}, {'X-test-header' => '42'})
76
- status.should.equal 200
77
- response["REQUEST_METHOD"].should.equal "POST"
78
- response["SCRIPT_NAME"].should.equal "/test.fcgi"
79
- response["REQUEST_PATH"].should.equal "/"
80
- response["QUERY_STRING"].should.equal ""
81
- response["HTTP_X_TEST_HEADER"].should.equal "42"
82
- response["test.postdata"].should.equal "rack-form-data=23"
83
- end
84
-
85
- should "support HTTP auth" do
86
- GET("/test.fcgi", {:user => "ruth", :passwd => "secret"})
87
- response["HTTP_AUTHORIZATION"].should.equal "Basic cnV0aDpzZWNyZXQ="
88
- end
89
-
90
- should "set status" do
91
- GET("/test.fcgi?secret")
92
- status.should.equal 403
93
- response["rack.url_scheme"].should.equal "http"
94
- end
95
-
96
- # Keep this last.
97
- should "shutdown" do
98
- Process.kill 15, $pid
99
- Process.wait($pid).should.equal $pid
100
- end
101
- end
102
-
103
- rescue RuntimeError
104
- $stderr.puts "Skipping Rack::Handler::FastCGI tests (lighttpd is required). Install lighttpd and try again."
105
- rescue LoadError
106
- $stderr.puts "Skipping Rack::Handler::FastCGI tests (FCGI is required). `gem install fcgi` and try again."
107
- end
data/test/spec_file.rb DELETED
@@ -1,221 +0,0 @@
1
- require 'rack/file'
2
- require 'rack/lint'
3
- require 'rack/mock'
4
-
5
- describe Rack::File do
6
- DOCROOT = File.expand_path(File.dirname(__FILE__)) unless defined? DOCROOT
7
-
8
- def file(*args)
9
- Rack::Lint.new Rack::File.new(*args)
10
- end
11
-
12
- should "serve files" do
13
- res = Rack::MockRequest.new(file(DOCROOT)).get("/cgi/test")
14
-
15
- res.should.be.ok
16
- res.should =~ /ruby/
17
- end
18
-
19
- should "set Last-Modified header" do
20
- res = Rack::MockRequest.new(file(DOCROOT)).get("/cgi/test")
21
-
22
- path = File.join(DOCROOT, "/cgi/test")
23
-
24
- res.should.be.ok
25
- res["Last-Modified"].should.equal File.mtime(path).httpdate
26
- end
27
-
28
- should "return 304 if file isn't modified since last serve" do
29
- path = File.join(DOCROOT, "/cgi/test")
30
- res = Rack::MockRequest.new(file(DOCROOT)).
31
- get("/cgi/test", 'HTTP_IF_MODIFIED_SINCE' => File.mtime(path).httpdate)
32
-
33
- res.status.should.equal 304
34
- res.body.should.be.empty
35
- end
36
-
37
- should "return the file if it's modified since last serve" do
38
- path = File.join(DOCROOT, "/cgi/test")
39
- res = Rack::MockRequest.new(file(DOCROOT)).
40
- get("/cgi/test", 'HTTP_IF_MODIFIED_SINCE' => (File.mtime(path) - 100).httpdate)
41
-
42
- res.should.be.ok
43
- end
44
-
45
- should "serve files with URL encoded filenames" do
46
- res = Rack::MockRequest.new(file(DOCROOT)).get("/cgi/%74%65%73%74") # "/cgi/test"
47
-
48
- res.should.be.ok
49
- res.should =~ /ruby/
50
- end
51
-
52
- should "allow safe directory traversal" do
53
- req = Rack::MockRequest.new(file(DOCROOT))
54
-
55
- res = req.get('/cgi/../cgi/test')
56
- res.should.be.successful
57
-
58
- res = req.get('.')
59
- res.should.be.not_found
60
-
61
- res = req.get("test/..")
62
- res.should.be.not_found
63
- end
64
-
65
- should "not allow unsafe directory traversal" do
66
- req = Rack::MockRequest.new(file(DOCROOT))
67
-
68
- res = req.get("/../README.rdoc")
69
- res.should.be.client_error
70
-
71
- res = req.get("../test/spec_file.rb")
72
- res.should.be.client_error
73
-
74
- res = req.get("../README.rdoc")
75
- res.should.be.client_error
76
-
77
- res.should.be.not_found
78
- end
79
-
80
- should "allow files with .. in their name" do
81
- req = Rack::MockRequest.new(file(DOCROOT))
82
- res = req.get("/cgi/..test")
83
- res.should.be.not_found
84
-
85
- res = req.get("/cgi/test..")
86
- res.should.be.not_found
87
-
88
- res = req.get("/cgi../test..")
89
- res.should.be.not_found
90
- end
91
-
92
- should "not allow unsafe directory traversal with encoded periods" do
93
- res = Rack::MockRequest.new(file(DOCROOT)).get("/%2E%2E/README")
94
-
95
- res.should.be.client_error?
96
- res.should.be.not_found
97
- end
98
-
99
- should "allow safe directory traversal with encoded periods" do
100
- res = Rack::MockRequest.new(file(DOCROOT)).get("/cgi/%2E%2E/cgi/test")
101
-
102
- res.should.be.successful
103
- end
104
-
105
- should "404 if it can't find the file" do
106
- res = Rack::MockRequest.new(file(DOCROOT)).get("/cgi/blubb")
107
-
108
- res.should.be.not_found
109
- end
110
-
111
- should "detect SystemCallErrors" do
112
- res = Rack::MockRequest.new(file(DOCROOT)).get("/cgi")
113
-
114
- res.should.be.not_found
115
- end
116
-
117
- should "return bodies that respond to #to_path" do
118
- env = Rack::MockRequest.env_for("/cgi/test")
119
- status, _, body = Rack::File.new(DOCROOT).call(env)
120
-
121
- path = File.join(DOCROOT, "/cgi/test")
122
-
123
- status.should.equal 200
124
- body.should.respond_to :to_path
125
- body.to_path.should.equal path
126
- end
127
-
128
- should "return correct byte range in body" do
129
- env = Rack::MockRequest.env_for("/cgi/test")
130
- env["HTTP_RANGE"] = "bytes=22-33"
131
- res = Rack::MockResponse.new(*file(DOCROOT).call(env))
132
-
133
- res.status.should.equal 206
134
- res["Content-Length"].should.equal "12"
135
- res["Content-Range"].should.equal "bytes 22-33/193"
136
- res.body.should.equal "-*- ruby -*-"
137
- end
138
-
139
- should "return error for unsatisfiable byte range" do
140
- env = Rack::MockRequest.env_for("/cgi/test")
141
- env["HTTP_RANGE"] = "bytes=1234-5678"
142
- res = Rack::MockResponse.new(*file(DOCROOT).call(env))
143
-
144
- res.status.should.equal 416
145
- res["Content-Range"].should.equal "bytes */193"
146
- end
147
-
148
- should "support custom http headers" do
149
- env = Rack::MockRequest.env_for("/cgi/test")
150
- status, heads, _ = file(DOCROOT, 'Cache-Control' => 'public, max-age=38',
151
- 'Access-Control-Allow-Origin' => '*').call(env)
152
-
153
- status.should.equal 200
154
- heads['Cache-Control'].should.equal 'public, max-age=38'
155
- heads['Access-Control-Allow-Origin'].should.equal '*'
156
- end
157
-
158
- should "support not add custom http headers if none are supplied" do
159
- env = Rack::MockRequest.env_for("/cgi/test")
160
- status, heads, _ = file(DOCROOT).call(env)
161
-
162
- status.should.equal 200
163
- heads['Cache-Control'].should.equal nil
164
- heads['Access-Control-Allow-Origin'].should.equal nil
165
- end
166
-
167
- should "only support GET, HEAD, and OPTIONS requests" do
168
- req = Rack::MockRequest.new(file(DOCROOT))
169
-
170
- forbidden = %w[post put patch delete]
171
- forbidden.each do |method|
172
- res = req.send(method, "/cgi/test")
173
- res.should.be.client_error
174
- res.should.be.method_not_allowed
175
- res.headers['Allow'].split(/, */).sort.should == %w(GET HEAD OPTIONS)
176
- end
177
-
178
- allowed = %w[get head options]
179
- allowed.each do |method|
180
- res = req.send(method, "/cgi/test")
181
- res.should.be.successful
182
- end
183
- end
184
-
185
- should "set Allow correctly for OPTIONS requests" do
186
- req = Rack::MockRequest.new(file(DOCROOT))
187
- res = req.options('/cgi/test')
188
- res.should.be.successful
189
- res.headers['Allow'].should.not.equal nil
190
- res.headers['Allow'].split(/, */).sort.should == %w(GET HEAD OPTIONS)
191
- end
192
-
193
- should "set Content-Length correctly for HEAD requests" do
194
- req = Rack::MockRequest.new(Rack::Lint.new(Rack::File.new(DOCROOT)))
195
- res = req.head "/cgi/test"
196
- res.should.be.successful
197
- res['Content-Length'].should.equal "193"
198
- end
199
-
200
- should "default to a mime type of text/plain" do
201
- req = Rack::MockRequest.new(Rack::Lint.new(Rack::File.new(DOCROOT)))
202
- res = req.get "/cgi/test"
203
- res.should.be.successful
204
- res['Content-Type'].should.equal "text/plain"
205
- end
206
-
207
- should "allow the default mime type to be set" do
208
- req = Rack::MockRequest.new(Rack::Lint.new(Rack::File.new(DOCROOT, nil, 'application/octet-stream')))
209
- res = req.get "/cgi/test"
210
- res.should.be.successful
211
- res['Content-Type'].should.equal "application/octet-stream"
212
- end
213
-
214
- should "not set Content-Type if the mime type is not set" do
215
- req = Rack::MockRequest.new(Rack::Lint.new(Rack::File.new(DOCROOT, nil, nil)))
216
- res = req.get "/cgi/test"
217
- res.should.be.successful
218
- res['Content-Type'].should.equal nil
219
- end
220
-
221
- end
data/test/spec_handler.rb DELETED
@@ -1,72 +0,0 @@
1
- require 'rack/handler'
2
-
3
- class Rack::Handler::Lobster; end
4
- class RockLobster; end
5
-
6
- describe Rack::Handler do
7
- it "has registered default handlers" do
8
- Rack::Handler.get('cgi').should.equal Rack::Handler::CGI
9
- Rack::Handler.get('webrick').should.equal Rack::Handler::WEBrick
10
-
11
- begin
12
- Rack::Handler.get('fastcgi').should.equal Rack::Handler::FastCGI
13
- rescue LoadError
14
- end
15
-
16
- begin
17
- Rack::Handler.get('mongrel').should.equal Rack::Handler::Mongrel
18
- rescue LoadError
19
- end
20
- end
21
-
22
- should "raise LoadError if handler doesn't exist" do
23
- lambda {
24
- Rack::Handler.get('boom')
25
- }.should.raise(LoadError)
26
- end
27
-
28
- should "raise LoadError if handler isn't nested under Rack::Handler" do
29
- # Feature-detect whether Ruby can do non-inherited const lookups.
30
- # If it can't, then Rack::Handler may lookup non-handler toplevel
31
- # constants, so the best we can do is no-op here and not test it.
32
- begin
33
- Rack::Handler._const_get('Object', false)
34
- rescue NameError
35
- lambda {
36
- Rack::Handler.get('Object')
37
- }.should.raise(LoadError)
38
- end
39
- end
40
-
41
- should "get unregistered, but already required, handler by name" do
42
- Rack::Handler.get('Lobster').should.equal Rack::Handler::Lobster
43
- end
44
-
45
- should "register custom handler" do
46
- Rack::Handler.register('rock_lobster', 'RockLobster')
47
- Rack::Handler.get('rock_lobster').should.equal RockLobster
48
- end
49
-
50
- should "not need registration for properly coded handlers even if not already required" do
51
- begin
52
- $LOAD_PATH.push File.expand_path('../unregistered_handler', __FILE__)
53
- Rack::Handler.get('Unregistered').should.equal Rack::Handler::Unregistered
54
- lambda {
55
- Rack::Handler.get('UnRegistered')
56
- }.should.raise LoadError
57
- Rack::Handler.get('UnregisteredLongOne').should.equal Rack::Handler::UnregisteredLongOne
58
- ensure
59
- $LOAD_PATH.delete File.expand_path('../unregistered_handler', __FILE__)
60
- end
61
- end
62
-
63
- should "allow autoloaded handlers to be registered properly while being loaded" do
64
- path = File.expand_path('../registering_handler', __FILE__)
65
- begin
66
- $LOAD_PATH.push path
67
- Rack::Handler.get('registering_myself').should.equal Rack::Handler::RegisteringMyself
68
- ensure
69
- $LOAD_PATH.delete path
70
- end
71
- end
72
- end
data/test/spec_head.rb DELETED
@@ -1,45 +0,0 @@
1
- require 'rack/head'
2
- require 'rack/lint'
3
- require 'rack/mock'
4
-
5
- describe Rack::Head do
6
-
7
- def test_response(headers = {})
8
- body = StringIO.new "foo"
9
- app = lambda do |env|
10
- [200, {"Content-type" => "test/plain", "Content-length" => "3"}, body]
11
- end
12
- request = Rack::MockRequest.env_for("/", headers)
13
- response = Rack::Lint.new(Rack::Head.new(app)).call(request)
14
-
15
- return response, body
16
- end
17
-
18
- should "pass GET, POST, PUT, DELETE, OPTIONS, TRACE requests" do
19
- %w[GET POST PUT DELETE OPTIONS TRACE].each do |type|
20
- resp, _ = test_response("REQUEST_METHOD" => type)
21
-
22
- resp[0].should.equal(200)
23
- resp[1].should.equal({"Content-type" => "test/plain", "Content-length" => "3"})
24
- resp[2].to_enum.to_a.should.equal(["foo"])
25
- end
26
- end
27
-
28
- should "remove body from HEAD requests" do
29
- resp, _ = test_response("REQUEST_METHOD" => "HEAD")
30
-
31
- resp[0].should.equal(200)
32
- resp[1].should.equal({"Content-type" => "test/plain", "Content-length" => "3"})
33
- resp[2].to_enum.to_a.should.equal([])
34
- end
35
-
36
- should "close the body when it is removed" do
37
- resp, body = test_response("REQUEST_METHOD" => "HEAD")
38
- resp[0].should.equal(200)
39
- resp[1].should.equal({"Content-type" => "test/plain", "Content-length" => "3"})
40
- resp[2].to_enum.to_a.should.equal([])
41
- body.should.not.be.closed
42
- resp[2].close
43
- body.should.be.closed
44
- end
45
- end