nghttpx: Don't call get_config() repeatedly

This commit is contained in:
Tatsuhiro Tsujikawa 2016-10-08 11:34:23 +09:00
parent 8babaac8c3
commit 1b4ccd0d51
13 changed files with 207 additions and 181 deletions

View File

@ -291,16 +291,19 @@ int worker_process_last_pid() {
namespace { namespace {
int chown_to_running_user(const char *path) { int chown_to_running_user(const char *path) {
return chown(path, get_config()->uid, get_config()->gid); auto config = get_config();
return chown(path, config->uid, config->gid);
} }
} // namespace } // namespace
namespace { namespace {
int save_pid() { int save_pid() {
constexpr auto SUFFIX = StringRef::from_lit(".XXXXXX"); auto config = get_config();
auto &pid_file = get_config()->pid_file;
auto len = get_config()->pid_file.size() + SUFFIX.size(); constexpr auto SUFFIX = StringRef::from_lit(".XXXXXX");
auto &pid_file = config->pid_file;
auto len = config->pid_file.size() + SUFFIX.size();
auto buf = make_unique<char[]>(len + 1); auto buf = make_unique<char[]>(len + 1);
auto p = buf.get(); auto p = buf.get();
@ -318,7 +321,7 @@ int save_pid() {
return -1; return -1;
} }
auto content = util::utos(get_config()->pid) + '\n'; auto content = util::utos(config->pid) + '\n';
if (write(fd, content.c_str(), content.size()) == -1) { if (write(fd, content.c_str(), content.size()) == -1) {
auto error = errno; auto error = errno;
@ -346,7 +349,7 @@ int save_pid() {
return -1; return -1;
} }
if (get_config()->uid != 0) { if (config->uid != 0) {
if (chown_to_running_user(pid_file.c_str()) == -1) { if (chown_to_running_user(pid_file.c_str()) == -1) {
auto error = errno; auto error = errno;
LOG(WARN) << "Changing owner of pid file " << pid_file LOG(WARN) << "Changing owner of pid file " << pid_file
@ -1195,7 +1198,9 @@ namespace {
int event_loop() { int event_loop() {
shrpx_signal_set_master_proc_ign_handler(); shrpx_signal_set_master_proc_ign_handler();
if (get_config()->daemon) { auto config = mod_config();
if (config->daemon) {
if (call_daemon() == -1) { if (call_daemon() == -1) {
auto error = errno; auto error = errno;
LOG(FATAL) << "Failed to daemonize: " << strerror(error); LOG(FATAL) << "Failed to daemonize: " << strerror(error);
@ -1210,15 +1215,15 @@ int event_loop() {
redirect_stderr_to_errorlog(); redirect_stderr_to_errorlog();
} }
auto iaddrs = get_inherited_addr_from_env(mod_config()); auto iaddrs = get_inherited_addr_from_env(config);
if (create_acceptor_socket(mod_config(), iaddrs) != 0) { if (create_acceptor_socket(config, iaddrs) != 0) {
return -1; return -1;
} }
close_unused_inherited_addr(iaddrs); close_unused_inherited_addr(iaddrs);
auto loop = ev_default_loop(get_config()->ev_loop_flags); auto loop = ev_default_loop(config->ev_loop_flags);
int ipc_fd; int ipc_fd;
@ -1234,7 +1239,7 @@ int event_loop() {
// This makes easier to write restart script for nghttpx. Because // This makes easier to write restart script for nghttpx. Because
// when we know that PID file is recreated, it means we can send // when we know that PID file is recreated, it means we can send
// QUIT signal to the old process to make it shutdown gracefully. // QUIT signal to the old process to make it shutdown gracefully.
if (!get_config()->pid_file.empty()) { if (!config->pid_file.empty()) {
save_pid(); save_pid();
} }
@ -1467,6 +1472,8 @@ A reverse proxy for HTTP/2, HTTP/1 and SPDY.)" << std::endl;
namespace { namespace {
void print_help(std::ostream &out) { void print_help(std::ostream &out) {
auto config = get_config();
print_usage(out); print_usage(out);
out << R"( out << R"(
<PRIVATE_KEY> <PRIVATE_KEY>
@ -1637,7 +1644,7 @@ Connections:
Default: *,3000 Default: *,3000
--backlog=<N> --backlog=<N>
Set listen backlog size. Set listen backlog size.
Default: )" << get_config()->conn.listener.backlog << R"( Default: )" << config->conn.listener.backlog << R"(
--backend-address-family=(auto|IPv4|IPv6) --backend-address-family=(auto|IPv4|IPv6)
Specify address family of backend connections. If Specify address family of backend connections. If
"auto" is given, both IPv4 and IPv6 are considered. If "auto" is given, both IPv4 and IPv6 are considered. If
@ -1663,29 +1670,25 @@ Connections:
Performance: Performance:
-n, --workers=<N> -n, --workers=<N>
Set the number of worker threads. Set the number of worker threads.
Default: )" << get_config()->num_worker << R"( Default: )" << config->num_worker << R"(
--read-rate=<SIZE> --read-rate=<SIZE>
Set maximum average read rate on frontend connection. Set maximum average read rate on frontend connection.
Setting 0 to this option means read rate is unlimited. Setting 0 to this option means read rate is unlimited.
Default: )" << get_config()->conn.upstream.ratelimit.read.rate Default: )" << config->conn.upstream.ratelimit.read.rate << R"(
<< R"(
--read-burst=<SIZE> --read-burst=<SIZE>
Set maximum read burst size on frontend connection. Set maximum read burst size on frontend connection.
Setting 0 to this option means read burst size is Setting 0 to this option means read burst size is
unlimited. unlimited.
Default: )" << get_config()->conn.upstream.ratelimit.read.burst Default: )" << config->conn.upstream.ratelimit.read.burst << R"(
<< R"(
--write-rate=<SIZE> --write-rate=<SIZE>
Set maximum average write rate on frontend connection. Set maximum average write rate on frontend connection.
Setting 0 to this option means write rate is unlimited. Setting 0 to this option means write rate is unlimited.
Default: )" << get_config()->conn.upstream.ratelimit.write.rate Default: )" << config->conn.upstream.ratelimit.write.rate << R"(
<< R"(
--write-burst=<SIZE> --write-burst=<SIZE>
Set maximum write burst size on frontend connection. Set maximum write burst size on frontend connection.
Setting 0 to this option means write burst size is Setting 0 to this option means write burst size is
unlimited. unlimited.
Default: )" << get_config()->conn.upstream.ratelimit.write.burst Default: )" << config->conn.upstream.ratelimit.write.burst << R"(
<< R"(
--worker-read-rate=<SIZE> --worker-read-rate=<SIZE>
Set maximum average read rate on frontend connection per Set maximum average read rate on frontend connection per
worker. Setting 0 to this option means read rate is worker. Setting 0 to this option means read rate is
@ -1709,8 +1712,7 @@ Performance:
--worker-frontend-connections=<N> --worker-frontend-connections=<N>
Set maximum number of simultaneous connections frontend Set maximum number of simultaneous connections frontend
accepts. Setting 0 means unlimited. accepts. Setting 0 means unlimited.
Default: )" << get_config()->conn.upstream.worker_connections Default: )" << config->conn.upstream.worker_connections << R"(
<< R"(
--backend-connections-per-host=<N> --backend-connections-per-host=<N>
Set maximum number of backend concurrent connections Set maximum number of backend concurrent connections
(and/or streams in case of HTTP/2) per origin host. (and/or streams in case of HTTP/2) per origin host.
@ -1720,7 +1722,7 @@ Performance:
HTTP/2). To limit the number of connections per HTTP/2). To limit the number of connections per
frontend for default mode, use frontend for default mode, use
--backend-connections-per-frontend. --backend-connections-per-frontend.
Default: )" << get_config()->conn.downstream->connections_per_host Default: )" << config->conn.downstream->connections_per_host
<< R"( << R"(
--backend-connections-per-frontend=<N> --backend-connections-per-frontend=<N>
Set maximum number of backend concurrent connections Set maximum number of backend concurrent connections
@ -1729,28 +1731,26 @@ Performance:
unlimited. To limit the number of connections per host unlimited. To limit the number of connections per host
with --http2-proxy option, use with --http2-proxy option, use
--backend-connections-per-host. --backend-connections-per-host.
Default: )" Default: )" << config->conn.downstream->connections_per_frontend
<< get_config()->conn.downstream->connections_per_frontend << R"( << R"(
--rlimit-nofile=<N> --rlimit-nofile=<N>
Set maximum number of open files (RLIMIT_NOFILE) to <N>. Set maximum number of open files (RLIMIT_NOFILE) to <N>.
If 0 is given, nghttpx does not set the limit. If 0 is given, nghttpx does not set the limit.
Default: )" << get_config()->rlimit_nofile << R"( Default: )" << config->rlimit_nofile << R"(
--backend-request-buffer=<SIZE> --backend-request-buffer=<SIZE>
Set buffer size used to store backend request. Set buffer size used to store backend request.
Default: )" Default: )"
<< util::utos_unit(get_config()->conn.downstream->request_buffer_size) << util::utos_unit(config->conn.downstream->request_buffer_size) << R"(
<< R"(
--backend-response-buffer=<SIZE> --backend-response-buffer=<SIZE>
Set buffer size used to store backend response. Set buffer size used to store backend response.
Default: )" Default: )"
<< util::utos_unit(get_config()->conn.downstream->response_buffer_size) << util::utos_unit(config->conn.downstream->response_buffer_size) << R"(
<< R"(
--fastopen=<N> --fastopen=<N>
Enables "TCP Fast Open" for the listening socket and Enables "TCP Fast Open" for the listening socket and
limits the maximum length for the queue of connections limits the maximum length for the queue of connections
that have not yet completed the three-way handshake. If that have not yet completed the three-way handshake. If
value is 0 then fast open is disabled. value is 0 then fast open is disabled.
Default: )" << get_config()->conn.listener.fastopen << R"( Default: )" << config->conn.listener.fastopen << R"(
--no-kqueue Don't use kqueue. This option is only applicable for --no-kqueue Don't use kqueue. This option is only applicable for
the platforms which have kqueue. For other platforms, the platforms which have kqueue. For other platforms,
this option will be simply ignored. this option will be simply ignored.
@ -1760,57 +1760,53 @@ Timeout:
Specify read timeout for HTTP/2 and SPDY frontend Specify read timeout for HTTP/2 and SPDY frontend
connection. connection.
Default: )" Default: )"
<< util::duration_str(get_config()->conn.upstream.timeout.http2_read) << util::duration_str(config->conn.upstream.timeout.http2_read) << R"(
<< R"(
--frontend-read-timeout=<DURATION> --frontend-read-timeout=<DURATION>
Specify read timeout for HTTP/1.1 frontend connection. Specify read timeout for HTTP/1.1 frontend connection.
Default: )" Default: )"
<< util::duration_str(get_config()->conn.upstream.timeout.read) << R"( << util::duration_str(config->conn.upstream.timeout.read) << R"(
--frontend-write-timeout=<DURATION> --frontend-write-timeout=<DURATION>
Specify write timeout for all frontend connections. Specify write timeout for all frontend connections.
Default: )" Default: )"
<< util::duration_str(get_config()->conn.upstream.timeout.write) << R"( << util::duration_str(config->conn.upstream.timeout.write) << R"(
--stream-read-timeout=<DURATION> --stream-read-timeout=<DURATION>
Specify read timeout for HTTP/2 and SPDY streams. 0 Specify read timeout for HTTP/2 and SPDY streams. 0
means no timeout. means no timeout.
Default: )" Default: )"
<< util::duration_str(get_config()->http2.timeout.stream_read) << R"( << util::duration_str(config->http2.timeout.stream_read) << R"(
--stream-write-timeout=<DURATION> --stream-write-timeout=<DURATION>
Specify write timeout for HTTP/2 and SPDY streams. 0 Specify write timeout for HTTP/2 and SPDY streams. 0
means no timeout. means no timeout.
Default: )" Default: )"
<< util::duration_str(get_config()->http2.timeout.stream_write) << R"( << util::duration_str(config->http2.timeout.stream_write) << R"(
--backend-read-timeout=<DURATION> --backend-read-timeout=<DURATION>
Specify read timeout for backend connection. Specify read timeout for backend connection.
Default: )" Default: )"
<< util::duration_str(get_config()->conn.downstream->timeout.read) << R"( << util::duration_str(config->conn.downstream->timeout.read) << R"(
--backend-write-timeout=<DURATION> --backend-write-timeout=<DURATION>
Specify write timeout for backend connection. Specify write timeout for backend connection.
Default: )" Default: )"
<< util::duration_str(get_config()->conn.downstream->timeout.write) << R"( << util::duration_str(config->conn.downstream->timeout.write) << R"(
--backend-keep-alive-timeout=<DURATION> --backend-keep-alive-timeout=<DURATION>
Specify keep-alive timeout for backend connection. Specify keep-alive timeout for backend connection.
Default: )" Default: )"
<< util::duration_str(get_config()->conn.downstream->timeout.idle_read) << util::duration_str(config->conn.downstream->timeout.idle_read) << R"(
<< R"(
--listener-disable-timeout=<DURATION> --listener-disable-timeout=<DURATION>
After accepting connection failed, connection listener After accepting connection failed, connection listener
is disabled for a given amount of time. Specifying 0 is disabled for a given amount of time. Specifying 0
disables this feature. disables this feature.
Default: )" Default: )"
<< util::duration_str(get_config()->conn.listener.timeout.sleep) << R"( << util::duration_str(config->conn.listener.timeout.sleep) << R"(
--frontend-http2-setting-timeout=<DURATION> --frontend-http2-setting-timeout=<DURATION>
Specify timeout before SETTINGS ACK is received from Specify timeout before SETTINGS ACK is received from
client. client.
Default: )" Default: )"
<< util::duration_str(get_config()->http2.upstream.timeout.settings) << util::duration_str(config->http2.upstream.timeout.settings) << R"(
<< R"(
--backend-http2-settings-timeout=<DURATION> --backend-http2-settings-timeout=<DURATION>
Specify timeout before SETTINGS ACK is received from Specify timeout before SETTINGS ACK is received from
backend server. backend server.
Default: )" Default: )"
<< util::duration_str(get_config()->http2.downstream.timeout.settings) << util::duration_str(config->http2.downstream.timeout.settings) << R"(
<< R"(
--backend-max-backoff=<DURATION> --backend-max-backoff=<DURATION>
Specify maximum backoff interval. This is used when Specify maximum backoff interval. This is used when
doing health check against offline backend (see "fail" doing health check against offline backend (see "fail"
@ -1821,8 +1817,7 @@ Timeout:
consecutive failed attempts increase the interval. This consecutive failed attempts increase the interval. This
option caps its maximum value. option caps its maximum value.
Default: )" Default: )"
<< util::duration_str(get_config()->conn.downstream->timeout.max_backoff) << util::duration_str(config->conn.downstream->timeout.max_backoff) << R"(
<< R"(
SSL/TLS: SSL/TLS:
--ciphers=<SUITE> --ciphers=<SUITE>
@ -1834,7 +1829,7 @@ SSL/TLS:
in the preference order. The supported curves depend on in the preference order. The supported curves depend on
the linked OpenSSL library. This function requires the linked OpenSSL library. This function requires
OpenSSL >= 1.0.2. OpenSSL >= 1.0.2.
Default: )" << get_config()->tls.ecdh_curves << R"( Default: )" << config->tls.ecdh_curves << R"(
-k, --insecure -k, --insecure
Don't verify backend server's certificate if TLS is Don't verify backend server's certificate if TLS is
enabled for backend connections. enabled for backend connections.
@ -1934,7 +1929,7 @@ SSL/TLS:
--tls-ticket-key-memcached-interval=<DURATION> --tls-ticket-key-memcached-interval=<DURATION>
Set interval to get TLS ticket keys from memcached. Set interval to get TLS ticket keys from memcached.
Default: )" Default: )"
<< util::duration_str(get_config()->tls.ticket.memcached.interval) << R"( << util::duration_str(config->tls.ticket.memcached.interval) << R"(
--tls-ticket-key-memcached-max-retry=<N> --tls-ticket-key-memcached-max-retry=<N>
Set maximum number of consecutive retries before Set maximum number of consecutive retries before
abandoning TLS ticket key retrieval. If this number is abandoning TLS ticket key retrieval. If this number is
@ -1942,11 +1937,11 @@ SSL/TLS:
"failure" count is incremented by 1, which contributed "failure" count is incremented by 1, which contributed
to the value controlled to the value controlled
--tls-ticket-key-memcached-max-fail option. --tls-ticket-key-memcached-max-fail option.
Default: )" << get_config()->tls.ticket.memcached.max_retry << R"( Default: )" << config->tls.ticket.memcached.max_retry << R"(
--tls-ticket-key-memcached-max-fail=<N> --tls-ticket-key-memcached-max-fail=<N>
Set maximum number of consecutive failure before Set maximum number of consecutive failure before
disabling TLS ticket until next scheduled key retrieval. disabling TLS ticket until next scheduled key retrieval.
Default: )" << get_config()->tls.ticket.memcached.max_fail << R"( Default: )" << config->tls.ticket.memcached.max_fail << R"(
--tls-ticket-key-cipher=<CIPHER> --tls-ticket-key-cipher=<CIPHER>
Specify cipher to encrypt TLS session ticket. Specify Specify cipher to encrypt TLS session ticket. Specify
either aes-128-cbc or aes-256-cbc. By default, either aes-128-cbc or aes-256-cbc. By default,
@ -1960,12 +1955,11 @@ SSL/TLS:
--fetch-ocsp-response-file=<PATH> --fetch-ocsp-response-file=<PATH>
Path to fetch-ocsp-response script file. It should be Path to fetch-ocsp-response script file. It should be
absolute path. absolute path.
Default: )" << get_config()->tls.ocsp.fetch_ocsp_response_file Default: )" << config->tls.ocsp.fetch_ocsp_response_file << R"(
<< R"(
--ocsp-update-interval=<DURATION> --ocsp-update-interval=<DURATION>
Set interval to update OCSP response cache. Set interval to update OCSP response cache.
Default: )" Default: )"
<< util::duration_str(get_config()->tls.ocsp.update_interval) << R"( << util::duration_str(config->tls.ocsp.update_interval) << R"(
--no-ocsp Disable OCSP stapling. --no-ocsp Disable OCSP stapling.
--tls-session-cache-memcached=<HOST>,<PORT>[;tls] --tls-session-cache-memcached=<HOST>,<PORT>[;tls]
Specify address of memcached server to store session Specify address of memcached server to store session
@ -1998,14 +1992,14 @@ SSL/TLS:
period. This behaviour applies to all TLS based period. This behaviour applies to all TLS based
frontends, and TLS HTTP/2 backends. frontends, and TLS HTTP/2 backends.
Default: )" Default: )"
<< util::utos_unit(get_config()->tls.dyn_rec.warmup_threshold) << R"( << util::utos_unit(config->tls.dyn_rec.warmup_threshold) << R"(
--tls-dyn-rec-idle-timeout=<DURATION> --tls-dyn-rec-idle-timeout=<DURATION>
Specify TLS dynamic record size behaviour timeout. See Specify TLS dynamic record size behaviour timeout. See
--tls-dyn-rec-warmup-threshold for more information. --tls-dyn-rec-warmup-threshold for more information.
This behaviour applies to all TLS based frontends, and This behaviour applies to all TLS based frontends, and
TLS HTTP/2 backends. TLS HTTP/2 backends.
Default: )" Default: )"
<< util::duration_str(get_config()->tls.dyn_rec.idle_timeout) << R"( << util::duration_str(config->tls.dyn_rec.idle_timeout) << R"(
--no-http2-cipher-black-list --no-http2-cipher-black-list
Allow black listed cipher suite on HTTP/2 connection. Allow black listed cipher suite on HTTP/2 connection.
See https://tools.ietf.org/html/rfc7540#appendix-A for See https://tools.ietf.org/html/rfc7540#appendix-A for
@ -2015,34 +2009,34 @@ HTTP/2 and SPDY:
-c, --frontend-http2-max-concurrent-streams=<N> -c, --frontend-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
frontend HTTP/2 and SPDY session. frontend HTTP/2 and SPDY session.
Default: )" Default: )" << config->http2.upstream.max_concurrent_streams
<< get_config()->http2.upstream.max_concurrent_streams << R"( << R"(
--backend-http2-max-concurrent-streams=<N> --backend-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
backend HTTP/2 session. This sets maximum number of backend HTTP/2 session. This sets maximum number of
concurrent opened pushed streams. The maximum number of concurrent opened pushed streams. The maximum number of
concurrent requests are set by a remote server. concurrent requests are set by a remote server.
Default: )" Default: )" << config->http2.downstream.max_concurrent_streams
<< get_config()->http2.downstream.max_concurrent_streams << R"( << R"(
--frontend-http2-window-size=<SIZE> --frontend-http2-window-size=<SIZE>
Sets the per-stream initial window size of HTTP/2 and Sets the per-stream initial window size of HTTP/2 and
SPDY frontend connection. SPDY frontend connection.
Default: )" << get_config()->http2.upstream.window_size << R"( Default: )" << config->http2.upstream.window_size << R"(
--frontend-http2-connection-window-size=<SIZE> --frontend-http2-connection-window-size=<SIZE>
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 SPDY connection, the value frontend connection. For SPDY connection, the value
less than 64KiB is rounded up to 64KiB. less than 64KiB is rounded up to 64KiB.
Default: )" << get_config()->http2.upstream.connection_window_size Default: )" << config->http2.upstream.connection_window_size
<< R"( << R"(
--backend-http2-window-size=<SIZE> --backend-http2-window-size=<SIZE>
Sets the initial window size of HTTP/2 backend Sets the initial window size of HTTP/2 backend
connection. connection.
Default: )" << get_config()->http2.downstream.window_size << R"( Default: )" << config->http2.downstream.window_size << R"(
--backend-http2-connection-window-size=<SIZE> --backend-http2-connection-window-size=<SIZE>
Sets the per-connection window size of HTTP/2 backend Sets the per-connection window size of HTTP/2 backend
connection. connection.
Default: )" Default: )" << config->http2.downstream.connection_window_size
<< get_config()->http2.downstream.connection_window_size << R"( << R"(
--http2-no-cookie-crumbling --http2-no-cookie-crumbling
Don't crumble cookie header field. Don't crumble cookie header field.
--padding=<N> --padding=<N>
@ -2086,14 +2080,14 @@ HTTP/2 and SPDY:
Then the negotiated dynamic table size is the minimum of Then the negotiated dynamic table size is the minimum of
this option value and the value which client specified. this option value and the value which client specified.
Default: )" Default: )"
<< util::utos_unit( << util::utos_unit(config->http2.upstream.encoder_dynamic_table_size)
get_config()->http2.upstream.encoder_dynamic_table_size) << R"( << R"(
--frontend-http2-decoder-dynamic-table-size=<SIZE> --frontend-http2-decoder-dynamic-table-size=<SIZE>
Specify the maximum dynamic table size of HPACK decoder Specify the maximum dynamic table size of HPACK decoder
in the frontend HTTP/2 connection. in the frontend HTTP/2 connection.
Default: )" Default: )"
<< util::utos_unit( << util::utos_unit(config->http2.upstream.decoder_dynamic_table_size)
get_config()->http2.upstream.decoder_dynamic_table_size) << R"( << R"(
--backend-http2-encoder-dynamic-table-size=<SIZE> --backend-http2-encoder-dynamic-table-size=<SIZE>
Specify the maximum dynamic table size of HPACK encoder Specify the maximum dynamic table size of HPACK encoder
in the backend HTTP/2 connection. The decoder (backend) in the backend HTTP/2 connection. The decoder (backend)
@ -2101,14 +2095,14 @@ HTTP/2 and SPDY:
Then the negotiated dynamic table size is the minimum of Then the negotiated dynamic table size is the minimum of
this option value and the value which backend specified. this option value and the value which backend specified.
Default: )" Default: )"
<< util::utos_unit( << util::utos_unit(config->http2.downstream.encoder_dynamic_table_size)
get_config()->http2.downstream.encoder_dynamic_table_size) << R"( << R"(
--backend-http2-decoder-dynamic-table-size=<SIZE> --backend-http2-decoder-dynamic-table-size=<SIZE>
Specify the maximum dynamic table size of HPACK decoder Specify the maximum dynamic table size of HPACK decoder
in the backend HTTP/2 connection. in the backend HTTP/2 connection.
Default: )" Default: )"
<< util::utos_unit( << util::utos_unit(config->http2.downstream.decoder_dynamic_table_size)
get_config()->http2.downstream.decoder_dynamic_table_size) << R"( << R"(
Mode: Mode:
(default mode) (default mode)
@ -2172,14 +2166,14 @@ Logging:
Set path to write error log. To reopen file, send USR1 Set path to write error log. To reopen file, send USR1
signal to nghttpx. stderr will be redirected to the signal to nghttpx. stderr will be redirected to the
error log file unless --errorlog-syslog is used. error log file unless --errorlog-syslog is used.
Default: )" << get_config()->logging.error.file << R"( Default: )" << config->logging.error.file << R"(
--errorlog-syslog --errorlog-syslog
Send error log to syslog. If this option is used, Send error log to syslog. If this option is used,
--errorlog-file option is ignored. --errorlog-file option is ignored.
--syslog-facility=<FACILITY> --syslog-facility=<FACILITY>
Set syslog facility to <FACILITY>. Set syslog facility to <FACILITY>.
Default: )" Default: )"
<< str_syslog_facility(get_config()->logging.syslog_facility) << R"( << str_syslog_facility(config->logging.syslog_facility) << R"(
HTTP: HTTP:
--add-x-forwarded-for --add-x-forwarded-for
@ -2256,25 +2250,24 @@ HTTP:
bytes. If trailer fields exist, they are counted bytes. If trailer fields exist, they are counted
towards this number. towards this number.
Default: )" Default: )"
<< util::utos_unit(get_config()->http.request_header_field_buffer) << R"( << util::utos_unit(config->http.request_header_field_buffer) << R"(
--max-request-header-fields=<N> --max-request-header-fields=<N>
Set maximum number of incoming HTTP request header Set maximum number of incoming HTTP request header
fields. If trailer fields exist, they are counted fields. If trailer fields exist, they are counted
towards this number. towards this number.
Default: )" << get_config()->http.max_request_header_fields << R"( Default: )" << config->http.max_request_header_fields << R"(
--response-header-field-buffer=<SIZE> --response-header-field-buffer=<SIZE>
Set maximum buffer size for incoming HTTP response Set maximum buffer size for incoming HTTP response
header field list. This is the sum of header name and header field list. This is the sum of header name and
value in bytes. If trailer fields exist, they are value in bytes. If trailer fields exist, they are
counted towards this number. counted towards this number.
Default: )" Default: )"
<< util::utos_unit(get_config()->http.response_header_field_buffer) << R"( << util::utos_unit(config->http.response_header_field_buffer) << R"(
--max-response-header-fields=<N> --max-response-header-fields=<N>
Set maximum number of incoming HTTP response header Set maximum number of incoming HTTP response header
fields. If trailer fields exist, they are counted fields. If trailer fields exist, they are counted
towards this number. towards this number.
Default: )" << get_config()->http.max_response_header_fields Default: )" << config->http.max_response_header_fields << R"(
<< R"(
--error-page=(<CODE>|*)=<PATH> --error-page=(<CODE>|*)=<PATH>
Set file path to custom error page served when nghttpx Set file path to custom error page served when nghttpx
originally generates HTTP error status code <CODE>. originally generates HTTP error status code <CODE>.
@ -2284,7 +2277,7 @@ HTTP:
backend server, the custom error pages are not used. backend server, the custom error pages are not used.
--server-name=<NAME> --server-name=<NAME>
Change server response header field value to <NAME>. Change server response header field value to <NAME>.
Default: )" << get_config()->http.server_name << R"( Default: )" << config->http.server_name << R"(
--no-server-rewrite --no-server-rewrite
Don't rewrite server header field in default mode. When Don't rewrite server header field in default mode. When
--http2-proxy is used, these headers will not be altered --http2-proxy is used, these headers will not be altered
@ -2293,7 +2286,7 @@ HTTP:
API: API:
--api-max-request-body=<SIZE> --api-max-request-body=<SIZE>
Set the maximum size of request body for API request. Set the maximum size of request body for API request.
Default: )" << util::utos_unit(get_config()->api.max_request_body) Default: )" << util::utos_unit(config->api.max_request_body)
<< R"( << R"(
Debug: Debug:
@ -2331,7 +2324,7 @@ Scripting:
Misc: Misc:
--conf=<PATH> --conf=<PATH>
Load configuration from <PATH>. Load configuration from <PATH>.
Default: )" << get_config()->conf_path << R"( Default: )" << config->conf_path << R"(
--include=<PATH> --include=<PATH>
Load additional configurations from <PATH>. File <PATH> Load additional configurations from <PATH>. File <PATH>
is read when configuration parser encountered this is read when configuration parser encountered this

View File

@ -214,11 +214,12 @@ int APIDownstreamConnection::end_upload_data() {
iov[0].iov_len = len; iov[0].iov_len = len;
} }
Config config{}; Config new_config{};
config.conn.downstream = std::make_shared<DownstreamConfig>(); new_config.conn.downstream = std::make_shared<DownstreamConfig>();
const auto &downstreamconf = config.conn.downstream; const auto &downstreamconf = new_config.conn.downstream;
auto &src = get_config()->conn.downstream; auto config = get_config();
auto &src = config->conn.downstream;
downstreamconf->timeout = src->timeout; downstreamconf->timeout = src->timeout;
downstreamconf->connections_per_host = src->connections_per_host; downstreamconf->connections_per_host = src->connections_per_host;
@ -261,7 +262,7 @@ int APIDownstreamConnection::end_upload_data() {
continue; continue;
} }
if (parse_config(&config, optid, opt, optval, include_set) != 0) { if (parse_config(&new_config, optid, opt, optval, include_set) != 0) {
send_reply(400, API_FAILURE); send_reply(400, API_FAILURE);
return 0; return 0;
} }
@ -269,8 +270,8 @@ int APIDownstreamConnection::end_upload_data() {
first = ++eol; first = ++eol;
} }
auto &tlsconf = get_config()->tls; auto &tlsconf = config->tls;
if (configure_downstream_group(&config, get_config()->http2_proxy, true, if (configure_downstream_group(&new_config, config->http2_proxy, true,
tlsconf) != 0) { tlsconf) != 0) {
send_reply(400, API_FAILURE); send_reply(400, API_FAILURE);
return 0; return 0;

View File

@ -404,7 +404,9 @@ ClientHandler::ClientHandler(Worker *worker, int fd, SSL *ssl,
conn_.rlimit.startw(); conn_.rlimit.startw();
ev_timer_again(conn_.loop, &conn_.rt); ev_timer_again(conn_.loop, &conn_.rt);
if (get_config()->conn.upstream.accept_proxy_protocol) { auto config = get_config();
if (config->conn.upstream.accept_proxy_protocol) {
read_ = &ClientHandler::read_clear; read_ = &ClientHandler::read_clear;
write_ = &ClientHandler::noop; write_ = &ClientHandler::noop;
on_read_ = &ClientHandler::proxy_protocol_read; on_read_ = &ClientHandler::proxy_protocol_read;
@ -413,7 +415,7 @@ ClientHandler::ClientHandler(Worker *worker, int fd, SSL *ssl,
setup_upstream_io_callback(); setup_upstream_io_callback();
} }
auto &fwdconf = get_config()->http.forwarded; auto &fwdconf = config->http.forwarded;
if (fwdconf.params & FORWARDED_FOR) { if (fwdconf.params & FORWARDED_FOR) {
if (fwdconf.for_node_type == FORWARDED_NODE_OBFUSCATED) { if (fwdconf.for_node_type == FORWARDED_NODE_OBFUSCATED) {
@ -1212,16 +1214,17 @@ void ClientHandler::write_accesslog(Downstream *downstream) {
const auto &resp = downstream->response(); const auto &resp = downstream->response();
auto &balloc = downstream->get_block_allocator(); auto &balloc = downstream->get_block_allocator();
auto config = get_config();
upstream_accesslog( upstream_accesslog(
get_config()->logging.access.format, config->logging.access.format,
LogSpec{ LogSpec{
downstream, downstream->get_addr(), ipaddr_, downstream, downstream->get_addr(), ipaddr_,
http2::to_method_string(req.method), http2::to_method_string(req.method),
req.method == HTTP_CONNECT req.method == HTTP_CONNECT
? StringRef(req.authority) ? StringRef(req.authority)
: get_config()->http2_proxy : config->http2_proxy
? StringRef(construct_absolute_request_uri(balloc, req)) ? StringRef(construct_absolute_request_uri(balloc, req))
: req.path.empty() : req.path.empty()
? req.method == HTTP_OPTIONS ? req.method == HTTP_OPTIONS
@ -1237,7 +1240,7 @@ void ClientHandler::write_accesslog(Downstream *downstream) {
req.http_major, req.http_minor, resp.http_status, req.http_major, req.http_minor, resp.http_status,
downstream->response_sent_body_length, port_, faddr_->port, downstream->response_sent_body_length, port_, faddr_->port,
get_config()->pid, config->pid,
}); });
} }
@ -1246,9 +1249,10 @@ void ClientHandler::write_accesslog(int major, int minor, unsigned int status,
auto time_now = std::chrono::system_clock::now(); auto time_now = std::chrono::system_clock::now();
auto highres_now = std::chrono::high_resolution_clock::now(); auto highres_now = std::chrono::high_resolution_clock::now();
nghttp2::ssl::TLSSessionInfo tls_info; nghttp2::ssl::TLSSessionInfo tls_info;
auto config = get_config();
upstream_accesslog( upstream_accesslog(
get_config()->logging.access.format, config->logging.access.format,
LogSpec{ LogSpec{
nullptr, nullptr, ipaddr_, nullptr, nullptr, ipaddr_,
StringRef::from_lit("-"), // method StringRef::from_lit("-"), // method
@ -1259,7 +1263,7 @@ void ClientHandler::write_accesslog(int major, int minor, unsigned int status,
// there a better value? // there a better value?
highres_now, // request_end_time highres_now, // request_end_time
major, minor, // major, minor major, minor, // major, minor
status, body_bytes_sent, port_, faddr_->port, get_config()->pid, status, body_bytes_sent, port_, faddr_->port, config->pid,
}); });
} }

View File

@ -215,8 +215,9 @@ int ConnectionHandler::create_single_worker() {
all_ssl_ctx_.push_back(cl_ssl_ctx); all_ssl_ctx_.push_back(cl_ssl_ctx);
} }
auto &tlsconf = get_config()->tls; auto config = get_config();
auto &memcachedconf = get_config()->tls.session_cache.memcached; auto &tlsconf = config->tls;
auto &memcachedconf = config->tls.session_cache.memcached;
SSL_CTX *session_cache_ssl_ctx = nullptr; SSL_CTX *session_cache_ssl_ctx = nullptr;
if (memcachedconf.tls) { if (memcachedconf.tls) {
@ -231,7 +232,7 @@ int ConnectionHandler::create_single_worker() {
single_worker_ = make_unique<Worker>( single_worker_ = make_unique<Worker>(
loop_, sv_ssl_ctx, cl_ssl_ctx, session_cache_ssl_ctx, cert_tree_.get(), loop_, sv_ssl_ctx, cl_ssl_ctx, session_cache_ssl_ctx, cert_tree_.get(),
ticket_keys_, this, get_config()->conn.downstream); ticket_keys_, this, config->conn.downstream);
#ifdef HAVE_MRUBY #ifdef HAVE_MRUBY
if (single_worker_->create_mruby_context() != 0) { if (single_worker_->create_mruby_context() != 0) {
return -1; return -1;
@ -262,9 +263,10 @@ int ConnectionHandler::create_worker_thread(size_t num) {
all_ssl_ctx_.push_back(cl_ssl_ctx); all_ssl_ctx_.push_back(cl_ssl_ctx);
} }
auto &tlsconf = get_config()->tls; auto config = get_config();
auto &memcachedconf = get_config()->tls.session_cache.memcached; auto &tlsconf = config->tls;
auto &apiconf = get_config()->api; auto &memcachedconf = config->tls.session_cache.memcached;
auto &apiconf = config->api;
// We have dedicated worker for API request processing. // We have dedicated worker for API request processing.
if (apiconf.enabled) { if (apiconf.enabled) {
@ -272,7 +274,7 @@ int ConnectionHandler::create_worker_thread(size_t num) {
} }
for (size_t i = 0; i < num; ++i) { for (size_t i = 0; i < num; ++i) {
auto loop = ev_loop_new(get_config()->ev_loop_flags); auto loop = ev_loop_new(config->ev_loop_flags);
SSL_CTX *session_cache_ssl_ctx = nullptr; SSL_CTX *session_cache_ssl_ctx = nullptr;
if (memcachedconf.tls) { if (memcachedconf.tls) {
@ -286,7 +288,7 @@ int ConnectionHandler::create_worker_thread(size_t num) {
} }
auto worker = make_unique<Worker>( auto worker = make_unique<Worker>(
loop, sv_ssl_ctx, cl_ssl_ctx, session_cache_ssl_ctx, cert_tree_.get(), loop, sv_ssl_ctx, cl_ssl_ctx, session_cache_ssl_ctx, cert_tree_.get(),
ticket_keys_, this, get_config()->conn.downstream); ticket_keys_, this, config->conn.downstream);
#ifdef HAVE_MRUBY #ifdef HAVE_MRUBY
if (worker->create_mruby_context() != 0) { if (worker->create_mruby_context() != 0) {
return -1; return -1;
@ -362,8 +364,10 @@ int ConnectionHandler::handle_connection(int fd, sockaddr *addr, int addrlen,
<< util::numeric_name(addr, addrlen) << ", fd=" << fd; << util::numeric_name(addr, addrlen) << ", fd=" << fd;
} }
if (get_config()->num_worker == 1) { auto config = get_config();
auto &upstreamconf = get_config()->conn.upstream;
if (config->num_worker == 1) {
auto &upstreamconf = config->conn.upstream;
if (single_worker_->get_worker_stat()->num_connections >= if (single_worker_->get_worker_stat()->num_connections >=
upstreamconf.worker_connections) { upstreamconf.worker_connections) {
@ -404,7 +408,7 @@ int ConnectionHandler::handle_connection(int fd, sockaddr *addr, int addrlen,
} }
if (++worker_round_robin_cnt_ == workers_.size()) { if (++worker_round_robin_cnt_ == workers_.size()) {
auto &apiconf = get_config()->api; auto &apiconf = config->api;
if (apiconf.enabled) { if (apiconf.enabled) {
worker_round_robin_cnt_ = 1; worker_round_robin_cnt_ = 1;
@ -828,8 +832,9 @@ void ConnectionHandler::schedule_next_tls_ticket_key_memcached_get(
} }
SSL_CTX *ConnectionHandler::create_tls_ticket_key_memcached_ssl_ctx() { SSL_CTX *ConnectionHandler::create_tls_ticket_key_memcached_ssl_ctx() {
auto &tlsconf = get_config()->tls; auto config = get_config();
auto &memcachedconf = get_config()->tls.ticket.memcached; auto &tlsconf = config->tls;
auto &memcachedconf = config->tls.ticket.memcached;
auto ssl_ctx = ssl::create_ssl_client_context( auto ssl_ctx = ssl::create_ssl_client_context(
#ifdef HAVE_NEVERBLEED #ifdef HAVE_NEVERBLEED

View File

@ -246,11 +246,11 @@ int Http2DownstreamConnection::push_request_headers() {
auto &balloc = downstream_->get_block_allocator(); auto &balloc = downstream_->get_block_allocator();
auto &httpconf = get_config()->http; auto config = get_config();
auto &http2conf = get_config()->http2; auto &httpconf = config->http;
auto &http2conf = config->http2;
auto no_host_rewrite = httpconf.no_host_rewrite || auto no_host_rewrite = httpconf.no_host_rewrite || config->http2_proxy ||
get_config()->http2_proxy ||
req.method == HTTP_CONNECT; req.method == HTTP_CONNECT;
// http2session_ has already in CONNECTED state, so we can get // http2session_ has already in CONNECTED state, so we can get
@ -326,7 +326,7 @@ int Http2DownstreamConnection::push_request_headers() {
if (fwdconf.params) { if (fwdconf.params) {
auto params = fwdconf.params; auto params = fwdconf.params;
if (get_config()->http2_proxy || req.method == HTTP_CONNECT) { if (config->http2_proxy || req.method == HTTP_CONNECT) {
params &= ~FORWARDED_PROTO; params &= ~FORWARDED_PROTO;
} }
@ -369,7 +369,7 @@ int Http2DownstreamConnection::push_request_headers() {
nva.push_back(http2::make_nv_ls_nocopy("x-forwarded-for", xff->value)); nva.push_back(http2::make_nv_ls_nocopy("x-forwarded-for", xff->value));
} }
if (!get_config()->http2_proxy && req.method != HTTP_CONNECT) { if (!config->http2_proxy && req.method != HTTP_CONNECT) {
// 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)); nva.push_back(http2::make_nv_ls_nocopy("x-forwarded-proto", req.scheme));
} }

View File

@ -1561,7 +1561,8 @@ int Http2Session::connection_made() {
} }
} }
auto &http2conf = get_config()->http2; auto config = get_config();
auto &http2conf = config->http2;
rv = nghttp2_session_client_new2(&session_, http2conf.downstream.callbacks, rv = nghttp2_session_client_new2(&session_, http2conf.downstream.callbacks,
this, http2conf.downstream.option); this, http2conf.downstream.option);
@ -1578,7 +1579,7 @@ int Http2Session::connection_made() {
entry[1].settings_id = NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE; entry[1].settings_id = NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE;
entry[1].value = http2conf.downstream.window_size; entry[1].value = http2conf.downstream.window_size;
if (http2conf.no_server_push || get_config()->http2_proxy) { if (http2conf.no_server_push || config->http2_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;
++nentry; ++nentry;

View File

@ -163,8 +163,9 @@ int on_header_callback2(nghttp2_session *session, const nghttp2_frame *frame,
uint8_t flags, void *user_data) { uint8_t flags, void *user_data) {
auto namebuf = nghttp2_rcbuf_get_buf(name); auto namebuf = nghttp2_rcbuf_get_buf(name);
auto valuebuf = nghttp2_rcbuf_get_buf(value); auto valuebuf = nghttp2_rcbuf_get_buf(value);
auto config = get_config();
if (get_config()->http2.upstream.debug.frame_debug) { if (config->http2.upstream.debug.frame_debug) {
verbose_on_header_callback(session, frame, namebuf.base, namebuf.len, verbose_on_header_callback(session, frame, namebuf.base, namebuf.len,
valuebuf.base, valuebuf.len, flags, user_data); valuebuf.base, valuebuf.len, flags, user_data);
} }
@ -180,7 +181,7 @@ int on_header_callback2(nghttp2_session *session, const nghttp2_frame *frame,
auto &req = downstream->request(); auto &req = downstream->request();
auto &httpconf = get_config()->http; auto &httpconf = config->http;
if (req.fs.buffer_size() + namebuf.len + valuebuf.len > if (req.fs.buffer_size() + namebuf.len + valuebuf.len >
httpconf.request_header_field_buffer || httpconf.request_header_field_buffer ||
@ -309,7 +310,8 @@ int Http2Upstream::on_request_headers(Downstream *downstream,
<< downstream->get_stream_id() << "\n" << ss.str(); << downstream->get_stream_id() << "\n" << ss.str();
} }
auto &dump = get_config()->http2.upstream.debug.dump; auto config = get_config();
auto &dump = config->http2.upstream.debug.dump;
if (dump.request_header) { if (dump.request_header) {
http2::dump_nv(dump.request_header, nva); http2::dump_nv(dump.request_header, nva);
@ -338,8 +340,8 @@ int Http2Upstream::on_request_headers(Downstream *downstream,
auto faddr = handler_->get_upstream_addr(); auto faddr = handler_->get_upstream_addr();
// For HTTP/2 proxy, we require :authority. // For HTTP/2 proxy, we require :authority.
if (method_token != HTTP_CONNECT && get_config()->http2_proxy && if (method_token != HTTP_CONNECT && config->http2_proxy && !faddr->alt_mode &&
!faddr->alt_mode && !authority) { !authority) {
rst_stream(downstream, NGHTTP2_PROTOCOL_ERROR); rst_stream(downstream, NGHTTP2_PROTOCOL_ERROR);
return 0; return 0;
} }
@ -363,7 +365,7 @@ int Http2Upstream::on_request_headers(Downstream *downstream,
if (method_token == HTTP_OPTIONS && if (method_token == HTTP_OPTIONS &&
path->value == StringRef::from_lit("*")) { path->value == StringRef::from_lit("*")) {
// Server-wide OPTIONS request. Path is empty. // Server-wide OPTIONS request. Path is empty.
} else if (get_config()->http2_proxy && !faddr->alt_mode) { } else if (config->http2_proxy && !faddr->alt_mode) {
req.path = path->value; req.path = path->value;
} else { } else {
req.path = http2::rewrite_clean_path(downstream->get_block_allocator(), req.path = http2::rewrite_clean_path(downstream->get_block_allocator(),
@ -899,12 +901,14 @@ nghttp2_session_callbacks *create_http2_upstream_callbacks() {
nghttp2_session_callbacks_set_send_data_callback(callbacks, nghttp2_session_callbacks_set_send_data_callback(callbacks,
send_data_callback); send_data_callback);
if (get_config()->padding) { auto config = get_config();
if (config->padding) {
nghttp2_session_callbacks_set_select_padding_callback( nghttp2_session_callbacks_set_select_padding_callback(
callbacks, http::select_padding_callback); callbacks, http::select_padding_callback);
} }
if (get_config()->http2.upstream.debug.frame_debug) { if (config->http2.upstream.debug.frame_debug) {
nghttp2_session_callbacks_set_error_callback(callbacks, nghttp2_session_callbacks_set_error_callback(callbacks,
verbose_error_callback); verbose_error_callback);
} }
@ -933,7 +937,8 @@ Http2Upstream::Http2Upstream(ClientHandler *handler)
max_buffer_size_(MAX_BUFFER_SIZE) { max_buffer_size_(MAX_BUFFER_SIZE) {
int rv; int rv;
auto &http2conf = get_config()->http2; auto config = get_config();
auto &http2conf = config->http2;
auto faddr = handler_->get_upstream_addr(); auto faddr = handler_->get_upstream_addr();
@ -1026,7 +1031,7 @@ Http2Upstream::Http2Upstream(ClientHandler *handler)
#endif // defined(TCP_INFO) && defined(TCP_NOTSENT_LOWAT) #endif // defined(TCP_INFO) && defined(TCP_NOTSENT_LOWAT)
handler_->reset_upstream_read_timeout( handler_->reset_upstream_read_timeout(
get_config()->conn.upstream.timeout.http2_read); config->conn.upstream.timeout.http2_read);
handler_->signal_write(); handler_->signal_write();
} }
@ -1075,7 +1080,8 @@ int Http2Upstream::on_read() {
// After this function call, downstream may be deleted. // After this function call, downstream may be deleted.
int Http2Upstream::on_write() { int Http2Upstream::on_write() {
int rv; int rv;
auto &http2conf = get_config()->http2; auto config = get_config();
auto &http2conf = config->http2;
if ((http2conf.upstream.optimize_write_buffer_size || if ((http2conf.upstream.optimize_write_buffer_size ||
http2conf.upstream.optimize_window_size) && http2conf.upstream.optimize_window_size) &&
@ -1400,7 +1406,8 @@ int Http2Upstream::send_reply(Downstream *downstream, const uint8_t *body,
} }
const auto &resp = downstream->response(); const auto &resp = downstream->response();
auto &httpconf = get_config()->http; auto config = get_config();
auto &httpconf = config->http;
auto &balloc = downstream->get_block_allocator(); auto &balloc = downstream->get_block_allocator();
@ -1430,8 +1437,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", config->http.server_name));
http2::make_nv_ls_nocopy("server", get_config()->http.server_name));
} }
for (auto &p : httpconf.add_response_headers) { for (auto &p : httpconf.add_response_headers) {
@ -1542,9 +1548,10 @@ int Http2Upstream::on_downstream_header_complete(Downstream *downstream) {
} }
} }
auto &httpconf = get_config()->http; auto config = get_config();
auto &httpconf = config->http;
if (!get_config()->http2_proxy && !httpconf.no_location_rewrite) { if (!config->http2_proxy && !httpconf.no_location_rewrite) {
downstream->rewrite_location_response_header(req.scheme); downstream->rewrite_location_response_header(req.scheme);
} }
@ -1567,7 +1574,7 @@ int Http2Upstream::on_downstream_header_complete(Downstream *downstream) {
} }
#endif // HAVE_MRUBY #endif // HAVE_MRUBY
auto &http2conf = get_config()->http2; auto &http2conf = config->http2;
// We need some conditions that must be fulfilled to initiate server // We need some conditions that must be fulfilled to initiate server
// push. // push.
@ -1585,7 +1592,7 @@ int Http2Upstream::on_downstream_header_complete(Downstream *downstream) {
if (!http2conf.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 && (downstream->get_stream_id() % 2) && !config->http2_proxy && (downstream->get_stream_id() % 2) &&
resp.fs.header(http2::HD_LINK) && resp.fs.header(http2::HD_LINK) &&
(downstream->get_non_final_response() || resp.http_status == 200) && (downstream->get_non_final_response() || resp.http_status == 200) &&
(req.method == HTTP_GET || req.method == HTTP_POST)) { (req.method == HTTP_GET || req.method == HTTP_POST)) {
@ -1628,7 +1635,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 && !httpconf.no_server_rewrite) { if (!config->http2_proxy && !httpconf.no_server_rewrite) {
nva.push_back(http2::make_nv_ls_nocopy("server", httpconf.server_name)); nva.push_back(http2::make_nv_ls_nocopy("server", httpconf.server_name));
} else { } else {
auto server = resp.fs.header(http2::HD_SERVER); auto server = resp.fs.header(http2::HD_SERVER);
@ -1998,10 +2005,11 @@ int Http2Upstream::submit_push_promise(const StringRef &scheme,
} }
bool Http2Upstream::push_enabled() const { bool Http2Upstream::push_enabled() const {
return !(get_config()->http2.no_server_push || auto config = get_config();
return !(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); config->http2_proxy);
} }
int Http2Upstream::initiate_push(Downstream *downstream, const StringRef &uri) { int Http2Upstream::initiate_push(Downstream *downstream, const StringRef &uri) {

View File

@ -342,7 +342,8 @@ int HttpDownstreamConnection::push_request_headers() {
auto connect_method = req.method == HTTP_CONNECT; auto connect_method = req.method == HTTP_CONNECT;
auto &httpconf = get_config()->http; auto config = get_config();
auto &httpconf = config->http;
// Set request_sent to true because we write request into buffer // Set request_sent to true because we write request into buffer
// here. // here.
@ -352,7 +353,7 @@ int HttpDownstreamConnection::push_request_headers() {
// 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 = auto no_host_rewrite =
httpconf.no_host_rewrite || get_config()->http2_proxy || connect_method; httpconf.no_host_rewrite || config->http2_proxy || connect_method;
if (no_host_rewrite && !req.authority.empty()) { if (no_host_rewrite && !req.authority.empty()) {
authority = req.authority; authority = req.authority;
@ -369,7 +370,7 @@ int HttpDownstreamConnection::push_request_headers() {
if (connect_method) { if (connect_method) {
buf->append(authority); buf->append(authority);
} else if (get_config()->http2_proxy) { } else if (config->http2_proxy) {
// Construct absolute-form request target because we are going to // Construct absolute-form request target because we are going to
// send a request to a HTTP/1 proxy. // send a request to a HTTP/1 proxy.
assert(!req.scheme.empty()); assert(!req.scheme.empty());
@ -434,7 +435,7 @@ int HttpDownstreamConnection::push_request_headers() {
if (fwdconf.params) { if (fwdconf.params) {
auto params = fwdconf.params; auto params = fwdconf.params;
if (get_config()->http2_proxy || connect_method) { if (config->http2_proxy || connect_method) {
params &= ~FORWARDED_PROTO; params &= ~FORWARDED_PROTO;
} }
@ -478,7 +479,7 @@ int HttpDownstreamConnection::push_request_headers() {
buf->append((*xff).value); buf->append((*xff).value);
buf->append("\r\n"); buf->append("\r\n");
} }
if (!get_config()->http2_proxy && !connect_method) { if (!config->http2_proxy && !connect_method) {
buf->append("X-Forwarded-Proto: "); buf->append("X-Forwarded-Proto: ");
assert(!req.scheme.empty()); assert(!req.scheme.empty());
buf->append(req.scheme); buf->append(req.scheme);

View File

@ -344,6 +344,7 @@ int htp_hdrs_completecb(http_parser *htp) {
auto faddr = handler->get_upstream_addr(); auto faddr = handler->get_upstream_addr();
auto &balloc = downstream->get_block_allocator(); auto &balloc = downstream->get_block_allocator();
auto config = get_config();
if (method != HTTP_CONNECT) { if (method != HTTP_CONNECT) {
http_parser_url u{}; http_parser_url u{};
@ -372,9 +373,8 @@ int htp_hdrs_completecb(http_parser *htp) {
req.scheme = StringRef::from_lit("http"); req.scheme = StringRef::from_lit("http");
} }
} else { } else {
rewrite_request_host_path_from_uri(balloc, req, req.path, u, rewrite_request_host_path_from_uri(
get_config()->http2_proxy && balloc, req, req.path, u, config->http2_proxy && !faddr->alt_mode);
!faddr->alt_mode);
} }
} }
@ -394,7 +394,7 @@ int htp_hdrs_completecb(http_parser *htp) {
// mruby hook may change method value // mruby hook may change method value
if (req.no_authority && get_config()->http2_proxy && !faddr->alt_mode) { if (req.no_authority && config->http2_proxy && !faddr->alt_mode) {
// Request URI should be absolute-form for client proxy mode // Request URI should be absolute-form for client proxy mode
return -1; return -1;
} }
@ -832,6 +832,7 @@ int HttpsUpstream::send_reply(Downstream *downstream, const uint8_t *body,
const auto &req = downstream->request(); const auto &req = downstream->request();
auto &resp = downstream->response(); auto &resp = downstream->response();
auto &balloc = downstream->get_block_allocator(); auto &balloc = downstream->get_block_allocator();
auto config = get_config();
auto connection_close = false; auto connection_close = false;
@ -875,11 +876,11 @@ 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()->http.server_name); output->append(config->http.server_name);
output->append("\r\n"); output->append("\r\n");
} }
auto &httpconf = get_config()->http; auto &httpconf = config->http;
for (auto &p : httpconf.add_response_headers) { for (auto &p : httpconf.add_response_headers) {
output->append(p.name); output->append(p.name);
@ -1012,9 +1013,10 @@ int HttpsUpstream::on_downstream_header_complete(Downstream *downstream) {
buf->append(http2::get_status_string(balloc, resp.http_status)); buf->append(http2::get_status_string(balloc, resp.http_status));
buf->append("\r\n"); buf->append("\r\n");
auto &httpconf = get_config()->http; auto config = get_config();
auto &httpconf = config->http;
if (!get_config()->http2_proxy && !httpconf.no_location_rewrite) { if (!config->http2_proxy && !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());
} }
@ -1083,7 +1085,7 @@ int HttpsUpstream::on_downstream_header_complete(Downstream *downstream) {
} }
} }
if (!get_config()->http2_proxy && !httpconf.no_server_rewrite) { if (!config->http2_proxy && !httpconf.no_server_rewrite) {
buf->append("Server: "); buf->append("Server: ");
buf->append(httpconf.server_name); buf->append(httpconf.server_name);
buf->append("\r\n"); buf->append("\r\n");

View File

@ -106,14 +106,15 @@ Log::Log(int severity, const char *filename, int linenum)
Log::~Log() { Log::~Log() {
int rv; int rv;
auto config = get_config();
if (!get_config()) { if (!config) {
return; return;
} }
auto lgconf = log_config(); auto lgconf = log_config();
auto &errorconf = get_config()->logging.error; auto &errorconf = config->logging.error;
if (!log_enabled(severity_) || if (!log_enabled(severity_) ||
(lgconf->errorlog_fd == -1 && !errorconf.syslog)) { (lgconf->errorlog_fd == -1 && !errorconf.syslog)) {
@ -142,12 +143,12 @@ Log::~Log() {
if (severity_ == NOTICE) { if (severity_ == NOTICE) {
rv = rv =
snprintf(buf, sizeof(buf), "%s PID%d [%s%s%s] %s\n", time_local.c_str(), snprintf(buf, sizeof(buf), "%s PID%d [%s%s%s] %s\n", time_local.c_str(),
get_config()->pid, tty ? SEVERITY_COLOR[severity_] : "", config->pid, tty ? SEVERITY_COLOR[severity_] : "",
SEVERITY_STR[severity_].c_str(), tty ? "\033[0m" : "", SEVERITY_STR[severity_].c_str(), tty ? "\033[0m" : "",
stream_.str().c_str()); stream_.str().c_str());
} else { } else {
rv = snprintf(buf, sizeof(buf), "%s PID%d [%s%s%s] %s%s:%d%s %s\n", rv = snprintf(buf, sizeof(buf), "%s PID%d [%s%s%s] %s%s:%d%s %s\n",
time_local.c_str(), get_config()->pid, time_local.c_str(), config->pid,
tty ? SEVERITY_COLOR[severity_] : "", tty ? SEVERITY_COLOR[severity_] : "",
SEVERITY_STR[severity_].c_str(), tty ? "\033[0m" : "", SEVERITY_STR[severity_].c_str(), tty ? "\033[0m" : "",
tty ? "\033[1;30m" : "", filename_, linenum_, tty ? "\033[1;30m" : "", filename_, linenum_,
@ -411,8 +412,9 @@ int reopen_log_files() {
int new_errorlog_fd = -1; int new_errorlog_fd = -1;
auto lgconf = log_config(); auto lgconf = log_config();
auto &accessconf = get_config()->logging.access; auto config = get_config();
auto &errorconf = get_config()->logging.error; auto &accessconf = config->logging.access;
auto &errorconf = config->logging.error;
if (!accessconf.syslog && !accessconf.file.empty()) { if (!accessconf.syslog && !accessconf.file.empty()) {
new_accesslog_fd = util::open_log_file(accessconf.file.c_str()); new_accesslog_fd = util::open_log_file(accessconf.file.c_str());

View File

@ -165,6 +165,7 @@ namespace {
void on_ctrl_recv_callback(spdylay_session *session, spdylay_frame_type type, void on_ctrl_recv_callback(spdylay_session *session, spdylay_frame_type type,
spdylay_frame *frame, void *user_data) { spdylay_frame *frame, void *user_data) {
auto upstream = static_cast<SpdyUpstream *>(user_data); auto upstream = static_cast<SpdyUpstream *>(user_data);
auto config = get_config();
switch (type) { switch (type) {
case SPDYLAY_SYN_STREAM: { case SPDYLAY_SYN_STREAM: {
@ -202,7 +203,7 @@ 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; auto &httpconf = 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.
@ -293,7 +294,7 @@ void on_ctrl_recv_callback(spdylay_session *session, spdylay_frame_type type,
auto handler = upstream->get_client_handler(); auto handler = upstream->get_client_handler();
auto faddr = handler->get_upstream_addr(); auto faddr = handler->get_upstream_addr();
if (get_config()->http2_proxy && !faddr->alt_mode) { if (config->http2_proxy && !faddr->alt_mode) {
req.path = path->value; req.path = path->value;
} else if (method_token == HTTP_OPTIONS && } else if (method_token == HTTP_OPTIONS &&
path->value == StringRef::from_lit("*")) { path->value == StringRef::from_lit("*")) {
@ -584,7 +585,8 @@ 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; auto config = get_config();
auto &http2conf = config->http2;
auto faddr = handler_->get_upstream_addr(); auto faddr = handler_->get_upstream_addr();
@ -632,7 +634,7 @@ SpdyUpstream::SpdyUpstream(uint16_t version, ClientHandler *handler)
} }
handler_->reset_upstream_read_timeout( handler_->reset_upstream_read_timeout(
get_config()->conn.upstream.timeout.http2_read); config->conn.upstream.timeout.http2_read);
handler_->signal_write(); handler_->signal_write();
} }
@ -919,7 +921,8 @@ int SpdyUpstream::send_reply(Downstream *downstream, const uint8_t *body,
const auto &headers = resp.fs.headers(); const auto &headers = resp.fs.headers();
auto &httpconf = get_config()->http; auto config = get_config();
auto &httpconf = config->http;
auto nva = std::vector<const char *>(); auto nva = std::vector<const char *>();
// 6 for :status, :version and server. 1 for last terminal nullptr. // 6 for :status, :version and server. 1 for last terminal nullptr.
@ -948,7 +951,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()->http.server_name.c_str()); nva.push_back(config->http.server_name.c_str());
} }
for (auto &p : httpconf.add_response_headers) { for (auto &p : httpconf.add_response_headers) {
@ -1084,9 +1087,10 @@ 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; auto config = get_config();
auto &httpconf = config->http;
if (!get_config()->http2_proxy && !httpconf.no_location_rewrite) { if (!config->http2_proxy && !httpconf.no_location_rewrite) {
downstream->rewrite_location_response_header(req.scheme); downstream->rewrite_location_response_header(req.scheme);
} }

View File

@ -531,7 +531,8 @@ SSL_CTX *create_ssl_context(const char *private_key_file, const char *cert_file
SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION | SSL_OP_SINGLE_ECDH_USE | SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION | SSL_OP_SINGLE_ECDH_USE |
SSL_OP_SINGLE_DH_USE | SSL_OP_CIPHER_SERVER_PREFERENCE; SSL_OP_SINGLE_DH_USE | SSL_OP_CIPHER_SERVER_PREFERENCE;
auto &tlsconf = get_config()->tls; auto config = mod_config();
auto &tlsconf = config->tls;
SSL_CTX_set_options(ssl_ctx, ssl_opts | tlsconf.tls_proto_mask); SSL_CTX_set_options(ssl_ctx, ssl_opts | tlsconf.tls_proto_mask);
@ -608,7 +609,7 @@ SSL_CTX *create_ssl_context(const char *private_key_file, const char *cert_file
SSL_CTX_set_mode(ssl_ctx, SSL_MODE_RELEASE_BUFFERS); SSL_CTX_set_mode(ssl_ctx, SSL_MODE_RELEASE_BUFFERS);
if (!tlsconf.private_key_passwd.empty()) { if (!tlsconf.private_key_passwd.empty()) {
SSL_CTX_set_default_passwd_cb(ssl_ctx, ssl_pem_passwd_cb); SSL_CTX_set_default_passwd_cb(ssl_ctx, ssl_pem_passwd_cb);
SSL_CTX_set_default_passwd_cb_userdata(ssl_ctx, (void *)get_config()); SSL_CTX_set_default_passwd_cb_userdata(ssl_ctx, config);
} }
#ifndef HAVE_NEVERBLEED #ifndef HAVE_NEVERBLEED

View File

@ -63,19 +63,21 @@ void drop_privileges(
neverbleed_t *nb neverbleed_t *nb
#endif // HAVE_NEVERBLEED #endif // HAVE_NEVERBLEED
) { ) {
if (getuid() == 0 && get_config()->uid != 0) { auto config = get_config();
if (initgroups(get_config()->user.c_str(), get_config()->gid) != 0) {
if (getuid() == 0 && config->uid != 0) {
if (initgroups(config->user.c_str(), config->gid) != 0) {
auto error = errno; auto error = errno;
LOG(FATAL) << "Could not change supplementary groups: " LOG(FATAL) << "Could not change supplementary groups: "
<< strerror(error); << strerror(error);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
if (setgid(get_config()->gid) != 0) { if (setgid(config->gid) != 0) {
auto error = errno; auto error = errno;
LOG(FATAL) << "Could not change gid: " << strerror(error); LOG(FATAL) << "Could not change gid: " << strerror(error);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
if (setuid(get_config()->uid) != 0) { if (setuid(config->uid) != 0) {
auto error = errno; auto error = errno;
LOG(FATAL) << "Could not change uid: " << strerror(error); LOG(FATAL) << "Could not change uid: " << strerror(error);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
@ -86,7 +88,7 @@ void drop_privileges(
} }
#ifdef HAVE_NEVERBLEED #ifdef HAVE_NEVERBLEED
if (nb) { if (nb) {
neverbleed_setuidgid(nb, get_config()->user.c_str(), 1); neverbleed_setuidgid(nb, config->user.c_str(), 1);
} }
#endif // HAVE_NEVERBLEED #endif // HAVE_NEVERBLEED
} }
@ -395,7 +397,9 @@ int worker_process_event_loop(WorkerProcessConfig *wpconf) {
ConnectionHandler conn_handler(loop, gen); ConnectionHandler conn_handler(loop, gen);
for (auto &addr : get_config()->conn.listener.addrs) { auto config = get_config();
for (auto &addr : config->conn.listener.addrs) {
conn_handler.add_acceptor(make_unique<AcceptHandler>(&addr, &conn_handler)); conn_handler.add_acceptor(make_unique<AcceptHandler>(&addr, &conn_handler));
} }
@ -428,7 +432,7 @@ int worker_process_event_loop(WorkerProcessConfig *wpconf) {
ev_timer renew_ticket_key_timer; ev_timer renew_ticket_key_timer;
if (ssl::upstream_tls_enabled()) { if (ssl::upstream_tls_enabled()) {
auto &ticketconf = get_config()->tls.ticket; auto &ticketconf = config->tls.ticket;
auto &memcachedconf = ticketconf.memcached; auto &memcachedconf = ticketconf.memcached;
if (!memcachedconf.host.empty()) { if (!memcachedconf.host.empty()) {
@ -483,7 +487,7 @@ int worker_process_event_loop(WorkerProcessConfig *wpconf) {
int rv; int rv;
if (get_config()->num_worker == 1) { if (config->num_worker == 1) {
rv = conn_handler.create_single_worker(); rv = conn_handler.create_single_worker();
if (rv != 0) { if (rv != 0) {
return -1; return -1;
@ -501,7 +505,7 @@ int worker_process_event_loop(WorkerProcessConfig *wpconf) {
} }
#endif // !NOTHREADS #endif // !NOTHREADS
rv = conn_handler.create_worker_thread(get_config()->num_worker); rv = conn_handler.create_worker_thread(config->num_worker);
if (rv != 0) { if (rv != 0) {
return -1; return -1;
} }
@ -526,7 +530,7 @@ int worker_process_event_loop(WorkerProcessConfig *wpconf) {
ipcev.data = &conn_handler; ipcev.data = &conn_handler;
ev_io_start(loop, &ipcev); ev_io_start(loop, &ipcev);
if (ssl::upstream_tls_enabled() && !get_config()->tls.ocsp.disabled) { if (ssl::upstream_tls_enabled() && !config->tls.ocsp.disabled) {
conn_handler.proceed_next_cert_ocsp(); conn_handler.proceed_next_cert_ocsp();
} }