Skip to content

Commit 1c3e9a5

Browse files
committed
Merge pull request jaswope#6 from waterlink/fix/response-headers-arrays-vs-strings
Fix/response headers arrays vs strings
2 parents 344c01c + c805e11 commit 1c3e9a5

File tree

2 files changed

+17
-25
lines changed

2 files changed

+17
-25
lines changed

lib/rack/reverse_proxy.rb

Lines changed: 4 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ def initialize(app = nil, &b)
1818

1919
def call(env)
2020
rackreq = Rack::Request.new(env)
21-
matcher = get_matcher(rackreq.fullpath, extract_http_request_headers(rackreq.env), rackreq)
21+
matcher = get_matcher(rackreq.fullpath, Proxy.extract_http_request_headers(rackreq.env), rackreq)
2222
return @app.call(env) if matcher.nil?
2323

2424
if @global_options[:newrelic_instrumentation]
@@ -44,7 +44,7 @@ def proxy(env, source_request, matcher)
4444
target_request = Net::HTTP.const_get(source_request.request_method.capitalize).new(uri.request_uri)
4545

4646
# Setup headers
47-
target_request_headers = extract_http_request_headers(source_request.env)
47+
target_request_headers = Proxy.extract_http_request_headers(source_request.env)
4848

4949
if options[:preserve_host]
5050
if uri.port == uri.default_port
@@ -82,12 +82,12 @@ def proxy(env, source_request, matcher)
8282
target_response.use_ssl = "https" == uri.scheme
8383

8484
# Let rack set the transfer-encoding header
85-
response_headers = format_headers(target_response.headers)
85+
response_headers = Rack::Utils::HeaderHash.new Proxy.normalize_headers(format_headers(target_response.headers))
8686
response_headers.delete('Transfer-Encoding')
8787

8888
# Replace the location header with the proxy domain
8989
if response_headers['Location'] && options[:replace_response_host]
90-
response_location = URI(response_headers['Location'][0])
90+
response_location = URI(response_headers['location'])
9191
response_location.host = source_request.host
9292
response_location.port = source_request.port
9393
response_headers['Location'] = response_location.to_s
@@ -96,26 +96,6 @@ def proxy(env, source_request, matcher)
9696
[target_response.status, response_headers, target_response.body]
9797
end
9898

99-
def extract_http_request_headers(env)
100-
headers = env.reject do |k, v|
101-
!(/^HTTP_[A-Z_]+$/ === k) || v.nil?
102-
end.map do |k, v|
103-
[reconstruct_header_name(k), v]
104-
end.inject(Utils::HeaderHash.new) do |hash, k_v|
105-
k, v = k_v
106-
hash[k] = v
107-
hash
108-
end
109-
110-
x_forwarded_for = (headers["X-Forwarded-For"].to_s.split(/, +/) << env["REMOTE_ADDR"]).join(", ")
111-
112-
headers.merge!("X-Forwarded-For" => x_forwarded_for)
113-
end
114-
115-
def reconstruct_header_name(name)
116-
name.sub(/^HTTP_/, "").gsub("_", "-")
117-
end
118-
11999
def get_matcher(path, headers, rackreq)
120100
matches = @matchers.select do |matcher|
121101
matcher.match?(path, headers, rackreq)

spec/rack/reverse_proxy_spec.rb

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,19 @@ def app
3131
last_response.body.should == "Proxied App"
3232
end
3333

34+
it "should produce a response header of type HeaderHash" do
35+
stub_request(:get, 'http://example.com/test')
36+
get '/test'
37+
last_response.headers.should be_an_instance_of Rack::Utils::HeaderHash
38+
end
39+
40+
it "should parse the headers as a Hash with values of type String" do
41+
stub_request(:get, 'http://example.com/test').to_return({:headers => {'cache-control'=> 'max-age=300, public'} })
42+
get '/test'
43+
last_response.headers['cache-control'].should be_an_instance_of String
44+
last_response.headers['cache-control'].should == 'max-age=300, public'
45+
end
46+
3447
it "should proxy requests to a lambda url when a pattern is matched" do
3548
stub_request(:get, 'http://example.com/2test').to_return({:body => "Proxied App2"})
3649
get '/2test'
@@ -166,7 +179,6 @@ def app
166179
it "should replace the location response header" do
167180
stub_request(:get, "http://example.com/test/stuff").to_return(:headers => {"location" => "http://test.com/bar"})
168181
get 'http://example.com/test/stuff'
169-
# puts last_response.headers.inspect
170182
last_response.headers['location'].should == "http://example.com/bar"
171183
end
172184

0 commit comments

Comments
 (0)