Modify Location header field if redirect URI refers to downstream

This commit is contained in:
Tatsuhiro Tsujikawa 2012-06-13 00:08:28 +09:00
parent eb9458bba9
commit 9893b7e2b0
4 changed files with 46 additions and 0 deletions

View File

@ -27,6 +27,11 @@
#include <sstream>
#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

View File

@ -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

View File

@ -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 &&

View File

@ -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 += ", ";
}