handle proxy redirects even if the scheme doesn't match

Normally, when receiving a Location header, nginx will rewrite it to
reference a URL if it matches the proxy_pass. This breaks when the
scheme changes, since proxy_pass can have a scheme. For instance, if you
have a proxy: "https://www.foo.com", but the Location on a redirect from
that site returns "http://www.foo.com" nginx won't rewrite the URL. This
fixes it by specifying the redirect for both http and https.
parent a2e3a022
......@@ -29,6 +29,9 @@ class NginxConfig
json["proxies"][loc]["path"] = uri.path
uri.path = ""
json["proxies"][loc]["host"] = uri.to_s
redirect_scheme = uri.scheme == "https" ? "http" : "https"
json["proxies"][loc]["redirect"] = uri.dup.tap {|u| u.scheme = redirect_scheme }.to_s
json["proxies"][loc]["redirect"] += "/" if !uri.to_s.end_with?("/")
end
json["clean_urls"] ||= DEFAULT[:clean_urls]
......
......@@ -81,6 +81,8 @@ http {
location <%= location %> {
proxy_pass <%= hash['origin'] %>;
proxy_ssl_server_name on;
proxy_redirect default;
proxy_redirect <%= hash["redirect"] %> <%= location %>;
}
<% end %>
......@@ -95,6 +97,8 @@ http {
rewrite ^<%= location %>(.*)$ <%= hash['path'] %>/$1 break;
proxy_pass <%= hash['host'] %>;
proxy_ssl_server_name on;
proxy_redirect default;
proxy_redirect <%= hash["redirect"] %> <%= location %>;
}
<% end %>
......
......@@ -383,6 +383,7 @@ STATIC_JSON
include PathHelper
let(:name) { "proxies" }
let(:proxy_scheme) { "http" }
let(:static_json_path) { fixtures_path("proxies/static.json") }
let(:proxy) do
<<PROXY
......@@ -393,6 +394,16 @@ end
get "/foo/baz/" do
"baz"
end
get "/foo/http_redirect/" do
uri = URI("http://\#{request.host}/foo/redirect")
redirect URI(uri), 307
end
get "/foo/https_redirect/" do
uri = URI("https://\#{request.host}/foo/redirect")
redirect URI(uri), 307
end
PROXY
end
let(:setup_static_json) do
......@@ -402,7 +413,7 @@ PROXY
{
"proxies": {
"/api/": {
"origin": "http://#{@proxy_ip_address}#{path}"
"origin": "#{proxy_scheme}://#{@proxy_ip_address}#{path}"
}
},
"headers": {
......@@ -419,7 +430,7 @@ STATIC_JSON
before do
@proxy_ip_address = app.proxy.ip_address
setup_static_json.call("/foo/")
setup_static_json.call("/foo")
end
after do
......@@ -439,6 +450,18 @@ STATIC_JSON
expect(response["X-Header"]).to be_nil
end
end
it "should hanadle redirects regardless of scheme" do
app.run do
response = app.get("/api/http_redirect/")
expect(response.code).to eq("307")
expect(response["Location"]).not_to include(@proxy_ip_address)
response = app.get("/api/https_redirect/")
expect(response.code).to eq("307")
expect(response["Location"]).not_to include(@proxy_ip_address)
end
end
end
end
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment