rack 1.6.12 → 2.0.7

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 (141) hide show
  1. checksums.yaml +5 -5
  2. data/COPYING +1 -1
  3. data/HISTORY.md +138 -8
  4. data/README.rdoc +18 -28
  5. data/Rakefile +6 -14
  6. data/SPEC +10 -11
  7. data/contrib/rack_logo.svg +164 -111
  8. data/example/protectedlobster.rb +1 -1
  9. data/example/protectedlobster.ru +1 -1
  10. data/lib/rack.rb +70 -21
  11. data/lib/rack/auth/abstract/request.rb +5 -1
  12. data/lib/rack/auth/digest/params.rb +2 -3
  13. data/lib/rack/auth/digest/request.rb +1 -1
  14. data/lib/rack/body_proxy.rb +14 -9
  15. data/lib/rack/builder.rb +3 -3
  16. data/lib/rack/chunked.rb +5 -5
  17. data/lib/rack/{commonlogger.rb → common_logger.rb} +3 -3
  18. data/lib/rack/{conditionalget.rb → conditional_get.rb} +0 -0
  19. data/lib/rack/content_length.rb +2 -2
  20. data/lib/rack/deflater.rb +4 -39
  21. data/lib/rack/directory.rb +66 -54
  22. data/lib/rack/etag.rb +5 -4
  23. data/lib/rack/events.rb +154 -0
  24. data/lib/rack/file.rb +64 -40
  25. data/lib/rack/handler.rb +3 -25
  26. data/lib/rack/handler/cgi.rb +15 -16
  27. data/lib/rack/handler/fastcgi.rb +13 -14
  28. data/lib/rack/handler/lsws.rb +11 -11
  29. data/lib/rack/handler/scgi.rb +15 -15
  30. data/lib/rack/handler/thin.rb +3 -0
  31. data/lib/rack/handler/webrick.rb +24 -26
  32. data/lib/rack/head.rb +15 -17
  33. data/lib/rack/lint.rb +40 -40
  34. data/lib/rack/lobster.rb +1 -1
  35. data/lib/rack/lock.rb +15 -10
  36. data/lib/rack/logger.rb +2 -2
  37. data/lib/rack/media_type.rb +38 -0
  38. data/lib/rack/{methodoverride.rb → method_override.rb} +6 -6
  39. data/lib/rack/mime.rb +18 -5
  40. data/lib/rack/mock.rb +36 -54
  41. data/lib/rack/multipart.rb +35 -6
  42. data/lib/rack/multipart/generator.rb +5 -5
  43. data/lib/rack/multipart/parser.rb +270 -157
  44. data/lib/rack/multipart/uploaded_file.rb +1 -2
  45. data/lib/rack/{nulllogger.rb → null_logger.rb} +1 -1
  46. data/lib/rack/query_parser.rb +192 -0
  47. data/lib/rack/recursive.rb +8 -8
  48. data/lib/rack/request.rb +394 -305
  49. data/lib/rack/response.rb +130 -57
  50. data/lib/rack/rewindable_input.rb +1 -12
  51. data/lib/rack/runtime.rb +10 -18
  52. data/lib/rack/sendfile.rb +5 -7
  53. data/lib/rack/server.rb +30 -23
  54. data/lib/rack/session/abstract/id.rb +108 -138
  55. data/lib/rack/session/cookie.rb +26 -28
  56. data/lib/rack/session/memcache.rb +8 -14
  57. data/lib/rack/session/pool.rb +14 -21
  58. data/lib/rack/show_exceptions.rb +386 -0
  59. data/lib/rack/{showstatus.rb → show_status.rb} +3 -3
  60. data/lib/rack/static.rb +30 -5
  61. data/lib/rack/tempfile_reaper.rb +2 -2
  62. data/lib/rack/urlmap.rb +15 -14
  63. data/lib/rack/utils.rb +136 -211
  64. data/rack.gemspec +10 -9
  65. data/test/builder/an_underscore_app.rb +5 -0
  66. data/test/builder/options.ru +1 -1
  67. data/test/cgi/test.fcgi +1 -0
  68. data/test/cgi/test.gz +0 -0
  69. data/test/helper.rb +34 -0
  70. data/test/multipart/filename_with_encoded_words +7 -0
  71. data/test/multipart/filename_with_single_quote +7 -0
  72. data/test/multipart/quoted +15 -0
  73. data/test/multipart/rack-logo.png +0 -0
  74. data/test/multipart/unity3d_wwwform +11 -0
  75. data/test/registering_handler/rack/handler/registering_myself.rb +1 -1
  76. data/test/spec_auth_basic.rb +27 -19
  77. data/test/spec_auth_digest.rb +47 -46
  78. data/test/spec_body_proxy.rb +27 -27
  79. data/test/spec_builder.rb +51 -41
  80. data/test/spec_cascade.rb +24 -22
  81. data/test/spec_cgi.rb +49 -67
  82. data/test/spec_chunked.rb +37 -35
  83. data/test/{spec_commonlogger.rb → spec_common_logger.rb} +23 -21
  84. data/test/{spec_conditionalget.rb → spec_conditional_get.rb} +29 -28
  85. data/test/spec_config.rb +3 -2
  86. data/test/spec_content_length.rb +18 -17
  87. data/test/spec_content_type.rb +13 -12
  88. data/test/spec_deflater.rb +85 -49
  89. data/test/spec_directory.rb +87 -27
  90. data/test/spec_etag.rb +32 -31
  91. data/test/spec_events.rb +133 -0
  92. data/test/spec_fastcgi.rb +50 -72
  93. data/test/spec_file.rb +120 -77
  94. data/test/spec_handler.rb +19 -34
  95. data/test/spec_head.rb +15 -14
  96. data/test/spec_lint.rb +164 -199
  97. data/test/spec_lobster.rb +24 -23
  98. data/test/spec_lock.rb +79 -39
  99. data/test/spec_logger.rb +4 -3
  100. data/test/spec_media_type.rb +42 -0
  101. data/test/{spec_methodoverride.rb → spec_method_override.rb} +34 -35
  102. data/test/spec_mime.rb +19 -19
  103. data/test/spec_mock.rb +206 -144
  104. data/test/spec_multipart.rb +322 -200
  105. data/test/{spec_nulllogger.rb → spec_null_logger.rb} +5 -4
  106. data/test/spec_recursive.rb +17 -14
  107. data/test/spec_request.rb +780 -605
  108. data/test/spec_response.rb +215 -112
  109. data/test/spec_rewindable_input.rb +50 -40
  110. data/test/spec_runtime.rb +11 -10
  111. data/test/spec_sendfile.rb +30 -35
  112. data/test/spec_server.rb +78 -52
  113. data/test/spec_session_abstract_id.rb +11 -33
  114. data/test/spec_session_abstract_session_hash.rb +45 -0
  115. data/test/spec_session_cookie.rb +99 -67
  116. data/test/spec_session_memcache.rb +63 -101
  117. data/test/spec_session_pool.rb +48 -84
  118. data/test/{spec_showexceptions.rb → spec_show_exceptions.rb} +23 -28
  119. data/test/{spec_showstatus.rb → spec_show_status.rb} +36 -35
  120. data/test/spec_static.rb +71 -32
  121. data/test/spec_tempfile_reaper.rb +11 -10
  122. data/test/spec_thin.rb +55 -50
  123. data/test/spec_urlmap.rb +79 -78
  124. data/test/spec_utils.rb +441 -346
  125. data/test/spec_version.rb +2 -8
  126. data/test/spec_webrick.rb +93 -71
  127. data/test/static/foo.html +1 -0
  128. data/test/testrequest.rb +1 -1
  129. data/test/unregistered_handler/rack/handler/unregistered.rb +1 -1
  130. data/test/unregistered_handler/rack/handler/unregistered_long_one.rb +1 -1
  131. metadata +92 -70
  132. data/KNOWN-ISSUES +0 -44
  133. data/lib/rack/backports/uri/common_18.rb +0 -56
  134. data/lib/rack/backports/uri/common_192.rb +0 -52
  135. data/lib/rack/backports/uri/common_193.rb +0 -29
  136. data/lib/rack/handler/evented_mongrel.rb +0 -8
  137. data/lib/rack/handler/mongrel.rb +0 -106
  138. data/lib/rack/handler/swiftiplied_mongrel.rb +0 -8
  139. data/lib/rack/showexceptions.rb +0 -387
  140. data/lib/rack/utils/okjson.rb +0 -600
  141. data/test/spec_mongrel.rb +0 -182
