diff --git a/examples/shrpx_downstream.cc b/examples/shrpx_downstream.cc index e121638b..b7a8d741 100644 --- a/examples/shrpx_downstream.cc +++ b/examples/shrpx_downstream.cc @@ -30,6 +30,7 @@ #include "shrpx_client_handler.h" #include "shrpx_config.h" #include "shrpx_error.h" +#include "shrpx_http.h" #include "util.h" using namespace spdylay; @@ -43,10 +44,14 @@ Downstream::Downstream(Upstream *upstream, int stream_id, int priority) priority_(priority), ioctrl_(0), request_state_(INITIAL), + request_major_(1), + request_minor_(1), chunked_request_(false), request_connection_close_(false), response_state_(INITIAL), response_http_status_(0), + response_major_(1), + response_minor_(1), chunked_response_(false), response_htp_(htparser_new()), response_body_buf_(0) @@ -140,6 +145,16 @@ void Downstream::set_request_path(const std::string& path) request_path_ = path; } +void Downstream::set_request_major(int major) +{ + request_major_ = major; +} + +void Downstream::set_request_minor(int minor) +{ + request_minor_ = minor; +} + Upstream* Downstream::get_upstream() const { return upstream_; @@ -208,11 +223,16 @@ int Downstream::push_request_headers() hdrs += "Host: "; hdrs += get_config()->downstream_hostport; hdrs += "\r\n"; + std::string via_value; for(Headers::const_iterator i = request_headers_.begin(); i != request_headers_.end(); ++i) { if(util::strieq((*i).first.c_str(), "X-Forwarded-Proto")) { continue; } + if(util::strieq((*i).first.c_str(), "via")) { + via_value = (*i).second; + continue; + } hdrs += (*i).first; hdrs += ": "; hdrs += (*i).second; @@ -231,6 +251,14 @@ int Downstream::push_request_headers() } hdrs += "X-Forwarded-Proto: https\r\n"; + hdrs += "Via: "; + hdrs += via_value; + if(!via_value.empty()) { + hdrs += ", "; + } + hdrs += http::create_via_header_value(request_major_, request_minor_); + hdrs += "\r\n"; + hdrs += "\r\n"; if(ENABLE_LOG) { LOG(INFO) << "Downstream request headers\n" << hdrs; @@ -299,6 +327,26 @@ void Downstream::set_response_http_status(unsigned int status) response_http_status_ = status; } +void Downstream::set_response_major(int major) +{ + response_major_ = major; +} + +void Downstream::set_response_minor(int minor) +{ + response_minor_ = minor; +} + +int Downstream::get_response_major() const +{ + return response_major_; +} + +int Downstream::get_response_minor() const +{ + return response_minor_; +} + bool Downstream::get_chunked_response() const { return chunked_response_; @@ -310,6 +358,8 @@ int htp_hdrs_completecb(htparser *htp) Downstream *downstream; downstream = reinterpret_cast(htparser_get_userdata(htp)); downstream->set_response_http_status(htparser_get_status(htp)); + downstream->set_response_major(htparser_get_major(htp)); + downstream->set_response_minor(htparser_get_minor(htp)); downstream->set_response_state(Downstream::HEADER_COMPLETE); downstream->get_upstream()->on_downstream_header_complete(downstream); return 0; diff --git a/examples/shrpx_downstream.h b/examples/shrpx_downstream.h index d4c8d987..dfafa5dd 100644 --- a/examples/shrpx_downstream.h +++ b/examples/shrpx_downstream.h @@ -63,6 +63,8 @@ public: void set_last_request_header_value(const std::string& value); void set_request_method(const std::string& method); void set_request_path(const std::string& path); + void set_request_major(int major); + void set_request_minor(int minor); int push_request_headers(); bool get_chunked_request() const; bool get_request_connection_close() const; @@ -84,6 +86,10 @@ public: void set_last_response_header_value(const std::string& value); unsigned int get_response_http_status() const; void set_response_http_status(unsigned int status); + void set_response_major(int major); + void set_response_minor(int minor); + int get_response_major() const; + int get_response_minor() const; bool get_chunked_response() const; int parse_http_response(); void set_response_state(int state); @@ -99,12 +105,16 @@ private: int request_state_; std::string request_method_; std::string request_path_; + int request_major_; + int request_minor_; bool chunked_request_; bool request_connection_close_; Headers request_headers_; int response_state_; unsigned int response_http_status_; + int response_major_; + int response_minor_; bool chunked_response_; Headers response_headers_; htparser *response_htp_; diff --git a/examples/shrpx_http.cc b/examples/shrpx_http.cc index 4037677a..357da788 100644 --- a/examples/shrpx_http.cc +++ b/examples/shrpx_http.cc @@ -93,6 +93,16 @@ std::string create_error_html(int status_code) return ss.str(); } +std::string create_via_header_value(int major, int minor) +{ + std::string hdrs; + hdrs += static_cast(major+'0'); + hdrs += "."; + hdrs += static_cast(minor+'0'); + hdrs += " shrpx"; + return hdrs; +} + } // namespace http } // namespace shrpx diff --git a/examples/shrpx_http.h b/examples/shrpx_http.h index 75b1b18c..4b7cf363 100644 --- a/examples/shrpx_http.h +++ b/examples/shrpx_http.h @@ -35,6 +35,8 @@ const char* get_status_string(int status_code); std::string create_error_html(int status_code); +std::string create_via_header_value(int major, int minor); + } // namespace http } // namespace shrpx diff --git a/examples/shrpx_https_upstream.cc b/examples/shrpx_https_upstream.cc index 8bf3623b..779de536 100644 --- a/examples/shrpx_https_upstream.cc +++ b/examples/shrpx_https_upstream.cc @@ -154,6 +154,9 @@ int htp_hdrs_completecb(htparser *htp) upstream = reinterpret_cast(htparser_get_userdata(htp)); Downstream *downstream = upstream->get_last_downstream(); + downstream->set_request_major(htparser_get_major(htp)); + downstream->set_request_minor(htparser_get_minor(htp)); + downstream->push_request_headers(); downstream->set_request_state(Downstream::HEADER_COMPLETE); @@ -452,6 +455,7 @@ int HttpsUpstream::on_downstream_header_complete(Downstream *downstream) if(ENABLE_LOG) { LOG(INFO) << "Downstream on_downstream_header_complete"; } + std::string via_value; std::string hdrs = "HTTP/1.1 "; hdrs += http::get_status_string(downstream->get_response_http_status()); hdrs += "\r\n"; @@ -461,21 +465,26 @@ int HttpsUpstream::on_downstream_header_complete(Downstream *downstream) util::strieq((*i).first.c_str(), "connection") || util:: strieq((*i).first.c_str(), "proxy-connection")) { // These are ignored + } else if(util::strieq((*i).first.c_str(), "via")) { + via_value = (*i).second; } else { - if(util::strieq((*i).first.c_str(), "server")) { - hdrs += "Server: "; - hdrs += get_config()->server_name; - } else { - hdrs += (*i).first; - hdrs += ": "; - hdrs += (*i).second; - } + hdrs += (*i).first; + hdrs += ": "; + hdrs += (*i).second; hdrs += "\r\n"; } } if(get_client_handler()->get_should_close_after_write()) { hdrs += "Connection: close\r\n"; } + hdrs += "Via: "; + hdrs += via_value; + if(!via_value.empty()) { + hdrs += ", "; + } + hdrs += http::create_via_header_value + (downstream->get_response_major(), downstream->get_response_minor()); + hdrs += "\r\n"; hdrs += "\r\n"; if(ENABLE_LOG) { LOG(INFO) << "Upstream https response headers\n" << hdrs; diff --git a/examples/shrpx_spdy_upstream.cc b/examples/shrpx_spdy_upstream.cc index 7ac4f273..5d6e8659 100644 --- a/examples/shrpx_spdy_upstream.cc +++ b/examples/shrpx_spdy_upstream.cc @@ -499,9 +499,6 @@ int SpdyUpstream::on_downstream_header_complete(Downstream *downstream) util::strieq((*i).first.c_str(), "connection") || util:: strieq((*i).first.c_str(), "proxy-connection")) { // These are ignored - } else if(util::strieq((*i).first.c_str(), "server")) { - nv[hdidx++] = "server"; - nv[hdidx++] = get_config()->server_name; } else { nv[hdidx++] = (*i).first.c_str(); nv[hdidx++] = (*i).second.c_str();