Skip to content

Commit 680f339

Browse files
janraaschwaterlink
authored andcommitted
Normalize headers from HttpStreamingResponse
Since HttpStreamingResponse#headers returns a `Hash` with `Array`-keys, e.g. ```ruby {"cache-control"=>["max-age=300, public"]} ``` we need to normalise this to something like ```ruby {"cache-control"=> "max-age=300, public"} ``` in order to **not break other middlewares** processing the headers further down the pipe. In our case we encountered a problem when working with `rack-wwwhisper`, see `Rack::WWWhisper::NoPublicCache#call` (https://github.com/wrr/rack-wwwhisper), since it is calling `gsub` on the 'Cache-Control' header.
1 parent 344c01c commit 680f339

File tree

2 files changed

+15
-3
lines changed

2 files changed

+15
-3
lines changed

lib/rack/reverse_proxy.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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

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)