@@ -44,24 +44,23 @@ module Rack
44
44
  env = request.env
45
45
  env.delete "HTTP_CONTENT_LENGTH"
46
46
 
47
- env["SCRIPT_NAME"] = "" if env["SCRIPT_NAME"] == "/"
47
+ env[SCRIPT_NAME] = "" if env[SCRIPT_NAME] == "/"
48
48
 
49
49
  rack_input = RewindableInput.new(request.in)
50
50
 
51
- env.update({"rack.version" => Rack::VERSION,
52
- "rack.input" => rack_input,
53
- "rack.errors" => request.err,
51
+ env.update(
52
+ RACK_VERSION => Rack::VERSION,
53
+ RACK_INPUT => rack_input,
54
+ RACK_ERRORS => request.err,
55
+ RACK_MULTITHREAD => false,
56
+ RACK_MULTIPROCESS => true,
57
+ RACK_RUNONCE => false,
58
+ RACK_URL_SCHEME => ["yes", "on", "1"].include?(env[HTTPS]) ? "https" : "http"
59
+ )
54
60
 
55
- "rack.multithread" => false,
56
- "rack.multiprocess" => true,
57
- "rack.run_once" => false,
58
-
59
- "rack.url_scheme" => ["yes", "on", "1"].include?(env["HTTPS"]) ? "https" : "http"
60
- })
61
-
62
- env[QUERY_STRING] ||= ""
63
- env["HTTP_VERSION"] ||= env["SERVER_PROTOCOL"]
64
- env["REQUEST_PATH"] ||= "/"
61
+ env[QUERY_STRING] ||= ""
62
+ env[HTTP_VERSION] ||= env[SERVER_PROTOCOL]
63
+ env[REQUEST_PATH] ||= "/"
65
64
  env.delete "CONTENT_TYPE" if env["CONTENT_TYPE"] == ""
