Merge branch 'nghttpx-xfp-take2'
This commit is contained in:
commit
e61ac4682e
|
@ -164,6 +164,8 @@ OPTIONS = [
|
||||||
"frontend-max-requests",
|
"frontend-max-requests",
|
||||||
"single-thread",
|
"single-thread",
|
||||||
"single-process",
|
"single-process",
|
||||||
|
"no-add-x-forwarded-proto",
|
||||||
|
"no-strip-incoming-x-forwarded-proto",
|
||||||
]
|
]
|
||||||
|
|
||||||
LOGVARS = [
|
LOGVARS = [
|
||||||
|
|
|
@ -35,6 +35,105 @@ func TestH2H1PlainGET(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestH2H1AddXfp tests that server appends :scheme to the existing
|
||||||
|
// x-forwarded-proto header field.
|
||||||
|
func TestH2H1AddXfp(t *testing.T) {
|
||||||
|
st := newServerTester([]string{"--no-strip-incoming-x-forwarded-proto"}, t, func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
xfp := r.Header.Get("X-Forwarded-Proto")
|
||||||
|
if got, want := xfp, "foo, http"; got != want {
|
||||||
|
t.Errorf("X-Forwarded-Proto = %q; want %q", got, want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
defer st.Close()
|
||||||
|
|
||||||
|
res, err := st.http2(requestParam{
|
||||||
|
name: "TestH2H1AddXfp",
|
||||||
|
header: []hpack.HeaderField{
|
||||||
|
pair("x-forwarded-proto", "foo"),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error st.http2() = %v", err)
|
||||||
|
}
|
||||||
|
if got, want := res.status, 200; got != want {
|
||||||
|
t.Errorf("status = %v; want %v", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestH2H1NoAddXfp tests that server does not append :scheme to the
|
||||||
|
// existing x-forwarded-proto header field.
|
||||||
|
func TestH2H1NoAddXfp(t *testing.T) {
|
||||||
|
st := newServerTester([]string{"--no-add-x-forwarded-proto", "--no-strip-incoming-x-forwarded-proto"}, t, func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
xfp := r.Header.Get("X-Forwarded-Proto")
|
||||||
|
if got, want := xfp, "foo"; got != want {
|
||||||
|
t.Errorf("X-Forwarded-Proto = %q; want %q", got, want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
defer st.Close()
|
||||||
|
|
||||||
|
res, err := st.http2(requestParam{
|
||||||
|
name: "TestH2H1NoAddXfp",
|
||||||
|
header: []hpack.HeaderField{
|
||||||
|
pair("x-forwarded-proto", "foo"),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error st.http2() = %v", err)
|
||||||
|
}
|
||||||
|
if got, want := res.status, 200; got != want {
|
||||||
|
t.Errorf("status = %v; want %v", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestH2H1StripXfp tests that server strips incoming
|
||||||
|
// x-forwarded-proto header field.
|
||||||
|
func TestH2H1StripXfp(t *testing.T) {
|
||||||
|
st := newServerTester(nil, t, func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
xfp := r.Header.Get("X-Forwarded-Proto")
|
||||||
|
if got, want := xfp, "http"; got != want {
|
||||||
|
t.Errorf("X-Forwarded-Proto = %q; want %q", got, want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
defer st.Close()
|
||||||
|
|
||||||
|
res, err := st.http2(requestParam{
|
||||||
|
name: "TestH2H1StripXfp",
|
||||||
|
header: []hpack.HeaderField{
|
||||||
|
pair("x-forwarded-proto", "foo"),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error st.http2() = %v", err)
|
||||||
|
}
|
||||||
|
if got, want := res.status, 200; got != want {
|
||||||
|
t.Errorf("status = %v; want %v", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestH2H1StripNoAddXfp tests that server strips incoming
|
||||||
|
// x-forwarded-proto header field, and does not add another.
|
||||||
|
func TestH2H1StripNoAddXfp(t *testing.T) {
|
||||||
|
st := newServerTester([]string{"--no-add-x-forwarded-proto"}, t, func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if got, found := r.Header["X-Forwarded-Proto"]; found {
|
||||||
|
t.Errorf("X-Forwarded-Proto = %q; want nothing", got)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
defer st.Close()
|
||||||
|
|
||||||
|
res, err := st.http2(requestParam{
|
||||||
|
name: "TestH2H1StripNoAddXfp",
|
||||||
|
header: []hpack.HeaderField{
|
||||||
|
pair("x-forwarded-proto", "foo"),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error st.http2() = %v", err)
|
||||||
|
}
|
||||||
|
if got, want := res.status, 200; got != want {
|
||||||
|
t.Errorf("status = %v; want %v", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TestH2H1AddXff tests that server generates X-Forwarded-For header
|
// TestH2H1AddXff tests that server generates X-Forwarded-For header
|
||||||
// field when forwarding request to backend.
|
// field when forwarding request to backend.
|
||||||
func TestH2H1AddXff(t *testing.T) {
|
func TestH2H1AddXff(t *testing.T) {
|
||||||
|
@ -1773,6 +1872,105 @@ func TestH2H2TLSXfp(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestH2H2AddXfp tests that server appends :scheme to the existing
|
||||||
|
// x-forwarded-proto header field.
|
||||||
|
func TestH2H2AddXfp(t *testing.T) {
|
||||||
|
st := newServerTesterTLS([]string{"--http2-bridge", "--no-strip-incoming-x-forwarded-proto"}, t, func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
xfp := r.Header.Get("X-Forwarded-Proto")
|
||||||
|
if got, want := xfp, "foo, http"; got != want {
|
||||||
|
t.Errorf("X-Forwarded-Proto = %q; want %q", got, want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
defer st.Close()
|
||||||
|
|
||||||
|
res, err := st.http2(requestParam{
|
||||||
|
name: "TestH2H2AddXfp",
|
||||||
|
header: []hpack.HeaderField{
|
||||||
|
pair("x-forwarded-proto", "foo"),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error st.http2() = %v", err)
|
||||||
|
}
|
||||||
|
if got, want := res.status, 200; got != want {
|
||||||
|
t.Errorf("status = %v; want %v", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestH2H2NoAddXfp tests that server does not append :scheme to the
|
||||||
|
// existing x-forwarded-proto header field.
|
||||||
|
func TestH2H2NoAddXfp(t *testing.T) {
|
||||||
|
st := newServerTesterTLS([]string{"--http2-bridge", "--no-add-x-forwarded-proto", "--no-strip-incoming-x-forwarded-proto"}, t, func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
xfp := r.Header.Get("X-Forwarded-Proto")
|
||||||
|
if got, want := xfp, "foo"; got != want {
|
||||||
|
t.Errorf("X-Forwarded-Proto = %q; want %q", got, want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
defer st.Close()
|
||||||
|
|
||||||
|
res, err := st.http2(requestParam{
|
||||||
|
name: "TestH2H2NoAddXfp",
|
||||||
|
header: []hpack.HeaderField{
|
||||||
|
pair("x-forwarded-proto", "foo"),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error st.http2() = %v", err)
|
||||||
|
}
|
||||||
|
if got, want := res.status, 200; got != want {
|
||||||
|
t.Errorf("status = %v; want %v", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestH2H2StripXfp tests that server strips incoming
|
||||||
|
// x-forwarded-proto header field.
|
||||||
|
func TestH2H2StripXfp(t *testing.T) {
|
||||||
|
st := newServerTesterTLS([]string{"--http2-bridge"}, t, func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
xfp := r.Header.Get("X-Forwarded-Proto")
|
||||||
|
if got, want := xfp, "http"; got != want {
|
||||||
|
t.Errorf("X-Forwarded-Proto = %q; want %q", got, want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
defer st.Close()
|
||||||
|
|
||||||
|
res, err := st.http2(requestParam{
|
||||||
|
name: "TestH2H2StripXfp",
|
||||||
|
header: []hpack.HeaderField{
|
||||||
|
pair("x-forwarded-proto", "foo"),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error st.http2() = %v", err)
|
||||||
|
}
|
||||||
|
if got, want := res.status, 200; got != want {
|
||||||
|
t.Errorf("status = %v; want %v", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestH2H2StripNoAddXfp tests that server strips incoming
|
||||||
|
// x-forwarded-proto header field, and does not add another.
|
||||||
|
func TestH2H2StripNoAddXfp(t *testing.T) {
|
||||||
|
st := newServerTesterTLS([]string{"--http2-bridge", "--no-add-x-forwarded-proto"}, t, func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if got, found := r.Header["X-Forwarded-Proto"]; found {
|
||||||
|
t.Errorf("X-Forwarded-Proto = %q; want nothing", got)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
defer st.Close()
|
||||||
|
|
||||||
|
res, err := st.http2(requestParam{
|
||||||
|
name: "TestH2H2StripNoAddXfp",
|
||||||
|
header: []hpack.HeaderField{
|
||||||
|
pair("x-forwarded-proto", "foo"),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error st.http2() = %v", err)
|
||||||
|
}
|
||||||
|
if got, want := res.status, 200; got != want {
|
||||||
|
t.Errorf("status = %v; want %v", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TestH2H2AddXff tests that server generates X-Forwarded-For header
|
// TestH2H2AddXff tests that server generates X-Forwarded-For header
|
||||||
// field when forwarding request to backend.
|
// field when forwarding request to backend.
|
||||||
func TestH2H2AddXff(t *testing.T) {
|
func TestH2H2AddXff(t *testing.T) {
|
||||||
|
|
24
src/shrpx.cc
24
src/shrpx.cc
|
@ -1478,6 +1478,8 @@ void fill_default_config(Config *config) {
|
||||||
httpconf.max_response_header_fields = 500;
|
httpconf.max_response_header_fields = 500;
|
||||||
httpconf.redirect_https_port = StringRef::from_lit("443");
|
httpconf.redirect_https_port = StringRef::from_lit("443");
|
||||||
httpconf.max_requests = std::numeric_limits<size_t>::max();
|
httpconf.max_requests = std::numeric_limits<size_t>::max();
|
||||||
|
httpconf.xfp.add = true;
|
||||||
|
httpconf.xfp.strip_incoming = true;
|
||||||
|
|
||||||
auto &http2conf = config->http2;
|
auto &http2conf = config->http2;
|
||||||
{
|
{
|
||||||
|
@ -2485,6 +2487,15 @@ HTTP:
|
||||||
--strip-incoming-x-forwarded-for
|
--strip-incoming-x-forwarded-for
|
||||||
Strip X-Forwarded-For header field from inbound client
|
Strip X-Forwarded-For header field from inbound client
|
||||||
requests.
|
requests.
|
||||||
|
--no-add-x-forwarded-proto
|
||||||
|
Don't append additional X-Forwarded-Proto header field
|
||||||
|
to the backend request. If inbound client sets
|
||||||
|
X-Forwarded-Proto, and
|
||||||
|
--no-strip-incoming-x-forwarded-proto option is used,
|
||||||
|
they are passed to the backend.
|
||||||
|
--no-strip-incoming-x-forwarded-proto
|
||||||
|
Don't strip X-Forwarded-Proto header field from inbound
|
||||||
|
client requests.
|
||||||
--add-forwarded=<LIST>
|
--add-forwarded=<LIST>
|
||||||
Append RFC 7239 Forwarded header field with parameters
|
Append RFC 7239 Forwarded header field with parameters
|
||||||
specified in comma delimited list <LIST>. The supported
|
specified in comma delimited list <LIST>. The supported
|
||||||
|
@ -3327,6 +3338,9 @@ int main(int argc, char **argv) {
|
||||||
{SHRPX_OPT_FRONTEND_MAX_REQUESTS.c_str(), required_argument, &flag,
|
{SHRPX_OPT_FRONTEND_MAX_REQUESTS.c_str(), required_argument, &flag,
|
||||||
155},
|
155},
|
||||||
{SHRPX_OPT_SINGLE_THREAD.c_str(), no_argument, &flag, 156},
|
{SHRPX_OPT_SINGLE_THREAD.c_str(), no_argument, &flag, 156},
|
||||||
|
{SHRPX_OPT_NO_ADD_X_FORWARDED_PROTO.c_str(), no_argument, &flag, 157},
|
||||||
|
{SHRPX_OPT_NO_STRIP_INCOMING_X_FORWARDED_PROTO.c_str(), no_argument,
|
||||||
|
&flag, 158},
|
||||||
{SHRPX_OPT_SINGLE_PROCESS.c_str(), no_argument, &flag, 159},
|
{SHRPX_OPT_SINGLE_PROCESS.c_str(), no_argument, &flag, 159},
|
||||||
{nullptr, 0, nullptr, 0}};
|
{nullptr, 0, nullptr, 0}};
|
||||||
|
|
||||||
|
@ -4064,6 +4078,16 @@ int main(int argc, char **argv) {
|
||||||
cmdcfgs.emplace_back(SHRPX_OPT_SINGLE_THREAD,
|
cmdcfgs.emplace_back(SHRPX_OPT_SINGLE_THREAD,
|
||||||
StringRef::from_lit("yes"));
|
StringRef::from_lit("yes"));
|
||||||
break;
|
break;
|
||||||
|
case 157:
|
||||||
|
// --no-add-x-forwarded-proto
|
||||||
|
cmdcfgs.emplace_back(SHRPX_OPT_NO_ADD_X_FORWARDED_PROTO,
|
||||||
|
StringRef::from_lit("yes"));
|
||||||
|
break;
|
||||||
|
case 158:
|
||||||
|
// --no-strip-incoming-x-forwarded-proto
|
||||||
|
cmdcfgs.emplace_back(SHRPX_OPT_NO_STRIP_INCOMING_X_FORWARDED_PROTO,
|
||||||
|
StringRef::from_lit("yes"));
|
||||||
|
break;
|
||||||
case 159:
|
case 159:
|
||||||
// --single-process
|
// --single-process
|
||||||
cmdcfgs.emplace_back(SHRPX_OPT_SINGLE_PROCESS,
|
cmdcfgs.emplace_back(SHRPX_OPT_SINGLE_PROCESS,
|
||||||
|
|
|
@ -1905,6 +1905,11 @@ int option_lookup_token(const char *name, size_t namelen) {
|
||||||
return SHRPX_OPTID_FETCH_OCSP_RESPONSE_FILE;
|
return SHRPX_OPTID_FETCH_OCSP_RESPONSE_FILE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'o':
|
||||||
|
if (util::strieq_l("no-add-x-forwarded-prot", name, 23)) {
|
||||||
|
return SHRPX_OPTID_NO_ADD_X_FORWARDED_PROTO;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
if (util::strieq_l("listener-disable-timeou", name, 23)) {
|
if (util::strieq_l("listener-disable-timeou", name, 23)) {
|
||||||
return SHRPX_OPTID_LISTENER_DISABLE_TIMEOUT;
|
return SHRPX_OPTID_LISTENER_DISABLE_TIMEOUT;
|
||||||
|
@ -2101,6 +2106,11 @@ int option_lookup_token(const char *name, size_t namelen) {
|
||||||
return SHRPX_OPTID_FRONTEND_HTTP2_OPTIMIZE_WINDOW_SIZE;
|
return SHRPX_OPTID_FRONTEND_HTTP2_OPTIMIZE_WINDOW_SIZE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'o':
|
||||||
|
if (util::strieq_l("no-strip-incoming-x-forwarded-prot", name, 34)) {
|
||||||
|
return SHRPX_OPTID_NO_STRIP_INCOMING_X_FORWARDED_PROTO;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
if (util::strieq_l("frontend-http2-dump-response-heade", name, 34)) {
|
if (util::strieq_l("frontend-http2-dump-response-heade", name, 34)) {
|
||||||
return SHRPX_OPTID_FRONTEND_HTTP2_DUMP_RESPONSE_HEADER;
|
return SHRPX_OPTID_FRONTEND_HTTP2_DUMP_RESPONSE_HEADER;
|
||||||
|
@ -3363,6 +3373,14 @@ int parse_config(Config *config, int optid, const StringRef &opt,
|
||||||
case SHRPX_OPTID_SINGLE_PROCESS:
|
case SHRPX_OPTID_SINGLE_PROCESS:
|
||||||
config->single_process = util::strieq_l("yes", optarg);
|
config->single_process = util::strieq_l("yes", optarg);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
case SHRPX_OPTID_NO_ADD_X_FORWARDED_PROTO:
|
||||||
|
config->http.xfp.add = !util::strieq_l("yes", optarg);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
case SHRPX_OPTID_NO_STRIP_INCOMING_X_FORWARDED_PROTO:
|
||||||
|
config->http.xfp.strip_incoming = !util::strieq_l("yes", optarg);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
case SHRPX_OPTID_CONF:
|
case SHRPX_OPTID_CONF:
|
||||||
LOG(WARN) << "conf: ignored";
|
LOG(WARN) << "conf: ignored";
|
||||||
|
|
|
@ -337,6 +337,10 @@ constexpr auto SHRPX_OPT_FRONTEND_MAX_REQUESTS =
|
||||||
StringRef::from_lit("frontend-max-requests");
|
StringRef::from_lit("frontend-max-requests");
|
||||||
constexpr auto SHRPX_OPT_SINGLE_THREAD = StringRef::from_lit("single-thread");
|
constexpr auto SHRPX_OPT_SINGLE_THREAD = StringRef::from_lit("single-thread");
|
||||||
constexpr auto SHRPX_OPT_SINGLE_PROCESS = StringRef::from_lit("single-process");
|
constexpr auto SHRPX_OPT_SINGLE_PROCESS = StringRef::from_lit("single-process");
|
||||||
|
constexpr auto SHRPX_OPT_NO_ADD_X_FORWARDED_PROTO =
|
||||||
|
StringRef::from_lit("no-add-x-forwarded-proto");
|
||||||
|
constexpr auto SHRPX_OPT_NO_STRIP_INCOMING_X_FORWARDED_PROTO =
|
||||||
|
StringRef::from_lit("no-strip-incoming-x-forwarded-proto");
|
||||||
|
|
||||||
constexpr size_t SHRPX_OBFUSCATED_NODE_LENGTH = 8;
|
constexpr size_t SHRPX_OBFUSCATED_NODE_LENGTH = 8;
|
||||||
|
|
||||||
|
@ -639,6 +643,10 @@ struct HttpConfig {
|
||||||
bool add;
|
bool add;
|
||||||
bool strip_incoming;
|
bool strip_incoming;
|
||||||
} xff;
|
} xff;
|
||||||
|
struct {
|
||||||
|
bool add;
|
||||||
|
bool strip_incoming;
|
||||||
|
} xfp;
|
||||||
std::vector<AltSvc> altsvcs;
|
std::vector<AltSvc> altsvcs;
|
||||||
std::vector<ErrorPage> error_pages;
|
std::vector<ErrorPage> error_pages;
|
||||||
HeaderRefs add_request_headers;
|
HeaderRefs add_request_headers;
|
||||||
|
@ -1023,6 +1031,7 @@ enum {
|
||||||
SHRPX_OPTID_MAX_REQUEST_HEADER_FIELDS,
|
SHRPX_OPTID_MAX_REQUEST_HEADER_FIELDS,
|
||||||
SHRPX_OPTID_MAX_RESPONSE_HEADER_FIELDS,
|
SHRPX_OPTID_MAX_RESPONSE_HEADER_FIELDS,
|
||||||
SHRPX_OPTID_MRUBY_FILE,
|
SHRPX_OPTID_MRUBY_FILE,
|
||||||
|
SHRPX_OPTID_NO_ADD_X_FORWARDED_PROTO,
|
||||||
SHRPX_OPTID_NO_HOST_REWRITE,
|
SHRPX_OPTID_NO_HOST_REWRITE,
|
||||||
SHRPX_OPTID_NO_HTTP2_CIPHER_BLACK_LIST,
|
SHRPX_OPTID_NO_HTTP2_CIPHER_BLACK_LIST,
|
||||||
SHRPX_OPTID_NO_KQUEUE,
|
SHRPX_OPTID_NO_KQUEUE,
|
||||||
|
@ -1030,6 +1039,7 @@ enum {
|
||||||
SHRPX_OPTID_NO_OCSP,
|
SHRPX_OPTID_NO_OCSP,
|
||||||
SHRPX_OPTID_NO_SERVER_PUSH,
|
SHRPX_OPTID_NO_SERVER_PUSH,
|
||||||
SHRPX_OPTID_NO_SERVER_REWRITE,
|
SHRPX_OPTID_NO_SERVER_REWRITE,
|
||||||
|
SHRPX_OPTID_NO_STRIP_INCOMING_X_FORWARDED_PROTO,
|
||||||
SHRPX_OPTID_NO_VIA,
|
SHRPX_OPTID_NO_VIA,
|
||||||
SHRPX_OPTID_NPN_LIST,
|
SHRPX_OPTID_NPN_LIST,
|
||||||
SHRPX_OPTID_OCSP_UPDATE_INTERVAL,
|
SHRPX_OPTID_OCSP_UPDATE_INTERVAL,
|
||||||
|
|
|
@ -371,8 +371,24 @@ int Http2DownstreamConnection::push_request_headers() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!config->http2_proxy && req.method != HTTP_CONNECT) {
|
if (!config->http2_proxy && req.method != HTTP_CONNECT) {
|
||||||
|
auto &xfpconf = httpconf.xfp;
|
||||||
|
auto xfp = xfpconf.strip_incoming
|
||||||
|
? nullptr
|
||||||
|
: req.fs.header(http2::HD_X_FORWARDED_PROTO);
|
||||||
|
|
||||||
|
if (xfpconf.add) {
|
||||||
|
StringRef xfp_value;
|
||||||
// We use same protocol with :scheme header field
|
// We use same protocol with :scheme header field
|
||||||
nva.push_back(http2::make_nv_ls_nocopy("x-forwarded-proto", req.scheme));
|
if (xfp) {
|
||||||
|
xfp_value = concat_string_ref(balloc, xfp->value,
|
||||||
|
StringRef::from_lit(", "), req.scheme);
|
||||||
|
} else {
|
||||||
|
xfp_value = req.scheme;
|
||||||
|
}
|
||||||
|
nva.push_back(http2::make_nv_ls_nocopy("x-forwarded-proto", xfp_value));
|
||||||
|
} else if (xfp) {
|
||||||
|
nva.push_back(http2::make_nv_ls_nocopy("x-forwarded-proto", xfp->value));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto via = req.fs.header(http2::HD_VIA);
|
auto via = req.fs.header(http2::HD_VIA);
|
||||||
|
|
|
@ -630,10 +630,25 @@ int HttpDownstreamConnection::push_request_headers() {
|
||||||
buf->append("\r\n");
|
buf->append("\r\n");
|
||||||
}
|
}
|
||||||
if (!config->http2_proxy && !connect_method) {
|
if (!config->http2_proxy && !connect_method) {
|
||||||
|
auto &xfpconf = httpconf.xfp;
|
||||||
|
auto xfp = xfpconf.strip_incoming
|
||||||
|
? nullptr
|
||||||
|
: req.fs.header(http2::HD_X_FORWARDED_PROTO);
|
||||||
|
|
||||||
|
if (xfpconf.add) {
|
||||||
buf->append("X-Forwarded-Proto: ");
|
buf->append("X-Forwarded-Proto: ");
|
||||||
|
if (xfp) {
|
||||||
|
buf->append((*xfp).value);
|
||||||
|
buf->append(", ");
|
||||||
|
}
|
||||||
assert(!req.scheme.empty());
|
assert(!req.scheme.empty());
|
||||||
buf->append(req.scheme);
|
buf->append(req.scheme);
|
||||||
buf->append("\r\n");
|
buf->append("\r\n");
|
||||||
|
} else if (xfp) {
|
||||||
|
buf->append("X-Forwarded-Proto: ");
|
||||||
|
buf->append((*xfp).value);
|
||||||
|
buf->append("\r\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
auto via = req.fs.header(http2::HD_VIA);
|
auto via = req.fs.header(http2::HD_VIA);
|
||||||
if (httpconf.no_via) {
|
if (httpconf.no_via) {
|
||||||
|
|
Loading…
Reference in New Issue