Skip to content

Commit a30497d

Browse files
committed
fix replace_response_host to not add a 443 port for https requests
When proxying an https request, rack reverse proxy would always add a :443 port to the raplaced host, even though that's the default port for https requests. This fixes the behaviour by not adding any port when the port is default for the protocol.
1 parent 69fde96 commit a30497d

File tree

2 files changed

+19
-2
lines changed

2 files changed

+19
-2
lines changed

lib/rack_reverse_proxy/middleware.rb

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,11 @@ def proxy(env, source_request, rule)
115115
# Replace the location header with the proxy domain
116116
if response_headers["Location"] && options[:replace_response_host]
117117
response_location = URI(response_headers["location"])
118-
response_location.host = source_request.host
119-
response_location.port = source_request.port
118+
response_location.scheme = source_request.scheme
119+
response_location.host = source_request.host
120+
unless default_port_for_scheme?(source_request.scheme, source_request.port)
121+
response_location.port = source_request.port
122+
end
120123
response_headers["Location"] = response_location.to_s
121124
end
122125

@@ -155,5 +158,9 @@ def format_headers(headers)
155158
acc
156159
end
157160
end
161+
162+
def default_port_for_scheme?(scheme, port)
163+
scheme == 'http' && port == 80 || scheme == 'https' && port == 443
164+
end
158165
end
159166
end

spec/rack/reverse_proxy_spec.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,16 @@ def app
255255
get "http://example.com:3000/test/stuff"
256256
expect(last_response.headers["location"]).to eq("http://example.com:3000/bar")
257257
end
258+
259+
it "doesn't keep the port when it's default for the protocol" do
260+
# webmock doesn't allow to stub an https URI, but this is enough to
261+
# reply to the https code path
262+
stub_request(:get, "http://example.com/test/stuff").to_return(
263+
:headers => { "location" => "http://test.com/bar" }
264+
)
265+
get "https://example.com/test/stuff"
266+
expect(last_response.headers["location"]).to eq("https://example.com/bar")
267+
end
258268
end
259269

260270
describe "with ambiguous routes and all matching" do

0 commit comments

Comments
 (0)