66
65
  env.delete "CONTENT_LENGTH" if env["CONTENT_LENGTH"] == ""
67
66
 
@@ -13,23 +13,23 @@ module Rack
13
13
  def self.serve(app)
14
14
  env = ENV.to_hash
15
15
  env.delete "HTTP_CONTENT_LENGTH"
16
- env["SCRIPT_NAME"] = "" if env["SCRIPT_NAME"] == "/"
16
+ env[SCRIPT_NAME] = "" if env[SCRIPT_NAME] == "/"
17
17
 
18
18
  rack_input = RewindableInput.new($stdin.read.to_s)
19
19
 
20
20
  env.update(
21
- "rack.version" => Rack::VERSION,
22
- "rack.input" => rack_input,
23
- "rack.errors" => $stderr,
24
- "rack.multithread" => false,
25
- "rack.multiprocess" => true,
26
- "rack.run_once" => false,
27
- "rack.url_scheme" => ["yes", "on", "1"].include?(ENV["HTTPS"]) ? "https" : "http"
21
+ RACK_VERSION => Rack::VERSION,
22
+ RACK_INPUT => rack_input,
23
+ RACK_ERRORS => $stderr,
24
+ RACK_MULTITHREAD => false,
25
+ RACK_MULTIPROCESS => true,
26
+ RACK_RUNONCE => false,
27
+ RACK_URL_SCHEME => ["yes", "on", "1"].include?(ENV[HTTPS]) ? "https" : "http"
28
28
  )
29
29
 
30
- env[QUERY_STRING] ||= ""
31
- env["HTTP_VERSION"] ||= env["SERVER_PROTOCOL"]
32
- env["REQUEST_PATH"] ||= "/"
30
+ env[QUERY_STRING] ||= ""
31
+ env[HTTP_VERSION] ||= env[SERVER_PROTOCOL]
32
+ env[REQUEST_PATH] ||= "/"
33
33
  status, headers, body = app.call(env)
34
34
  begin
35
35
  send_headers status, headers
@@ -35,24 +35,24 @@ module Rack
35
35
  env = Hash[request]
36
36
  env.delete "HTTP_CONTENT_TYPE"
37
37
  env.delete "HTTP_CONTENT_LENGTH"
38
- env["REQUEST_PATH"], env[QUERY_STRING] = env["REQUEST_URI"].split('?', 2)
39
- env["HTTP_VERSION"] ||= env["SERVER_PROTOCOL"]
40
- env[PATH_INFO] = env["REQUEST_PATH"]
41
- env["QUERY_STRING"] ||= ""
42
- env["SCRIPT_NAME"] = ""
38
+ env[REQUEST_PATH], env[QUERY_STRING] = env["REQUEST_URI"].split('?', 2)
39
+ env[HTTP_VERSION] ||= env[SERVER_PROTOCOL]
40
+ env[PATH_INFO] = env[REQUEST_PATH]
41
+ env[QUERY_STRING] ||= ""
42
+ env[SCRIPT_NAME] = ""
43
43
 
44
- rack_input = StringIO.new(input_body)
45
- rack_input.set_encoding(Encoding::BINARY) if rack_input.respond_to?(:set_encoding)
44
+ rack_input = StringIO.new(input_body, encoding: Encoding::BINARY)
46
45
 
47
- env.update({"rack.version" => Rack::VERSION,
48
- "rack.input" => rack_input,
49
- "rack.errors" => $stderr,
50
- "rack.multithread" => true,
51
- "rack.multiprocess" => true,
52
- "rack.run_once" => false,
46
+ env.update(
47
+ RACK_VERSION => Rack::VERSION,
48
+ RACK_INPUT => rack_input,
49
+ RACK_ERRORS => $stderr,
50
+ RACK_MULTITHREAD => true,
51
+ RACK_MULTIPROCESS => true,
52
+ RACK_RUNONCE => false,
53
+ RACK_URL_SCHEME => ["yes", "on", "1"].include?(env[HTTPS]) ? "https" : "http"
54
+ )
53
55
 
54
- "rack.url_scheme" => ["yes", "on", "1"].include?(env["HTTPS"]) ? "https" : "http"
55
- })
56
56
  status, headers, body = app.call(env)
57
57
  begin
58
58
  socket.write("Status: #{status}\r\n")
@@ -1,4 +1,7 @@
1
1
  require "thin"
2
+ require "thin/server"
3
+ require "thin/logging"
4
+ require "thin/backends/tcp_server"
2
5
  require "rack/content_length"
3
6
  require "rack/chunked"
4
7
 
@@ -3,7 +3,7 @@ require 'stringio'
3
3
  require 'rack/content_length'
4
4
 
5
5
  # This monkey patch allows for applications to perform their own chunking
6
- # through WEBrick::HTTPResponse iff rack is set to true.
6
+ # through WEBrick::HTTPResponse if rack is set to true.
7
7
  class WEBrick::HTTPResponse
8
8
  attr_accessor :rack
9
9
 
@@ -24,7 +24,7 @@ module Rack
24
24
  class WEBrick < ::WEBrick::HTTPServlet::AbstractServlet
25
25
  def self.run(app, options={})
26
26
  environment = ENV['RACK_ENV'] || 'development'
27
- default_host = environment == 'development' ? 'localhost' : '0.0.0.0'
27
+ default_host = environment == 'development' ? 'localhost' : nil
28
28
 
29
29
  options[:BindAddress] = options.delete(:Host) || default_host
30
30
  options[:Port] ||= 8080
@@ -60,38 +60,37 @@ module Rack
60
60
  env.delete_if { |k, v| v.nil? }
61
61
 
62
62
  rack_input = StringIO.new(req.body.to_s)
