mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
parent
e2a5de2bb2
commit
9af59b2468
5 changed files with 119 additions and 36 deletions
|
@ -1,5 +1,16 @@
|
|||
## Rails 4.0.0 (unreleased) ##
|
||||
|
||||
* `ActionDispatch::IntegrationTest` allows headers and rack env
|
||||
variables to be passed when performing requests.
|
||||
Fixes #6513.
|
||||
|
||||
Example:
|
||||
|
||||
get "/success", {}, "HTTP_REFERER" => "http://test.com/",
|
||||
"Host" => "http://test.com"
|
||||
|
||||
*Yves Senn*
|
||||
|
||||
* Http::Headers respects headers that are not prefixed with HTTP_
|
||||
|
||||
*Yves Senn*
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -17,7 +17,7 @@ module ActionDispatch
|
|||
# a Hash, or a String that is appropriately encoded
|
||||
# (<tt>application/x-www-form-urlencoded</tt> or
|
||||
# <tt>multipart/form-data</tt>).
|
||||
# - +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
|
||||
|
|
|
@ -573,6 +573,21 @@ class MetalIntegrationTest < ActionDispatch::IntegrationTest
|
|||
def test_generate_url_without_controller
|
||||
assert_equal 'http://www.example.com/foo', url_for(:controller => "foo")
|
||||
end
|
||||
|
||||
def test_pass_headers
|
||||
get "/success", {}, "Referer" => "http://www.example.com/foo", "Host" => "http://nohost.com"
|
||||
|
||||
assert_equal "http://nohost.com", @request.env["HTTP_HOST"]
|
||||
assert_equal "http://www.example.com/foo", @request.env["HTTP_REFERER"]
|
||||
end
|
||||
|
||||
def test_pass_env
|
||||
get "/success", {}, "HTTP_REFERER" => "http://test.com/", "HTTP_HOST" => "http://test.com"
|
||||
|
||||
assert_equal "http://test.com", @request.env["HTTP_HOST"]
|
||||
assert_equal "http://test.com/", @request.env["HTTP_REFERER"]
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class ApplicationIntegrationTest < ActionDispatch::IntegrationTest
|
||||
|
|
|
@ -8,7 +8,23 @@ class HeaderTest < ActiveSupport::TestCase
|
|||
)
|
||||
end
|
||||
|
||||
test "each" do
|
||||
test "#new with mixed headers and env" do
|
||||
headers = ActionDispatch::Http::Headers.new(
|
||||
"Content-Type" => "application/json",
|
||||
"HTTP_REFERER" => "/some/page",
|
||||
"Host" => "http://test.com")
|
||||
|
||||
assert_equal({"CONTENT_TYPE" => "application/json",
|
||||
"HTTP_REFERER" => "/some/page",
|
||||
"HTTP_HOST" => "http://test.com"}, headers.env)
|
||||
end
|
||||
|
||||
test "#env returns the headers as env variables" do
|
||||
assert_equal({"CONTENT_TYPE" => "text/plain",
|
||||
"HTTP_REFERER" => "/some/page"}, @headers.env)
|
||||
end
|
||||
|
||||
test "#each iterates through the env variables" do
|
||||
headers = []
|
||||
@headers.each { |pair| headers << pair }
|
||||
assert_equal [["CONTENT_TYPE", "text/plain"],
|
||||
|
@ -54,4 +70,31 @@ class HeaderTest < ActiveSupport::TestCase
|
|||
assert_equal "text/plain", @headers.fetch("content-type", nil)
|
||||
assert_equal "not found", @headers.fetch("not-found", "not found")
|
||||
end
|
||||
|
||||
test "#merge! headers with mutation" do
|
||||
@headers.merge!("Host" => "http://example.test",
|
||||
"Content-Type" => "text/html")
|
||||
assert_equal({"HTTP_HOST" => "http://example.test",
|
||||
"CONTENT_TYPE" => "text/html",
|
||||
"HTTP_REFERER" => "/some/page"}, @headers.env)
|
||||
end
|
||||
|
||||
test "#merge! env with mutation" do
|
||||
@headers.merge!("HTTP_HOST" => "http://first.com",
|
||||
"CONTENT_TYPE" => "text/html")
|
||||
assert_equal({"HTTP_HOST" => "http://first.com",
|
||||
"CONTENT_TYPE" => "text/html",
|
||||
"HTTP_REFERER" => "/some/page"}, @headers.env)
|
||||
end
|
||||
|
||||
test "merge without mutation" do
|
||||
combined = @headers.merge("HTTP_HOST" => "http://example.com",
|
||||
"CONTENT_TYPE" => "text/html")
|
||||
assert_equal({"HTTP_HOST" => "http://example.com",
|
||||
"CONTENT_TYPE" => "text/html",
|
||||
"HTTP_REFERER" => "/some/page"}, combined.env)
|
||||
|
||||
assert_equal({"CONTENT_TYPE" => "text/plain",
|
||||
"HTTP_REFERER" => "/some/page"}, @headers.env)
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue