diff --git a/examples/shrpx_http.cc b/examples/shrpx_http.cc index 357da788..d5bcd905 100644 --- a/examples/shrpx_http.cc +++ b/examples/shrpx_http.cc @@ -27,6 +27,11 @@ #include #include "shrpx_config.h" +#include "util.h" +#include "uri.h" + +using namespace spdylay; + namespace shrpx { namespace http { @@ -103,6 +108,27 @@ std::string create_via_header_value(int major, int minor) return hdrs; } +std::string modify_location_header_value(const std::string& uri) +{ + std::string norm_uri = uri; + if(util::istartsWith(uri.c_str(), "//")) { + norm_uri.insert(0, "http:"); + } else if(!util::istartsWith(uri.c_str(), "http://")) { + return uri; + } + uri::UriStruct us; + if(uri::parse(us, norm_uri)) { + if(util::strieq(us.host.c_str(), get_config()->downstream_host) && + us.port == get_config()->downstream_port) { + us.protocol = "https"; + us.host = get_config()->host; + us.port = get_config()->port; + return uri::construct(us); + } + } + return uri; +} + } // namespace http } // namespace shrpx diff --git a/examples/shrpx_http.h b/examples/shrpx_http.h index 4b7cf363..256ad521 100644 --- a/examples/shrpx_http.h +++ b/examples/shrpx_http.h @@ -37,6 +37,8 @@ std::string create_error_html(int status_code); std::string create_via_header_value(int major, int minor); +std::string modify_location_header_value(const std::string& uri); + } // namespace http } // namespace shrpx diff --git a/examples/shrpx_https_upstream.cc b/examples/shrpx_https_upstream.cc index b6c8a2bf..f6c233bf 100644 --- a/examples/shrpx_https_upstream.cc +++ b/examples/shrpx_https_upstream.cc @@ -521,6 +521,7 @@ int HttpsUpstream::on_downstream_header_complete(Downstream *downstream) LOG(INFO) << "Downstream on_downstream_header_complete"; } std::string via_value; + std::string location; std::string hdrs = "HTTP/1.1 "; hdrs += http::get_status_string(downstream->get_response_http_status()); hdrs += "\r\n"; @@ -532,6 +533,8 @@ int HttpsUpstream::on_downstream_header_complete(Downstream *downstream) // These are ignored } else if(util::strieq((*i).first.c_str(), "via")) { via_value = (*i).second; + } else if(util::strieq((*i).first.c_str(), "location")) { + location = (*i).second; } else { hdrs += (*i).first; hdrs += ": "; @@ -539,6 +542,11 @@ int HttpsUpstream::on_downstream_header_complete(Downstream *downstream) hdrs += "\r\n"; } } + if(!location.empty()) { + hdrs += "Location: "; + hdrs += http::modify_location_header_value(location); + hdrs += "\r\n"; + } if(get_client_handler()->get_should_close_after_write()) { hdrs += "Connection: close\r\n"; } else if(downstream->get_request_major() == 1 && diff --git a/examples/shrpx_spdy_upstream.cc b/examples/shrpx_spdy_upstream.cc index 60540c85..ab974c74 100644 --- a/examples/shrpx_spdy_upstream.cc +++ b/examples/shrpx_spdy_upstream.cc @@ -590,6 +590,7 @@ int SpdyUpstream::on_downstream_header_complete(Downstream *downstream) const char **nv = new const char*[nheader * 2 + 6 + 1]; size_t hdidx = 0; std::string via_value; + std::string location; nv[hdidx++] = ":status"; nv[hdidx++] = http::get_status_string(downstream->get_response_http_status()); nv[hdidx++] = ":version"; @@ -603,11 +604,20 @@ int SpdyUpstream::on_downstream_header_complete(Downstream *downstream) // These are ignored } else if(util::strieq((*i).first.c_str(), "via")) { via_value = (*i).second; + } else if(util::strieq((*i).first.c_str(), "location")) { + location = (*i).second; } else { nv[hdidx++] = (*i).first.c_str(); nv[hdidx++] = (*i).second.c_str(); } } + if(!location.empty()) { + nv[hdidx++] = "location"; + // Assign location to store the result. Otherwise we lose the + // return value. + location = http::modify_location_header_value(location); + nv[hdidx++] = location.c_str(); + } if(!via_value.empty()) { via_value += ", "; }