diff --git a/SPEC b/SPEC index 7e3af40a1..260a24bda 100644 --- a/SPEC +++ b/SPEC @@ -60,8 +60,8 @@ below. the presence or absence of the appropriate HTTP header in the request. See - {https://tools.ietf.org/html/rfc3875#section-4.1.18 - RFC3875 section 4.1.18} for + + RFC3875 section 4.1.18 for specific behavior. In addition to this, the Rack environment must include these Rack-specific variables: @@ -98,12 +98,13 @@ Rack-specific variables: Additional environment specifications have approved to standardized middleware APIs. None of these are required to be implemented by the server. -rack.session:: A hash like interface for storing request session data. +rack.session:: A hash like interface for storing + request session data. The store must implement: - store(key, value) (aliased as []=); - fetch(key, default = nil) (aliased as []); - delete(key); - clear; + store(key, value) (aliased as []=); + fetch(key, default = nil) (aliased as []); + delete(key); + clear; rack.logger:: A common object interface for logging messages. The object must implement: info(message, &block) diff --git a/lib/rack/auth/abstract/handler.rb b/lib/rack/auth/abstract/handler.rb index c657691e1..214df6299 100644 --- a/lib/rack/auth/abstract/handler.rb +++ b/lib/rack/auth/abstract/handler.rb @@ -17,8 +17,8 @@ def initialize(app, realm=nil, &authenticator) def unauthorized(www_authenticate = challenge) return [ 401, - { CONTENT_TYPE => 'text/plain', - CONTENT_LENGTH => '0', + { 'Content-Type' => 'text/plain', + 'Content-Length' => '0', 'WWW-Authenticate' => www_authenticate.to_s }, [] ] @@ -26,8 +26,8 @@ def unauthorized(www_authenticate = challenge) def bad_request return [ 400, - { CONTENT_TYPE => 'text/plain', - CONTENT_LENGTH => '0' }, + { 'Content-Type' => 'text/plain', + 'Content-Length' => '0' }, [] ] end diff --git a/lib/rack/auth/digest/request.rb b/lib/rack/auth/digest/request.rb index 105c76747..706c651c5 100644 --- a/lib/rack/auth/digest/request.rb +++ b/lib/rack/auth/digest/request.rb @@ -7,7 +7,7 @@ module Auth module Digest class Request < Auth::AbstractRequest def method - @env[RACK_METHODOVERRIDE_ORIGINAL_METHOD] || @env[REQUEST_METHOD] + @env['rack.methodoverride.original_method'] || @env['REQUEST_METHOD'] end def digest? diff --git a/lib/rack/cascade.rb b/lib/rack/cascade.rb index 6b8f415ae..8b390867e 100644 --- a/lib/rack/cascade.rb +++ b/lib/rack/cascade.rb @@ -4,7 +4,7 @@ module Rack # status codes). class Cascade - NotFound = [404, {CONTENT_TYPE => "text/plain"}, []] + NotFound = [404, {'Content-Type' => "text/plain"}, []] attr_reader :apps diff --git a/lib/rack/chunked.rb b/lib/rack/chunked.rb index 4b8f270e1..77261231f 100644 --- a/lib/rack/chunked.rb +++ b/lib/rack/chunked.rb @@ -54,14 +54,14 @@ def call(env) status, headers, body = @app.call(env) headers = HeaderHash.new(headers) - if ! chunkable_version?(env[HTTP_VERSION]) || + if ! chunkable_version?(env['HTTP_VERSION']) || STATUS_WITH_NO_ENTITY_BODY.include?(status) || - headers[CONTENT_LENGTH] || - headers[TRANSFER_ENCODING] + headers['Content-Length'] || + headers['Transfer-Encoding'] [status, headers, body] else - headers.delete(CONTENT_LENGTH) - headers[TRANSFER_ENCODING] = 'chunked' + headers.delete('Content-Length') + headers['Transfer-Encoding'] = 'chunked' [status, headers, Body.new(body)] end end diff --git a/lib/rack/common_logger.rb b/lib/rack/common_logger.rb index ae410430e..f1e21f0e1 100644 --- a/lib/rack/common_logger.rb +++ b/lib/rack/common_logger.rb @@ -46,15 +46,15 @@ def log(env, status, header, began_at) env['HTTP_X_FORWARDED_FOR'] || env["REMOTE_ADDR"] || "-", env["REMOTE_USER"] || "-", now.strftime("%d/%b/%Y:%H:%M:%S %z"), - env[REQUEST_METHOD], - env[PATH_INFO], - env[QUERY_STRING].empty? ? "" : "?#{env[QUERY_STRING]}", - env[HTTP_VERSION], + env['REQUEST_METHOD'], + env['PATH_INFO'], + env['QUERY_STRING'].empty? ? "" : "?#{env['QUERY_STRING']}", + env['HTTP_VERSION'], status.to_s[0..3], length, now - began_at ] - logger = @logger || env[RACK_ERRORS] + logger = @logger || env['rack.errors'] # Standard library logger doesn't support write but it supports << which actually # calls to write on the log device without formatting if logger.respond_to?(:write) @@ -65,7 +65,7 @@ def log(env, status, header, began_at) end def extract_content_length(headers) - value = headers[CONTENT_LENGTH] or return '-' + value = headers['Content-Length'] or return '-' value.to_s == '0' ? '-' : value end end diff --git a/lib/rack/conditional_get.rb b/lib/rack/conditional_get.rb index 441dd3823..885731667 100644 --- a/lib/rack/conditional_get.rb +++ b/lib/rack/conditional_get.rb @@ -20,14 +20,14 @@ def initialize(app) end def call(env) - case env[REQUEST_METHOD] + case env['REQUEST_METHOD'] when "GET", "HEAD" status, headers, body = @app.call(env) headers = Utils::HeaderHash.new(headers) if status == 200 && fresh?(env, headers) status = 304 - headers.delete(CONTENT_TYPE) - headers.delete(CONTENT_LENGTH) + headers.delete('Content-Type') + headers.delete('Content-Length') original_body = body body = Rack::BodyProxy.new([]) do original_body.close if original_body.respond_to?(:close) diff --git a/lib/rack/content_length.rb b/lib/rack/content_length.rb index 2df7dfc81..93c39be4b 100644 --- a/lib/rack/content_length.rb +++ b/lib/rack/content_length.rb @@ -16,8 +16,8 @@ def call(env) headers = HeaderHash.new(headers) if !STATUS_WITH_NO_ENTITY_BODY.include?(status.to_i) && - !headers[CONTENT_LENGTH] && - !headers[TRANSFER_ENCODING] && + !headers['Content-Length'] && + !headers['Transfer-Encoding'] && body.respond_to?(:to_ary) obody = body @@ -28,7 +28,7 @@ def call(env) obody.close if obody.respond_to?(:close) end - headers[CONTENT_LENGTH] = length.to_s + headers['Content-Length'] = length.to_s end [status, headers, body] diff --git a/lib/rack/content_type.rb b/lib/rack/content_type.rb index 78ba43b71..dd96e9598 100644 --- a/lib/rack/content_type.rb +++ b/lib/rack/content_type.rb @@ -20,7 +20,7 @@ def call(env) headers = Utils::HeaderHash.new(headers) unless STATUS_WITH_NO_ENTITY_BODY.include?(status) - headers[CONTENT_TYPE] ||= @content_type + headers['Content-Type'] ||= @content_type end [status, headers, body] diff --git a/lib/rack/deflater.rb b/lib/rack/deflater.rb index 62a112436..f7ef35a08 100644 --- a/lib/rack/deflater.rb +++ b/lib/rack/deflater.rb @@ -53,20 +53,20 @@ def call(env) case encoding when "gzip" headers['Content-Encoding'] = "gzip" - headers.delete(CONTENT_LENGTH) + headers.delete('Content-Length') mtime = headers.key?("Last-Modified") ? Time.httpdate(headers["Last-Modified"]) : Time.now [status, headers, GzipStream.new(body, mtime)] when "deflate" headers['Content-Encoding'] = "deflate" - headers.delete(CONTENT_LENGTH) + headers.delete('Content-Length') [status, headers, DeflateStream.new(body)] when "identity" [status, headers, body] when nil message = "An acceptable encoding for the requested resource #{request.fullpath} could not be found." bp = Rack::BodyProxy.new([message]) { body.close if body.respond_to?(:close) } - [406, {CONTENT_TYPE => "text/plain", CONTENT_LENGTH => message.length.to_s}, bp] + [406, {'Content-Type' => "text/plain", 'Content-Length' => message.length.to_s}, bp] end end @@ -137,13 +137,13 @@ def should_deflate?(env, status, headers, body) # Skip compressing empty entity body responses and responses with # no-transform set. if Utils::STATUS_WITH_NO_ENTITY_BODY.include?(status) || - headers[CACHE_CONTROL].to_s =~ /\bno-transform\b/ || + headers['Cache-Control'].to_s =~ /\bno-transform\b/ || (headers['Content-Encoding'] && headers['Content-Encoding'] !~ /\bidentity\b/) return false end # Skip if @compressible_types are given and does not include request's content type - return false if @compressible_types && !(headers.has_key?(CONTENT_TYPE) && @compressible_types.include?(headers[CONTENT_TYPE][/[^;]*/])) + return false if @compressible_types && !(headers.has_key?('Content-Type') && @compressible_types.include?(headers['Content-Type'][/[^;]*/])) # Skip if @condition lambda is given and evaluates to false return false if @condition && !@condition.call(env, status, headers, body) diff --git a/lib/rack/directory.rb b/lib/rack/directory.rb index 89cfe807a..e27bd2c9a 100644 --- a/lib/rack/directory.rb +++ b/lib/rack/directory.rb @@ -68,8 +68,8 @@ def call(env) end def get(env) - script_name = env[SCRIPT_NAME] - path_info = Utils.unescape_path(env[PATH_INFO]) + script_name = env['SCRIPT_NAME'] + path_info = Utils.unescape_path(env['PATH_INFO']) if bad_request = check_bad_request(path_info) bad_request @@ -86,8 +86,8 @@ def check_bad_request(path_info) body = "Bad Request\n" size = body.bytesize - return [400, {CONTENT_TYPE => "text/plain", - CONTENT_LENGTH => size.to_s, + return [400, {'Content-Type' => "text/plain", + 'Content-Length' => size.to_s, "X-Cascade" => "pass"}, [body]] end @@ -96,8 +96,8 @@ def check_forbidden(path_info) body = "Forbidden\n" size = body.bytesize - return [403, {CONTENT_TYPE => "text/plain", - CONTENT_LENGTH => size.to_s, + return [403, {'Content-Type' => "text/plain", + 'Content-Length' => size.to_s, "X-Cascade" => "pass"}, [body]] end @@ -126,7 +126,7 @@ def list_directory(path_info, path, script_name) files << [ url, basename, size, type, mtime ] end - return [ 200, { CONTENT_TYPE =>'text/html; charset=utf-8'}, DirectoryBody.new(@root, path, files) ] + return [ 200, { 'Content-Type' =>'text/html; charset=utf-8'}, DirectoryBody.new(@root, path, files) ] end def stat(node) @@ -154,8 +154,8 @@ def list_path(env, path, path_info, script_name) def entity_not_found(path_info) body = "Entity not found: #{path_info}\n" size = body.bytesize - return [404, {CONTENT_TYPE => "text/plain", - CONTENT_LENGTH => size.to_s, + return [404, {'Content-Type' => "text/plain", + 'Content-Length' => size.to_s, "X-Cascade" => "pass"}, [body]] end diff --git a/lib/rack/etag.rb b/lib/rack/etag.rb index a0041062f..d894aec78 100644 --- a/lib/rack/etag.rb +++ b/lib/rack/etag.rb @@ -12,7 +12,7 @@ module Rack # used when Etag is absent and a directive when it is present. The first # defaults to nil, while the second defaults to "max-age=0, private, must-revalidate" class ETag - ETAG_STRING = Rack::ETAG + ETAG_STRING = 'ETag' DEFAULT_CACHE_CONTROL = "max-age=0, private, must-revalidate".freeze def initialize(app, no_cache_control = nil, cache_control = DEFAULT_CACHE_CONTROL) @@ -30,14 +30,14 @@ def call(env) body = Rack::BodyProxy.new(new_body) do original_body.close if original_body.respond_to?(:close) end - headers[ETAG_STRING] = %(W/"#{digest}") if digest + headers['ETag'] = %(W/"#{digest}") if digest end - unless headers[CACHE_CONTROL] + unless headers['Cache-Control'] if digest - headers[CACHE_CONTROL] = @cache_control if @cache_control + headers['Cache-Control'] = @cache_control if @cache_control else - headers[CACHE_CONTROL] = @no_cache_control if @no_cache_control + headers['Cache-Control'] = @no_cache_control if @no_cache_control end end @@ -55,8 +55,8 @@ def etag_body?(body) end def skip_caching?(headers) - (headers[CACHE_CONTROL] && headers[CACHE_CONTROL].include?('no-cache')) || - headers.key?(ETAG_STRING) || headers.key?('Last-Modified') + (headers['Cache-Control'] && headers['Cache-Control'].include?('no-cache')) || + headers.key?('ETag') || headers.key?('Last-Modified') end def digest_body(body) diff --git a/lib/rack/file.rb b/lib/rack/file.rb index 0a257b3d5..d8b5dcd9c 100644 --- a/lib/rack/file.rb +++ b/lib/rack/file.rb @@ -58,14 +58,14 @@ def get(env) def serving(request, path) if request.options? - return [200, {'Allow' => ALLOW_HEADER, CONTENT_LENGTH => '0'}, []] + return [200, {'Allow' => ALLOW_HEADER, 'Content-Length' => '0'}, []] end last_modified = ::File.mtime(path).httpdate return [304, {}, []] if request.get_header('HTTP_IF_MODIFIED_SINCE') == last_modified headers = { "Last-Modified" => last_modified } mime_type = mime_type path, @default_mime - headers[CONTENT_TYPE] = mime_type if mime_type + headers['Content-Type'] = mime_type if mime_type # Set custom headers @headers.each { |field, content| headers[field] = content } if @headers @@ -96,7 +96,7 @@ def serving(request, path) response[2] = [response_body] unless response_body.nil? - response[1][CONTENT_LENGTH] = size.to_s + response[1]['Content-Length'] = size.to_s response[2] = make_body request, path, range response end @@ -143,8 +143,8 @@ def fail(status, body, headers = {}) [ status, { - CONTENT_TYPE => "text/plain", - CONTENT_LENGTH => body.size.to_s, + 'Content-Type' => "text/plain", + 'Content-Length' => body.size.to_s, "X-Cascade" => "pass" }.merge!(headers), [body] diff --git a/lib/rack/handler.rb b/lib/rack/handler.rb index 70a77fa97..f1fa9a7bd 100644 --- a/lib/rack/handler.rb +++ b/lib/rack/handler.rb @@ -47,7 +47,7 @@ def self.default # Guess. if ENV.include?("PHP_FCGI_CHILDREN") Rack::Handler::FastCGI - elsif ENV.include?(REQUEST_METHOD) + elsif ENV.include?('REQUEST_METHOD') Rack::Handler::CGI elsif ENV.include?("RACK_HANDLER") self.get(ENV["RACK_HANDLER"]) diff --git a/lib/rack/handler/cgi.rb b/lib/rack/handler/cgi.rb index 528076946..c086897ff 100644 --- a/lib/rack/handler/cgi.rb +++ b/lib/rack/handler/cgi.rb @@ -13,21 +13,21 @@ def self.serve(app) env = ENV.to_hash env.delete "HTTP_CONTENT_LENGTH" - env[SCRIPT_NAME] = "" if env[SCRIPT_NAME] == "/" + env['SCRIPT_NAME'] = "" if env['SCRIPT_NAME'] == "/" env.update( - RACK_VERSION => Rack::VERSION, - RACK_INPUT => Rack::RewindableInput.new($stdin), - RACK_ERRORS => $stderr, + 'rack.version' => Rack::VERSION, + 'rack.input' => Rack::RewindableInput.new($stdin), + 'rack.errors' => $stderr, RACK_MULTITHREAD => false, RACK_MULTIPROCESS => true, RACK_RUNONCE => true, - RACK_URL_SCHEME => ["yes", "on", "1"].include?(ENV[HTTPS]) ? "https" : "http" + RACK_URL_SCHEME => ["yes", "on", "1"].include?(ENV['HTTPS']) ? "https" : "http" ) - env[QUERY_STRING] ||= "" - env[HTTP_VERSION] ||= env[SERVER_PROTOCOL] - env[REQUEST_PATH] ||= "/" + env['QUERY_STRING'] ||= "" + env['HTTP_VERSION'] ||= env['SERVER_PROTOCOL'] + env['REQUEST_PATH'] ||= "/" status, headers, body = app.call(env) begin diff --git a/lib/rack/handler/fastcgi.rb b/lib/rack/handler/fastcgi.rb index e918dc94b..8b525bef5 100644 --- a/lib/rack/handler/fastcgi.rb +++ b/lib/rack/handler/fastcgi.rb @@ -44,23 +44,23 @@ def self.serve(request, app) env = request.env env.delete "HTTP_CONTENT_LENGTH" - env[SCRIPT_NAME] = "" if env[SCRIPT_NAME] == "/" + env['SCRIPT_NAME'] = "" if env['SCRIPT_NAME'] == "/" rack_input = RewindableInput.new(request.in) env.update( - RACK_VERSION => Rack::VERSION, - RACK_INPUT => rack_input, - RACK_ERRORS => request.err, + 'rack.version' => Rack::VERSION, + 'rack.input' => rack_input, + 'rack.errors' => request.err, RACK_MULTITHREAD => false, RACK_MULTIPROCESS => true, RACK_RUNONCE => false, - RACK_URL_SCHEME => ["yes", "on", "1"].include?(env[HTTPS]) ? "https" : "http" + RACK_URL_SCHEME => ["yes", "on", "1"].include?(env['HTTPS']) ? "https" : "http" ) - env[QUERY_STRING] ||= "" - env[HTTP_VERSION] ||= env[SERVER_PROTOCOL] - env[REQUEST_PATH] ||= "/" + env['QUERY_STRING'] ||= "" + env['HTTP_VERSION'] ||= env['SERVER_PROTOCOL'] + env['REQUEST_PATH'] ||= "/" env.delete "CONTENT_TYPE" if env["CONTENT_TYPE"] == "" env.delete "CONTENT_LENGTH" if env["CONTENT_LENGTH"] == "" diff --git a/lib/rack/handler/lsws.rb b/lib/rack/handler/lsws.rb index d2cfd7935..97db9ef3b 100644 --- a/lib/rack/handler/lsws.rb +++ b/lib/rack/handler/lsws.rb @@ -13,23 +13,23 @@ def self.run(app, options=nil) def self.serve(app) env = ENV.to_hash env.delete "HTTP_CONTENT_LENGTH" - env[SCRIPT_NAME] = "" if env[SCRIPT_NAME] == "/" + env['SCRIPT_NAME'] = "" if env['SCRIPT_NAME'] == "/" rack_input = RewindableInput.new($stdin.read.to_s) env.update( - RACK_VERSION => Rack::VERSION, - RACK_INPUT => rack_input, - RACK_ERRORS => $stderr, - RACK_MULTITHREAD => false, - RACK_MULTIPROCESS => true, - RACK_RUNONCE => false, - RACK_URL_SCHEME => ["yes", "on", "1"].include?(ENV[HTTPS]) ? "https" : "http" + 'rack.version' => Rack::VERSION, + 'rack.input' => rack_input, + 'rack.errors' => $stderr, + 'rack.multithread' => false, + 'rack.multiprocess' => true, + 'rack.run_once' => false, + 'rack.url_scheme' => ["yes", "on", "1"].include?(ENV['HTTPS']) ? "https" : "http" ) - env[QUERY_STRING] ||= "" - env[HTTP_VERSION] ||= env[SERVER_PROTOCOL] - env[REQUEST_PATH] ||= "/" + env['QUERY_STRING'] ||= "" + env['HTTP_VERSION'] ||= env['SERVER_PROTOCOL'] + env['REQUEST_PATH'] ||= "/" status, headers, body = app.call(env) begin send_headers status, headers diff --git a/lib/rack/handler/scgi.rb b/lib/rack/handler/scgi.rb index e056a01d8..c1b504099 100644 --- a/lib/rack/handler/scgi.rb +++ b/lib/rack/handler/scgi.rb @@ -35,22 +35,22 @@ def process_request(request, input_body, socket) env = Hash[request] env.delete "HTTP_CONTENT_TYPE" env.delete "HTTP_CONTENT_LENGTH" - env[REQUEST_PATH], env[QUERY_STRING] = env["REQUEST_URI"].split('?', 2) - env[HTTP_VERSION] ||= env[SERVER_PROTOCOL] - env[PATH_INFO] = env[REQUEST_PATH] - env[QUERY_STRING] ||= "" - env[SCRIPT_NAME] = "" + env['REQUEST_PATH'], env['QUERY_STRING'] = env["REQUEST_URI"].split('?', 2) + env['HTTP_VERSION'] ||= env['SERVER_PROTOCOL'] + env['PATH_INFO'] = env['REQUEST_PATH'] + env['QUERY_STRING'] ||= "" + env['SCRIPT_NAME'] = "" rack_input = StringIO.new(input_body, encoding: Encoding::BINARY) env.update( - RACK_VERSION => Rack::VERSION, - RACK_INPUT => rack_input, - RACK_ERRORS => $stderr, - RACK_MULTITHREAD => true, - RACK_MULTIPROCESS => true, - RACK_RUNONCE => false, - RACK_URL_SCHEME => ["yes", "on", "1"].include?(env[HTTPS]) ? "https" : "http" + 'rack.version' => Rack::VERSION, + 'rack.input' => rack_input, + 'rack.errors' => $stderr, + 'rack.multithread' => true, + 'rack.multiprocess' => true, + 'rack.run_once' => false, + 'rack.url_scheme' => ["yes", "on", "1"].include?(env['HTTPS']) ? "https" : "http" ) status, headers, body = app.call(env) diff --git a/lib/rack/handler/webrick.rb b/lib/rack/handler/webrick.rb index 95aa8927d..4ceea2642 100644 --- a/lib/rack/handler/webrick.rb +++ b/lib/rack/handler/webrick.rb @@ -63,31 +63,31 @@ def service(req, res) rack_input.set_encoding(Encoding::BINARY) env.update( - RACK_VERSION => Rack::VERSION, - RACK_INPUT => rack_input, - RACK_ERRORS => $stderr, - RACK_MULTITHREAD => true, - RACK_MULTIPROCESS => false, - RACK_RUNONCE => false, - RACK_URL_SCHEME => ["yes", "on", "1"].include?(env[HTTPS]) ? "https" : "http", - RACK_IS_HIJACK => true, - RACK_HIJACK => lambda { raise NotImplementedError, "only partial hijack is supported."}, - RACK_HIJACK_IO => nil + 'rack.version' => Rack::VERSION, + 'rack.input' => rack_input, + 'rack.errors' => $stderr, + 'rack.multithread' => true, + 'rack.multiprocess' => false, + 'rack.run_once' => false, + 'rack.url_scheme' => ["yes", "on", "1"].include?(env['HTTPS']) ? "https" : "http", + 'rack.hijack?' => true, + 'rack.hijack' => lambda { raise NotImplementedError, "only partial hijack is supported."}, + 'rack.hijack_io' => nil ) - env[HTTP_VERSION] ||= env[SERVER_PROTOCOL] - env[QUERY_STRING] ||= "" - unless env[PATH_INFO] == "" - path, n = req.request_uri.path, env[SCRIPT_NAME].length - env[PATH_INFO] = path[n, path.length-n] + env['HTTP_VERSION'] ||= env['SERVER_PROTOCOL'] + env['QUERY_STRING'] ||= "" + unless env['PATH_INFO'] == "" + path, n = req.request_uri.path, env['SCRIPT_NAME'].length + env['PATH_INFO'] = path[n, path.length-n] end - env[REQUEST_PATH] ||= [env[SCRIPT_NAME], env[PATH_INFO]].join + env['REQUEST_PATH'] ||= [env['SCRIPT_NAME'], env['PATH_INFO']].join status, headers, body = @app.call(env) begin res.status = status.to_i headers.each { |k, vs| - next if k.downcase == RACK_HIJACK + next if k.downcase == 'rack.hijack' if k.downcase == "set-cookie" res.cookies.concat vs.split("\n") @@ -98,7 +98,7 @@ def service(req, res) end } - io_lambda = headers[RACK_HIJACK] + io_lambda = headers['rack.hijack'] if io_lambda rd, wr = IO.pipe res.body = rd diff --git a/lib/rack/head.rb b/lib/rack/head.rb index 6f1d74728..d38b55922 100644 --- a/lib/rack/head.rb +++ b/lib/rack/head.rb @@ -11,7 +11,7 @@ def initialize(app) def call(env) status, headers, body = @app.call(env) - if env[REQUEST_METHOD] == HEAD + if env['REQUEST_METHOD'] == 'HEAD' [ status, headers, Rack::BodyProxy.new([]) do body.close if body.respond_to? :close diff --git a/lib/rack/lint.rb b/lib/rack/lint.rb index 54d378223..be60c35ff 100644 --- a/lib/rack/lint.rb +++ b/lib/rack/lint.rb @@ -42,8 +42,8 @@ def _call(env) assert("No env given") { env } check_env env - env[RACK_INPUT] = InputWrapper.new(env[RACK_INPUT]) - env[RACK_ERRORS] = ErrorWrapper.new(env[RACK_ERRORS]) + env['rack.input'] = InputWrapper.new(env['rack.input']) + env['rack.errors'] = ErrorWrapper.new(env['rack.errors']) ## and returns an Array of exactly three values: status, headers, @body = @app.call(env) @@ -57,7 +57,7 @@ def _call(env) ## and the *body*. check_content_type status, headers check_content_length status, headers - @head_request = env[REQUEST_METHOD] == HEAD + @head_request = env['REQUEST_METHOD'] == 'HEAD' [status, headers, self] end @@ -177,7 +177,7 @@ def check_env(env) ## rack.session:: A hash like interface for storing ## request session data. ## The store must implement: - if session = env[RACK_SESSION] + if session = env['rack.session'] ## store(key, value) (aliased as []=); assert("session #{session.inspect} must respond to store and []=") { session.respond_to?(:store) && session.respond_to?(:[]=) @@ -201,7 +201,7 @@ def check_env(env) ## rack.logger:: A common object interface for logging messages. ## The object must implement: - if logger = env[RACK_LOGGER] + if logger = env['rack.logger'] ## info(message, &block) assert("logger #{logger.inspect} must respond to info") { logger.respond_to?(:info) @@ -229,16 +229,16 @@ def check_env(env) end ## rack.multipart.buffer_size:: An Integer hint to the multipart parser as to what chunk size to use for reads and writes. - if bufsize = env[RACK_MULTIPART_BUFFER_SIZE] + if bufsize = env['rack.multipart.buffer_size'] assert("rack.multipart.buffer_size must be an Integer > 0 if specified") { bufsize.is_a?(Integer) && bufsize > 0 } end ## rack.multipart.tempfile_factory:: 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. - if tempfile_factory = env[RACK_MULTIPART_TEMPFILE_FACTORY] + if tempfile_factory = env['rack.multipart.tempfile_factory'] assert("rack.multipart.tempfile_factory must respond to #call") { tempfile_factory.respond_to?(:call) } - env[RACK_MULTIPART_TEMPFILE_FACTORY] = lambda do |filename, content_type| + env['rack.multipart.tempfile_factory'] = lambda do |filename, content_type| io = tempfile_factory.call(filename, content_type) assert("rack.multipart.tempfile_factory return value must respond to #<<") { io.respond_to?(:<<) } io @@ -279,37 +279,37 @@ def check_env(env) ## There are the following restrictions: ## * rack.version must be an array of Integers. - assert("rack.version must be an Array, was #{env[RACK_VERSION].class}") { - env[RACK_VERSION].kind_of? Array + assert("rack.version must be an Array, was #{env['rack.version'].class}") { + env['rack.version'].kind_of? Array } ## * rack.url_scheme must either be +http+ or +https+. - assert("rack.url_scheme unknown: #{env[RACK_URL_SCHEME].inspect}") { - %w[http https].include?(env[RACK_URL_SCHEME]) + assert("rack.url_scheme unknown: #{env['rack.url_scheme'].inspect}") { + %w[http https].include?(env['rack.url_scheme']) } ## * There must be a valid input stream in rack.input. - check_input env[RACK_INPUT] + check_input env['rack.input'] ## * There must be a valid error stream in rack.errors. - check_error env[RACK_ERRORS] + check_error env['rack.errors'] ## * There may be a valid hijack stream in rack.hijack_io check_hijack env ## * The REQUEST_METHOD must be a valid token. - assert("REQUEST_METHOD unknown: #{env[REQUEST_METHOD]}") { - env[REQUEST_METHOD] =~ /\A[0-9A-Za-z!\#$%&'*+.^_`|~-]+\z/ + assert("REQUEST_METHOD unknown: #{env['REQUEST_METHOD']}") { + env['REQUEST_METHOD'] =~ /\A[0-9A-Za-z!\#$%&'*+.^_`|~-]+\z/ } ## * The SCRIPT_NAME, if non-empty, must start with / assert("SCRIPT_NAME must start with /") { - !env.include?(SCRIPT_NAME) || - env[SCRIPT_NAME] == "" || - env[SCRIPT_NAME] =~ /\A\// + !env.include?('SCRIPT_NAME') || + env['SCRIPT_NAME'] == "" || + env['SCRIPT_NAME'] =~ /\A\// } ## * The PATH_INFO, if non-empty, must start with / assert("PATH_INFO must start with /") { - !env.include?(PATH_INFO) || - env[PATH_INFO] == "" || - env[PATH_INFO] =~ /\A\// + !env.include?('PATH_INFO') || + env['PATH_INFO'] == "" || + env['PATH_INFO'] =~ /\A\// } ## * The CONTENT_LENGTH, if given, must consist of digits only. assert("Invalid CONTENT_LENGTH: #{env["CONTENT_LENGTH"]}") { @@ -319,12 +319,12 @@ def check_env(env) ## * One of SCRIPT_NAME or PATH_INFO must be ## set. PATH_INFO should be / if ## SCRIPT_NAME is empty. - assert("One of SCRIPT_NAME or PATH_INFO must be set (make PATH_INFO '/' if SCRIPT_NAME is empty)") { - env[SCRIPT_NAME] || env[PATH_INFO] + assert("One of 'SCRIPT_NAME' or 'PATH_INFO' must be set (make 'PATH_INFO' '/' if 'SCRIPT_NAME' is empty)") { + env['SCRIPT_NAME'] || env['PATH_INFO'] } ## SCRIPT_NAME never should be /, but instead be empty. - assert("SCRIPT_NAME cannot be '/', make it '' and PATH_INFO '/'") { - env[SCRIPT_NAME] != "/" + assert("SCRIPT_NAME cannot be '/', make it '' and 'PATH_INFO' '/'") { + env['SCRIPT_NAME'] != "/" } end @@ -518,11 +518,11 @@ def initialize(io) # ## ==== Request (before status) def check_hijack(env) - if env[RACK_IS_HIJACK] + if env['rack.hijack?'] ## If rack.hijack? is true then rack.hijack must respond to #call. - original_hijack = env[RACK_HIJACK] + original_hijack = env['rack.hijack'] assert("rack.hijack must respond to call") { original_hijack.respond_to?(:call) } - env[RACK_HIJACK] = proc do + env['rack.hijack'] = proc do ## rack.hijack must return the io that will also be assigned (or is ## already present, in rack.hijack_io. io = original_hijack.call @@ -548,16 +548,16 @@ def check_hijack(env) ## hijack_io to provide additional features to users. The purpose of ## rack.hijack is for Rack to "get out of the way", as such, Rack only ## provides the minimum of specification and support. - env[RACK_HIJACK_IO] = HijackWrapper.new(env[RACK_HIJACK_IO]) + env['rack.hijack_io'] = HijackWrapper.new(env['rack.hijack_io']) io end else ## ## If rack.hijack? is false, then rack.hijack should not be set. - assert("rack.hijack? is false, but rack.hijack is present") { env[RACK_HIJACK].nil? } + assert("rack.hijack? is false, but rack.hijack is present") { env['rack.hijack'].nil? } ## ## If rack.hijack? is false, then rack.hijack_io should not be set. - assert("rack.hijack? is false, but rack.hijack_io is present") { env[RACK_HIJACK_IO].nil? } + assert("rack.hijack? is false, but rack.hijack_io is present") { env['rack.hijack_io'].nil? } end end @@ -587,12 +587,12 @@ def check_hijack_response(headers, env) ## Servers must ignore the body part of the response tuple when ## the rack.hijack response API is in use. - if env[RACK_IS_HIJACK] && headers[RACK_HIJACK] + if env['rack.hijack?'] && headers['rack.hijack'] assert('rack.hijack header must respond to #call') { - headers[RACK_HIJACK].respond_to? :call + headers['rack.hijack'].respond_to? :call } - original_hijack = headers[RACK_HIJACK] - headers[RACK_HIJACK] = proc do |io| + original_hijack = headers['rack.hijack'] + headers['rack.hijack'] = proc do |io| original_hijack.call HijackWrapper.new(io) end else @@ -600,7 +600,7 @@ def check_hijack_response(headers, env) ## The special response header rack.hijack must only be set ## if the request env has rack.hijack? true. assert('rack.hijack header must not be present if server does not support hijacking') { - headers[RACK_HIJACK].nil? + headers['rack.hijack'].nil? } end end diff --git a/lib/rack/lobster.rb b/lib/rack/lobster.rb index 4d6e39f2b..d4457621e 100644 --- a/lib/rack/lobster.rb +++ b/lib/rack/lobster.rb @@ -12,7 +12,7 @@ class Lobster I8jyiTlhTcYXkekJAzTyYN6E08A+dk8voBkAVTJQ==".delete("\n ").unpack("m*")[0]) LambdaLobster = lambda { |env| - if env[QUERY_STRING].include?("flip") + if env['QUERY_STRING'].include?("flip") lobster = LobsterString.split("\n"). map { |line| line.ljust(42).reverse }. join("\n") @@ -26,7 +26,7 @@ class Lobster "
", lobster, "
", "flip!"] length = content.inject(0) { |a,e| a+e.size }.to_s - [200, {CONTENT_TYPE => "text/html", CONTENT_LENGTH => length}, content] + [200, {'Content-Type' => "text/html", 'Content-Length' => length}, content] } def call(env) diff --git a/lib/rack/lock.rb b/lib/rack/lock.rb index 923dca593..dec942c80 100644 --- a/lib/rack/lock.rb +++ b/lib/rack/lock.rb @@ -12,7 +12,7 @@ def initialize(app, mutex = Mutex.new) def call(env) @mutex.lock begin - response = @app.call(env.merge(RACK_MULTITHREAD => false)) + response = @app.call(env.merge('rack.multithread' => false)) returned = response << BodyProxy.new(response.pop) { @mutex.unlock } ensure @mutex.unlock unless returned diff --git a/lib/rack/logger.rb b/lib/rack/logger.rb index 01fc321c7..88f9837d0 100644 --- a/lib/rack/logger.rb +++ b/lib/rack/logger.rb @@ -8,10 +8,10 @@ def initialize(app, level = ::Logger::INFO) end def call(env) - logger = ::Logger.new(env[RACK_ERRORS]) + logger = ::Logger.new(env['rack.errors']) logger.level = @level - env[RACK_LOGGER] = logger + env['rack.logger'] = logger @app.call(env) end end diff --git a/lib/rack/media_type.rb b/lib/rack/media_type.rb index 7e6cd3a85..679ccbdd2 100644 --- a/lib/rack/media_type.rb +++ b/lib/rack/media_type.rb @@ -5,8 +5,8 @@ class MediaType SPLIT_PATTERN = %r{\s*[;,]\s*} class << self - # The media type (type/subtype) portion of the CONTENT_TYPE header - # without any media type parameters. e.g., when CONTENT_TYPE is + # The media type (type/subtype) portion of the 'Content-Type' header + # without any media type parameters. e.g., when 'Content-Type' is # "text/plain;charset=utf-8", the media-type is "text/plain". # # For more information on the use of media types in HTTP, see: @@ -16,9 +16,9 @@ def type(content_type) content_type.split(SPLIT_PATTERN, 2).first.downcase end - # The media type parameters provided in CONTENT_TYPE as a Hash, or - # an empty Hash if no CONTENT_TYPE or media-type parameters were - # provided. e.g., when the CONTENT_TYPE is "text/plain;charset=utf-8", + # The media type parameters provided in 'Content-Type' as a Hash, or + # an empty Hash if no 'Content-Type' or media-type parameters were + # provided. e.g., when the 'Content-Type' is "text/plain;charset=utf-8", # this method responds with the following Hash: # { 'charset' => 'utf-8' } def params(content_type) diff --git a/lib/rack/method_override.rb b/lib/rack/method_override.rb index f56377711..1376efd0d 100644 --- a/lib/rack/method_override.rb +++ b/lib/rack/method_override.rb @@ -11,11 +11,11 @@ def initialize(app) end def call(env) - if allowed_methods.include?(env[REQUEST_METHOD]) + if allowed_methods.include?(env['REQUEST_METHOD']) method = method_override(env) if HTTP_METHODS.include?(method) - env[RACK_METHODOVERRIDE_ORIGINAL_METHOD] = env[REQUEST_METHOD] - env[REQUEST_METHOD] = method + env['rack.methodoverride.original_method'] = env['REQUEST_METHOD'] + env['REQUEST_METHOD'] = method end end diff --git a/lib/rack/mock.rb b/lib/rack/mock.rb index 4ebc4df14..62de22b50 100644 --- a/lib/rack/mock.rb +++ b/lib/rack/mock.rb @@ -41,27 +41,27 @@ def string end DEFAULT_ENV = { - RACK_VERSION => Rack::VERSION, - RACK_INPUT => StringIO.new, - RACK_ERRORS => StringIO.new, - RACK_MULTITHREAD => true, - RACK_MULTIPROCESS => true, - RACK_RUNONCE => false, + 'rack.version' => Rack::VERSION, + 'rack.input' => StringIO.new, + 'rack.errors' => StringIO.new, + 'rack.multithread' => true, + 'rack.multiprocess' => true, + 'rack.run_once' => false, }.freeze def initialize(app) @app = app end - def get(uri, opts={}) request(GET, uri, opts) end - def post(uri, opts={}) request(POST, uri, opts) end - def put(uri, opts={}) request(PUT, uri, opts) end - def patch(uri, opts={}) request(PATCH, uri, opts) end - def delete(uri, opts={}) request(DELETE, uri, opts) end - def head(uri, opts={}) request(HEAD, uri, opts) end - def options(uri, opts={}) request(OPTIONS, uri, opts) end + def get(uri, opts={}) request('GET', uri, opts) end + def post(uri, opts={}) request('POST', uri, opts) end + def put(uri, opts={}) request('PUT', uri, opts) end + def patch(uri, opts={}) request('PATCH', uri, opts) end + def delete(uri, opts={}) request('DELETE', uri, opts) end + def head(uri, opts={}) request('HEAD', uri, opts) end + def options(uri, opts={}) request('OPTIONS', uri, opts) end - def request(method=GET, uri="", opts={}) + def request(method='GET', uri="", opts={}) env = self.class.env_for(uri, opts.merge(:method => method)) if opts[:lint] @@ -70,7 +70,7 @@ def request(method=GET, uri="", opts={}) app = @app end - errors = env[RACK_ERRORS] + errors = env['rack.errors'] status, headers, body = app.call(env) MockResponse.new(status, headers, body, errors) ensure @@ -91,27 +91,27 @@ def self.env_for(uri="", opts={}) env = DEFAULT_ENV.dup - env[REQUEST_METHOD] = opts[:method] ? opts[:method].to_s.upcase : GET - env[SERVER_NAME] = uri.host || "example.org" - env[SERVER_PORT] = uri.port ? uri.port.to_s : "80" - env[QUERY_STRING] = uri.query.to_s - env[PATH_INFO] = (!uri.path || uri.path.empty?) ? "/" : uri.path - env[RACK_URL_SCHEME] = uri.scheme || "http" - env[HTTPS] = env[RACK_URL_SCHEME] == "https" ? "on" : "off" + env['REQUEST_METHOD'] = opts[:method] ? opts[:method].to_s.upcase : 'GET' + env['SERVER_NAME'] = uri.host || "example.org" + env['SERVER_PORT'] = uri.port ? uri.port.to_s : "80" + env['QUERY_STRING'] = uri.query.to_s + env['PATH_INFO'] = (!uri.path || uri.path.empty?) ? "/" : uri.path + env['rack.url_scheme'] = uri.scheme || "http" + env['HTTPS'] = env['rack.url_scheme'] == "https" ? "on" : "off" - env[SCRIPT_NAME] = opts[:script_name] || "" + env['SCRIPT_NAME'] = opts[:script_name] || "" if opts[:fatal] - env[RACK_ERRORS] = FatalWarner.new + env['rack.errors'] = FatalWarner.new else - env[RACK_ERRORS] = StringIO.new + env['rack.errors'] = StringIO.new end if params = opts[:params] - if env[REQUEST_METHOD] == GET + if env['REQUEST_METHOD'] == 'GET' params = Utils.parse_nested_query(params) if params.is_a?(String) - params.update(Utils.parse_nested_query(env[QUERY_STRING])) - env[QUERY_STRING] = Utils.build_nested_query(params) + params.update(Utils.parse_nested_query(env['QUERY_STRING'])) + env['QUERY_STRING'] = Utils.build_nested_query(params) elsif !opts.has_key?(:input) opts["CONTENT_TYPE"] = "application/x-www-form-urlencoded" if params.is_a?(Hash) @@ -137,9 +137,9 @@ def self.env_for(uri="", opts={}) end rack_input.set_encoding(Encoding::BINARY) - env[RACK_INPUT] = rack_input + env['rack.input'] = rack_input - env["CONTENT_LENGTH"] ||= env[RACK_INPUT].length.to_s + env["CONTENT_LENGTH"] ||= env['rack.input'].length.to_s opts.each { |field, value| env[field] = value if String === field diff --git a/lib/rack/multipart.rb b/lib/rack/multipart.rb index db59ee59a..4b0cf10b1 100644 --- a/lib/rack/multipart.rb +++ b/lib/rack/multipart.rb @@ -41,16 +41,16 @@ def parse_multipart(env, params = Rack::Utils.default_query_parser) end def extract_multipart(req, params = Rack::Utils.default_query_parser) - io = req.get_header(RACK_INPUT) + io = req.get_header('rack.input') io.rewind content_length = req.content_length content_length = content_length.to_i if content_length - tempfile = req.get_header(RACK_MULTIPART_TEMPFILE_FACTORY) || Parser::TEMPFILE_FACTORY - bufsize = req.get_header(RACK_MULTIPART_BUFFER_SIZE) || Parser::BUFSIZE + tempfile = req.get_header('rack.multipart.tempfile_factory') || Parser::TEMPFILE_FACTORY + bufsize = req.get_header('rack.multipart.buffer_size') || Parser::BUFSIZE info = Parser.parse io, content_length, req.get_header('CONTENT_TYPE'), tempfile, bufsize, params - req.set_header(RACK_TEMPFILES, info.tmp_files) + req.set_header('rack.tempfiles', info.tmp_files) info.params end diff --git a/lib/rack/null_logger.rb b/lib/rack/null_logger.rb index abc612062..2d5a2c976 100644 --- a/lib/rack/null_logger.rb +++ b/lib/rack/null_logger.rb @@ -5,7 +5,7 @@ def initialize(app) end def call(env) - env[RACK_LOGGER] = self + env['rack.logger'] = self @app.call(env) end diff --git a/lib/rack/recursive.rb b/lib/rack/recursive.rb index 7645d284a..371730bbb 100644 --- a/lib/rack/recursive.rb +++ b/lib/rack/recursive.rb @@ -14,11 +14,11 @@ def initialize(url, env={}) @url = URI(url) @env = env - @env[PATH_INFO] = @url.path - @env[QUERY_STRING] = @url.query if @url.query - @env[HTTP_HOST] = @url.host if @url.host - @env["HTTP_PORT"] = @url.port if @url.port - @env[RACK_URL_SCHEME] = @url.scheme if @url.scheme + @env['PATH_INFO'] = @url.path + @env['QUERY_STRING'] = @url.query if @url.query + @env['HTTP_HOST'] = @url.host if @url.host + @env['HTTP_PORT'] = @url.port if @url.port + @env['rack.url_scheme'] = @url.scheme if @url.scheme super "forwarding to #{url}" end @@ -39,8 +39,8 @@ def call(env) end def _call(env) - @script_name = env[SCRIPT_NAME] - @app.call(env.merge(RACK_RECURSIVE_INCLUDE => method(:include))) + @script_name = env['SCRIPT_NAME'] + @app.call(env.merge('rack.recursive.include' => method(:include))) rescue ForwardRequest => req call(env.merge(req.env)) end @@ -51,11 +51,11 @@ def include(env, path) raise ArgumentError, "can only include below #{@script_name}, not #{path}" end - env = env.merge(PATH_INFO => path, - SCRIPT_NAME => @script_name, - REQUEST_METHOD => GET, + env = env.merge('PATH_INFO' => path, + 'SCRIPT_NAME' => @script_name, + 'REQUEST_METHOD' => 'GET', "CONTENT_LENGTH" => "0", "CONTENT_TYPE" => "", - RACK_INPUT => StringIO.new("")) + 'rack.input' => StringIO.new("")) @app.call(env) end end diff --git a/lib/rack/request.rb b/lib/rack/request.rb index 5bf3eb17a..3d101ad46 100644 --- a/lib/rack/request.rb +++ b/lib/rack/request.rb @@ -123,68 +123,68 @@ module Helpers HTTP_X_FORWARDED_PORT = 'HTTP_X_FORWARDED_PORT'.freeze HTTP_X_FORWARDED_SSL = 'HTTP_X_FORWARDED_SSL'.freeze - def body; get_header(RACK_INPUT) end - def script_name; get_header(SCRIPT_NAME).to_s end - def script_name=(s); set_header(SCRIPT_NAME, s.to_s) end + def body; get_header('rack.input') end + def script_name; get_header('SCRIPT_NAME').to_s end + def script_name=(s); set_header('SCRIPT_NAME', s.to_s) end - def path_info; get_header(PATH_INFO).to_s end - def path_info=(s); set_header(PATH_INFO, s.to_s) end + def path_info; get_header('PATH_INFO').to_s end + def path_info=(s); set_header('PATH_INFO', s.to_s) end - def request_method; get_header(REQUEST_METHOD) end - def query_string; get_header(QUERY_STRING).to_s end + def request_method; get_header('REQUEST_METHOD') end + def query_string; get_header('QUERY_STRING').to_s end def content_length; get_header('CONTENT_LENGTH') end - def logger; get_header(RACK_LOGGER) end + def logger; get_header('rack.logger') end def user_agent; get_header('HTTP_USER_AGENT') end - def multithread?; get_header(RACK_MULTITHREAD) end + def multithread?; get_header('rack.multithread') end # the referer of the client def referer; get_header('HTTP_REFERER') end alias referrer referer def session - fetch_header(RACK_SESSION) do |k| - set_header RACK_SESSION, default_session + fetch_header('rack.session') do |k| + set_header 'rack.session', default_session end end def session_options - fetch_header(RACK_SESSION_OPTIONS) do |k| - set_header RACK_SESSION_OPTIONS, {} + fetch_header('rack.session.options') do |k| + set_header 'rack.session.options', {} end end # Checks the HTTP request method (or verb) to see if it was of type DELETE - def delete?; request_method == DELETE end + def delete?; request_method == 'DELETE' end # Checks the HTTP request method (or verb) to see if it was of type GET - def get?; request_method == GET end + def get?; request_method == 'GET' end # Checks the HTTP request method (or verb) to see if it was of type HEAD - def head?; request_method == HEAD end + def head?; request_method == 'HEAD' end # Checks the HTTP request method (or verb) to see if it was of type OPTIONS - def options?; request_method == OPTIONS end + def options?; request_method == 'OPTIONS' end # Checks the HTTP request method (or verb) to see if it was of type LINK - def link?; request_method == LINK end + def link?; request_method == 'LINK' end # Checks the HTTP request method (or verb) to see if it was of type PATCH - def patch?; request_method == PATCH end + def patch?; request_method == 'PATCH' end # Checks the HTTP request method (or verb) to see if it was of type POST - def post?; request_method == POST end + def post?; request_method == 'POST' end # Checks the HTTP request method (or verb) to see if it was of type PUT - def put?; request_method == PUT end + def put?; request_method == 'PUT' end # Checks the HTTP request method (or verb) to see if it was of type TRACE - def trace?; request_method == TRACE end + def trace?; request_method == 'TRACE' end # Checks the HTTP request method (or verb) to see if it was of type UNLINK - def unlink?; request_method == UNLINK end + def unlink?; request_method == 'UNLINK' end def scheme - if get_header(HTTPS) == 'on' + if get_header('HTTPS') == 'on' 'https' elsif get_header(HTTP_X_FORWARDED_SSL) == 'on' 'https' @@ -193,23 +193,23 @@ def scheme elsif get_header(HTTP_X_FORWARDED_PROTO) get_header(HTTP_X_FORWARDED_PROTO).split(',')[0] else - get_header(RACK_URL_SCHEME) + get_header('rack.url_scheme') end end def authority - get_header(SERVER_NAME) + ':' + get_header(SERVER_PORT) + get_header('SERVER_NAME') + ':' + get_header('SERVER_PORT') end def cookies - hash = fetch_header(RACK_REQUEST_COOKIE_HASH) do |k| + hash = fetch_header('rack.request.cookie_hash') do |k| set_header(k, {}) end - string = get_header HTTP_COOKIE + string = get_header 'HTTP_COOKIE' - return hash if string == get_header(RACK_REQUEST_COOKIE_STRING) - hash.replace Utils.parse_cookies_header get_header HTTP_COOKIE - set_header(RACK_REQUEST_COOKIE_STRING, string) + return hash if string == get_header('rack.request.cookie_string') + hash.replace Utils.parse_cookies_header get_header 'HTTP_COOKIE' + set_header('rack.request.cookie_string', string) hash end @@ -226,7 +226,7 @@ def host_with_port if forwarded = get_header(HTTP_X_FORWARDED_HOST) forwarded.split(/,\s?/).last else - get_header(HTTP_HOST) || "#{get_header(SERVER_NAME) || get_header(SERVER_ADDR)}:#{get_header(SERVER_PORT)}" + get_header('HTTP_HOST') || "#{get_header('SERVER_NAME') || get_header('SERVER_ADDR')}:#{get_header('SERVER_PORT')}" end end @@ -245,7 +245,7 @@ def port elsif has_header?(HTTP_X_FORWARDED_PROTO) DEFAULT_PORTS[get_header(HTTP_X_FORWARDED_PROTO).split(',')[0]] else - get_header(SERVER_PORT).to_i + get_header('SERVER_PORT').to_i end end @@ -264,8 +264,8 @@ def ip return reject_trusted_ip_addresses(forwarded_ips).last || get_header("REMOTE_ADDR") end - # The media type (type/subtype) portion of the CONTENT_TYPE header - # without any media type parameters. e.g., when CONTENT_TYPE is + # The media type (type/subtype) portion of the 'Content-Type' header + # without any media type parameters. e.g., when 'Content-Type' is # "text/plain;charset=utf-8", the media-type is "text/plain". # # For more information on the use of media types in HTTP, see: @@ -274,9 +274,9 @@ def media_type MediaType.type(content_type) end - # The media type parameters provided in CONTENT_TYPE as a Hash, or - # an empty Hash if no CONTENT_TYPE or media-type parameters were - # provided. e.g., when the CONTENT_TYPE is "text/plain;charset=utf-8", + # The media type parameters provided in 'Content-Type' as a Hash, or + # an empty Hash if no 'Content-Type' or media-type parameters were + # provided. e.g., when the 'Content-Type' is "text/plain;charset=utf-8", # this method responds with the following Hash: # { 'charset' => 'utf-8' } def media_type_params @@ -301,8 +301,8 @@ def content_charset # Content-Type header is provided and the request_method is POST. def form_data? type = media_type - meth = get_header(RACK_METHODOVERRIDE_ORIGINAL_METHOD) || get_header(REQUEST_METHOD) - (meth == POST && type.nil?) || FORM_DATA_MEDIA_TYPES.include?(type) + meth = get_header('rack.methodoverride.original_method') || get_header('REQUEST_METHOD') + (meth == 'POST' && type.nil?) || FORM_DATA_MEDIA_TYPES.include?(type) end # Determine whether the request body contains data by checking @@ -313,12 +313,12 @@ def parseable_data? # Returns the data received in the query string. def GET - if get_header(RACK_REQUEST_QUERY_STRING) == query_string - get_header(RACK_REQUEST_QUERY_HASH) + if get_header('rack.request.query_string') == query_string + get_header('rack.request.query_hash') else query_hash = parse_query(query_string, '&;') - set_header(RACK_REQUEST_QUERY_STRING, query_string) - set_header(RACK_REQUEST_QUERY_HASH, query_hash) + set_header('rack.request.query_string', query_string) + set_header('rack.request.query_hash', query_hash) end end @@ -327,25 +327,25 @@ def GET # This method support both application/x-www-form-urlencoded and # multipart/form-data. def POST - if get_header(RACK_INPUT).nil? + if get_header('rack.input').nil? raise "Missing rack.input" - elsif get_header(RACK_REQUEST_FORM_INPUT) == get_header(RACK_INPUT) - get_header(RACK_REQUEST_FORM_HASH) + elsif get_header('rack.request.form_input') == get_header('rack.input') + get_header('rack.request.form_hash') elsif form_data? || parseable_data? - unless set_header(RACK_REQUEST_FORM_HASH, parse_multipart) - form_vars = get_header(RACK_INPUT).read + unless set_header('rack.request.form_hash', parse_multipart) + form_vars = get_header('rack.input').read # Fix for Safari Ajax postings that always append \0 # form_vars.sub!(/\0\z/, '') # performance replacement: form_vars.slice!(-1) if form_vars[-1] == ?\0 - set_header RACK_REQUEST_FORM_VARS, form_vars - set_header RACK_REQUEST_FORM_HASH, parse_query(form_vars, '&') + set_header 'rack.request.form_vars', form_vars + set_header 'rack.request.form_hash', parse_query(form_vars, '&') - get_header(RACK_INPUT).rewind + get_header('rack.input').rewind end - set_header RACK_REQUEST_FORM_INPUT, get_header(RACK_INPUT) - get_header RACK_REQUEST_FORM_HASH + set_header 'rack.request.form_input', get_header('rack.input') + get_header 'rack.request.form_hash' else {} end diff --git a/lib/rack/response.rb b/lib/rack/response.rb index 9ac47aade..43bf4c553 100644 --- a/lib/rack/response.rb +++ b/lib/rack/response.rb @@ -54,15 +54,15 @@ def redirect(target, status=302) end def chunked? - CHUNKED == get_header(TRANSFER_ENCODING) + CHUNKED == get_header('Transfer-Encoding') end def finish(&block) @block = block if [204, 205, 304].include?(status.to_i) - delete_header CONTENT_TYPE - delete_header CONTENT_LENGTH + delete_header 'Content-Type' + delete_header 'Content-Length' close [status.to_i, header, []] else @@ -87,7 +87,7 @@ def write(str) @length += s.bytesize unless chunked? @writer.call s - set_header(CONTENT_LENGTH, @length.to_s) unless chunked? + set_header('Content-Length', @length.to_s) unless chunked? str end @@ -155,7 +155,7 @@ def add_header key, v end def content_type - get_header CONTENT_TYPE + get_header 'Content-Type' end def media_type @@ -167,7 +167,7 @@ def media_type_params end def content_length - cl = get_header CONTENT_LENGTH + cl = get_header 'Content-Length' cl ? cl.to_i : cl end @@ -180,36 +180,36 @@ def location=(location) end def set_cookie(key, value) - cookie_header = get_header SET_COOKIE - set_header SET_COOKIE, ::Rack::Utils.add_cookie_to_header(cookie_header, key, value) + cookie_header = get_header 'Set-Cookie' + set_header 'Set-Cookie', ::Rack::Utils.add_cookie_to_header(cookie_header, key, value) end def delete_cookie(key, value={}) - set_header SET_COOKIE, ::Rack::Utils.add_remove_cookie_to_header(get_header(SET_COOKIE), key, value) + set_header 'Set-Cookie', ::Rack::Utils.add_remove_cookie_to_header(get_header('Set-Cookie'), key, value) end def set_cookie_header - get_header SET_COOKIE + get_header 'Set-Cookie' end def set_cookie_header= v - set_header SET_COOKIE, v + set_header 'Set-Cookie', v end def cache_control - get_header CACHE_CONTROL + get_header 'Cache-Control' end def cache_control= v - set_header CACHE_CONTROL, v + set_header 'Cache-Control', v end def etag - get_header ETAG + get_header 'ETag' end def etag= v - set_header ETAG, v + set_header 'ETag', v end end diff --git a/lib/rack/sendfile.rb b/lib/rack/sendfile.rb index bdb7cf2fb..4be6f59f8 100644 --- a/lib/rack/sendfile.rb +++ b/lib/rack/sendfile.rb @@ -114,18 +114,18 @@ def call(env) when 'X-Accel-Redirect' path = ::File.expand_path(body.to_path) if url = map_accel_path(env, path) - headers[CONTENT_LENGTH] = '0' + headers['Content-Length'] = '0' headers[type] = url obody = body body = Rack::BodyProxy.new([]) do obody.close if obody.respond_to?(:close) end else - env[RACK_ERRORS].puts "X-Accel-Mapping header missing" + env['rack.errors'].puts "X-Accel-Mapping header missing" end when 'X-Sendfile', 'X-Lighttpd-Send-File' path = ::File.expand_path(body.to_path) - headers[CONTENT_LENGTH] = '0' + headers['Content-Length'] = '0' headers[type] = path obody = body body = Rack::BodyProxy.new([]) do @@ -133,7 +133,7 @@ def call(env) end when '', nil else - env[RACK_ERRORS].puts "Unknown x-sendfile variation: '#{type}'.\n" + env['rack.errors'].puts "Unknown x-sendfile variation: '#{type}'.\n" end end [status, headers, body] diff --git a/lib/rack/server.rb b/lib/rack/server.rb index 690f10960..ebe087a49 100644 --- a/lib/rack/server.rb +++ b/lib/rack/server.rb @@ -327,7 +327,7 @@ def build_app_from_string def parse_options(args) # Don't evaluate CGI ISINDEX parameters. # http://www.meb.uni-bonn.de/docs/cgi/cl.html - args.clear if ENV.include?(REQUEST_METHOD) + args.clear if ENV.include?('REQUEST_METHOD') @options = opt_parser.parse!(args) @options[:config] = ::File.expand_path(options[:config]) diff --git a/lib/rack/session/abstract/id.rb b/lib/rack/session/abstract/id.rb index 204bdb341..6b07d2867 100644 --- a/lib/rack/session/abstract/id.rb +++ b/lib/rack/session/abstract/id.rb @@ -19,15 +19,15 @@ class SessionHash attr_writer :id def self.find(req) - req.get_header RACK_SESSION + req.get_header 'rack.session' end def self.set(req, session) - req.set_header RACK_SESSION, session + req.set_header 'rack.session', session end def self.set_options(req, options) - req.set_header RACK_SESSION_OPTIONS, options.dup + req.set_header 'rack.session.options', options.dup end def initialize(store, req) @@ -189,7 +189,7 @@ def stringify_keys(other) class Persisted DEFAULT_OPTIONS = { - :key => RACK_SESSION, + :key => 'rack.session', :path => '/', :domain => nil, :expire_after => nil, @@ -255,10 +255,10 @@ def generate_sid(secure = @sid_secure) # metadata into 'rack.session.options'. def prepare_session(req) - session_was = req.get_header RACK_SESSION + session_was = req.get_header 'rack.session' session = session_class.new(self, req) - req.set_header RACK_SESSION, session - req.set_header RACK_SESSION_OPTIONS, @default_options.dup + req.set_header 'rack.session', session + req.set_header 'rack.session.options', @default_options.dup session.merge! session_was if session_was end @@ -282,7 +282,7 @@ def extract_session_id(request) # Returns the current session id from the SessionHash. def current_session_id(req) - req.get_header(RACK_SESSION).id + req.get_header('rack.session').id end # Check if the session exists or not. @@ -327,7 +327,7 @@ def security_matches?(request, options) # response with the session's id. def commit_session(req, res) - session = req.get_header RACK_SESSION + session = req.get_header 'rack.session' options = session.options if options[:drop] || options[:renew] @@ -342,9 +342,9 @@ def commit_session(req, res) session_data = session.to_hash.delete_if { |k,v| v.nil? } if not data = write_session(req, session_id, session_data, options) - req.get_header(RACK_ERRORS).puts("Warning! #{self.class.name} failed to save session. Content dropped.") + req.get_header('rack.errors').puts("Warning! #{self.class.name} failed to save session. Content dropped.") elsif options[:defer] and not options[:renew] - req.get_header(RACK_ERRORS).puts("Deferring cookie for #{session_id}") if $VERBOSE + req.get_header('rack.errors').puts("Deferring cookie for #{session_id}") if $VERBOSE else cookie = Hash.new cookie[:value] = data diff --git a/lib/rack/session/cookie.rb b/lib/rack/session/cookie.rb index 71bb96f4f..c551ebeed 100644 --- a/lib/rack/session/cookie.rb +++ b/lib/rack/session/cookie.rb @@ -133,7 +133,7 @@ def extract_session_id(request) end def unpacked_cookie_data(request) - request.fetch_header(RACK_SESSION_UNPACKED_COOKIE_DATA) do |k| + request.fetch_header('rack.session.unpacked_cookie_data') do |k| session_data = request.cookies[@key] if @secrets.size > 0 && session_data @@ -162,7 +162,7 @@ def write_session(req, session_id, session, options) end if session_data.size > (4096 - @key.size) - req.get_header(RACK_ERRORS).puts("Warning! Rack::Session::Cookie data size exceeds 4K.") + req.get_header('rack.errors').puts("Warning! Rack::Session::Cookie data size exceeds 4K.") nil else session_data diff --git a/lib/rack/session/memcache.rb b/lib/rack/session/memcache.rb index 4cf5ea09e..6dca282e1 100644 --- a/lib/rack/session/memcache.rb +++ b/lib/rack/session/memcache.rb @@ -76,7 +76,7 @@ def destroy_session(env, session_id, options) end def with_lock(env) - @mutex.lock if env[RACK_MULTITHREAD] + @mutex.lock if env['rack.multithread'] yield rescue MemCache::MemCacheError, Errno::ECONNREFUSED if $VERBOSE diff --git a/lib/rack/show_exceptions.rb b/lib/rack/show_exceptions.rb index ca86b2b2a..e3791b531 100644 --- a/lib/rack/show_exceptions.rb +++ b/lib/rack/show_exceptions.rb @@ -24,8 +24,8 @@ def call(env) rescue StandardError, LoadError, SyntaxError => e exception_string = dump_exception(e) - env[RACK_ERRORS].puts(exception_string) - env[RACK_ERRORS].flush + env['rack.errors'].puts(exception_string) + env['rack.errors'].flush if accepts_html?(env) content_type = "text/html" @@ -38,8 +38,8 @@ def call(env) [ 500, { - CONTENT_TYPE => content_type, - CONTENT_LENGTH => body.bytesize.to_s, + 'Content-Type' => content_type, + 'Content-Length' => body.bytesize.to_s, }, [body], ] diff --git a/lib/rack/show_status.rb b/lib/rack/show_status.rb index 54db8f471..eb01ec35f 100644 --- a/lib/rack/show_status.rb +++ b/lib/rack/show_status.rb @@ -19,10 +19,10 @@ def initialize(app) def call(env) status, headers, body = @app.call(env) headers = Utils::HeaderHash.new(headers) - empty = headers[CONTENT_LENGTH].to_i <= 0 + empty = headers['Content-Length'].to_i <= 0 # client or server error, or explicit message - if (status.to_i >= 400 && empty) || env[RACK_SHOWSTATUS_DETAIL] + if (status.to_i >= 400 && empty) || env['rack.showstatus.detail'] # This double assignment is to prevent an "unused variable" warning on # Ruby 1.9.3. Yes, it is dumb, but I don't like Ruby yelling at me. req = req = Rack::Request.new(env) @@ -31,11 +31,11 @@ def call(env) # This double assignment is to prevent an "unused variable" warning on # Ruby 1.9.3. Yes, it is dumb, but I don't like Ruby yelling at me. - detail = detail = env[RACK_SHOWSTATUS_DETAIL] || message + detail = detail = env['rack.showstatus.detail'] || message body = @template.result(binding) size = body.bytesize - [status, headers.merge(CONTENT_TYPE => "text/html", CONTENT_LENGTH => size.to_s), [body]] + [status, headers.merge('Content-Type' => "text/html", 'Content-Length' => size.to_s), [body]] else [status, headers, body] end diff --git a/lib/rack/static.rb b/lib/rack/static.rb index 17f476494..81160167e 100644 --- a/lib/rack/static.rb +++ b/lib/rack/static.rb @@ -93,7 +93,7 @@ def initialize(app, options={}) # HTTP Headers @header_rules = options[:header_rules] || [] # Allow for legacy :cache_control option while prioritizing global header_rules setting - @header_rules.unshift([:all, {CACHE_CONTROL => options[:cache_control]}]) if options[:cache_control] + @header_rules.unshift([:all, {'Cache-Control' => options[:cache_control]}]) if options[:cache_control] @file_server = Rack::File.new(root) end @@ -115,28 +115,28 @@ def can_serve(path) end def call(env) - path = env[PATH_INFO] + path = env['PATH_INFO'] if can_serve(path) if overwrite_file_path(path) - env[PATH_INFO] = (add_index_root?(path) ? path + @index : @urls[path]) + env['PATH_INFO'] = (add_index_root?(path) ? path + @index : @urls[path]) elsif @gzip && env['HTTP_ACCEPT_ENCODING'] =~ /\bgzip\b/ - path = env[PATH_INFO] - env[PATH_INFO] += '.gz' + path = env['PATH_INFO'] + env['PATH_INFO'] += '.gz' response = @file_server.call(env) - env[PATH_INFO] = path + env['PATH_INFO'] = path if response[0] == 404 response = nil else if mime_type = Mime.mime_type(::File.extname(path), 'text/plain') - response[1][CONTENT_TYPE] = mime_type + response[1]['Content-Type'] = mime_type end response[1]['Content-Encoding'] = 'gzip' end end - path = env[PATH_INFO] + path = env['PATH_INFO'] response ||= @file_server.call(env) headers = response[1] diff --git a/lib/rack/tempfile_reaper.rb b/lib/rack/tempfile_reaper.rb index d82998061..404ff708d 100644 --- a/lib/rack/tempfile_reaper.rb +++ b/lib/rack/tempfile_reaper.rb @@ -11,10 +11,10 @@ def initialize(app) end def call(env) - env[RACK_TEMPFILES] ||= [] + env['rack.tempfiles'] ||= [] status, headers, body = @app.call(env) body_proxy = BodyProxy.new(body) do - env[RACK_TEMPFILES].each(&:close!) unless env[RACK_TEMPFILES].nil? + env['rack.tempfiles'].each(&:close!) unless env['rack.tempfiles'].nil? end [status, headers, body_proxy] end diff --git a/lib/rack/urlmap.rb b/lib/rack/urlmap.rb index 510b4b500..89528564f 100644 --- a/lib/rack/urlmap.rb +++ b/lib/rack/urlmap.rb @@ -3,7 +3,7 @@ module Rack # dispatches accordingly. Support for HTTP/1.1 host names exists if # the URLs start with http:// or https://. # - # URLMap modifies the SCRIPT_NAME and PATH_INFO such that the part + # URLMap modifies the 'SCRIPT_NAME' and 'PATH_INFO' such that the part # relevant for dispatch is in the SCRIPT_NAME, and the rest in the # PATH_INFO. This should be taken care of when you need to # reconstruct the URL in order to create links. @@ -41,11 +41,11 @@ def remap(map) end def call(env) - path = env[PATH_INFO] - script_name = env[SCRIPT_NAME] - http_host = env[HTTP_HOST] - server_name = env[SERVER_NAME] - server_port = env[SERVER_PORT] + path = env['PATH_INFO'] + script_name = env['SCRIPT_NAME'] + http_host = env['HTTP_HOST'] + server_name = env['SERVER_NAME'] + server_port = env['SERVER_PORT'] is_same_server = casecmp?(http_host, server_name) || casecmp?(http_host, "#{server_name}:#{server_port}") @@ -62,17 +62,17 @@ def call(env) rest = m[1] next unless !rest || rest.empty? || rest[0] == ?/ - env[SCRIPT_NAME] = (script_name + location) - env[PATH_INFO] = rest + env['SCRIPT_NAME'] = (script_name + location) + env['PATH_INFO'] = rest return app.call(env) end - [404, {CONTENT_TYPE => "text/plain", "X-Cascade" => "pass"}, ["Not Found: #{path}"]] + [404, {'Content-Type' => "text/plain", "X-Cascade" => "pass"}, ["Not Found: #{path}"]] ensure - env[PATH_INFO] = path - env[SCRIPT_NAME] = script_name + env['PATH_INFO'] = path + env['SCRIPT_NAME'] = script_name end private diff --git a/lib/rack/utils.rb b/lib/rack/utils.rb index 7b8421253..37c11fd50 100644 --- a/lib/rack/utils.rb +++ b/lib/rack/utils.rb @@ -200,7 +200,7 @@ def select_best_encoding(available_encodings, accept_encoding) module_function :select_best_encoding def parse_cookies(env) - parse_cookies_header env[HTTP_COOKIE] + parse_cookies_header env['HTTP_COOKIE'] end module_function :parse_cookies @@ -280,7 +280,7 @@ def add_cookie_to_header(header, key, value) module_function :add_cookie_to_header def set_cookie_header!(header, key, value) - header[SET_COOKIE] = add_cookie_to_header(header[SET_COOKIE], key, value) + header['Set-Cookie'] = add_cookie_to_header(header['Set-Cookie'], key, value) nil end module_function :set_cookie_header! @@ -310,7 +310,7 @@ def make_delete_cookie_header(header, key, value) module_function :make_delete_cookie_header def delete_cookie_header!(header, key, value = {}) - header[SET_COOKIE] = add_remove_cookie_to_header(header[SET_COOKIE], key, value) + header['Set-Cookie'] = add_remove_cookie_to_header(header['Set-Cookie'], key, value) nil end module_function :delete_cookie_header! diff --git a/test/spec_request.rb b/test/spec_request.rb index 74f2fa871..0c075445c 100644 --- a/test/spec_request.rb +++ b/test/spec_request.rb @@ -931,7 +931,7 @@ def initialize(*) options = { "CONTENT_TYPE" => "multipart/form-data; boundary=AaB03x", "CONTENT_LENGTH" => data.length.to_s, - Rack::RACK_MULTIPART_TEMPFILE_FACTORY => lambda { |filename, content_type| + 'rack.multipart.tempfile_factory' => lambda { |filename, content_type| file = Tempfile.new(["RackMultipart", ::File.extname(filename)]) files << file file