aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_dispatch/http/headers.rb
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack/lib/action_dispatch/http/headers.rb')
-rw-r--r--actionpack/lib/action_dispatch/http/headers.rb99
1 files changed, 99 insertions, 0 deletions
diff --git a/actionpack/lib/action_dispatch/http/headers.rb b/actionpack/lib/action_dispatch/http/headers.rb
new file mode 100644
index 0000000000..bc5410dc38
--- /dev/null
+++ b/actionpack/lib/action_dispatch/http/headers.rb
@@ -0,0 +1,99 @@
+module ActionDispatch
+ module Http
+ # Provides access to the request's HTTP headers from the environment.
+ #
+ # env = { "CONTENT_TYPE" => "text/plain" }
+ # headers = ActionDispatch::Http::Headers.new(env)
+ # headers["Content-Type"] # => "text/plain"
+ class Headers
+ CGI_VARIABLES = Set.new(%W[
+ AUTH_TYPE
+ CONTENT_LENGTH
+ CONTENT_TYPE
+ GATEWAY_INTERFACE
+ HTTPS
+ PATH_INFO
+ PATH_TRANSLATED
+ QUERY_STRING
+ REMOTE_ADDR
+ REMOTE_HOST
+ REMOTE_IDENT
+ REMOTE_USER
+ REQUEST_METHOD
+ SCRIPT_NAME
+ SERVER_NAME
+ SERVER_PORT
+ SERVER_PROTOCOL
+ SERVER_SOFTWARE
+ ]).freeze
+
+ HTTP_HEADER = /\A[A-Za-z0-9-]+\z/
+
+ include Enumerable
+ attr_reader :env
+
+ def initialize(env = {}) # :nodoc:
+ @env = env
+ end
+
+ # Returns the value for the given key mapped to @env.
+ def [](key)
+ @env[env_name(key)]
+ end
+
+ # Sets the given value for the key mapped to @env.
+ def []=(key, value)
+ @env[env_name(key)] = value
+ end
+
+ def key?(key)
+ @env.key? env_name(key)
+ end
+ alias :include? :key?
+
+ # Returns the value for the given key mapped to @env.
+ #
+ # If the key is not found and an optional code block is not provided,
+ # raises a <tt>KeyError</tt> exception.
+ #
+ # If the code block is provided, then it will be run and
+ # its result returned.
+ def fetch(key, *args, &block)
+ @env.fetch env_name(key), *args, &block
+ end
+
+ def each(&block)
+ @env.each(&block)
+ end
+
+ # Returns a new Http::Headers instance containing the contents of
+ # <tt>headers_or_env</tt> and the original instance.
+ def merge(headers_or_env)
+ headers = Http::Headers.new(env.dup)
+ headers.merge!(headers_or_env)
+ headers
+ end
+
+ # Adds the contents of <tt>headers_or_env</tt> to original instance
+ # entries; duplicate keys are overwritten with the values from
+ # <tt>headers_or_env</tt>.
+ def merge!(headers_or_env)
+ headers_or_env.each do |key, value|
+ self[env_name(key)] = value
+ end
+ end
+
+ private
+ # Converts a HTTP header name to an environment variable name if it is
+ # not contained within the headers hash.
+ def env_name(key)
+ key = key.to_s
+ if key =~ HTTP_HEADER
+ key = key.upcase.tr('-', '_')
+ key = "HTTP_" + key unless CGI_VARIABLES.include?(key)
+ end
+ key
+ end
+ end
+ end
+end