63
- rack_input.set_encoding(Encoding::BINARY) if rack_input.respond_to?(:set_encoding)
64
-
65
- env.update({"rack.version" => Rack::VERSION,
66
- "rack.input" => rack_input,
67
- "rack.errors" => $stderr,
68
-
69
- "rack.multithread" => true,
70
- "rack.multiprocess" => false,
71
- "rack.run_once" => false,
72
-
73
- "rack.url_scheme" => ["yes", "on", "1"].include?(env["HTTPS"]) ? "https" : "http",
74
-
75
- "rack.hijack?" => true,
76
- "rack.hijack" => lambda { raise NotImplementedError, "only partial hijack is supported."},
77
- "rack.hijack_io" => nil,
78
- })
79
-
80
- env["HTTP_VERSION"] ||= env["SERVER_PROTOCOL"]
63
+ rack_input.set_encoding(Encoding::BINARY)
64
+
65
+ env.update(
66
+ RACK_VERSION => Rack::VERSION,
67
+ RACK_INPUT => rack_input,
68
+ RACK_ERRORS => $stderr,
69
+ RACK_MULTITHREAD => true,
70
+ RACK_MULTIPROCESS => false,
71
+ RACK_RUNONCE => false,
72
+ RACK_URL_SCHEME => ["yes", "on", "1"].include?(env[HTTPS]) ? "https" : "http",
73
+ RACK_IS_HIJACK => true,
74
+ RACK_HIJACK => lambda { raise NotImplementedError, "only partial hijack is supported."},
75
+ RACK_HIJACK_IO => nil
76
+ )
77
+
78
+ env[HTTP_VERSION] ||= env[SERVER_PROTOCOL]
81
79
  env[QUERY_STRING] ||= ""
82
80
  unless env[PATH_INFO] == ""
83
- path, n = req.request_uri.path, env["SCRIPT_NAME"].length
81
+ path, n = req.request_uri.path, env[SCRIPT_NAME].length
84
82
  env[PATH_INFO] = path[n, path.length-n]
85
83
  end
86
- env["REQUEST_PATH"] ||= [env["SCRIPT_NAME"], env[PATH_INFO]].join
84
+ env[REQUEST_PATH] ||= [env[SCRIPT_NAME], env[PATH_INFO]].join
87
85
 
88
86
  status, headers, body = @app.call(env)
89
87
  begin
90
88
  res.status = status.to_i
89
+ io_lambda = nil
91
90
  headers.each { |k, vs|
92
- next if k.downcase == "rack.hijack"
93
-
94
- if k.downcase == "set-cookie"
91
+ if k == RACK_HIJACK
92
+ io_lambda = vs
93
+ elsif k.downcase == "set-cookie"
95
94
  res.cookies.concat vs.split("\n")
96
95
  else
97
96
  # Since WEBrick won't accept repeated headers,
@@ -100,7 +99,6 @@ module Rack
100
99
  end
101
100
  }
102
101
 
103
- io_lambda = headers["rack.hijack"]
104
102
  if io_lambda
105
103
  rd, wr = IO.pipe
106
104
  res.body = rd
@@ -1,27 +1,25 @@
1
1
  require 'rack/body_proxy'
2
2
 
3
3
  module Rack
4
-
5
- class Head
6
4
  # Rack::Head returns an empty body for all HEAD requests. It leaves
7
5
  # all other requests unchanged.
8
- def initialize(app)
9
- @app = app
10
- end
6
+ class Head
7
+ def initialize(app)
8
+ @app = app
9
+ end
11
10
 
12
- def call(env)
13
- status, headers, body = @app.call(env)
11
+ def call(env)
12
+ status, headers, body = @app.call(env)
14
13
 
15
- if env[REQUEST_METHOD] == HEAD
16
- [
17
- status, headers, Rack::BodyProxy.new([]) do
18
- body.close if body.respond_to? :close
19
- end
20
- ]
21
- else
22
- [status, headers, body]
14
+ if env[REQUEST_METHOD] == HEAD
15
+ [
16
+ status, headers, Rack::BodyProxy.new([]) do
17
+ body.close if body.respond_to? :close
18
+ end
19
+ ]
20
+ else
21
+ [status, headers, body]
22
+ end
23
23
  end
24
24
  end
25
25
  end
26
-
27
- end
@@ -15,8 +15,8 @@ module Rack
15
15
 
16
16
  class LintError < RuntimeError; end
17
17
  module Assertion
18
- def assert(message, &block)
19
- unless block.call
18
+ def assert(message)
19
+ unless yield
20
20
  raise LintError, message
21
21
  end
22
22
  end
@@ -42,8 +42,8 @@ module Rack
42
42
  assert("No env given") { env }
43
43
  check_env env
44
44
 
