diff --git a/src/shrpx.cc b/src/shrpx.cc index 54f92ef1..4af6f387 100644 --- a/src/shrpx.cc +++ b/src/shrpx.cc @@ -1350,6 +1350,12 @@ HTTP: HTTP/1.1 frontend. This option can be used multiple times to specify multiple alternative services. Example: --altsvc=h2,443 + --add-request-header=
+ Specify additional header field to add to request header + set. This option just appends header field and won't + replace anything already set. This option can be used + several times to specify multiple header fields. + Example: --add-request-header="foo: bar" --add-response-header=
Specify additional header field to add to response header set. This option just appends header field and @@ -1544,6 +1550,7 @@ int main(int argc, char **argv) { {SHRPX_OPT_NO_OCSP, no_argument, &flag, 79}, {SHRPX_OPT_HEADER_FIELD_BUFFER, required_argument, &flag, 80}, {SHRPX_OPT_MAX_HEADER_FIELDS, required_argument, &flag, 81}, + {SHRPX_OPT_ADD_REQUEST_HEADER, required_argument, &flag, 82}, {nullptr, 0, nullptr, 0}}; int option_index = 0; @@ -1902,6 +1909,10 @@ int main(int argc, char **argv) { // --max-header-fields cmdcfgs.emplace_back(SHRPX_OPT_MAX_HEADER_FIELDS, optarg); break; + case 82: + // --add-request-header + cmdcfgs.emplace_back(SHRPX_OPT_ADD_REQUEST_HEADER, optarg); + break; default: break; } diff --git a/src/shrpx_config.cc b/src/shrpx_config.cc index 95d995d2..b9fb36dd 100644 --- a/src/shrpx_config.cc +++ b/src/shrpx_config.cc @@ -997,14 +997,18 @@ int parse_config(const char *opt, const char *optarg) { return 0; } - if (util::strieq(opt, SHRPX_OPT_ADD_RESPONSE_HEADER)) { + if (util::strieq(opt, SHRPX_OPT_ADD_REQUEST_HEADER) || + util::strieq(opt, SHRPX_OPT_ADD_RESPONSE_HEADER)) { auto p = parse_header(optarg); if (p.first.empty()) { LOG(ERROR) << opt << ": header field name is empty: " << optarg; return -1; } - mod_config()->add_response_headers.push_back(std::move(p)); - + if (util::strieq(opt, SHRPX_OPT_ADD_REQUEST_HEADER)) { + mod_config()->add_request_headers.push_back(std::move(p)); + } else { + mod_config()->add_response_headers.push_back(std::move(p)); + } return 0; } diff --git a/src/shrpx_config.h b/src/shrpx_config.h index 6ae5546b..c50ab64b 100644 --- a/src/shrpx_config.h +++ b/src/shrpx_config.h @@ -140,6 +140,7 @@ constexpr char SHRPX_OPT_HTTP2_NO_COOKIE_CRUMBLING[] = constexpr char SHRPX_OPT_FRONTEND_FRAME_DEBUG[] = "frontend-frame-debug"; constexpr char SHRPX_OPT_PADDING[] = "padding"; constexpr char SHRPX_OPT_ALTSVC[] = "altsvc"; +constexpr char SHRPX_OPT_ADD_REQUEST_HEADER[] = "add-request-header"; constexpr char SHRPX_OPT_ADD_RESPONSE_HEADER[] = "add-response-header"; constexpr char SHRPX_OPT_WORKER_FRONTEND_CONNECTIONS[] = "worker-frontend-connections"; @@ -220,6 +221,7 @@ struct Config { // The list of (private key file, certificate file) pair std::vector> subcerts; std::vector altsvcs; + std::vector> add_request_headers; std::vector> add_response_headers; std::vector alpn_prefs; std::vector accesslog_format; diff --git a/src/shrpx_http2_downstream_connection.cc b/src/shrpx_http2_downstream_connection.cc index 41417a8b..d4a4b090 100644 --- a/src/shrpx_http2_downstream_connection.cc +++ b/src/shrpx_http2_downstream_connection.cc @@ -313,7 +313,8 @@ int Http2DownstreamConnection::push_request_headers() { // 7. x-forwarded-proto (optional) // 8. te (optional) auto nva = std::vector(); - nva.reserve(nheader + 8 + cookies.size()); + nva.reserve(nheader + 8 + cookies.size() + + get_config()->add_request_headers.size()); std::string via_value; std::string xff_value; @@ -411,6 +412,10 @@ int Http2DownstreamConnection::push_request_headers() { nva.push_back(http2::make_nv_ll("te", "trailers")); } + for (auto &p : get_config()->add_request_headers) { + nva.push_back(http2::make_nv(p.first, p.second)); + } + if (LOG_ENABLED(INFO)) { std::stringstream ss; for (auto &nv : nva) { diff --git a/src/shrpx_http_downstream_connection.cc b/src/shrpx_http_downstream_connection.cc index faf1d0a6..930edff6 100644 --- a/src/shrpx_http_downstream_connection.cc +++ b/src/shrpx_http_downstream_connection.cc @@ -366,6 +366,13 @@ int HttpDownstreamConnection::push_request_headers() { hdrs += "\r\n"; } + for (auto &p : get_config()->add_request_headers) { + hdrs += p.first; + hdrs += ": "; + hdrs += p.second; + hdrs += "\r\n"; + } + hdrs += "\r\n"; if (LOG_ENABLED(INFO)) { const char *hdrp;