diff --git a/src/http2.cc b/src/http2.cc index eb87f2e7..a516f97a 100644 --- a/src/http2.cc +++ b/src/http2.cc @@ -193,6 +193,7 @@ const char *IGN_HD[] = { "http2-settings", "keep-alive", "proxy-connection", + "server", "te", "transfer-encoding", "upgrade", @@ -213,6 +214,7 @@ const char *HTTP1_IGN_HD[] = { "http2-settings", "keep-alive", "proxy-connection", + "server", "upgrade", "via", "x-forwarded-for", diff --git a/src/shrpx_http2_upstream.cc b/src/shrpx_http2_upstream.cc index c0e0ff1c..e9a03e6b 100644 --- a/src/shrpx_http2_upstream.cc +++ b/src/shrpx_http2_upstream.cc @@ -1183,8 +1183,8 @@ int Http2Upstream::on_downstream_header_complete(Downstream *downstream) auto end_headers = std::end(downstream->get_response_headers()); size_t nheader = downstream->get_response_headers().size(); auto nva = std::vector(); - // 2 means :status and possible via header field. - nva.reserve(nheader + 2 + get_config()->add_response_headers.size()); + // 3 means :status and possible server and via header field. + nva.reserve(nheader + 3 + get_config()->add_response_headers.size()); std::string via_value; auto response_status = util::utos(downstream->get_response_http_status()); nva.push_back(http2::make_nv_ls(":status", response_status)); @@ -1210,6 +1210,15 @@ int Http2Upstream::on_downstream_header_complete(Downstream *downstream) return 0; } + if(!get_config()->http2_proxy && !get_config()->client_proxy) { + nva.push_back(http2::make_nv_lc("server", get_config()->server_name)); + } else { + auto server = downstream->get_norm_response_header("server"); + if(server != end_headers) { + nva.push_back(http2::make_nv_ls("server", (*server).value)); + } + } + auto via = downstream->get_norm_response_header("via"); if(get_config()->no_via) { if(via != end_headers) { diff --git a/src/shrpx_https_upstream.cc b/src/shrpx_https_upstream.cc index 8a5d2423..68651ecb 100644 --- a/src/shrpx_https_upstream.cc +++ b/src/shrpx_https_upstream.cc @@ -823,6 +823,19 @@ int HttpsUpstream::on_downstream_header_complete(Downstream *downstream) } } + if(!get_config()->http2_proxy && !get_config()->client_proxy) { + hdrs += "Server: "; + hdrs += get_config()->server_name; + hdrs += "\r\n"; + } else { + auto server = downstream->get_norm_response_header("server"); + if(server != end_headers) { + hdrs += "Server: "; + hdrs += (*server).value; + hdrs += "\r\n"; + } + } + auto via = downstream->get_norm_response_header("via"); if(get_config()->no_via) { if(via != end_headers) { diff --git a/src/shrpx_spdy_upstream.cc b/src/shrpx_spdy_upstream.cc index 690a79c6..a88aab02 100644 --- a/src/shrpx_spdy_upstream.cc +++ b/src/shrpx_spdy_upstream.cc @@ -917,9 +917,9 @@ int SpdyUpstream::on_downstream_header_complete(Downstream *downstream) (get_client_handler()->get_upstream_scheme(), get_config()->port); } size_t nheader = downstream->get_response_headers().size(); - // 6 means :status, :version and possible via header field. + // 8 means server, :status, :version and possible via header field. auto nv = util::make_unique - (nheader * 2 + 6 + get_config()->add_response_headers.size() * 2 + 1); + (nheader * 2 + 8 + get_config()->add_response_headers.size() * 2 + 1); size_t hdidx = 0; std::string via_value; @@ -939,11 +939,20 @@ int SpdyUpstream::on_downstream_header_complete(Downstream *downstream) } else if(!get_config()->no_via && util::strieq(hd.name.c_str(), "via")) { via_value = hd.value; + } else if(!get_config()->http2_proxy && !get_config()->client_proxy && + util::strieq(hd.name.c_str(), "server")) { + // Rewrite server header field later } else { nv[hdidx++] = hd.name.c_str(); nv[hdidx++] = hd.value.c_str(); } } + + if(!get_config()->http2_proxy && !get_config()->client_proxy) { + nv[hdidx++] = "server"; + nv[hdidx++] = get_config()->server_name; + } + if(!get_config()->no_via) { if(!via_value.empty()) { via_value += ", ";