45
- env['rack.input'] = InputWrapper.new(env['rack.input'])
46
- env['rack.errors'] = ErrorWrapper.new(env['rack.errors'])
45
+ env[RACK_INPUT] = InputWrapper.new(env[RACK_INPUT])
46
+ env[RACK_ERRORS] = ErrorWrapper.new(env[RACK_ERRORS])
47
47
 
48
48
  ## and returns an Array of exactly three values:
49
49
  status, headers, @body = @app.call(env)
@@ -57,7 +57,7 @@ module Rack
57
57
  ## and the *body*.
58
58
  check_content_type status, headers
59
59
  check_content_length status, headers
60
- @head_request = env[REQUEST_METHOD] == "HEAD"
60
+ @head_request = env[REQUEST_METHOD] == HEAD
61
61
  [status, headers, self]
62
62
  end
63
63
 
@@ -95,7 +95,7 @@ module Rack
95
95
  ## empty string, if the request URL targets
96
96
  ## the application root and does not have a
97
97
  ## trailing slash. This value may be
98
- ## percent-encoded when I originating from
98
+ ## percent-encoded when originating from
99
99
  ## a URL.
100
100
 
101
101
  ## <tt>QUERY_STRING</tt>:: The portion of the request URL that
@@ -177,7 +177,7 @@ module Rack
177
177
  ## <tt>rack.session</tt>:: A hash like interface for storing
178
178
  ## request session data.
179
179
  ## The store must implement:
180
- if session = env['rack.session']
180
+ if session = env[RACK_SESSION]
181
181
  ## store(key, value) (aliased as []=);
