From 8945be464feb8c9ec8c4e7be52e5195f17a1ef5e Mon Sep 17 00:00:00 2001 From: Yves Senn Date: Wed, 13 Mar 2013 11:14:49 +0100 Subject: Http::Headers respects headers that are not prefixed with HTTP_ --- actionpack/lib/action_dispatch/http/headers.rb | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'actionpack/lib') diff --git a/actionpack/lib/action_dispatch/http/headers.rb b/actionpack/lib/action_dispatch/http/headers.rb index dc04d4577b..187e83cbd9 100644 --- a/actionpack/lib/action_dispatch/http/headers.rb +++ b/actionpack/lib/action_dispatch/http/headers.rb @@ -1,6 +1,16 @@ module ActionDispatch module Http class Headers + NON_PREFIX_VARIABLES = %w( + CONTENT_TYPE CONTENT_LENGTH + HTTPS AUTH_TYPE GATEWAY_INTERFACE + 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 + ) + HEADER_REGEXP = /\A[A-Za-z-]+\z/ + include Enumerable def initialize(env = {}) @@ -32,7 +42,9 @@ module ActionDispatch end def cgi_name(k) - "HTTP_#{k.upcase.gsub(/-/, '_')}" + k = k.upcase.gsub(/-/, '_') + k = "HTTP_#{k.upcase.gsub(/-/, '_')}" unless NON_PREFIX_VARIABLES.include?(k) + k end end end -- cgit v1.2.3 From e2a5de2bb200773943e605cdddb9b18bbfa77e13 Mon Sep 17 00:00:00 2001 From: Yves Senn Date: Wed, 13 Mar 2013 11:30:45 +0100 Subject: refactor, `Http::Headers` stores headers in env notation Also: cleanup, use consistent syntax for `Http::Header` and test. --- actionpack/lib/action_dispatch/http/headers.rb | 38 ++++++++++++++------------ 1 file changed, 21 insertions(+), 17 deletions(-) (limited to 'actionpack/lib') diff --git a/actionpack/lib/action_dispatch/http/headers.rb b/actionpack/lib/action_dispatch/http/headers.rb index 187e83cbd9..ecf050a869 100644 --- a/actionpack/lib/action_dispatch/http/headers.rb +++ b/actionpack/lib/action_dispatch/http/headers.rb @@ -14,37 +14,41 @@ module ActionDispatch include Enumerable def initialize(env = {}) - @headers = env + @env = env end - def [](header_name) - @headers[env_name(header_name)] + def [](key) + @env[env_name(key)] end - def []=(k,v); @headers[k] = v; end - def key?(k); @headers.key? k; end + def []=(key, value) + @env[env_name(key)] = value + end + + def key?(key); @env.key? key; end alias :include? :key? - def fetch(header_name, *args, &block) - @headers.fetch env_name(header_name), *args, &block + def fetch(key, *args, &block) + @env.fetch env_name(key), *args, &block end def each(&block) - @headers.each(&block) + @env.each(&block) end private - - # Converts a HTTP header name to an environment variable name if it is - # not contained within the headers hash. - def env_name(header_name) - @headers.include?(header_name) ? header_name : cgi_name(header_name) + def env_name(key) + if key =~ HEADER_REGEXP + cgi_name(key) + else + key + end end - def cgi_name(k) - k = k.upcase.gsub(/-/, '_') - k = "HTTP_#{k.upcase.gsub(/-/, '_')}" unless NON_PREFIX_VARIABLES.include?(k) - k + def cgi_name(key) + key = key.upcase.gsub(/-/, '_') + key = "HTTP_#{key}" unless NON_PREFIX_VARIABLES.include?(key) + key end end end -- cgit v1.2.3 From 9af59b2468e4ad6c3c2ca89f90968fdcaa417aba Mon Sep 17 00:00:00 2001 From: Yves Senn Date: Wed, 13 Mar 2013 12:25:32 +0100 Subject: allow headers and env to be passed in `IntegrationTest`. Closes #6513. --- actionpack/lib/action_dispatch/http/headers.rb | 16 ++++- .../lib/action_dispatch/testing/integration.rb | 68 +++++++++++----------- 2 files changed, 49 insertions(+), 35 deletions(-) (limited to 'actionpack/lib') diff --git a/actionpack/lib/action_dispatch/http/headers.rb b/actionpack/lib/action_dispatch/http/headers.rb index ecf050a869..3f3f71b280 100644 --- a/actionpack/lib/action_dispatch/http/headers.rb +++ b/actionpack/lib/action_dispatch/http/headers.rb @@ -12,9 +12,11 @@ module ActionDispatch HEADER_REGEXP = /\A[A-Za-z-]+\z/ include Enumerable + attr_reader :env def initialize(env = {}) - @env = env + @env = {} + merge!(env) end def [](key) @@ -36,6 +38,18 @@ module ActionDispatch @env.each(&block) end + def merge(headers_or_env) + headers = Http::Headers.new(env.dup) + headers.merge!(headers_or_env) + headers + end + + def merge!(headers_or_env) + headers_or_env.each do |key, value| + self[env_name(key)] = value + end + end + private def env_name(key) if key =~ HEADER_REGEXP diff --git a/actionpack/lib/action_dispatch/testing/integration.rb b/actionpack/lib/action_dispatch/testing/integration.rb index ed4e88aab6..ae1b0b5dea 100644 --- a/actionpack/lib/action_dispatch/testing/integration.rb +++ b/actionpack/lib/action_dispatch/testing/integration.rb @@ -17,7 +17,7 @@ module ActionDispatch # a Hash, or a String that is appropriately encoded # (application/x-www-form-urlencoded or # multipart/form-data). - # - +headers+: Additional headers to pass, as a Hash. The headers will be + # - +headers_or_env+: Additional headers to pass, as a Hash. The headers will be # merged into the Rack env hash. # # This method returns a Response object, which one can use to @@ -28,44 +28,44 @@ module ActionDispatch # # You can also perform POST, PATCH, PUT, DELETE, and HEAD requests with # +#post+, +#patch+, +#put+, +#delete+, and +#head+. - def get(path, parameters = nil, headers = nil) - process :get, path, parameters, headers + def get(path, parameters = nil, headers_or_env = nil) + process :get, path, parameters, headers_or_env end # Performs a POST request with the given parameters. See +#get+ for more # details. - def post(path, parameters = nil, headers = nil) - process :post, path, parameters, headers + def post(path, parameters = nil, headers_or_env = nil) + process :post, path, parameters, headers_or_env end # Performs a PATCH request with the given parameters. See +#get+ for more # details. - def patch(path, parameters = nil, headers = nil) - process :patch, path, parameters, headers + def patch(path, parameters = nil, headers_or_env = nil) + process :patch, path, parameters, headers_or_env end # Performs a PUT request with the given parameters. See +#get+ for more # details. - def put(path, parameters = nil, headers = nil) - process :put, path, parameters, headers + def put(path, parameters = nil, headers_or_env = nil) + process :put, path, parameters, headers_or_env end # Performs a DELETE request with the given parameters. See +#get+ for # more details. - def delete(path, parameters = nil, headers = nil) - process :delete, path, parameters, headers + def delete(path, parameters = nil, headers_or_env = nil) + process :delete, path, parameters, headers_or_env end # Performs a HEAD request with the given parameters. See +#get+ for more # details. - def head(path, parameters = nil, headers = nil) - process :head, path, parameters, headers + def head(path, parameters = nil, headers_or_env = nil) + process :head, path, parameters, headers_or_env end # Performs a OPTIONS request with the given parameters. See +#get+ for # more details. - def options(path, parameters = nil, headers = nil) - process :options, path, parameters, headers + def options(path, parameters = nil, headers_or_env = nil) + process :options, path, parameters, headers_or_env end # Performs an XMLHttpRequest request with the given parameters, mirroring @@ -74,11 +74,11 @@ module ActionDispatch # The request_method is +:get+, +:post+, +:patch+, +:put+, +:delete+ or # +:head+; the parameters are +nil+, a hash, or a url-encoded or multipart # string; the headers are a hash. - def xml_http_request(request_method, path, parameters = nil, headers = nil) - headers ||= {} - headers['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest' - headers['HTTP_ACCEPT'] ||= [Mime::JS, Mime::HTML, Mime::XML, 'text/xml', Mime::ALL].join(', ') - process(request_method, path, parameters, headers) + def xml_http_request(request_method, path, parameters = nil, headers_or_env = nil) + headers_or_env ||= {} + headers_or_env['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest' + headers_or_env['HTTP_ACCEPT'] ||= [Mime::JS, Mime::HTML, Mime::XML, 'text/xml', Mime::ALL].join(', ') + process(request_method, path, parameters, headers_or_env) end alias xhr :xml_http_request @@ -95,40 +95,40 @@ module ActionDispatch # redirect. Note that the redirects are followed until the response is # not a redirect--this means you may run into an infinite loop if your # redirect loops back to itself. - def request_via_redirect(http_method, path, parameters = nil, headers = nil) - process(http_method, path, parameters, headers) + def request_via_redirect(http_method, path, parameters = nil, headers_or_env = nil) + process(http_method, path, parameters, headers_or_env) follow_redirect! while redirect? status end # Performs a GET request, following any subsequent redirect. # See +request_via_redirect+ for more information. - def get_via_redirect(path, parameters = nil, headers = nil) - request_via_redirect(:get, path, parameters, headers) + def get_via_redirect(path, parameters = nil, headers_or_env = nil) + request_via_redirect(:get, path, parameters, headers_or_env) end # Performs a POST request, following any subsequent redirect. # See +request_via_redirect+ for more information. - def post_via_redirect(path, parameters = nil, headers = nil) - request_via_redirect(:post, path, parameters, headers) + def post_via_redirect(path, parameters = nil, headers_or_env = nil) + request_via_redirect(:post, path, parameters, headers_or_env) end # Performs a PATCH request, following any subsequent redirect. # See +request_via_redirect+ for more information. - def patch_via_redirect(path, parameters = nil, headers = nil) - request_via_redirect(:patch, path, parameters, headers) + def patch_via_redirect(path, parameters = nil, headers_or_env = nil) + request_via_redirect(:patch, path, parameters, headers_or_env) end # Performs a PUT request, following any subsequent redirect. # See +request_via_redirect+ for more information. - def put_via_redirect(path, parameters = nil, headers = nil) - request_via_redirect(:put, path, parameters, headers) + def put_via_redirect(path, parameters = nil, headers_or_env = nil) + request_via_redirect(:put, path, parameters, headers_or_env) end # Performs a DELETE request, following any subsequent redirect. # See +request_via_redirect+ for more information. - def delete_via_redirect(path, parameters = nil, headers = nil) - request_via_redirect(:delete, path, parameters, headers) + def delete_via_redirect(path, parameters = nil, headers_or_env = nil) + request_via_redirect(:delete, path, parameters, headers_or_env) end end @@ -268,8 +268,8 @@ module ActionDispatch end # Performs the actual request. - def process(method, path, parameters = nil, rack_env = nil) - rack_env ||= {} + def process(method, path, parameters = nil, headers_or_env = nil) + rack_env = Http::Headers.new(headers_or_env || {}).env if path =~ %r{://} location = URI.parse(path) https! URI::HTTPS === location if location.scheme -- cgit v1.2.3 From a709246d1739c44e04b00412e7a4ec09c1500fc3 Mon Sep 17 00:00:00 2001 From: Yves Senn Date: Wed, 13 Mar 2013 16:25:28 +0100 Subject: `Http::Headers` respects dotted env vars, symbols, headers with numbers. --- actionpack/lib/action_dispatch/http/headers.rb | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) (limited to 'actionpack/lib') diff --git a/actionpack/lib/action_dispatch/http/headers.rb b/actionpack/lib/action_dispatch/http/headers.rb index 3f3f71b280..1574518a16 100644 --- a/actionpack/lib/action_dispatch/http/headers.rb +++ b/actionpack/lib/action_dispatch/http/headers.rb @@ -1,7 +1,7 @@ module ActionDispatch module Http class Headers - NON_PREFIX_VARIABLES = %w( + CGI_VARIABLES = %w( CONTENT_TYPE CONTENT_LENGTH HTTPS AUTH_TYPE GATEWAY_INTERFACE PATH_INFO PATH_TRANSLATED QUERY_STRING @@ -9,7 +9,7 @@ module ActionDispatch REQUEST_METHOD SCRIPT_NAME SERVER_NAME SERVER_PORT SERVER_PROTOCOL SERVER_SOFTWARE ) - HEADER_REGEXP = /\A[A-Za-z-]+\z/ + HTTP_HEADER = /\A[A-Za-z0-9-]+\z/ include Enumerable attr_reader :env @@ -52,16 +52,11 @@ module ActionDispatch private def env_name(key) - if key =~ HEADER_REGEXP - cgi_name(key) - else - key + key = key.to_s + if key =~ HTTP_HEADER + key = key.upcase.tr('-', '_') + key = "HTTP_" + key unless CGI_VARIABLES.include?(key) end - end - - def cgi_name(key) - key = key.upcase.gsub(/-/, '_') - key = "HTTP_#{key}" unless NON_PREFIX_VARIABLES.include?(key) key end end -- cgit v1.2.3