nghttpx: Structured configurations for http and http2
This commit is contained in:
parent
f3e1dc7a4f
commit
16549bb276
177
src/shrpx.cc
177
src/shrpx.cc
|
@ -900,7 +900,6 @@ void fill_default_config() {
|
||||||
mod_config()->verbose = false;
|
mod_config()->verbose = false;
|
||||||
mod_config()->daemon = false;
|
mod_config()->daemon = false;
|
||||||
|
|
||||||
mod_config()->server_name = "nghttpx nghttp2/" NGHTTP2_VERSION;
|
|
||||||
mod_config()->host = strcopy("*");
|
mod_config()->host = strcopy("*");
|
||||||
mod_config()->port = 3000;
|
mod_config()->port = 3000;
|
||||||
|
|
||||||
|
@ -926,25 +925,10 @@ void fill_default_config() {
|
||||||
// Timeout for pooled (idle) connections
|
// Timeout for pooled (idle) connections
|
||||||
mod_config()->downstream_idle_read_timeout = 2.;
|
mod_config()->downstream_idle_read_timeout = 2.;
|
||||||
|
|
||||||
// window bits for HTTP/2 and SPDY upstream/downstream connection
|
|
||||||
// per stream. 2**16-1 = 64KiB-1, which is HTTP/2 default. Please
|
|
||||||
// note that SPDY/3 default is 64KiB.
|
|
||||||
mod_config()->http2_upstream_window_bits = 16;
|
|
||||||
mod_config()->http2_downstream_window_bits = 16;
|
|
||||||
|
|
||||||
// HTTP/2 SPDY/3.1 has connection-level flow control. The default
|
|
||||||
// window size for HTTP/2 is 64KiB - 1. SPDY/3's default is 64KiB
|
|
||||||
mod_config()->http2_upstream_connection_window_bits = 16;
|
|
||||||
mod_config()->http2_downstream_connection_window_bits = 16;
|
|
||||||
|
|
||||||
mod_config()->upstream_no_tls = false;
|
mod_config()->upstream_no_tls = false;
|
||||||
mod_config()->downstream_no_tls = false;
|
mod_config()->downstream_no_tls = false;
|
||||||
|
|
||||||
mod_config()->num_worker = 1;
|
mod_config()->num_worker = 1;
|
||||||
mod_config()->http2_max_concurrent_streams = 100;
|
|
||||||
mod_config()->add_x_forwarded_for = false;
|
|
||||||
mod_config()->strip_incoming_x_forwarded_for = false;
|
|
||||||
mod_config()->no_via = false;
|
|
||||||
mod_config()->accesslog_file = nullptr;
|
mod_config()->accesslog_file = nullptr;
|
||||||
mod_config()->accesslog_syslog = false;
|
mod_config()->accesslog_syslog = false;
|
||||||
mod_config()->accesslog_format = parse_log_format(DEFAULT_ACCESSLOG_FORMAT);
|
mod_config()->accesslog_format = parse_log_format(DEFAULT_ACCESSLOG_FORMAT);
|
||||||
|
@ -966,7 +950,6 @@ void fill_default_config() {
|
||||||
mod_config()->pid = getpid();
|
mod_config()->pid = getpid();
|
||||||
mod_config()->backend_ipv4 = false;
|
mod_config()->backend_ipv4 = false;
|
||||||
mod_config()->backend_ipv6 = false;
|
mod_config()->backend_ipv6 = false;
|
||||||
mod_config()->downstream_http_proxy_port = 0;
|
|
||||||
mod_config()->read_rate = 0;
|
mod_config()->read_rate = 0;
|
||||||
mod_config()->read_burst = 0;
|
mod_config()->read_burst = 0;
|
||||||
mod_config()->write_rate = 0;
|
mod_config()->write_rate = 0;
|
||||||
|
@ -975,25 +958,9 @@ void fill_default_config() {
|
||||||
mod_config()->worker_read_burst = 0;
|
mod_config()->worker_read_burst = 0;
|
||||||
mod_config()->worker_write_rate = 0;
|
mod_config()->worker_write_rate = 0;
|
||||||
mod_config()->worker_write_burst = 0;
|
mod_config()->worker_write_burst = 0;
|
||||||
mod_config()->http2_upstream_dump_request_header = nullptr;
|
|
||||||
mod_config()->http2_upstream_dump_response_header = nullptr;
|
|
||||||
mod_config()->http2_no_cookie_crumbling = false;
|
|
||||||
mod_config()->upstream_frame_debug = false;
|
|
||||||
mod_config()->padding = 0;
|
mod_config()->padding = 0;
|
||||||
mod_config()->worker_frontend_connections = 0;
|
mod_config()->worker_frontend_connections = 0;
|
||||||
|
|
||||||
nghttp2_option_new(&mod_config()->http2_option);
|
|
||||||
nghttp2_option_set_no_auto_window_update(get_config()->http2_option, 1);
|
|
||||||
nghttp2_option_set_no_recv_client_magic(get_config()->http2_option, 1);
|
|
||||||
|
|
||||||
nghttp2_option_new(&mod_config()->http2_client_option);
|
|
||||||
nghttp2_option_set_no_auto_window_update(get_config()->http2_client_option,
|
|
||||||
1);
|
|
||||||
nghttp2_option_set_peer_max_concurrent_streams(
|
|
||||||
get_config()->http2_client_option, 100);
|
|
||||||
|
|
||||||
mod_config()->no_location_rewrite = false;
|
|
||||||
mod_config()->no_host_rewrite = true;
|
|
||||||
mod_config()->argc = 0;
|
mod_config()->argc = 0;
|
||||||
mod_config()->argv = nullptr;
|
mod_config()->argv = nullptr;
|
||||||
mod_config()->downstream_connections_per_host = 8;
|
mod_config()->downstream_connections_per_host = 8;
|
||||||
|
@ -1001,11 +968,7 @@ void fill_default_config() {
|
||||||
mod_config()->listener_disable_timeout = 0.;
|
mod_config()->listener_disable_timeout = 0.;
|
||||||
mod_config()->downstream_request_buffer_size = 16_k;
|
mod_config()->downstream_request_buffer_size = 16_k;
|
||||||
mod_config()->downstream_response_buffer_size = 16_k;
|
mod_config()->downstream_response_buffer_size = 16_k;
|
||||||
mod_config()->no_server_push = false;
|
|
||||||
mod_config()->host_unix = false;
|
mod_config()->host_unix = false;
|
||||||
mod_config()->http2_downstream_connections_per_worker = 0;
|
|
||||||
mod_config()->header_field_buffer = 64_k;
|
|
||||||
mod_config()->max_header_fields = 100;
|
|
||||||
mod_config()->downstream_addr_group_catch_all = 0;
|
mod_config()->downstream_addr_group_catch_all = 0;
|
||||||
mod_config()->fastopen = 0;
|
mod_config()->fastopen = 0;
|
||||||
|
|
||||||
|
@ -1040,12 +1003,57 @@ void fill_default_config() {
|
||||||
tlsconf.tls_proto_mask = 0;
|
tlsconf.tls_proto_mask = 0;
|
||||||
tlsconf.insecure = false;
|
tlsconf.insecure = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto &httpconf = mod_config()->http;
|
||||||
|
{
|
||||||
|
auto &xffconf = httpconf.xff;
|
||||||
|
xffconf.add = false;
|
||||||
|
xffconf.strip_incoming = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
httpconf.server_name = "nghttpx nghttp2/" NGHTTP2_VERSION;
|
||||||
|
httpconf.no_via = false;
|
||||||
|
httpconf.no_location_rewrite = false;
|
||||||
|
httpconf.no_host_rewrite = true;
|
||||||
|
httpconf.header_field_buffer = 64_k;
|
||||||
|
httpconf.max_header_fields = 100;
|
||||||
|
|
||||||
|
auto &http2conf = mod_config()->http2;
|
||||||
|
{
|
||||||
|
auto &upstreamconf = http2conf.upstream;
|
||||||
|
// window bits for HTTP/2 and SPDY upstream connection per
|
||||||
|
// stream. 2**16-1 = 64KiB-1, which is HTTP/2 default. Please note
|
||||||
|
// that SPDY/3 default is 64KiB.
|
||||||
|
upstreamconf.window_bits = 16;
|
||||||
|
// HTTP/2 SPDY/3.1 has connection-level flow control. The default
|
||||||
|
// window size for HTTP/2 is 64KiB - 1. SPDY/3's default is 64KiB
|
||||||
|
upstreamconf.connection_window_bits = 16;
|
||||||
|
|
||||||
|
nghttp2_option_new(&upstreamconf.option);
|
||||||
|
nghttp2_option_set_no_auto_window_update(upstreamconf.option, 1);
|
||||||
|
nghttp2_option_set_no_recv_client_magic(upstreamconf.option, 1);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto &downstreamconf = http2conf.downstream;
|
||||||
|
downstreamconf.window_bits = 16;
|
||||||
|
downstreamconf.connection_window_bits = 16;
|
||||||
|
downstreamconf.connections_per_worker = 0;
|
||||||
|
|
||||||
|
nghttp2_option_new(&downstreamconf.option);
|
||||||
|
nghttp2_option_set_no_auto_window_update(downstreamconf.option, 1);
|
||||||
|
nghttp2_option_set_peer_max_concurrent_streams(downstreamconf.option, 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
http2conf.max_concurrent_streams = 100;
|
||||||
|
http2conf.no_cookie_crumbling = false;
|
||||||
|
http2conf.no_server_push = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
void print_version(std::ostream &out) {
|
void print_version(std::ostream &out) {
|
||||||
out << get_config()->server_name.c_str() << std::endl;
|
out << get_config()->http.server_name.c_str() << std::endl;
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
@ -1450,29 +1458,29 @@ HTTP/2 and SPDY:
|
||||||
-c, --http2-max-concurrent-streams=<N>
|
-c, --http2-max-concurrent-streams=<N>
|
||||||
Set the maximum number of the concurrent streams in one
|
Set the maximum number of the concurrent streams in one
|
||||||
HTTP/2 and SPDY session.
|
HTTP/2 and SPDY session.
|
||||||
Default: )" << get_config()->http2_max_concurrent_streams << R"(
|
Default: )" << get_config()->http2.max_concurrent_streams << R"(
|
||||||
--frontend-http2-window-bits=<N>
|
--frontend-http2-window-bits=<N>
|
||||||
Sets the per-stream initial window size of HTTP/2 SPDY
|
Sets the per-stream initial window size of HTTP/2 SPDY
|
||||||
frontend connection. For HTTP/2, the size is 2**<N>-1.
|
frontend connection. For HTTP/2, the size is 2**<N>-1.
|
||||||
For SPDY, the size is 2**<N>.
|
For SPDY, the size is 2**<N>.
|
||||||
Default: )" << get_config()->http2_upstream_window_bits << R"(
|
Default: )" << get_config()->http2.upstream.window_bits << R"(
|
||||||
--frontend-http2-connection-window-bits=<N>
|
--frontend-http2-connection-window-bits=<N>
|
||||||
Sets the per-connection window size of HTTP/2 and SPDY
|
Sets the per-connection window size of HTTP/2 and SPDY
|
||||||
frontend connection. For HTTP/2, the size is
|
frontend connection. For HTTP/2, the size is
|
||||||
2**<N>-1. For SPDY, the size is 2**<N>.
|
2**<N>-1. For SPDY, the size is 2**<N>.
|
||||||
Default: )" << get_config()->http2_upstream_connection_window_bits
|
Default: )" << get_config()->http2.upstream.connection_window_bits
|
||||||
<< R"(
|
<< R"(
|
||||||
--frontend-no-tls
|
--frontend-no-tls
|
||||||
Disable SSL/TLS on frontend connections.
|
Disable SSL/TLS on frontend connections.
|
||||||
--backend-http2-window-bits=<N>
|
--backend-http2-window-bits=<N>
|
||||||
Sets the initial window size of HTTP/2 backend
|
Sets the initial window size of HTTP/2 backend
|
||||||
connection to 2**<N>-1.
|
connection to 2**<N>-1.
|
||||||
Default: )" << get_config()->http2_downstream_window_bits << R"(
|
Default: )" << get_config()->http2.downstream.window_bits << R"(
|
||||||
--backend-http2-connection-window-bits=<N>
|
--backend-http2-connection-window-bits=<N>
|
||||||
Sets the per-connection window size of HTTP/2 backend
|
Sets the per-connection window size of HTTP/2 backend
|
||||||
connection to 2**<N>-1.
|
connection to 2**<N>-1.
|
||||||
Default: )"
|
Default: )"
|
||||||
<< get_config()->http2_downstream_connection_window_bits << R"(
|
<< get_config()->http2.downstream.connection_window_bits << R"(
|
||||||
--backend-no-tls
|
--backend-no-tls
|
||||||
Disable SSL/TLS on backend connections.
|
Disable SSL/TLS on backend connections.
|
||||||
--http2-no-cookie-crumbling
|
--http2-no-cookie-crumbling
|
||||||
|
@ -1650,13 +1658,13 @@ HTTP:
|
||||||
Set maximum buffer size for incoming HTTP request header
|
Set maximum buffer size for incoming HTTP request header
|
||||||
field list. This is the sum of header name and value in
|
field list. This is the sum of header name and value in
|
||||||
bytes.
|
bytes.
|
||||||
Default: )" << util::utos_unit(get_config()->header_field_buffer)
|
Default: )"
|
||||||
<< R"(
|
<< util::utos_unit(get_config()->http.header_field_buffer) << R"(
|
||||||
--max-header-fields=<N>
|
--max-header-fields=<N>
|
||||||
Set maximum number of incoming HTTP request header
|
Set maximum number of incoming HTTP request header
|
||||||
fields, which appear in one request or response header
|
fields, which appear in one request or response header
|
||||||
field list.
|
field list.
|
||||||
Default: )" << get_config()->max_header_fields << R"(
|
Default: )" << get_config()->http.max_header_fields << R"(
|
||||||
|
|
||||||
Debug:
|
Debug:
|
||||||
--frontend-http2-dump-request-header=<PATH>
|
--frontend-http2-dump-request-header=<PATH>
|
||||||
|
@ -2374,44 +2382,49 @@ int main(int argc, char **argv) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (get_config()->http2_upstream_dump_request_header_file) {
|
auto &http2conf = mod_config()->http2;
|
||||||
auto path = get_config()->http2_upstream_dump_request_header_file.get();
|
{
|
||||||
auto f = open_file_for_write(path);
|
auto &dumpconf = http2conf.upstream.debug.dump;
|
||||||
|
|
||||||
if (f == nullptr) {
|
if (dumpconf.request_header_file) {
|
||||||
LOG(FATAL) << "Failed to open http2 upstream request header file: "
|
auto path = dumpconf.request_header_file.get();
|
||||||
<< path;
|
auto f = open_file_for_write(path);
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
mod_config()->http2_upstream_dump_request_header = f;
|
if (f == nullptr) {
|
||||||
|
LOG(FATAL) << "Failed to open http2 upstream request header file: "
|
||||||
|
<< path;
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
if (get_config()->uid != 0) {
|
dumpconf.request_header = f;
|
||||||
if (chown_to_running_user(path) == -1) {
|
|
||||||
auto error = errno;
|
if (get_config()->uid != 0) {
|
||||||
LOG(WARN) << "Changing owner of http2 upstream request header file "
|
if (chown_to_running_user(path) == -1) {
|
||||||
<< path << " failed: " << strerror(error);
|
auto error = errno;
|
||||||
|
LOG(WARN) << "Changing owner of http2 upstream request header file "
|
||||||
|
<< path << " failed: " << strerror(error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (get_config()->http2_upstream_dump_response_header_file) {
|
if (dumpconf.response_header_file) {
|
||||||
auto path = get_config()->http2_upstream_dump_response_header_file.get();
|
auto path = dumpconf.response_header_file.get();
|
||||||
auto f = open_file_for_write(path);
|
auto f = open_file_for_write(path);
|
||||||
|
|
||||||
if (f == nullptr) {
|
if (f == nullptr) {
|
||||||
LOG(FATAL) << "Failed to open http2 upstream response header file: "
|
LOG(FATAL) << "Failed to open http2 upstream response header file: "
|
||||||
<< path;
|
<< path;
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
mod_config()->http2_upstream_dump_response_header = f;
|
dumpconf.response_header = f;
|
||||||
|
|
||||||
if (get_config()->uid != 0) {
|
if (get_config()->uid != 0) {
|
||||||
if (chown_to_running_user(path) == -1) {
|
if (chown_to_running_user(path) == -1) {
|
||||||
auto error = errno;
|
auto error = errno;
|
||||||
LOG(WARN) << "Changing owner of http2 upstream response header file"
|
LOG(WARN) << "Changing owner of http2 upstream response header file"
|
||||||
<< " " << path << " failed: " << strerror(error);
|
<< " " << path << " failed: " << strerror(error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2617,16 +2630,18 @@ int main(int argc, char **argv) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (get_config()->forwarded_by_node_type == FORWARDED_NODE_OBFUSCATED &&
|
auto &fwdconf = mod_config()->http.forwarded;
|
||||||
get_config()->forwarded_by_obfuscated.empty()) {
|
|
||||||
|
if (fwdconf.by_node_type == FORWARDED_NODE_OBFUSCATED &&
|
||||||
|
fwdconf.by_obfuscated.empty()) {
|
||||||
std::random_device rd;
|
std::random_device rd;
|
||||||
std::mt19937 gen(rd());
|
std::mt19937 gen(rd());
|
||||||
auto &dst = mod_config()->forwarded_by_obfuscated;
|
auto &dst = fwdconf.by_obfuscated;
|
||||||
dst = "_";
|
dst = "_";
|
||||||
dst += util::random_alpha_digit(gen, SHRPX_OBFUSCATED_NODE_LENGTH);
|
dst += util::random_alpha_digit(gen, SHRPX_OBFUSCATED_NODE_LENGTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (get_config()->upstream_frame_debug) {
|
if (get_config()->http2.upstream.debug.frame_debug) {
|
||||||
// To make it sync to logging
|
// To make it sync to logging
|
||||||
set_output(stderr);
|
set_output(stderr);
|
||||||
if (isatty(fileno(stdout))) {
|
if (isatty(fileno(stdout))) {
|
||||||
|
@ -2635,8 +2650,8 @@ int main(int argc, char **argv) {
|
||||||
reset_timer();
|
reset_timer();
|
||||||
}
|
}
|
||||||
|
|
||||||
mod_config()->http2_upstream_callbacks = create_http2_upstream_callbacks();
|
mod_config()->http2.upstream.callbacks = create_http2_upstream_callbacks();
|
||||||
mod_config()->http2_downstream_callbacks =
|
mod_config()->http2.downstream.callbacks =
|
||||||
create_http2_downstream_callbacks();
|
create_http2_downstream_callbacks();
|
||||||
|
|
||||||
if (event_loop() != 0) {
|
if (event_loop() != 0) {
|
||||||
|
|
|
@ -404,14 +404,16 @@ ClientHandler::ClientHandler(Worker *worker, int fd, SSL *ssl,
|
||||||
setup_upstream_io_callback();
|
setup_upstream_io_callback();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((get_config()->forwarded_params & FORWARDED_FOR) &&
|
auto &fwdconf = get_config()->http.forwarded;
|
||||||
get_config()->forwarded_for_node_type == FORWARDED_NODE_OBFUSCATED) {
|
|
||||||
if (get_config()->forwarded_for_obfuscated.empty()) {
|
if ((fwdconf.params & FORWARDED_FOR) &&
|
||||||
|
fwdconf.for_node_type == FORWARDED_NODE_OBFUSCATED) {
|
||||||
|
if (fwdconf.for_obfuscated.empty()) {
|
||||||
forwarded_for_obfuscated_ = "_";
|
forwarded_for_obfuscated_ = "_";
|
||||||
forwarded_for_obfuscated_ += util::random_alpha_digit(
|
forwarded_for_obfuscated_ += util::random_alpha_digit(
|
||||||
worker_->get_randgen(), SHRPX_OBFUSCATED_NODE_LENGTH);
|
worker_->get_randgen(), SHRPX_OBFUSCATED_NODE_LENGTH);
|
||||||
} else {
|
} else {
|
||||||
forwarded_for_obfuscated_ = get_config()->forwarded_for_obfuscated;
|
forwarded_for_obfuscated_ = fwdconf.for_obfuscated;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1120,8 +1122,10 @@ int ClientHandler::proxy_protocol_read() {
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string &ClientHandler::get_forwarded_by() {
|
const std::string &ClientHandler::get_forwarded_by() {
|
||||||
if (get_config()->forwarded_by_node_type == FORWARDED_NODE_OBFUSCATED) {
|
auto &fwdconf = get_config()->http.forwarded;
|
||||||
return get_config()->forwarded_by_obfuscated;
|
|
||||||
|
if (fwdconf.by_node_type == FORWARDED_NODE_OBFUSCATED) {
|
||||||
|
return fwdconf.by_obfuscated;
|
||||||
}
|
}
|
||||||
if (!local_hostport_.empty()) {
|
if (!local_hostport_.empty()) {
|
||||||
return local_hostport_;
|
return local_hostport_;
|
||||||
|
@ -1158,7 +1162,7 @@ const std::string &ClientHandler::get_forwarded_by() {
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string &ClientHandler::get_forwarded_for() const {
|
const std::string &ClientHandler::get_forwarded_for() const {
|
||||||
if (get_config()->forwarded_for_node_type == FORWARDED_NODE_OBFUSCATED) {
|
if (get_config()->http.forwarded.for_node_type == FORWARDED_NODE_OBFUSCATED) {
|
||||||
return forwarded_for_obfuscated_;
|
return forwarded_for_obfuscated_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1447,7 +1447,7 @@ int parse_config(const char *opt, const char *optarg,
|
||||||
return parse_uint(&mod_config()->num_worker, opt, optarg);
|
return parse_uint(&mod_config()->num_worker, opt, optarg);
|
||||||
#endif // !NOTHREADS
|
#endif // !NOTHREADS
|
||||||
case SHRPX_OPTID_HTTP2_MAX_CONCURRENT_STREAMS:
|
case SHRPX_OPTID_HTTP2_MAX_CONCURRENT_STREAMS:
|
||||||
return parse_uint(&mod_config()->http2_max_concurrent_streams, opt, optarg);
|
return parse_uint(&mod_config()->http2.max_concurrent_streams, opt, optarg);
|
||||||
case SHRPX_OPTID_LOG_LEVEL:
|
case SHRPX_OPTID_LOG_LEVEL:
|
||||||
if (Log::set_severity_level_by_name(optarg) == -1) {
|
if (Log::set_severity_level_by_name(optarg) == -1) {
|
||||||
LOG(ERROR) << opt << ": Invalid severity level: " << optarg;
|
LOG(ERROR) << opt << ": Invalid severity level: " << optarg;
|
||||||
|
@ -1472,15 +1472,15 @@ int parse_config(const char *opt, const char *optarg,
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
case SHRPX_OPTID_ADD_X_FORWARDED_FOR:
|
case SHRPX_OPTID_ADD_X_FORWARDED_FOR:
|
||||||
mod_config()->add_x_forwarded_for = util::strieq(optarg, "yes");
|
mod_config()->http.xff.add = util::strieq(optarg, "yes");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
case SHRPX_OPTID_STRIP_INCOMING_X_FORWARDED_FOR:
|
case SHRPX_OPTID_STRIP_INCOMING_X_FORWARDED_FOR:
|
||||||
mod_config()->strip_incoming_x_forwarded_for = util::strieq(optarg, "yes");
|
mod_config()->http.xff.strip_incoming = util::strieq(optarg, "yes");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
case SHRPX_OPTID_NO_VIA:
|
case SHRPX_OPTID_NO_VIA:
|
||||||
mod_config()->no_via = util::strieq(optarg, "yes");
|
mod_config()->http.no_via = util::strieq(optarg, "yes");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
case SHRPX_OPTID_FRONTEND_HTTP2_READ_TIMEOUT:
|
case SHRPX_OPTID_FRONTEND_HTTP2_READ_TIMEOUT:
|
||||||
|
@ -1541,9 +1541,9 @@ int parse_config(const char *opt, const char *optarg,
|
||||||
size_t *resp;
|
size_t *resp;
|
||||||
|
|
||||||
if (optid == SHRPX_OPTID_FRONTEND_HTTP2_WINDOW_BITS) {
|
if (optid == SHRPX_OPTID_FRONTEND_HTTP2_WINDOW_BITS) {
|
||||||
resp = &mod_config()->http2_upstream_window_bits;
|
resp = &mod_config()->http2.upstream.window_bits;
|
||||||
} else {
|
} else {
|
||||||
resp = &mod_config()->http2_downstream_window_bits;
|
resp = &mod_config()->http2.downstream.window_bits;
|
||||||
}
|
}
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
|
@ -1569,9 +1569,9 @@ int parse_config(const char *opt, const char *optarg,
|
||||||
size_t *resp;
|
size_t *resp;
|
||||||
|
|
||||||
if (optid == SHRPX_OPTID_FRONTEND_HTTP2_CONNECTION_WINDOW_BITS) {
|
if (optid == SHRPX_OPTID_FRONTEND_HTTP2_CONNECTION_WINDOW_BITS) {
|
||||||
resp = &mod_config()->http2_upstream_connection_window_bits;
|
resp = &mod_config()->http2.upstream.connection_window_bits;
|
||||||
} else {
|
} else {
|
||||||
resp = &mod_config()->http2_downstream_connection_window_bits;
|
resp = &mod_config()->http2.downstream.connection_window_bits;
|
||||||
}
|
}
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
|
@ -1786,19 +1786,22 @@ int parse_config(const char *opt, const char *optarg,
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
case SHRPX_OPTID_FRONTEND_HTTP2_DUMP_REQUEST_HEADER:
|
case SHRPX_OPTID_FRONTEND_HTTP2_DUMP_REQUEST_HEADER:
|
||||||
mod_config()->http2_upstream_dump_request_header_file = strcopy(optarg);
|
mod_config()->http2.upstream.debug.dump.request_header_file =
|
||||||
|
strcopy(optarg);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
case SHRPX_OPTID_FRONTEND_HTTP2_DUMP_RESPONSE_HEADER:
|
case SHRPX_OPTID_FRONTEND_HTTP2_DUMP_RESPONSE_HEADER:
|
||||||
mod_config()->http2_upstream_dump_response_header_file = strcopy(optarg);
|
mod_config()->http2.upstream.debug.dump.response_header_file =
|
||||||
|
strcopy(optarg);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
case SHRPX_OPTID_HTTP2_NO_COOKIE_CRUMBLING:
|
case SHRPX_OPTID_HTTP2_NO_COOKIE_CRUMBLING:
|
||||||
mod_config()->http2_no_cookie_crumbling = util::strieq(optarg, "yes");
|
mod_config()->http2.no_cookie_crumbling = util::strieq(optarg, "yes");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
case SHRPX_OPTID_FRONTEND_FRAME_DEBUG:
|
case SHRPX_OPTID_FRONTEND_FRAME_DEBUG:
|
||||||
mod_config()->upstream_frame_debug = util::strieq(optarg, "yes");
|
mod_config()->http2.upstream.debug.frame_debug =
|
||||||
|
util::strieq(optarg, "yes");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
case SHRPX_OPTID_PADDING:
|
case SHRPX_OPTID_PADDING:
|
||||||
|
@ -1845,7 +1848,7 @@ int parse_config(const char *opt, const char *optarg,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mod_config()->altsvcs.push_back(std::move(altsvc));
|
mod_config()->http.altsvcs.push_back(std::move(altsvc));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1857,16 +1860,16 @@ int parse_config(const char *opt, const char *optarg,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (optid == SHRPX_OPTID_ADD_REQUEST_HEADER) {
|
if (optid == SHRPX_OPTID_ADD_REQUEST_HEADER) {
|
||||||
mod_config()->add_request_headers.push_back(std::move(p));
|
mod_config()->http.add_request_headers.push_back(std::move(p));
|
||||||
} else {
|
} else {
|
||||||
mod_config()->add_response_headers.push_back(std::move(p));
|
mod_config()->http.add_response_headers.push_back(std::move(p));
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
case SHRPX_OPTID_WORKER_FRONTEND_CONNECTIONS:
|
case SHRPX_OPTID_WORKER_FRONTEND_CONNECTIONS:
|
||||||
return parse_uint(&mod_config()->worker_frontend_connections, opt, optarg);
|
return parse_uint(&mod_config()->worker_frontend_connections, opt, optarg);
|
||||||
case SHRPX_OPTID_NO_LOCATION_REWRITE:
|
case SHRPX_OPTID_NO_LOCATION_REWRITE:
|
||||||
mod_config()->no_location_rewrite = util::strieq(optarg, "yes");
|
mod_config()->http.no_location_rewrite = util::strieq(optarg, "yes");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
case SHRPX_OPTID_NO_HOST_REWRITE:
|
case SHRPX_OPTID_NO_HOST_REWRITE:
|
||||||
|
@ -1941,11 +1944,11 @@ int parse_config(const char *opt, const char *optarg,
|
||||||
}
|
}
|
||||||
|
|
||||||
case SHRPX_OPTID_NO_SERVER_PUSH:
|
case SHRPX_OPTID_NO_SERVER_PUSH:
|
||||||
mod_config()->no_server_push = util::strieq(optarg, "yes");
|
mod_config()->http2.no_server_push = util::strieq(optarg, "yes");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
case SHRPX_OPTID_BACKEND_HTTP2_CONNECTIONS_PER_WORKER:
|
case SHRPX_OPTID_BACKEND_HTTP2_CONNECTIONS_PER_WORKER:
|
||||||
return parse_uint(&mod_config()->http2_downstream_connections_per_worker,
|
return parse_uint(&mod_config()->http2.downstream.connections_per_worker,
|
||||||
opt, optarg);
|
opt, optarg);
|
||||||
case SHRPX_OPTID_FETCH_OCSP_RESPONSE_FILE:
|
case SHRPX_OPTID_FETCH_OCSP_RESPONSE_FILE:
|
||||||
mod_config()->tls.ocsp.fetch_ocsp_response_file = strcopy(optarg);
|
mod_config()->tls.ocsp.fetch_ocsp_response_file = strcopy(optarg);
|
||||||
|
@ -1958,10 +1961,10 @@ int parse_config(const char *opt, const char *optarg,
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
case SHRPX_OPTID_HEADER_FIELD_BUFFER:
|
case SHRPX_OPTID_HEADER_FIELD_BUFFER:
|
||||||
return parse_uint_with_unit(&mod_config()->header_field_buffer, opt,
|
return parse_uint_with_unit(&mod_config()->http.header_field_buffer, opt,
|
||||||
optarg);
|
optarg);
|
||||||
case SHRPX_OPTID_MAX_HEADER_FIELDS:
|
case SHRPX_OPTID_MAX_HEADER_FIELDS:
|
||||||
return parse_uint(&mod_config()->max_header_fields, opt, optarg);
|
return parse_uint(&mod_config()->http.max_header_fields, opt, optarg);
|
||||||
case SHRPX_OPTID_INCLUDE: {
|
case SHRPX_OPTID_INCLUDE: {
|
||||||
if (included_set.count(optarg)) {
|
if (included_set.count(optarg)) {
|
||||||
LOG(ERROR) << opt << ": " << optarg << " has already been included";
|
LOG(ERROR) << opt << ": " << optarg << " has already been included";
|
||||||
|
@ -1992,7 +1995,7 @@ int parse_config(const char *opt, const char *optarg,
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
case SHRPX_OPTID_HOST_REWRITE:
|
case SHRPX_OPTID_HOST_REWRITE:
|
||||||
mod_config()->no_host_rewrite = !util::strieq(optarg, "yes");
|
mod_config()->http.no_host_rewrite = !util::strieq(optarg, "yes");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
case SHRPX_OPTID_TLS_SESSION_CACHE_MEMCACHED: {
|
case SHRPX_OPTID_TLS_SESSION_CACHE_MEMCACHED: {
|
||||||
|
@ -2065,23 +2068,24 @@ int parse_config(const char *opt, const char *optarg,
|
||||||
mod_config()->accept_proxy_protocol = util::strieq(optarg, "yes");
|
mod_config()->accept_proxy_protocol = util::strieq(optarg, "yes");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
case SHRPX_OPTID_ADD_FORWARDED:
|
case SHRPX_OPTID_ADD_FORWARDED: {
|
||||||
mod_config()->forwarded_params = FORWARDED_NONE;
|
auto &fwdconf = mod_config()->http.forwarded;
|
||||||
|
fwdconf.params = FORWARDED_NONE;
|
||||||
for (const auto ¶m : util::parse_config_str_list(optarg)) {
|
for (const auto ¶m : util::parse_config_str_list(optarg)) {
|
||||||
if (util::strieq(param, "by")) {
|
if (util::strieq(param, "by")) {
|
||||||
mod_config()->forwarded_params |= FORWARDED_BY;
|
fwdconf.params |= FORWARDED_BY;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (util::strieq(param, "for")) {
|
if (util::strieq(param, "for")) {
|
||||||
mod_config()->forwarded_params |= FORWARDED_FOR;
|
fwdconf.params |= FORWARDED_FOR;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (util::strieq(param, "host")) {
|
if (util::strieq(param, "host")) {
|
||||||
mod_config()->forwarded_params |= FORWARDED_HOST;
|
fwdconf.params |= FORWARDED_HOST;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (util::strieq(param, "proto")) {
|
if (util::strieq(param, "proto")) {
|
||||||
mod_config()->forwarded_params |= FORWARDED_PROTO;
|
fwdconf.params |= FORWARDED_PROTO;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2091,8 +2095,9 @@ int parse_config(const char *opt, const char *optarg,
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
case SHRPX_OPTID_STRIP_INCOMING_FORWARDED:
|
case SHRPX_OPTID_STRIP_INCOMING_FORWARDED:
|
||||||
mod_config()->strip_incoming_forwarded = util::strieq(optarg, "yes");
|
mod_config()->http.forwarded.strip_incoming = util::strieq(optarg, "yes");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
case SHRPX_OPTID_FORWARDED_BY:
|
case SHRPX_OPTID_FORWARDED_BY:
|
||||||
|
@ -2105,23 +2110,23 @@ int parse_config(const char *opt, const char *optarg,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto &fwdconf = mod_config()->http.forwarded;
|
||||||
|
|
||||||
switch (optid) {
|
switch (optid) {
|
||||||
case SHRPX_OPTID_FORWARDED_BY:
|
case SHRPX_OPTID_FORWARDED_BY:
|
||||||
mod_config()->forwarded_by_node_type =
|
fwdconf.by_node_type = static_cast<shrpx_forwarded_node_type>(type);
|
||||||
static_cast<shrpx_forwarded_node_type>(type);
|
|
||||||
if (optarg[0] == '_') {
|
if (optarg[0] == '_') {
|
||||||
mod_config()->forwarded_by_obfuscated = optarg;
|
fwdconf.by_obfuscated = optarg;
|
||||||
} else {
|
} else {
|
||||||
mod_config()->forwarded_by_obfuscated = "";
|
fwdconf.by_obfuscated = "";
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SHRPX_OPTID_FORWARDED_FOR:
|
case SHRPX_OPTID_FORWARDED_FOR:
|
||||||
mod_config()->forwarded_for_node_type =
|
fwdconf.for_node_type = static_cast<shrpx_forwarded_node_type>(type);
|
||||||
static_cast<shrpx_forwarded_node_type>(type);
|
|
||||||
if (optarg[0] == '_') {
|
if (optarg[0] == '_') {
|
||||||
mod_config()->forwarded_for_obfuscated = optarg;
|
fwdconf.for_obfuscated = optarg;
|
||||||
} else {
|
} else {
|
||||||
mod_config()->forwarded_for_obfuscated = "";
|
fwdconf.for_obfuscated = "";
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -289,6 +289,7 @@ struct HttpProxy {
|
||||||
std::string host;
|
std::string host;
|
||||||
// userinfo in http proxy URI, not percent-encoded form
|
// userinfo in http proxy URI, not percent-encoded form
|
||||||
std::string userinfo;
|
std::string userinfo;
|
||||||
|
// port in http proxy URI
|
||||||
uint16_t port;
|
uint16_t port;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -371,23 +372,76 @@ struct TLSConfig {
|
||||||
bool insecure;
|
bool insecure;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Config {
|
struct HttpConfig {
|
||||||
|
struct {
|
||||||
|
// obfuscated value used in "by" parameter of Forwarded header
|
||||||
|
// field.
|
||||||
|
std::string by_obfuscated;
|
||||||
|
// obfuscated value used in "for" parameter of Forwarded header
|
||||||
|
// field. This is only used when user defined static obfuscated
|
||||||
|
// string is provided.
|
||||||
|
std::string for_obfuscated;
|
||||||
|
// bitwise-OR of one or more of shrpx_forwarded_param values.
|
||||||
|
uint32_t params;
|
||||||
|
// type of value recorded in "by" parameter of Forwarded header
|
||||||
|
// field.
|
||||||
|
shrpx_forwarded_node_type by_node_type;
|
||||||
|
// type of value recorded in "for" parameter of Forwarded header
|
||||||
|
// field.
|
||||||
|
shrpx_forwarded_node_type for_node_type;
|
||||||
|
bool strip_incoming;
|
||||||
|
} forwarded;
|
||||||
|
struct {
|
||||||
|
bool add;
|
||||||
|
bool strip_incoming;
|
||||||
|
} xff;
|
||||||
std::vector<AltSvc> altsvcs;
|
std::vector<AltSvc> altsvcs;
|
||||||
std::vector<std::pair<std::string, std::string>> add_request_headers;
|
std::vector<std::pair<std::string, std::string>> add_request_headers;
|
||||||
std::vector<std::pair<std::string, std::string>> add_response_headers;
|
std::vector<std::pair<std::string, std::string>> add_response_headers;
|
||||||
|
StringRef server_name;
|
||||||
|
size_t header_field_buffer;
|
||||||
|
size_t max_header_fields;
|
||||||
|
bool no_via;
|
||||||
|
bool no_location_rewrite;
|
||||||
|
bool no_host_rewrite;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Http2Config {
|
||||||
|
struct {
|
||||||
|
struct {
|
||||||
|
struct {
|
||||||
|
std::unique_ptr<char[]> request_header_file;
|
||||||
|
std::unique_ptr<char[]> response_header_file;
|
||||||
|
FILE *request_header;
|
||||||
|
FILE *response_header;
|
||||||
|
} dump;
|
||||||
|
bool frame_debug;
|
||||||
|
} debug;
|
||||||
|
nghttp2_option *option;
|
||||||
|
nghttp2_session_callbacks *callbacks;
|
||||||
|
size_t window_bits;
|
||||||
|
size_t connection_window_bits;
|
||||||
|
} upstream;
|
||||||
|
struct {
|
||||||
|
nghttp2_option *option;
|
||||||
|
nghttp2_session_callbacks *callbacks;
|
||||||
|
size_t window_bits;
|
||||||
|
size_t connection_window_bits;
|
||||||
|
size_t connections_per_worker;
|
||||||
|
} downstream;
|
||||||
|
size_t max_concurrent_streams;
|
||||||
|
bool no_cookie_crumbling;
|
||||||
|
bool no_server_push;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Config {
|
||||||
std::vector<LogFragment> accesslog_format;
|
std::vector<LogFragment> accesslog_format;
|
||||||
std::vector<DownstreamAddrGroup> downstream_addr_groups;
|
std::vector<DownstreamAddrGroup> downstream_addr_groups;
|
||||||
Router router;
|
Router router;
|
||||||
HttpProxy downstream_http_proxy;
|
HttpProxy downstream_http_proxy;
|
||||||
|
HttpConfig http;
|
||||||
|
Http2Config http2;
|
||||||
TLSConfig tls;
|
TLSConfig tls;
|
||||||
// obfuscated value used in "by" parameter of Forwarded header
|
|
||||||
// field.
|
|
||||||
std::string forwarded_by_obfuscated;
|
|
||||||
// obfuscated value used in "for" parameter of Forwarded header
|
|
||||||
// field. This is only used when user defined static obfuscated
|
|
||||||
// string is provided.
|
|
||||||
std::string forwarded_for_obfuscated;
|
|
||||||
StringRef server_name;
|
|
||||||
ev_tstamp http2_upstream_read_timeout;
|
ev_tstamp http2_upstream_read_timeout;
|
||||||
ev_tstamp upstream_read_timeout;
|
ev_tstamp upstream_read_timeout;
|
||||||
ev_tstamp upstream_write_timeout;
|
ev_tstamp upstream_write_timeout;
|
||||||
|
@ -402,28 +456,14 @@ struct Config {
|
||||||
std::unique_ptr<char[]> host;
|
std::unique_ptr<char[]> host;
|
||||||
std::unique_ptr<char[]> pid_file;
|
std::unique_ptr<char[]> pid_file;
|
||||||
std::unique_ptr<char[]> conf_path;
|
std::unique_ptr<char[]> conf_path;
|
||||||
std::unique_ptr<char[]> http2_upstream_dump_request_header_file;
|
|
||||||
std::unique_ptr<char[]> http2_upstream_dump_response_header_file;
|
|
||||||
std::unique_ptr<char[]> accesslog_file;
|
std::unique_ptr<char[]> accesslog_file;
|
||||||
std::unique_ptr<char[]> errorlog_file;
|
std::unique_ptr<char[]> errorlog_file;
|
||||||
std::unique_ptr<char[]> user;
|
std::unique_ptr<char[]> user;
|
||||||
std::unique_ptr<char[]> mruby_file;
|
std::unique_ptr<char[]> mruby_file;
|
||||||
FILE *http2_upstream_dump_request_header;
|
|
||||||
FILE *http2_upstream_dump_response_header;
|
|
||||||
nghttp2_session_callbacks *http2_upstream_callbacks;
|
|
||||||
nghttp2_session_callbacks *http2_downstream_callbacks;
|
|
||||||
nghttp2_option *http2_option;
|
|
||||||
nghttp2_option *http2_client_option;
|
|
||||||
char **original_argv;
|
char **original_argv;
|
||||||
char **argv;
|
char **argv;
|
||||||
char *cwd;
|
char *cwd;
|
||||||
size_t num_worker;
|
size_t num_worker;
|
||||||
size_t http2_max_concurrent_streams;
|
|
||||||
size_t http2_upstream_window_bits;
|
|
||||||
size_t http2_downstream_window_bits;
|
|
||||||
size_t http2_upstream_connection_window_bits;
|
|
||||||
size_t http2_downstream_connection_window_bits;
|
|
||||||
size_t http2_downstream_connections_per_worker;
|
|
||||||
size_t downstream_connections_per_host;
|
size_t downstream_connections_per_host;
|
||||||
size_t downstream_connections_per_frontend;
|
size_t downstream_connections_per_frontend;
|
||||||
size_t read_rate;
|
size_t read_rate;
|
||||||
|
@ -439,20 +479,10 @@ struct Config {
|
||||||
size_t rlimit_nofile;
|
size_t rlimit_nofile;
|
||||||
size_t downstream_request_buffer_size;
|
size_t downstream_request_buffer_size;
|
||||||
size_t downstream_response_buffer_size;
|
size_t downstream_response_buffer_size;
|
||||||
size_t header_field_buffer;
|
|
||||||
size_t max_header_fields;
|
|
||||||
// The index of catch-all group in downstream_addr_groups.
|
// The index of catch-all group in downstream_addr_groups.
|
||||||
size_t downstream_addr_group_catch_all;
|
size_t downstream_addr_group_catch_all;
|
||||||
// downstream protocol; this will be determined by given options.
|
// downstream protocol; this will be determined by given options.
|
||||||
shrpx_proto downstream_proto;
|
shrpx_proto downstream_proto;
|
||||||
// bitwise-OR of one or more of shrpx_forwarded_param values.
|
|
||||||
uint32_t forwarded_params;
|
|
||||||
// type of value recorded in "by" parameter of Forwarded header
|
|
||||||
// field.
|
|
||||||
shrpx_forwarded_node_type forwarded_by_node_type;
|
|
||||||
// type of value recorded in "for" parameter of Forwarded header
|
|
||||||
// field.
|
|
||||||
shrpx_forwarded_node_type forwarded_for_node_type;
|
|
||||||
int syslog_facility;
|
int syslog_facility;
|
||||||
int backlog;
|
int backlog;
|
||||||
int argc;
|
int argc;
|
||||||
|
@ -463,17 +493,11 @@ struct Config {
|
||||||
// frontend listening port. 0 if frontend listens on UNIX domain
|
// frontend listening port. 0 if frontend listens on UNIX domain
|
||||||
// socket, in this case |host_unix| must be true.
|
// socket, in this case |host_unix| must be true.
|
||||||
uint16_t port;
|
uint16_t port;
|
||||||
// port in http proxy URI
|
|
||||||
uint16_t downstream_http_proxy_port;
|
|
||||||
bool verbose;
|
bool verbose;
|
||||||
bool daemon;
|
bool daemon;
|
||||||
bool http2_proxy;
|
bool http2_proxy;
|
||||||
bool http2_bridge;
|
bool http2_bridge;
|
||||||
bool client_proxy;
|
bool client_proxy;
|
||||||
bool add_x_forwarded_for;
|
|
||||||
bool strip_incoming_x_forwarded_for;
|
|
||||||
bool strip_incoming_forwarded;
|
|
||||||
bool no_via;
|
|
||||||
bool upstream_no_tls;
|
bool upstream_no_tls;
|
||||||
bool downstream_no_tls;
|
bool downstream_no_tls;
|
||||||
// Send accesslog to syslog, ignoring accesslog_file.
|
// Send accesslog to syslog, ignoring accesslog_file.
|
||||||
|
@ -485,11 +509,6 @@ struct Config {
|
||||||
bool client_mode;
|
bool client_mode;
|
||||||
bool backend_ipv4;
|
bool backend_ipv4;
|
||||||
bool backend_ipv6;
|
bool backend_ipv6;
|
||||||
bool http2_no_cookie_crumbling;
|
|
||||||
bool upstream_frame_debug;
|
|
||||||
bool no_location_rewrite;
|
|
||||||
bool no_host_rewrite;
|
|
||||||
bool no_server_push;
|
|
||||||
// true if host contains UNIX domain socket path
|
// true if host contains UNIX domain socket path
|
||||||
bool host_unix;
|
bool host_unix;
|
||||||
bool accept_proxy_protocol;
|
bool accept_proxy_protocol;
|
||||||
|
|
|
@ -44,7 +44,7 @@ std::string create_error_html(unsigned int status_code) {
|
||||||
res += "</title><body><h1>";
|
res += "</title><body><h1>";
|
||||||
res += status;
|
res += status;
|
||||||
res += "</h1><footer>";
|
res += "</h1><footer>";
|
||||||
const auto &server_name = get_config()->server_name;
|
const auto &server_name = get_config()->http.server_name;
|
||||||
res.append(server_name.c_str(), server_name.size());
|
res.append(server_name.c_str(), server_name.size());
|
||||||
res += " at port ";
|
res += " at port ";
|
||||||
res += util::utos(get_config()->port);
|
res += util::utos(get_config()->port);
|
||||||
|
|
|
@ -256,8 +256,11 @@ int Http2DownstreamConnection::push_request_headers() {
|
||||||
|
|
||||||
const auto &req = downstream_->request();
|
const auto &req = downstream_->request();
|
||||||
|
|
||||||
|
auto &httpconf = get_config()->http;
|
||||||
|
auto &http2conf = get_config()->http2;
|
||||||
|
|
||||||
auto no_host_rewrite =
|
auto no_host_rewrite =
|
||||||
get_config()->no_host_rewrite || get_config()->http2_proxy ||
|
httpconf.no_host_rewrite || get_config()->http2_proxy ||
|
||||||
get_config()->client_proxy || req.method == HTTP_CONNECT;
|
get_config()->client_proxy || req.method == HTTP_CONNECT;
|
||||||
|
|
||||||
// http2session_ has already in CONNECTED state, so we can get
|
// http2session_ has already in CONNECTED state, so we can get
|
||||||
|
@ -278,7 +281,7 @@ int Http2DownstreamConnection::push_request_headers() {
|
||||||
downstream_->set_request_downstream_host(authority.str());
|
downstream_->set_request_downstream_host(authority.str());
|
||||||
|
|
||||||
size_t num_cookies = 0;
|
size_t num_cookies = 0;
|
||||||
if (!get_config()->http2_no_cookie_crumbling) {
|
if (!http2conf.no_cookie_crumbling) {
|
||||||
num_cookies = downstream_->count_crumble_request_cookie();
|
num_cookies = downstream_->count_crumble_request_cookie();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -294,7 +297,7 @@ int Http2DownstreamConnection::push_request_headers() {
|
||||||
// 9. forwarded (optional)
|
// 9. forwarded (optional)
|
||||||
auto nva = std::vector<nghttp2_nv>();
|
auto nva = std::vector<nghttp2_nv>();
|
||||||
nva.reserve(req.fs.headers().size() + 9 + num_cookies +
|
nva.reserve(req.fs.headers().size() + 9 + num_cookies +
|
||||||
get_config()->add_request_headers.size());
|
httpconf.add_request_headers.size());
|
||||||
|
|
||||||
nva.push_back(
|
nva.push_back(
|
||||||
http2::make_nv_lc_nocopy(":method", http2::to_method_string(req.method)));
|
http2::make_nv_lc_nocopy(":method", http2::to_method_string(req.method)));
|
||||||
|
@ -328,7 +331,7 @@ int Http2DownstreamConnection::push_request_headers() {
|
||||||
chunked_encoding = true;
|
chunked_encoding = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!get_config()->http2_no_cookie_crumbling) {
|
if (!http2conf.no_cookie_crumbling) {
|
||||||
downstream_->crumble_request_cookie(nva);
|
downstream_->crumble_request_cookie(nva);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -337,12 +340,13 @@ int Http2DownstreamConnection::push_request_headers() {
|
||||||
|
|
||||||
std::string forwarded_value;
|
std::string forwarded_value;
|
||||||
|
|
||||||
auto fwd = get_config()->strip_incoming_forwarded
|
auto &fwdconf = httpconf.forwarded;
|
||||||
? nullptr
|
|
||||||
: req.fs.header(http2::HD_FORWARDED);
|
|
||||||
|
|
||||||
if (get_config()->forwarded_params) {
|
auto fwd =
|
||||||
auto params = get_config()->forwarded_params;
|
fwdconf.strip_incoming ? nullptr : req.fs.header(http2::HD_FORWARDED);
|
||||||
|
|
||||||
|
if (fwdconf.params) {
|
||||||
|
auto params = fwdconf.params;
|
||||||
|
|
||||||
if (get_config()->http2_proxy || get_config()->client_proxy ||
|
if (get_config()->http2_proxy || get_config()->client_proxy ||
|
||||||
req.method == HTTP_CONNECT) {
|
req.method == HTTP_CONNECT) {
|
||||||
|
@ -370,12 +374,14 @@ int Http2DownstreamConnection::push_request_headers() {
|
||||||
forwarded_value = fwd->value;
|
forwarded_value = fwd->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string xff_value;
|
auto &xffconf = httpconf.xff;
|
||||||
auto xff = get_config()->strip_incoming_x_forwarded_for
|
|
||||||
? nullptr
|
|
||||||
: req.fs.header(http2::HD_X_FORWARDED_FOR);
|
|
||||||
|
|
||||||
if (get_config()->add_x_forwarded_for) {
|
auto xff = xffconf.strip_incoming ? nullptr
|
||||||
|
: req.fs.header(http2::HD_X_FORWARDED_FOR);
|
||||||
|
|
||||||
|
std::string xff_value;
|
||||||
|
|
||||||
|
if (xffconf.add) {
|
||||||
if (xff) {
|
if (xff) {
|
||||||
xff_value = (*xff).value;
|
xff_value = (*xff).value;
|
||||||
xff_value += ", ";
|
xff_value += ", ";
|
||||||
|
@ -394,7 +400,7 @@ int Http2DownstreamConnection::push_request_headers() {
|
||||||
|
|
||||||
std::string via_value;
|
std::string via_value;
|
||||||
auto via = req.fs.header(http2::HD_VIA);
|
auto via = req.fs.header(http2::HD_VIA);
|
||||||
if (get_config()->no_via) {
|
if (httpconf.no_via) {
|
||||||
if (via) {
|
if (via) {
|
||||||
nva.push_back(http2::make_nv_ls_nocopy("via", (*via).value));
|
nva.push_back(http2::make_nv_ls_nocopy("via", (*via).value));
|
||||||
}
|
}
|
||||||
|
@ -415,7 +421,7 @@ int Http2DownstreamConnection::push_request_headers() {
|
||||||
nva.push_back(http2::make_nv_ll("te", "trailers"));
|
nva.push_back(http2::make_nv_ll("te", "trailers"));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto &p : get_config()->add_request_headers) {
|
for (auto &p : httpconf.add_request_headers) {
|
||||||
nva.push_back(http2::make_nv_nocopy(p.first, p.second));
|
nva.push_back(http2::make_nv_nocopy(p.first, p.second));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1309,9 +1309,10 @@ int Http2Session::connection_made() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rv = nghttp2_session_client_new2(&session_,
|
auto &http2conf = get_config()->http2;
|
||||||
get_config()->http2_downstream_callbacks,
|
|
||||||
this, get_config()->http2_client_option);
|
rv = nghttp2_session_client_new2(&session_, http2conf.downstream.callbacks,
|
||||||
|
this, http2conf.downstream.option);
|
||||||
|
|
||||||
if (rv != 0) {
|
if (rv != 0) {
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1322,12 +1323,12 @@ int Http2Session::connection_made() {
|
||||||
std::array<nghttp2_settings_entry, 3> entry;
|
std::array<nghttp2_settings_entry, 3> entry;
|
||||||
size_t nentry = 2;
|
size_t nentry = 2;
|
||||||
entry[0].settings_id = NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS;
|
entry[0].settings_id = NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS;
|
||||||
entry[0].value = get_config()->http2_max_concurrent_streams;
|
entry[0].value = http2conf.max_concurrent_streams;
|
||||||
|
|
||||||
entry[1].settings_id = NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE;
|
entry[1].settings_id = NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE;
|
||||||
entry[1].value = (1 << get_config()->http2_downstream_window_bits) - 1;
|
entry[1].value = (1 << http2conf.downstream.window_bits) - 1;
|
||||||
|
|
||||||
if (get_config()->no_server_push || get_config()->http2_proxy ||
|
if (http2conf.no_server_push || get_config()->http2_proxy ||
|
||||||
get_config()->client_proxy) {
|
get_config()->client_proxy) {
|
||||||
entry[nentry].settings_id = NGHTTP2_SETTINGS_ENABLE_PUSH;
|
entry[nentry].settings_id = NGHTTP2_SETTINGS_ENABLE_PUSH;
|
||||||
entry[nentry].value = 0;
|
entry[nentry].value = 0;
|
||||||
|
@ -1340,10 +1341,10 @@ int Http2Session::connection_made() {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (get_config()->http2_downstream_connection_window_bits > 16) {
|
auto connection_window_bits = http2conf.downstream.connection_window_bits;
|
||||||
int32_t delta =
|
if (connection_window_bits > 16) {
|
||||||
(1 << get_config()->http2_downstream_connection_window_bits) - 1 -
|
int32_t delta = (1 << connection_window_bits) - 1 -
|
||||||
NGHTTP2_INITIAL_CONNECTION_WINDOW_SIZE;
|
NGHTTP2_INITIAL_CONNECTION_WINDOW_SIZE;
|
||||||
rv = nghttp2_submit_window_update(session_, NGHTTP2_FLAG_NONE, 0, delta);
|
rv = nghttp2_submit_window_update(session_, NGHTTP2_FLAG_NONE, 0, delta);
|
||||||
if (rv != 0) {
|
if (rv != 0) {
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -154,7 +154,7 @@ int on_header_callback(nghttp2_session *session, const nghttp2_frame *frame,
|
||||||
const uint8_t *name, size_t namelen,
|
const uint8_t *name, size_t namelen,
|
||||||
const uint8_t *value, size_t valuelen, uint8_t flags,
|
const uint8_t *value, size_t valuelen, uint8_t flags,
|
||||||
void *user_data) {
|
void *user_data) {
|
||||||
if (get_config()->upstream_frame_debug) {
|
if (get_config()->http2.upstream.debug.frame_debug) {
|
||||||
verbose_on_header_callback(session, frame, name, namelen, value, valuelen,
|
verbose_on_header_callback(session, frame, name, namelen, value, valuelen,
|
||||||
flags, user_data);
|
flags, user_data);
|
||||||
}
|
}
|
||||||
|
@ -170,9 +170,11 @@ int on_header_callback(nghttp2_session *session, const nghttp2_frame *frame,
|
||||||
|
|
||||||
auto &req = downstream->request();
|
auto &req = downstream->request();
|
||||||
|
|
||||||
|
auto &httpconf = get_config()->http;
|
||||||
|
|
||||||
if (req.fs.buffer_size() + namelen + valuelen >
|
if (req.fs.buffer_size() + namelen + valuelen >
|
||||||
get_config()->header_field_buffer ||
|
httpconf.header_field_buffer ||
|
||||||
req.fs.num_fields() >= get_config()->max_header_fields) {
|
req.fs.num_fields() >= httpconf.max_header_fields) {
|
||||||
if (downstream->get_response_state() == Downstream::MSG_COMPLETE) {
|
if (downstream->get_response_state() == Downstream::MSG_COMPLETE) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -263,8 +265,10 @@ int Http2Upstream::on_request_headers(Downstream *downstream,
|
||||||
<< downstream->get_stream_id() << "\n" << ss.str();
|
<< downstream->get_stream_id() << "\n" << ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (get_config()->http2_upstream_dump_request_header) {
|
auto &dump = get_config()->http2.upstream.debug.dump;
|
||||||
http2::dump_nv(get_config()->http2_upstream_dump_request_header, nva);
|
|
||||||
|
if (dump.request_header) {
|
||||||
|
http2::dump_nv(dump.request_header, nva);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto content_length = req.fs.header(http2::HD_CONTENT_LENGTH);
|
auto content_length = req.fs.header(http2::HD_CONTENT_LENGTH);
|
||||||
|
@ -398,7 +402,7 @@ void Http2Upstream::initiate_downstream(Downstream *downstream) {
|
||||||
namespace {
|
namespace {
|
||||||
int on_frame_recv_callback(nghttp2_session *session, const nghttp2_frame *frame,
|
int on_frame_recv_callback(nghttp2_session *session, const nghttp2_frame *frame,
|
||||||
void *user_data) {
|
void *user_data) {
|
||||||
if (get_config()->upstream_frame_debug) {
|
if (get_config()->http2.upstream.debug.frame_debug) {
|
||||||
verbose_on_frame_recv_callback(session, frame, user_data);
|
verbose_on_frame_recv_callback(session, frame, user_data);
|
||||||
}
|
}
|
||||||
auto upstream = static_cast<Http2Upstream *>(user_data);
|
auto upstream = static_cast<Http2Upstream *>(user_data);
|
||||||
|
@ -500,7 +504,7 @@ int on_data_chunk_recv_callback(nghttp2_session *session, uint8_t flags,
|
||||||
namespace {
|
namespace {
|
||||||
int on_frame_send_callback(nghttp2_session *session, const nghttp2_frame *frame,
|
int on_frame_send_callback(nghttp2_session *session, const nghttp2_frame *frame,
|
||||||
void *user_data) {
|
void *user_data) {
|
||||||
if (get_config()->upstream_frame_debug) {
|
if (get_config()->http2.upstream.debug.frame_debug) {
|
||||||
verbose_on_frame_send_callback(session, frame, user_data);
|
verbose_on_frame_send_callback(session, frame, user_data);
|
||||||
}
|
}
|
||||||
auto upstream = static_cast<Http2Upstream *>(user_data);
|
auto upstream = static_cast<Http2Upstream *>(user_data);
|
||||||
|
@ -860,9 +864,10 @@ Http2Upstream::Http2Upstream(ClientHandler *handler)
|
||||||
|
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
rv = nghttp2_session_server_new2(&session_,
|
auto &http2conf = get_config()->http2;
|
||||||
get_config()->http2_upstream_callbacks, this,
|
|
||||||
get_config()->http2_option);
|
rv = nghttp2_session_server_new2(&session_, http2conf.upstream.callbacks,
|
||||||
|
this, http2conf.upstream.option);
|
||||||
|
|
||||||
assert(rv == 0);
|
assert(rv == 0);
|
||||||
|
|
||||||
|
@ -871,10 +876,10 @@ Http2Upstream::Http2Upstream(ClientHandler *handler)
|
||||||
// TODO Maybe call from outside?
|
// TODO Maybe call from outside?
|
||||||
std::array<nghttp2_settings_entry, 2> entry;
|
std::array<nghttp2_settings_entry, 2> entry;
|
||||||
entry[0].settings_id = NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS;
|
entry[0].settings_id = NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS;
|
||||||
entry[0].value = get_config()->http2_max_concurrent_streams;
|
entry[0].value = http2conf.max_concurrent_streams;
|
||||||
|
|
||||||
entry[1].settings_id = NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE;
|
entry[1].settings_id = NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE;
|
||||||
entry[1].value = (1 << get_config()->http2_upstream_window_bits) - 1;
|
entry[1].value = (1 << http2conf.upstream.window_bits) - 1;
|
||||||
|
|
||||||
rv = nghttp2_submit_settings(session_, NGHTTP2_FLAG_NONE, entry.data(),
|
rv = nghttp2_submit_settings(session_, NGHTTP2_FLAG_NONE, entry.data(),
|
||||||
entry.size());
|
entry.size());
|
||||||
|
@ -883,9 +888,9 @@ Http2Upstream::Http2Upstream(ClientHandler *handler)
|
||||||
<< nghttp2_strerror(rv);
|
<< nghttp2_strerror(rv);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (get_config()->http2_upstream_connection_window_bits > 16) {
|
if (http2conf.upstream.connection_window_bits > 16) {
|
||||||
int32_t delta = (1 << get_config()->http2_upstream_connection_window_bits) -
|
int32_t delta = (1 << http2conf.upstream.connection_window_bits) - 1 -
|
||||||
1 - NGHTTP2_INITIAL_CONNECTION_WINDOW_SIZE;
|
NGHTTP2_INITIAL_CONNECTION_WINDOW_SIZE;
|
||||||
rv = nghttp2_submit_window_update(session_, NGHTTP2_FLAG_NONE, 0, delta);
|
rv = nghttp2_submit_window_update(session_, NGHTTP2_FLAG_NONE, 0, delta);
|
||||||
|
|
||||||
if (rv != 0) {
|
if (rv != 0) {
|
||||||
|
@ -1337,7 +1342,7 @@ int Http2Upstream::send_reply(Downstream *downstream, const uint8_t *body,
|
||||||
|
|
||||||
if (!resp.fs.header(http2::HD_SERVER)) {
|
if (!resp.fs.header(http2::HD_SERVER)) {
|
||||||
nva.push_back(
|
nva.push_back(
|
||||||
http2::make_nv_ls_nocopy("server", get_config()->server_name));
|
http2::make_nv_ls_nocopy("server", get_config()->http.server_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
rv = nghttp2_submit_response(session_, downstream->get_stream_id(),
|
rv = nghttp2_submit_response(session_, downstream->get_stream_id(),
|
||||||
|
@ -1386,7 +1391,7 @@ int Http2Upstream::error_reply(Downstream *downstream,
|
||||||
: http2::make_nv_ls(":status",
|
: http2::make_nv_ls(":status",
|
||||||
(status_code_str = util::utos(status_code))),
|
(status_code_str = util::utos(status_code))),
|
||||||
http2::make_nv_ll("content-type", "text/html; charset=UTF-8"),
|
http2::make_nv_ll("content-type", "text/html; charset=UTF-8"),
|
||||||
http2::make_nv_ls_nocopy("server", get_config()->server_name),
|
http2::make_nv_ls_nocopy("server", get_config()->http.server_name),
|
||||||
http2::make_nv_ls("content-length", content_length),
|
http2::make_nv_ls("content-length", content_length),
|
||||||
http2::make_nv_ls("date", lgconf->time_http_str));
|
http2::make_nv_ls("date", lgconf->time_http_str));
|
||||||
|
|
||||||
|
@ -1442,8 +1447,10 @@ int Http2Upstream::on_downstream_header_complete(Downstream *downstream) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto &httpconf = get_config()->http;
|
||||||
|
|
||||||
if (!get_config()->http2_proxy && !get_config()->client_proxy &&
|
if (!get_config()->http2_proxy && !get_config()->client_proxy &&
|
||||||
!get_config()->no_location_rewrite) {
|
!httpconf.no_location_rewrite) {
|
||||||
downstream->rewrite_location_response_header(req.scheme);
|
downstream->rewrite_location_response_header(req.scheme);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1470,7 +1477,7 @@ int Http2Upstream::on_downstream_header_complete(Downstream *downstream) {
|
||||||
// 4 means :status and possible server, via and x-http2-push header
|
// 4 means :status and possible server, via and x-http2-push header
|
||||||
// field.
|
// field.
|
||||||
nva.reserve(resp.fs.headers().size() + 4 +
|
nva.reserve(resp.fs.headers().size() + 4 +
|
||||||
get_config()->add_response_headers.size());
|
httpconf.add_response_headers.size());
|
||||||
std::string via_value;
|
std::string via_value;
|
||||||
std::string response_status;
|
std::string response_status;
|
||||||
|
|
||||||
|
@ -1506,8 +1513,7 @@ int Http2Upstream::on_downstream_header_complete(Downstream *downstream) {
|
||||||
http2::copy_headers_to_nva_nocopy(nva, resp.fs.headers());
|
http2::copy_headers_to_nva_nocopy(nva, resp.fs.headers());
|
||||||
|
|
||||||
if (!get_config()->http2_proxy && !get_config()->client_proxy) {
|
if (!get_config()->http2_proxy && !get_config()->client_proxy) {
|
||||||
nva.push_back(
|
nva.push_back(http2::make_nv_ls_nocopy("server", httpconf.server_name));
|
||||||
http2::make_nv_ls_nocopy("server", get_config()->server_name));
|
|
||||||
} else {
|
} else {
|
||||||
auto server = resp.fs.header(http2::HD_SERVER);
|
auto server = resp.fs.header(http2::HD_SERVER);
|
||||||
if (server) {
|
if (server) {
|
||||||
|
@ -1516,7 +1522,7 @@ int Http2Upstream::on_downstream_header_complete(Downstream *downstream) {
|
||||||
}
|
}
|
||||||
|
|
||||||
auto via = resp.fs.header(http2::HD_VIA);
|
auto via = resp.fs.header(http2::HD_VIA);
|
||||||
if (get_config()->no_via) {
|
if (httpconf.no_via) {
|
||||||
if (via) {
|
if (via) {
|
||||||
nva.push_back(http2::make_nv_ls_nocopy("via", (*via).value));
|
nva.push_back(http2::make_nv_ls_nocopy("via", (*via).value));
|
||||||
}
|
}
|
||||||
|
@ -1530,7 +1536,7 @@ int Http2Upstream::on_downstream_header_complete(Downstream *downstream) {
|
||||||
nva.push_back(http2::make_nv_ls("via", via_value));
|
nva.push_back(http2::make_nv_ls("via", via_value));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto &p : get_config()->add_response_headers) {
|
for (auto &p : httpconf.add_response_headers) {
|
||||||
nva.push_back(http2::make_nv_nocopy(p.first, p.second));
|
nva.push_back(http2::make_nv_nocopy(p.first, p.second));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1544,9 +1550,11 @@ int Http2Upstream::on_downstream_header_complete(Downstream *downstream) {
|
||||||
log_response_headers(downstream, nva);
|
log_response_headers(downstream, nva);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (get_config()->http2_upstream_dump_response_header) {
|
auto &http2conf = get_config()->http2;
|
||||||
http2::dump_nv(get_config()->http2_upstream_dump_response_header,
|
|
||||||
nva.data(), nva.size());
|
if (http2conf.upstream.debug.dump.response_header) {
|
||||||
|
http2::dump_nv(http2conf.upstream.debug.dump.response_header, nva.data(),
|
||||||
|
nva.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
nghttp2_data_provider data_prd;
|
nghttp2_data_provider data_prd;
|
||||||
|
@ -1574,7 +1582,7 @@ int Http2Upstream::on_downstream_header_complete(Downstream *downstream) {
|
||||||
// * We requires GET or POST for associated resource. Probably we
|
// * We requires GET or POST for associated resource. Probably we
|
||||||
// don't want to push for HEAD request. Not sure other methods
|
// don't want to push for HEAD request. Not sure other methods
|
||||||
// are also eligible for push.
|
// are also eligible for push.
|
||||||
if (!get_config()->no_server_push &&
|
if (!http2conf.no_server_push &&
|
||||||
nghttp2_session_get_remote_settings(session_,
|
nghttp2_session_get_remote_settings(session_,
|
||||||
NGHTTP2_SETTINGS_ENABLE_PUSH) == 1 &&
|
NGHTTP2_SETTINGS_ENABLE_PUSH) == 1 &&
|
||||||
!get_config()->http2_proxy && !get_config()->client_proxy &&
|
!get_config()->http2_proxy && !get_config()->client_proxy &&
|
||||||
|
@ -1875,7 +1883,7 @@ int Http2Upstream::submit_push_promise(const std::string &scheme,
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Http2Upstream::push_enabled() const {
|
bool Http2Upstream::push_enabled() const {
|
||||||
return !(get_config()->no_server_push ||
|
return !(get_config()->http2.no_server_push ||
|
||||||
nghttp2_session_get_remote_settings(
|
nghttp2_session_get_remote_settings(
|
||||||
session_, NGHTTP2_SETTINGS_ENABLE_PUSH) == 0 ||
|
session_, NGHTTP2_SETTINGS_ENABLE_PUSH) == 0 ||
|
||||||
get_config()->http2_proxy || get_config()->client_proxy);
|
get_config()->http2_proxy || get_config()->client_proxy);
|
||||||
|
|
|
@ -217,10 +217,12 @@ int HttpDownstreamConnection::push_request_headers() {
|
||||||
|
|
||||||
auto connect_method = req.method == HTTP_CONNECT;
|
auto connect_method = req.method == HTTP_CONNECT;
|
||||||
|
|
||||||
|
auto &httpconf = get_config()->http;
|
||||||
|
|
||||||
// For HTTP/1.0 request, there is no authority in request. In that
|
// For HTTP/1.0 request, there is no authority in request. In that
|
||||||
// case, we use backend server's host nonetheless.
|
// case, we use backend server's host nonetheless.
|
||||||
auto authority = StringRef(downstream_hostport);
|
auto authority = StringRef(downstream_hostport);
|
||||||
auto no_host_rewrite = get_config()->no_host_rewrite ||
|
auto no_host_rewrite = httpconf.no_host_rewrite ||
|
||||||
get_config()->http2_proxy ||
|
get_config()->http2_proxy ||
|
||||||
get_config()->client_proxy || connect_method;
|
get_config()->client_proxy || connect_method;
|
||||||
|
|
||||||
|
@ -296,11 +298,13 @@ int HttpDownstreamConnection::push_request_headers() {
|
||||||
auto upstream = downstream_->get_upstream();
|
auto upstream = downstream_->get_upstream();
|
||||||
auto handler = upstream->get_client_handler();
|
auto handler = upstream->get_client_handler();
|
||||||
|
|
||||||
auto fwd = get_config()->strip_incoming_forwarded
|
auto &fwdconf = httpconf.forwarded;
|
||||||
? nullptr
|
|
||||||
: req.fs.header(http2::HD_FORWARDED);
|
auto fwd =
|
||||||
if (get_config()->forwarded_params) {
|
fwdconf.strip_incoming ? nullptr : req.fs.header(http2::HD_FORWARDED);
|
||||||
auto params = get_config()->forwarded_params;
|
|
||||||
|
if (fwdconf.params) {
|
||||||
|
auto params = fwdconf.params;
|
||||||
|
|
||||||
if (get_config()->http2_proxy || get_config()->client_proxy ||
|
if (get_config()->http2_proxy || get_config()->client_proxy ||
|
||||||
connect_method) {
|
connect_method) {
|
||||||
|
@ -328,11 +332,12 @@ int HttpDownstreamConnection::push_request_headers() {
|
||||||
buf->append("\r\n");
|
buf->append("\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
auto xff = get_config()->strip_incoming_x_forwarded_for
|
auto &xffconf = httpconf.xff;
|
||||||
? nullptr
|
|
||||||
: req.fs.header(http2::HD_X_FORWARDED_FOR);
|
|
||||||
|
|
||||||
if (get_config()->add_x_forwarded_for) {
|
auto xff = xffconf.strip_incoming ? nullptr
|
||||||
|
: req.fs.header(http2::HD_X_FORWARDED_FOR);
|
||||||
|
|
||||||
|
if (xffconf.add) {
|
||||||
buf->append("X-Forwarded-For: ");
|
buf->append("X-Forwarded-For: ");
|
||||||
if (xff) {
|
if (xff) {
|
||||||
buf->append((*xff).value);
|
buf->append((*xff).value);
|
||||||
|
@ -353,7 +358,7 @@ int HttpDownstreamConnection::push_request_headers() {
|
||||||
buf->append("\r\n");
|
buf->append("\r\n");
|
||||||
}
|
}
|
||||||
auto via = req.fs.header(http2::HD_VIA);
|
auto via = req.fs.header(http2::HD_VIA);
|
||||||
if (get_config()->no_via) {
|
if (httpconf.no_via) {
|
||||||
if (via) {
|
if (via) {
|
||||||
buf->append("Via: ");
|
buf->append("Via: ");
|
||||||
buf->append((*via).value);
|
buf->append((*via).value);
|
||||||
|
@ -369,7 +374,7 @@ int HttpDownstreamConnection::push_request_headers() {
|
||||||
buf->append("\r\n");
|
buf->append("\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto &p : get_config()->add_request_headers) {
|
for (auto &p : httpconf.add_request_headers) {
|
||||||
buf->append(p.first);
|
buf->append(p.first);
|
||||||
buf->append(": ");
|
buf->append(": ");
|
||||||
buf->append(p.second);
|
buf->append(p.second);
|
||||||
|
|
|
@ -88,7 +88,7 @@ int htp_uricb(http_parser *htp, const char *data, size_t len) {
|
||||||
// We happen to have the same value for method token.
|
// We happen to have the same value for method token.
|
||||||
req.method = htp->method;
|
req.method = htp->method;
|
||||||
|
|
||||||
if (req.fs.buffer_size() + len > get_config()->header_field_buffer) {
|
if (req.fs.buffer_size() + len > get_config()->http.header_field_buffer) {
|
||||||
if (LOG_ENABLED(INFO)) {
|
if (LOG_ENABLED(INFO)) {
|
||||||
ULOG(INFO, upstream) << "Too large URI size="
|
ULOG(INFO, upstream) << "Too large URI size="
|
||||||
<< req.fs.buffer_size() + len;
|
<< req.fs.buffer_size() + len;
|
||||||
|
@ -115,8 +115,9 @@ int htp_hdr_keycb(http_parser *htp, const char *data, size_t len) {
|
||||||
auto upstream = static_cast<HttpsUpstream *>(htp->data);
|
auto upstream = static_cast<HttpsUpstream *>(htp->data);
|
||||||
auto downstream = upstream->get_downstream();
|
auto downstream = upstream->get_downstream();
|
||||||
auto &req = downstream->request();
|
auto &req = downstream->request();
|
||||||
|
auto &httpconf = get_config()->http;
|
||||||
|
|
||||||
if (req.fs.buffer_size() + len > get_config()->header_field_buffer) {
|
if (req.fs.buffer_size() + len > httpconf.header_field_buffer) {
|
||||||
if (LOG_ENABLED(INFO)) {
|
if (LOG_ENABLED(INFO)) {
|
||||||
ULOG(INFO, upstream) << "Too large header block size="
|
ULOG(INFO, upstream) << "Too large header block size="
|
||||||
<< req.fs.buffer_size() + len;
|
<< req.fs.buffer_size() + len;
|
||||||
|
@ -130,7 +131,7 @@ int htp_hdr_keycb(http_parser *htp, const char *data, size_t len) {
|
||||||
if (req.fs.header_key_prev()) {
|
if (req.fs.header_key_prev()) {
|
||||||
req.fs.append_last_header_key(data, len);
|
req.fs.append_last_header_key(data, len);
|
||||||
} else {
|
} else {
|
||||||
if (req.fs.num_fields() >= get_config()->max_header_fields) {
|
if (req.fs.num_fields() >= httpconf.max_header_fields) {
|
||||||
if (LOG_ENABLED(INFO)) {
|
if (LOG_ENABLED(INFO)) {
|
||||||
ULOG(INFO, upstream)
|
ULOG(INFO, upstream)
|
||||||
<< "Too many header field num=" << req.fs.num_fields() + 1;
|
<< "Too many header field num=" << req.fs.num_fields() + 1;
|
||||||
|
@ -146,7 +147,7 @@ int htp_hdr_keycb(http_parser *htp, const char *data, size_t len) {
|
||||||
if (req.fs.trailer_key_prev()) {
|
if (req.fs.trailer_key_prev()) {
|
||||||
req.fs.append_last_trailer_key(data, len);
|
req.fs.append_last_trailer_key(data, len);
|
||||||
} else {
|
} else {
|
||||||
if (req.fs.num_fields() >= get_config()->max_header_fields) {
|
if (req.fs.num_fields() >= httpconf.max_header_fields) {
|
||||||
if (LOG_ENABLED(INFO)) {
|
if (LOG_ENABLED(INFO)) {
|
||||||
ULOG(INFO, upstream)
|
ULOG(INFO, upstream)
|
||||||
<< "Too many header field num=" << req.fs.num_fields() + 1;
|
<< "Too many header field num=" << req.fs.num_fields() + 1;
|
||||||
|
@ -166,7 +167,7 @@ int htp_hdr_valcb(http_parser *htp, const char *data, size_t len) {
|
||||||
auto downstream = upstream->get_downstream();
|
auto downstream = upstream->get_downstream();
|
||||||
auto &req = downstream->request();
|
auto &req = downstream->request();
|
||||||
|
|
||||||
if (req.fs.buffer_size() + len > get_config()->header_field_buffer) {
|
if (req.fs.buffer_size() + len > get_config()->http.header_field_buffer) {
|
||||||
if (LOG_ENABLED(INFO)) {
|
if (LOG_ENABLED(INFO)) {
|
||||||
ULOG(INFO, upstream) << "Too large header block size="
|
ULOG(INFO, upstream) << "Too large header block size="
|
||||||
<< req.fs.buffer_size() + len;
|
<< req.fs.buffer_size() + len;
|
||||||
|
@ -802,7 +803,7 @@ int HttpsUpstream::send_reply(Downstream *downstream, const uint8_t *body,
|
||||||
|
|
||||||
if (!resp.fs.header(http2::HD_SERVER)) {
|
if (!resp.fs.header(http2::HD_SERVER)) {
|
||||||
output->append("Server: ");
|
output->append("Server: ");
|
||||||
output->append(get_config()->server_name);
|
output->append(get_config()->http.server_name);
|
||||||
output->append("\r\n");
|
output->append("\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -839,8 +840,7 @@ void HttpsUpstream::error_reply(unsigned int status_code) {
|
||||||
auto status_str = http2::get_status_string(status_code);
|
auto status_str = http2::get_status_string(status_code);
|
||||||
output->append(status_str);
|
output->append(status_str);
|
||||||
output->append("\r\nServer: ");
|
output->append("\r\nServer: ");
|
||||||
const auto &server_name = get_config()->server_name;
|
output->append(get_config()->http.server_name);
|
||||||
output->append(server_name);
|
|
||||||
output->append("\r\nContent-Length: ");
|
output->append("\r\nContent-Length: ");
|
||||||
auto cl = util::utos(html.size());
|
auto cl = util::utos(html.size());
|
||||||
output->append(cl);
|
output->append(cl);
|
||||||
|
@ -927,8 +927,10 @@ int HttpsUpstream::on_downstream_header_complete(Downstream *downstream) {
|
||||||
buf->append(http2::get_status_string(resp.http_status));
|
buf->append(http2::get_status_string(resp.http_status));
|
||||||
buf->append("\r\n");
|
buf->append("\r\n");
|
||||||
|
|
||||||
|
auto &httpconf = get_config()->http;
|
||||||
|
|
||||||
if (!get_config()->http2_proxy && !get_config()->client_proxy &&
|
if (!get_config()->http2_proxy && !get_config()->client_proxy &&
|
||||||
!get_config()->no_location_rewrite) {
|
!httpconf.no_location_rewrite) {
|
||||||
downstream->rewrite_location_response_header(
|
downstream->rewrite_location_response_header(
|
||||||
get_client_handler()->get_upstream_scheme());
|
get_client_handler()->get_upstream_scheme());
|
||||||
}
|
}
|
||||||
|
@ -984,10 +986,10 @@ int HttpsUpstream::on_downstream_header_complete(Downstream *downstream) {
|
||||||
|
|
||||||
if (!resp.fs.header(http2::HD_ALT_SVC)) {
|
if (!resp.fs.header(http2::HD_ALT_SVC)) {
|
||||||
// We won't change or alter alt-svc from backend for now
|
// We won't change or alter alt-svc from backend for now
|
||||||
if (!get_config()->altsvcs.empty()) {
|
if (!httpconf.altsvcs.empty()) {
|
||||||
buf->append("Alt-Svc: ");
|
buf->append("Alt-Svc: ");
|
||||||
|
|
||||||
auto &altsvcs = get_config()->altsvcs;
|
auto &altsvcs = httpconf.altsvcs;
|
||||||
write_altsvc(buf, altsvcs[0]);
|
write_altsvc(buf, altsvcs[0]);
|
||||||
for (size_t i = 1; i < altsvcs.size(); ++i) {
|
for (size_t i = 1; i < altsvcs.size(); ++i) {
|
||||||
buf->append(", ");
|
buf->append(", ");
|
||||||
|
@ -999,7 +1001,7 @@ int HttpsUpstream::on_downstream_header_complete(Downstream *downstream) {
|
||||||
|
|
||||||
if (!get_config()->http2_proxy && !get_config()->client_proxy) {
|
if (!get_config()->http2_proxy && !get_config()->client_proxy) {
|
||||||
buf->append("Server: ");
|
buf->append("Server: ");
|
||||||
buf->append(get_config()->server_name);
|
buf->append(httpconf.server_name);
|
||||||
buf->append("\r\n");
|
buf->append("\r\n");
|
||||||
} else {
|
} else {
|
||||||
auto server = resp.fs.header(http2::HD_SERVER);
|
auto server = resp.fs.header(http2::HD_SERVER);
|
||||||
|
@ -1011,7 +1013,7 @@ int HttpsUpstream::on_downstream_header_complete(Downstream *downstream) {
|
||||||
}
|
}
|
||||||
|
|
||||||
auto via = resp.fs.header(http2::HD_VIA);
|
auto via = resp.fs.header(http2::HD_VIA);
|
||||||
if (get_config()->no_via) {
|
if (httpconf.no_via) {
|
||||||
if (via) {
|
if (via) {
|
||||||
buf->append("Via: ");
|
buf->append("Via: ");
|
||||||
buf->append((*via).value);
|
buf->append((*via).value);
|
||||||
|
@ -1028,7 +1030,7 @@ int HttpsUpstream::on_downstream_header_complete(Downstream *downstream) {
|
||||||
buf->append("\r\n");
|
buf->append("\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto &p : get_config()->add_response_headers) {
|
for (auto &p : httpconf.add_response_headers) {
|
||||||
buf->append(p.first);
|
buf->append(p.first);
|
||||||
buf->append(": ");
|
buf->append(": ");
|
||||||
buf->append(p.second);
|
buf->append(p.second);
|
||||||
|
|
|
@ -173,10 +173,12 @@ void on_ctrl_recv_callback(spdylay_session *session, spdylay_frame_type type,
|
||||||
header_buffer += strlen(nv[i]) + strlen(nv[i + 1]);
|
header_buffer += strlen(nv[i]) + strlen(nv[i + 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto &httpconf = get_config()->http;
|
||||||
|
|
||||||
// spdy does not define usage of trailer fields, and we ignores
|
// spdy does not define usage of trailer fields, and we ignores
|
||||||
// them.
|
// them.
|
||||||
if (header_buffer > get_config()->header_field_buffer ||
|
if (header_buffer > httpconf.header_field_buffer ||
|
||||||
num_headers > get_config()->max_header_fields) {
|
num_headers > httpconf.max_header_fields) {
|
||||||
upstream->rst_stream(downstream, SPDYLAY_INTERNAL_ERROR);
|
upstream->rst_stream(downstream, SPDYLAY_INTERNAL_ERROR);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -370,31 +372,33 @@ void on_data_chunk_recv_callback(spdylay_session *session, uint8_t flags,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto &http2conf = get_config()->http2;
|
||||||
|
|
||||||
// If connection-level window control is not enabled (e.g,
|
// If connection-level window control is not enabled (e.g,
|
||||||
// spdy/3), spdylay_session_get_recv_data_length() is always
|
// spdy/3), spdylay_session_get_recv_data_length() is always
|
||||||
// returns 0.
|
// returns 0.
|
||||||
if (spdylay_session_get_recv_data_length(session) >
|
if (spdylay_session_get_recv_data_length(session) >
|
||||||
std::max(SPDYLAY_INITIAL_WINDOW_SIZE,
|
std::max(SPDYLAY_INITIAL_WINDOW_SIZE,
|
||||||
1 << get_config()->http2_upstream_connection_window_bits)) {
|
1 << http2conf.upstream.connection_window_bits)) {
|
||||||
if (LOG_ENABLED(INFO)) {
|
if (LOG_ENABLED(INFO)) {
|
||||||
ULOG(INFO, upstream)
|
ULOG(INFO, upstream) << "Flow control error on connection: "
|
||||||
<< "Flow control error on connection: "
|
<< "recv_window_size="
|
||||||
<< "recv_window_size="
|
<< spdylay_session_get_recv_data_length(session)
|
||||||
<< spdylay_session_get_recv_data_length(session) << ", window_size="
|
<< ", window_size="
|
||||||
<< (1 << get_config()->http2_upstream_connection_window_bits);
|
<< (1 << http2conf.upstream.connection_window_bits);
|
||||||
}
|
}
|
||||||
spdylay_session_fail_session(session, SPDYLAY_GOAWAY_PROTOCOL_ERROR);
|
spdylay_session_fail_session(session, SPDYLAY_GOAWAY_PROTOCOL_ERROR);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (spdylay_session_get_stream_recv_data_length(session, stream_id) >
|
if (spdylay_session_get_stream_recv_data_length(session, stream_id) >
|
||||||
std::max(SPDYLAY_INITIAL_WINDOW_SIZE,
|
std::max(SPDYLAY_INITIAL_WINDOW_SIZE,
|
||||||
1 << get_config()->http2_upstream_window_bits)) {
|
1 << http2conf.upstream.window_bits)) {
|
||||||
if (LOG_ENABLED(INFO)) {
|
if (LOG_ENABLED(INFO)) {
|
||||||
ULOG(INFO, upstream) << "Flow control error: recv_window_size="
|
ULOG(INFO, upstream) << "Flow control error: recv_window_size="
|
||||||
<< spdylay_session_get_stream_recv_data_length(
|
<< spdylay_session_get_stream_recv_data_length(
|
||||||
session, stream_id)
|
session, stream_id)
|
||||||
<< ", initial_window_size="
|
<< ", initial_window_size="
|
||||||
<< (1 << get_config()->http2_upstream_window_bits);
|
<< (1 << http2conf.upstream.window_bits);
|
||||||
}
|
}
|
||||||
upstream->rst_stream(downstream, SPDYLAY_FLOW_CONTROL_ERROR);
|
upstream->rst_stream(downstream, SPDYLAY_FLOW_CONTROL_ERROR);
|
||||||
return;
|
return;
|
||||||
|
@ -518,10 +522,12 @@ SpdyUpstream::SpdyUpstream(uint16_t version, ClientHandler *handler)
|
||||||
&max_buffer, sizeof(max_buffer));
|
&max_buffer, sizeof(max_buffer));
|
||||||
assert(rv == 0);
|
assert(rv == 0);
|
||||||
|
|
||||||
|
auto &http2conf = get_config()->http2;
|
||||||
|
|
||||||
if (version >= SPDYLAY_PROTO_SPDY3) {
|
if (version >= SPDYLAY_PROTO_SPDY3) {
|
||||||
int val = 1;
|
int val = 1;
|
||||||
flow_control_ = true;
|
flow_control_ = true;
|
||||||
initial_window_size_ = 1 << get_config()->http2_upstream_window_bits;
|
initial_window_size_ = 1 << http2conf.upstream.window_bits;
|
||||||
rv = spdylay_session_set_option(
|
rv = spdylay_session_set_option(
|
||||||
session_, SPDYLAY_OPT_NO_AUTO_WINDOW_UPDATE2, &val, sizeof(val));
|
session_, SPDYLAY_OPT_NO_AUTO_WINDOW_UPDATE2, &val, sizeof(val));
|
||||||
assert(rv == 0);
|
assert(rv == 0);
|
||||||
|
@ -532,7 +538,7 @@ SpdyUpstream::SpdyUpstream(uint16_t version, ClientHandler *handler)
|
||||||
// TODO Maybe call from outside?
|
// TODO Maybe call from outside?
|
||||||
std::array<spdylay_settings_entry, 2> entry;
|
std::array<spdylay_settings_entry, 2> entry;
|
||||||
entry[0].settings_id = SPDYLAY_SETTINGS_MAX_CONCURRENT_STREAMS;
|
entry[0].settings_id = SPDYLAY_SETTINGS_MAX_CONCURRENT_STREAMS;
|
||||||
entry[0].value = get_config()->http2_max_concurrent_streams;
|
entry[0].value = http2conf.max_concurrent_streams;
|
||||||
entry[0].flags = SPDYLAY_ID_FLAG_SETTINGS_NONE;
|
entry[0].flags = SPDYLAY_ID_FLAG_SETTINGS_NONE;
|
||||||
|
|
||||||
entry[1].settings_id = SPDYLAY_SETTINGS_INITIAL_WINDOW_SIZE;
|
entry[1].settings_id = SPDYLAY_SETTINGS_INITIAL_WINDOW_SIZE;
|
||||||
|
@ -544,8 +550,8 @@ SpdyUpstream::SpdyUpstream(uint16_t version, ClientHandler *handler)
|
||||||
assert(rv == 0);
|
assert(rv == 0);
|
||||||
|
|
||||||
if (version >= SPDYLAY_PROTO_SPDY3_1 &&
|
if (version >= SPDYLAY_PROTO_SPDY3_1 &&
|
||||||
get_config()->http2_upstream_connection_window_bits > 16) {
|
http2conf.upstream.connection_window_bits > 16) {
|
||||||
int32_t delta = (1 << get_config()->http2_upstream_connection_window_bits) -
|
int32_t delta = (1 << http2conf.upstream.connection_window_bits) -
|
||||||
SPDYLAY_INITIAL_WINDOW_SIZE;
|
SPDYLAY_INITIAL_WINDOW_SIZE;
|
||||||
rv = spdylay_submit_window_update(session_, 0, delta);
|
rv = spdylay_submit_window_update(session_, 0, delta);
|
||||||
assert(rv == 0);
|
assert(rv == 0);
|
||||||
|
@ -875,7 +881,7 @@ int SpdyUpstream::send_reply(Downstream *downstream, const uint8_t *body,
|
||||||
|
|
||||||
if (!resp.fs.header(http2::HD_SERVER)) {
|
if (!resp.fs.header(http2::HD_SERVER)) {
|
||||||
nva.push_back("server");
|
nva.push_back("server");
|
||||||
nva.push_back(get_config()->server_name.c_str());
|
nva.push_back(get_config()->http.server_name.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
nva.push_back(nullptr);
|
nva.push_back(nullptr);
|
||||||
|
@ -919,7 +925,7 @@ int SpdyUpstream::error_reply(Downstream *downstream,
|
||||||
std::string status_string = http2::get_status_string(status_code);
|
std::string status_string = http2::get_status_string(status_code);
|
||||||
const char *nv[] = {":status", status_string.c_str(), ":version", "http/1.1",
|
const char *nv[] = {":status", status_string.c_str(), ":version", "http/1.1",
|
||||||
"content-type", "text/html; charset=UTF-8", "server",
|
"content-type", "text/html; charset=UTF-8", "server",
|
||||||
get_config()->server_name.c_str(), "content-length",
|
get_config()->http.server_name.c_str(), "content-length",
|
||||||
content_length.c_str(), "date",
|
content_length.c_str(), "date",
|
||||||
lgconf->time_http_str.c_str(), nullptr};
|
lgconf->time_http_str.c_str(), nullptr};
|
||||||
|
|
||||||
|
@ -997,15 +1003,17 @@ int SpdyUpstream::on_downstream_header_complete(Downstream *downstream) {
|
||||||
DLOG(INFO, downstream) << "HTTP response header completed";
|
DLOG(INFO, downstream) << "HTTP response header completed";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto &httpconf = get_config()->http;
|
||||||
|
|
||||||
if (!get_config()->http2_proxy && !get_config()->client_proxy &&
|
if (!get_config()->http2_proxy && !get_config()->client_proxy &&
|
||||||
!get_config()->no_location_rewrite) {
|
!httpconf.no_location_rewrite) {
|
||||||
downstream->rewrite_location_response_header(req.scheme);
|
downstream->rewrite_location_response_header(req.scheme);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 8 means server, :status, :version and possible via header field.
|
// 8 means server, :status, :version and possible via header field.
|
||||||
auto nv = make_unique<const char *[]>(
|
auto nv =
|
||||||
resp.fs.headers().size() * 2 + 8 +
|
make_unique<const char *[]>(resp.fs.headers().size() * 2 + 8 +
|
||||||
get_config()->add_response_headers.size() * 2 + 1);
|
httpconf.add_response_headers.size() * 2 + 1);
|
||||||
|
|
||||||
size_t hdidx = 0;
|
size_t hdidx = 0;
|
||||||
std::string via_value;
|
std::string via_value;
|
||||||
|
@ -1034,7 +1042,7 @@ int SpdyUpstream::on_downstream_header_complete(Downstream *downstream) {
|
||||||
|
|
||||||
if (!get_config()->http2_proxy && !get_config()->client_proxy) {
|
if (!get_config()->http2_proxy && !get_config()->client_proxy) {
|
||||||
nv[hdidx++] = "server";
|
nv[hdidx++] = "server";
|
||||||
nv[hdidx++] = get_config()->server_name.c_str();
|
nv[hdidx++] = httpconf.server_name.c_str();
|
||||||
} else {
|
} else {
|
||||||
auto server = resp.fs.header(http2::HD_SERVER);
|
auto server = resp.fs.header(http2::HD_SERVER);
|
||||||
if (server) {
|
if (server) {
|
||||||
|
@ -1044,7 +1052,7 @@ int SpdyUpstream::on_downstream_header_complete(Downstream *downstream) {
|
||||||
}
|
}
|
||||||
|
|
||||||
auto via = resp.fs.header(http2::HD_VIA);
|
auto via = resp.fs.header(http2::HD_VIA);
|
||||||
if (get_config()->no_via) {
|
if (httpconf.no_via) {
|
||||||
if (via) {
|
if (via) {
|
||||||
nv[hdidx++] = "via";
|
nv[hdidx++] = "via";
|
||||||
nv[hdidx++] = via->value.c_str();
|
nv[hdidx++] = via->value.c_str();
|
||||||
|
@ -1060,7 +1068,7 @@ int SpdyUpstream::on_downstream_header_complete(Downstream *downstream) {
|
||||||
nv[hdidx++] = via_value.c_str();
|
nv[hdidx++] = via_value.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto &p : get_config()->add_response_headers) {
|
for (auto &p : httpconf.add_response_headers) {
|
||||||
nv[hdidx++] = p.first.c_str();
|
nv[hdidx++] = p.first.c_str();
|
||||||
nv[hdidx++] = p.second.c_str();
|
nv[hdidx++] = p.second.c_str();
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,7 +91,7 @@ Worker::Worker(struct ev_loop *loop, SSL_CTX *sv_ssl_ctx, SSL_CTX *cl_ssl_ctx,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (get_config()->downstream_proto == PROTO_HTTP2) {
|
if (get_config()->downstream_proto == PROTO_HTTP2) {
|
||||||
auto n = get_config()->http2_downstream_connections_per_worker;
|
auto n = get_config()->http2.downstream.connections_per_worker;
|
||||||
size_t group = 0;
|
size_t group = 0;
|
||||||
for (auto &dgrp : dgrps_) {
|
for (auto &dgrp : dgrps_) {
|
||||||
auto m = n;
|
auto m = n;
|
||||||
|
|
Loading…
Reference in New Issue