182
182
  assert("session #{session.inspect} must respond to store and []=") {
183
183
  session.respond_to?(:store) && session.respond_to?(:[]=)
@@ -201,7 +201,7 @@ module Rack
201
201
 
202
202
  ## <tt>rack.logger</tt>:: A common object interface for logging messages.
203
203
  ## The object must implement:
204
- if logger = env['rack.logger']
204
+ if logger = env[RACK_LOGGER]
205
205
  ## info(message, &block)
206
206
  assert("logger #{logger.inspect} must respond to info") {
207
207
  logger.respond_to?(:info)
@@ -229,16 +229,16 @@ module Rack
229
229
  end
230
230
 
231
231
  ## <tt>rack.multipart.buffer_size</tt>:: An Integer hint to the multipart parser as to what chunk size to use for reads and writes.
232
- if bufsize = env['rack.multipart.buffer_size']
232
+ if bufsize = env[RACK_MULTIPART_BUFFER_SIZE]
233
233
  assert("rack.multipart.buffer_size must be an Integer > 0 if specified") {
234
234
  bufsize.is_a?(Integer) && bufsize > 0
235
235
  }
236
236
  end
237
237
 
238
238
  ## <tt>rack.multipart.tempfile_factory</tt>:: An object responding to #call with two arguments, the filename and content_type given for the multipart form field, and returning an IO-like object that responds to #<< and optionally #rewind. This factory will be used to instantiate the tempfile for each multipart form file upload field, rather than the default class of Tempfile.
239
- if tempfile_factory = env['rack.multipart.tempfile_factory']
239
+ if tempfile_factory = env[RACK_MULTIPART_TEMPFILE_FACTORY]
240
240
  assert("rack.multipart.tempfile_factory must respond to #call") { tempfile_factory.respond_to?(:call) }
241
- env['rack.multipart.tempfile_factory'] = lambda do |filename, content_type|
241
+ env[RACK_MULTIPART_TEMPFILE_FACTORY] = lambda do |filename, content_type|
242
242
  io = tempfile_factory.call(filename, content_type)
243
243
  assert("rack.multipart.tempfile_factory return value must respond to #<<") { io.respond_to?(:<<) }
244
244
  io
@@ -279,37 +279,37 @@ module Rack
279
279
  ## There are the following restrictions:
280
280
 
281
281
  ## * <tt>rack.version</tt> must be an array of Integers.
282
- assert("rack.version must be an Array, was #{env["rack.version"].class}") {
283
- env["rack.version"].kind_of? Array
282
+ assert("rack.version must be an Array, was #{env[RACK_VERSION].class}") {
283
+ env[RACK_VERSION].kind_of? Array
284
284
  }
285
285
  ## * <tt>rack.url_scheme</tt> must either be +http+ or +https+.
286
- assert("rack.url_scheme unknown: #{env["rack.url_scheme"].inspect}") {
287
- %w[http https].include? env["rack.url_scheme"]
286
+ assert("rack.url_scheme unknown: #{env[RACK_URL_SCHEME].inspect}") {
287
+ %w[http https].include?(env[RACK_URL_SCHEME])
288
288
  }
289
289
 
290
290
  ## * There must be a valid input stream in <tt>rack.input</tt>.
291
- check_input env["rack.input"]
291
+ check_input env[RACK_INPUT]
292
292
  ## * There must be a valid error stream in <tt>rack.errors</tt>.
293
- check_error env["rack.errors"]
293
+ check_error env[RACK_ERRORS]
294
294
  ## * There may be a valid hijack stream in <tt>rack.hijack_io</tt>
295
295
  check_hijack env
296
296
 
297
297
  ## * The <tt>REQUEST_METHOD</tt> must be a valid token.
298
298
  assert("REQUEST_METHOD unknown: #{env[REQUEST_METHOD]}") {
299
- env["REQUEST_METHOD"] =~ /\A[0-9A-Za-z!\#$%&'*+.^_`|~-]+\z/
299
+ env[REQUEST_METHOD] =~ /\A[0-9A-Za-z!\#$%&'*+.^_`|~-]+\z/
300
300
  }
301
301
 
302
302
  ## * The <tt>SCRIPT_NAME</tt>, if non-empty, must start with <tt>/</tt>
303
303
  assert("SCRIPT_NAME must start with /") {
304
- !env.include?("SCRIPT_NAME") ||
305
- env["SCRIPT_NAME"] == "" ||
306
- env["SCRIPT_NAME"] =~ /\A\//
304
+ !env.include?(SCRIPT_NAME) ||
305
+ env[SCRIPT_NAME] == "" ||
306
+ env[SCRIPT_NAME] =~ /\A\//
307
307
  }
308
308
  ## * The <tt>PATH_INFO</tt>, if non-empty, must start with <tt>/</tt>
309
309
  assert("PATH_INFO must start with /") {
310
- !env.include?("PATH_INFO") ||
311
- env["PATH_INFO"] == "" ||
312
- env["PATH_INFO"] =~ /\A\//
310
+ !env.include?(PATH_INFO) ||
311
+ env[PATH_INFO] == "" ||
312
+ env[PATH_INFO] =~ /\A\//
313
313
  }
314
314
  ## * The <tt>CONTENT_LENGTH</tt>, if given, must consist of digits only.
315
315
  assert("Invalid CONTENT_LENGTH: #{env["CONTENT_LENGTH"]}") {
@@ -320,11 +320,11 @@ module Rack
320
320
  ## set. <tt>PATH_INFO</tt> should be <tt>/</tt> if
321
321
  ## <tt>SCRIPT_NAME</tt> is empty.
322
322
  assert("One of SCRIPT_NAME or PATH_INFO must be set (make PATH_INFO '/' if SCRIPT_NAME is empty)") {
323
- env["SCRIPT_NAME"] || env["PATH_INFO"]
323
+ env[SCRIPT_NAME] || env[PATH_INFO]
324
324
  }
325
325
  ## <tt>SCRIPT_NAME</tt> never should be <tt>/</tt>, but instead be empty.
326
326
  assert("SCRIPT_NAME cannot be '/', make it '' and PATH_INFO '/'") {
327
- env["SCRIPT_NAME"] != "/"
327
+ env[SCRIPT_NAME] != "/"
328
328
  }
329
329
  end
330
330
 
@@ -518,11 +518,11 @@ module Rack
518
518
  #
519
519
  ## ==== Request (before status)
520
520
  def check_hijack(env)
521
- if env['rack.hijack?']
521
+ if env[RACK_IS_HIJACK]
522
522
  ## If rack.hijack? is true then rack.hijack must respond to #call.
523
- original_hijack = env['rack.hijack']
523
+ original_hijack = env[RACK_HIJACK]
524
524
  assert("rack.hijack must respond to call") { original_hijack.respond_to?(:call) }
525
- env['rack.hijack'] = proc do
525
+ env[RACK_HIJACK] = proc do
526
526
  ## rack.hijack must return the io that will also be assigned (or is
527
527
  ## already present, in rack.hijack_io.
528
528
  io = original_hijack.call
@@ -548,16 +548,16 @@ module Rack
548
548
  ## hijack_io to provide additional features to users. The purpose of
549
549
  ## rack.hijack is for Rack to "get out of the way", as such, Rack only
550
550
  ## provides the minimum of specification and support.
551
- env['rack.hijack_io'] = HijackWrapper.new(env['rack.hijack_io'])
551
+ env[RACK_HIJACK_IO] = HijackWrapper.new(env[RACK_HIJACK_IO])
552
552
  io
553
553
  end
554
554
  else
555
555
  ##
556
556
  ## If rack.hijack? is false, then rack.hijack should not be set.
557
- assert("rack.hijack? is false, but rack.hijack is present") { env['rack.hijack'].nil? }
557
+ assert("rack.hijack? is false, but rack.hijack is present") { env[RACK_HIJACK].nil? }
558
558
  ##
559
559
  ## If rack.hijack? is false, then rack.hijack_io should not be set.
560
- assert("rack.hijack? is false, but rack.hijack_io is present") { env['rack.hijack_io'].nil? }
560
+ assert("rack.hijack? is false, but rack.hijack_io is present") { env[RACK_HIJACK_IO].nil? }
561
561
  end
562
562
  end
563
563
 
@@ -587,12 +587,12 @@ module Rack
587
587
  ## Servers must ignore the <tt>body</tt> part of the response tuple when
588
588
  ## the <tt>rack.hijack</tt> response API is in use.
589
589
 
590
- if env['rack.hijack?'] && headers['rack.hijack']
590
+ if env[RACK_IS_HIJACK] && headers[RACK_HIJACK]
591
591
  assert('rack.hijack header must respond to #call') {
592
- headers['rack.hijack'].respond_to? :call
592
+ headers[RACK_HIJACK].respond_to? :call
593
593
  }
594
- original_hijack = headers['rack.hijack']
595
- headers['rack.hijack'] = proc do |io|
594
+ original_hijack = headers[RACK_HIJACK]
595
+ headers[RACK_HIJACK] = proc do |io|
596
596
  original_hijack.call HijackWrapper.new(io)
597
597
  end
598
598
  else
@@ -600,7 +600,7 @@ module Rack
600
600
  ## The special response header <tt>rack.hijack</tt> must only be set
601
601
  ## if the request env has <tt>rack.hijack?</tt> <tt>true</tt>.
602
602
  assert('rack.hijack header must not be present if server does not support hijacking') {
603
- headers['rack.hijack'].nil?
603
+ headers[RACK_HIJACK].nil?
604
604
  }
605
605
  end
606
606
  end
@@ -659,7 +659,7 @@ module Rack
659
659
  def check_content_type(status, headers)
660
660
  headers.each { |key, value|
661
661
  ## There must not be a <tt>Content-Type</tt>, when the +Status+ is 1xx,
662
- ## 204, 205 or 304.
662
+ ## 204 or 304.
663
663
  if key.downcase == "content-type"
664
664
  assert("Content-Type header found in #{status} response, not allowed") {
665
665
  not Rack::Utils::STATUS_WITH_NO_ENTITY_BODY.include? status.to_i
@@ -674,7 +674,7 @@ module Rack
674
674
  headers.each { |key, value|
675
675
  if key.downcase == 'content-length'
676
676
  ## There must not be a <tt>Content-Length</tt> header when the
677
- ## +Status+ is 1xx, 204, 205 or 304.
677
+ ## +Status+ is 1xx, 204 or 304.
678
678
  assert("Content-Length header found in #{status} response, not allowed") {
679
679
  not Rack::Utils::STATUS_WITH_NO_ENTITY_BODY.include? status.to_i
680
680
  }
@@ -710,7 +710,7 @@ module Rack
710
710
  assert("Body yielded non-string value #{part.inspect}") {
711
711
  part.kind_of? String
712
712
  }
713
- bytes += Rack::Utils.bytesize(part)
713
+ bytes += part.bytesize
714
714
  yield part
715
715
  }
716
716
  verify_content_length(bytes)