nghttpx: Organize connection related configuration into struct
This commit is contained in:
parent
35feae3b0c
commit
0402481be4
277
src/shrpx.cc
277
src/shrpx.cc
|
@ -299,13 +299,15 @@ void exec_binary(SignalServer *ssv) {
|
||||||
|
|
||||||
std::string fd, fd6, path, port;
|
std::string fd, fd6, path, port;
|
||||||
|
|
||||||
if (get_config()->host_unix) {
|
auto &listenerconf = get_config()->conn.listener;
|
||||||
|
|
||||||
|
if (listenerconf.host_unix) {
|
||||||
fd = ENV_UNIX_FD "=";
|
fd = ENV_UNIX_FD "=";
|
||||||
fd += util::utos(ssv->server_fd);
|
fd += util::utos(ssv->server_fd);
|
||||||
envp[envidx++] = &fd[0];
|
envp[envidx++] = &fd[0];
|
||||||
|
|
||||||
path = ENV_UNIX_PATH "=";
|
path = ENV_UNIX_PATH "=";
|
||||||
path += get_config()->host.get();
|
path += listenerconf.host.get();
|
||||||
envp[envidx++] = &path[0];
|
envp[envidx++] = &path[0];
|
||||||
} else {
|
} else {
|
||||||
if (ssv->server_fd) {
|
if (ssv->server_fd) {
|
||||||
|
@ -321,7 +323,7 @@ void exec_binary(SignalServer *ssv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
port = ENV_PORT "=";
|
port = ENV_PORT "=";
|
||||||
port += util::utos(get_config()->port);
|
port += util::utos(listenerconf.port);
|
||||||
envp[envidx++] = &port[0];
|
envp[envidx++] = &port[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -430,7 +432,9 @@ void worker_process_child_cb(struct ev_loop *loop, ev_child *w, int revents) {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
int create_unix_domain_server_socket() {
|
int create_unix_domain_server_socket() {
|
||||||
auto path = get_config()->host.get();
|
auto &listenerconf = get_config()->conn.listener;
|
||||||
|
|
||||||
|
auto path = listenerconf.host.get();
|
||||||
auto pathlen = strlen(path);
|
auto pathlen = strlen(path);
|
||||||
{
|
{
|
||||||
auto envfd = getenv(ENV_UNIX_FD);
|
auto envfd = getenv(ENV_UNIX_FD);
|
||||||
|
@ -490,7 +494,7 @@ int create_unix_domain_server_socket() {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (listen(fd, get_config()->backlog) != 0) {
|
if (listen(fd, listenerconf.backlog) != 0) {
|
||||||
auto error = errno;
|
auto error = errno;
|
||||||
LOG(FATAL) << "Failed to listen to UNIX domain socket, error=" << error;
|
LOG(FATAL) << "Failed to listen to UNIX domain socket, error=" << error;
|
||||||
close(fd);
|
close(fd);
|
||||||
|
@ -505,6 +509,8 @@ int create_unix_domain_server_socket() {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
int create_tcp_server_socket(int family) {
|
int create_tcp_server_socket(int family) {
|
||||||
|
auto &listenerconf = get_config()->conn.listener;
|
||||||
|
|
||||||
{
|
{
|
||||||
auto envfd =
|
auto envfd =
|
||||||
getenv(family == AF_INET ? ENV_LISTENER4_FD : ENV_LISTENER6_FD);
|
getenv(family == AF_INET ? ENV_LISTENER4_FD : ENV_LISTENER6_FD);
|
||||||
|
@ -517,14 +523,14 @@ int create_tcp_server_socket(int family) {
|
||||||
// Only do this iff NGHTTPX_PORT == get_config()->port.
|
// Only do this iff NGHTTPX_PORT == get_config()->port.
|
||||||
// Otherwise, close fd, and create server socket as usual.
|
// Otherwise, close fd, and create server socket as usual.
|
||||||
|
|
||||||
if (port == get_config()->port) {
|
if (port == listenerconf.port) {
|
||||||
LOG(NOTICE) << "Listening on port " << get_config()->port;
|
LOG(NOTICE) << "Listening on port " << listenerconf.port;
|
||||||
|
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG(WARN) << "Port was changed between old binary (" << port
|
LOG(WARN) << "Port was changed between old binary (" << port
|
||||||
<< ") and new binary (" << get_config()->port << ")";
|
<< ") and new binary (" << listenerconf.port << ")";
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -532,7 +538,7 @@ int create_tcp_server_socket(int family) {
|
||||||
int fd = -1;
|
int fd = -1;
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
auto service = util::utos(get_config()->port);
|
auto service = util::utos(listenerconf.port);
|
||||||
addrinfo hints{};
|
addrinfo hints{};
|
||||||
hints.ai_family = family;
|
hints.ai_family = family;
|
||||||
hints.ai_socktype = SOCK_STREAM;
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
|
@ -541,16 +547,16 @@ int create_tcp_server_socket(int family) {
|
||||||
hints.ai_flags |= AI_ADDRCONFIG;
|
hints.ai_flags |= AI_ADDRCONFIG;
|
||||||
#endif // AI_ADDRCONFIG
|
#endif // AI_ADDRCONFIG
|
||||||
|
|
||||||
auto node = strcmp("*", get_config()->host.get()) == 0
|
auto node = strcmp("*", listenerconf.host.get()) == 0
|
||||||
? nullptr
|
? nullptr
|
||||||
: get_config()->host.get();
|
: listenerconf.host.get();
|
||||||
|
|
||||||
addrinfo *res, *rp;
|
addrinfo *res, *rp;
|
||||||
rv = getaddrinfo(node, service.c_str(), &hints, &res);
|
rv = getaddrinfo(node, service.c_str(), &hints, &res);
|
||||||
if (rv != 0) {
|
if (rv != 0) {
|
||||||
if (LOG_ENABLED(INFO)) {
|
if (LOG_ENABLED(INFO)) {
|
||||||
LOG(INFO) << "Unable to get IPv" << (family == AF_INET ? "4" : "6")
|
LOG(INFO) << "Unable to get IPv" << (family == AF_INET ? "4" : "6")
|
||||||
<< " address for " << get_config()->host.get() << ": "
|
<< " address for " << listenerconf.host.get() << ": "
|
||||||
<< gai_strerror(rv);
|
<< gai_strerror(rv);
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -619,15 +625,15 @@ int create_tcp_server_socket(int family) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (get_config()->fastopen > 0) {
|
if (listenerconf.fastopen > 0) {
|
||||||
val = get_config()->fastopen;
|
val = listenerconf.fastopen;
|
||||||
if (setsockopt(fd, SOL_TCP, TCP_FASTOPEN, &val,
|
if (setsockopt(fd, SOL_TCP, TCP_FASTOPEN, &val,
|
||||||
static_cast<socklen_t>(sizeof(val))) == -1) {
|
static_cast<socklen_t>(sizeof(val))) == -1) {
|
||||||
LOG(WARN) << "Failed to set TCP_FASTOPEN option to listener socket";
|
LOG(WARN) << "Failed to set TCP_FASTOPEN option to listener socket";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (listen(fd, get_config()->backlog) == -1) {
|
if (listen(fd, listenerconf.backlog) == -1) {
|
||||||
auto error = errno;
|
auto error = errno;
|
||||||
LOG(WARN) << "listen() syscall failed, error=" << error;
|
LOG(WARN) << "listen() syscall failed, error=" << error;
|
||||||
close(fd);
|
close(fd);
|
||||||
|
@ -656,7 +662,7 @@ int create_tcp_server_socket(int family) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG(NOTICE) << "Listening on " << host << ", port " << get_config()->port;
|
LOG(NOTICE) << "Listening on " << host << ", port " << listenerconf.port;
|
||||||
|
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
@ -794,12 +800,14 @@ int event_loop() {
|
||||||
util::make_socket_closeonexec(fd);
|
util::make_socket_closeonexec(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (get_config()->host_unix) {
|
auto &listenerconf = get_config()->conn.listener;
|
||||||
|
|
||||||
|
if (listenerconf.host_unix) {
|
||||||
close_env_fd({ENV_LISTENER4_FD, ENV_LISTENER6_FD});
|
close_env_fd({ENV_LISTENER4_FD, ENV_LISTENER6_FD});
|
||||||
auto fd = create_unix_domain_server_socket();
|
auto fd = create_unix_domain_server_socket();
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
LOG(FATAL) << "Failed to listen on UNIX domain socket "
|
LOG(FATAL) << "Failed to listen on UNIX domain socket "
|
||||||
<< get_config()->host.get();
|
<< listenerconf.host.get();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -808,10 +816,10 @@ int event_loop() {
|
||||||
if (get_config()->uid != 0) {
|
if (get_config()->uid != 0) {
|
||||||
// fd is not associated to inode, so we cannot use fchown(2)
|
// fd is not associated to inode, so we cannot use fchown(2)
|
||||||
// here. https://lkml.org/lkml/2004/11/1/84
|
// here. https://lkml.org/lkml/2004/11/1/84
|
||||||
if (chown_to_running_user(get_config()->host.get()) == -1) {
|
if (chown_to_running_user(listenerconf.host.get()) == -1) {
|
||||||
auto error = errno;
|
auto error = errno;
|
||||||
LOG(WARN) << "Changing owner of UNIX domain socket "
|
LOG(WARN) << "Changing owner of UNIX domain socket "
|
||||||
<< get_config()->host.get() << " failed: " << strerror(error);
|
<< listenerconf.host.get() << " failed: " << strerror(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -819,8 +827,8 @@ int event_loop() {
|
||||||
auto fd6 = create_tcp_server_socket(AF_INET6);
|
auto fd6 = create_tcp_server_socket(AF_INET6);
|
||||||
auto fd4 = create_tcp_server_socket(AF_INET);
|
auto fd4 = create_tcp_server_socket(AF_INET);
|
||||||
if (fd6 == -1 && fd4 == -1) {
|
if (fd6 == -1 && fd4 == -1) {
|
||||||
LOG(FATAL) << "Failed to listen on address " << get_config()->host.get()
|
LOG(FATAL) << "Failed to listen on address " << listenerconf.host.get()
|
||||||
<< ", port " << get_config()->port;
|
<< ", port " << listenerconf.port;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -900,38 +908,8 @@ void fill_default_config() {
|
||||||
mod_config()->verbose = false;
|
mod_config()->verbose = false;
|
||||||
mod_config()->daemon = false;
|
mod_config()->daemon = false;
|
||||||
|
|
||||||
mod_config()->host = strcopy("*");
|
|
||||||
mod_config()->port = 3000;
|
|
||||||
|
|
||||||
// Read timeout for HTTP2 upstream connection
|
|
||||||
mod_config()->http2_upstream_read_timeout = 3_min;
|
|
||||||
|
|
||||||
// Read timeout for non-HTTP2 upstream connection
|
|
||||||
mod_config()->upstream_read_timeout = 1_min;
|
|
||||||
|
|
||||||
// Write timeout for HTTP2/non-HTTP2 upstream connection
|
|
||||||
mod_config()->upstream_write_timeout = 30.;
|
|
||||||
|
|
||||||
// Read/Write timeouts for downstream connection
|
|
||||||
mod_config()->downstream_read_timeout = 1_min;
|
|
||||||
mod_config()->downstream_write_timeout = 30.;
|
|
||||||
|
|
||||||
// Read timeout for HTTP/2 stream
|
|
||||||
mod_config()->stream_read_timeout = 0.;
|
|
||||||
|
|
||||||
// Write timeout for HTTP/2 stream
|
|
||||||
mod_config()->stream_write_timeout = 0.;
|
|
||||||
|
|
||||||
// Timeout for pooled (idle) connections
|
|
||||||
mod_config()->downstream_idle_read_timeout = 2.;
|
|
||||||
|
|
||||||
mod_config()->upstream_no_tls = false;
|
|
||||||
mod_config()->downstream_no_tls = false;
|
|
||||||
|
|
||||||
mod_config()->num_worker = 1;
|
mod_config()->num_worker = 1;
|
||||||
mod_config()->conf_path = strcopy("/etc/nghttpx/nghttpx.conf");
|
mod_config()->conf_path = strcopy("/etc/nghttpx/nghttpx.conf");
|
||||||
// Default accept() backlog
|
|
||||||
mod_config()->backlog = 512;
|
|
||||||
mod_config()->http2_proxy = false;
|
mod_config()->http2_proxy = false;
|
||||||
mod_config()->http2_bridge = false;
|
mod_config()->http2_bridge = false;
|
||||||
mod_config()->client_proxy = false;
|
mod_config()->client_proxy = false;
|
||||||
|
@ -942,29 +920,10 @@ void fill_default_config() {
|
||||||
mod_config()->uid = 0;
|
mod_config()->uid = 0;
|
||||||
mod_config()->gid = 0;
|
mod_config()->gid = 0;
|
||||||
mod_config()->pid = getpid();
|
mod_config()->pid = getpid();
|
||||||
mod_config()->backend_ipv4 = false;
|
|
||||||
mod_config()->backend_ipv6 = false;
|
|
||||||
mod_config()->read_rate = 0;
|
|
||||||
mod_config()->read_burst = 0;
|
|
||||||
mod_config()->write_rate = 0;
|
|
||||||
mod_config()->write_burst = 0;
|
|
||||||
mod_config()->worker_read_rate = 0;
|
|
||||||
mod_config()->worker_read_burst = 0;
|
|
||||||
mod_config()->worker_write_rate = 0;
|
|
||||||
mod_config()->worker_write_burst = 0;
|
|
||||||
mod_config()->padding = 0;
|
mod_config()->padding = 0;
|
||||||
mod_config()->worker_frontend_connections = 0;
|
|
||||||
|
|
||||||
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_frontend = 0;
|
|
||||||
mod_config()->listener_disable_timeout = 0.;
|
|
||||||
mod_config()->downstream_request_buffer_size = 16_k;
|
|
||||||
mod_config()->downstream_response_buffer_size = 16_k;
|
|
||||||
mod_config()->host_unix = false;
|
|
||||||
mod_config()->downstream_addr_group_catch_all = 0;
|
|
||||||
mod_config()->fastopen = 0;
|
|
||||||
|
|
||||||
auto &tlsconf = mod_config()->tls;
|
auto &tlsconf = mod_config()->tls;
|
||||||
{
|
{
|
||||||
|
@ -1014,6 +973,15 @@ void fill_default_config() {
|
||||||
|
|
||||||
auto &http2conf = mod_config()->http2;
|
auto &http2conf = mod_config()->http2;
|
||||||
{
|
{
|
||||||
|
auto &timeoutconf = http2conf.timeout;
|
||||||
|
{
|
||||||
|
// Read timeout for HTTP/2 stream
|
||||||
|
timeoutconf.stream_read = 0.;
|
||||||
|
|
||||||
|
// Write timeout for HTTP/2 stream
|
||||||
|
timeoutconf.stream_write = 0.;
|
||||||
|
}
|
||||||
|
|
||||||
auto &upstreamconf = http2conf.upstream;
|
auto &upstreamconf = http2conf.upstream;
|
||||||
// window bits for HTTP/2 and SPDY upstream connection per
|
// window bits for HTTP/2 and SPDY upstream connection per
|
||||||
// stream. 2**16-1 = 64KiB-1, which is HTTP/2 default. Please note
|
// stream. 2**16-1 = 64KiB-1, which is HTTP/2 default. Please note
|
||||||
|
@ -1054,6 +1022,54 @@ void fill_default_config() {
|
||||||
}
|
}
|
||||||
|
|
||||||
loggingconf.syslog_facility = LOG_DAEMON;
|
loggingconf.syslog_facility = LOG_DAEMON;
|
||||||
|
|
||||||
|
auto &connconf = mod_config()->conn;
|
||||||
|
{
|
||||||
|
auto &listenerconf = connconf.listener;
|
||||||
|
{
|
||||||
|
listenerconf.host = strcopy("*");
|
||||||
|
listenerconf.port = 3000;
|
||||||
|
// Default accept() backlog
|
||||||
|
listenerconf.backlog = 512;
|
||||||
|
listenerconf.host_unix = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto &upstreamconf = connconf.upstream;
|
||||||
|
{
|
||||||
|
auto &timeoutconf = upstreamconf.timeout;
|
||||||
|
// Read timeout for HTTP2 upstream connection
|
||||||
|
timeoutconf.http2_read = 3_min;
|
||||||
|
|
||||||
|
// Read timeout for non-HTTP2 upstream connection
|
||||||
|
timeoutconf.read = 1_min;
|
||||||
|
|
||||||
|
// Write timeout for HTTP2/non-HTTP2 upstream connection
|
||||||
|
timeoutconf.write = 30.;
|
||||||
|
}
|
||||||
|
|
||||||
|
upstreamconf.no_tls = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto &downstreamconf = connconf.downstream;
|
||||||
|
{
|
||||||
|
auto &timeoutconf = downstreamconf.timeout;
|
||||||
|
// Read/Write timeouts for downstream connection
|
||||||
|
timeoutconf.read = 1_min;
|
||||||
|
timeoutconf.write = 30.;
|
||||||
|
// Timeout for pooled (idle) connections
|
||||||
|
timeoutconf.idle_read = 2.;
|
||||||
|
}
|
||||||
|
|
||||||
|
downstreamconf.no_tls = false;
|
||||||
|
downstreamconf.ipv4 = false;
|
||||||
|
downstreamconf.ipv6 = false;
|
||||||
|
downstreamconf.connections_per_host = 8;
|
||||||
|
downstreamconf.request_buffer_size = 16_k;
|
||||||
|
downstreamconf.response_buffer_size = 16_k;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -1151,11 +1167,11 @@ Connections:
|
||||||
assumes all addresses including both IPv4 and IPv6.
|
assumes all addresses including both IPv4 and IPv6.
|
||||||
UNIX domain socket can be specified by prefixing path
|
UNIX domain socket can be specified by prefixing path
|
||||||
name with "unix:" (e.g., unix:/var/run/nghttpx.sock)
|
name with "unix:" (e.g., unix:/var/run/nghttpx.sock)
|
||||||
Default: )" << get_config()->host.get() << ","
|
Default: )" << get_config()->conn.listener.host.get() << ","
|
||||||
<< get_config()->port << R"(
|
<< get_config()->conn.listener.port << R"(
|
||||||
--backlog=<N>
|
--backlog=<N>
|
||||||
Set listen backlog size.
|
Set listen backlog size.
|
||||||
Default: )" << get_config()->backlog << R"(
|
Default: )" << get_config()->conn.listener.backlog << R"(
|
||||||
--backend-ipv4
|
--backend-ipv4
|
||||||
Resolve backend hostname to IPv4 address only.
|
Resolve backend hostname to IPv4 address only.
|
||||||
--backend-ipv6
|
--backend-ipv6
|
||||||
|
@ -1183,45 +1199,50 @@ Performance:
|
||||||
--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()->read_rate << R"(
|
Default: )" << get_config()->conn.upstream.ratelimit.read.rate
|
||||||
|
<< 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()->read_burst << R"(
|
Default: )" << get_config()->conn.upstream.ratelimit.read.burst
|
||||||
|
<< 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()->write_rate << R"(
|
Default: )" << get_config()->conn.upstream.ratelimit.write.rate
|
||||||
|
<< 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()->write_burst << R"(
|
Default: )" << get_config()->conn.upstream.ratelimit.write.burst
|
||||||
|
<< 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
|
||||||
unlimited. Not implemented yet.
|
unlimited. Not implemented yet.
|
||||||
Default: )" << get_config()->worker_read_rate << R"(
|
Default: 0
|
||||||
--worker-read-burst=<SIZE>
|
--worker-read-burst=<SIZE>
|
||||||
Set maximum read burst size on frontend connection per
|
Set maximum read burst size on frontend connection per
|
||||||
worker. Setting 0 to this option means read burst size
|
worker. Setting 0 to this option means read burst size
|
||||||
is unlimited. Not implemented yet.
|
is unlimited. Not implemented yet.
|
||||||
Default: )" << get_config()->worker_read_burst << R"(
|
Default: 0
|
||||||
--worker-write-rate=<SIZE>
|
--worker-write-rate=<SIZE>
|
||||||
Set maximum average write rate on frontend connection
|
Set maximum average write rate on frontend connection
|
||||||
per worker. Setting 0 to this option means write rate
|
per worker. Setting 0 to this option means write rate
|
||||||
is unlimited. Not implemented yet.
|
is unlimited. Not implemented yet.
|
||||||
Default: )" << get_config()->worker_write_rate << R"(
|
Default: 0
|
||||||
--worker-write-burst=<SIZE>
|
--worker-write-burst=<SIZE>
|
||||||
Set maximum write burst size on frontend connection per
|
Set maximum write burst size on frontend connection per
|
||||||
worker. Setting 0 to this option means write burst size
|
worker. Setting 0 to this option means write burst size
|
||||||
is unlimited. Not implemented yet.
|
is unlimited. Not implemented yet.
|
||||||
Default: )" << get_config()->worker_write_burst << R"(
|
Default: 0
|
||||||
--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()->worker_frontend_connections << R"(
|
Default: )" << get_config()->conn.upstream.worker_connections
|
||||||
|
<< R"(
|
||||||
--backend-http2-connections-per-worker=<N>
|
--backend-http2-connections-per-worker=<N>
|
||||||
Set maximum number of backend HTTP/2 physical
|
Set maximum number of backend HTTP/2 physical
|
||||||
connections per worker. If pattern is used in -b
|
connections per worker. If pattern is used in -b
|
||||||
|
@ -1239,7 +1260,7 @@ Performance:
|
||||||
header field for HTTP/2). To limit the number of
|
header field for HTTP/2). To limit the number of
|
||||||
connections per frontend for default mode, use
|
connections per frontend for default mode, use
|
||||||
--backend-http1-connections-per-frontend.
|
--backend-http1-connections-per-frontend.
|
||||||
Default: )" << get_config()->downstream_connections_per_host
|
Default: )" << get_config()->conn.downstream.connections_per_host
|
||||||
<< R"(
|
<< R"(
|
||||||
--backend-http1-connections-per-frontend=<N>
|
--backend-http1-connections-per-frontend=<N>
|
||||||
Set maximum number of backend concurrent HTTP/1
|
Set maximum number of backend concurrent HTTP/1
|
||||||
|
@ -1247,8 +1268,8 @@ Performance:
|
||||||
default mode. 0 means unlimited. To limit the number
|
default mode. 0 means unlimited. To limit the number
|
||||||
of connections per host for HTTP/2 or SPDY proxy mode
|
of connections per host for HTTP/2 or SPDY proxy mode
|
||||||
(-s option), use --backend-http1-connections-per-host.
|
(-s option), use --backend-http1-connections-per-host.
|
||||||
Default: )" << get_config()->downstream_connections_per_frontend
|
Default: )"
|
||||||
<< R"(
|
<< get_config()->conn.downstream.connections_per_frontend << 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.
|
||||||
|
@ -1256,59 +1277,63 @@ Performance:
|
||||||
--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()->downstream_request_buffer_size) << R"(
|
<< util::utos_unit(get_config()->conn.downstream.request_buffer_size)
|
||||||
|
<< 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()->downstream_response_buffer_size) << R"(
|
<< util::utos_unit(get_config()->conn.downstream.response_buffer_size)
|
||||||
|
<< 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()->fastopen << R"(
|
Default: )" << get_config()->conn.listener.fastopen << R"(
|
||||||
Timeout:
|
Timeout:
|
||||||
--frontend-http2-read-timeout=<DURATION>
|
--frontend-http2-read-timeout=<DURATION>
|
||||||
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()->http2_upstream_read_timeout) << R"(
|
<< util::duration_str(get_config()->conn.upstream.timeout.http2_read)
|
||||||
|
<< 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()->upstream_read_timeout) << R"(
|
<< util::duration_str(get_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()->upstream_write_timeout) << R"(
|
<< util::duration_str(get_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()->stream_read_timeout) << R"(
|
<< util::duration_str(get_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()->stream_write_timeout) << R"(
|
<< util::duration_str(get_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()->downstream_read_timeout) << R"(
|
<< util::duration_str(get_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()->downstream_write_timeout) << R"(
|
<< util::duration_str(get_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()->downstream_idle_read_timeout) << R"(
|
<< util::duration_str(get_config()->conn.downstream.timeout.idle_read)
|
||||||
|
<< 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()->listener_disable_timeout) << R"(
|
<< util::duration_str(get_config()->conn.listener.timeout.sleep) << R"(
|
||||||
|
|
||||||
SSL/TLS:
|
SSL/TLS:
|
||||||
--ciphers=<SUITE>
|
--ciphers=<SUITE>
|
||||||
|
@ -1858,15 +1883,18 @@ void process_options(
|
||||||
|
|
||||||
tlsconf.alpn_prefs = ssl::set_alpn_prefs(tlsconf.npn_list);
|
tlsconf.alpn_prefs = ssl::set_alpn_prefs(tlsconf.npn_list);
|
||||||
|
|
||||||
if (get_config()->backend_ipv4 && get_config()->backend_ipv6) {
|
auto &listenerconf = mod_config()->conn.listener;
|
||||||
|
auto &upstreamconf = mod_config()->conn.upstream;
|
||||||
|
auto &downstreamconf = mod_config()->conn.downstream;
|
||||||
|
|
||||||
|
if (downstreamconf.ipv4 && downstreamconf.ipv6) {
|
||||||
LOG(FATAL) << "--backend-ipv4 and --backend-ipv6 cannot be used at the "
|
LOG(FATAL) << "--backend-ipv4 and --backend-ipv6 cannot be used at the "
|
||||||
<< "same time.";
|
<< "same time.";
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (get_config()->worker_frontend_connections == 0) {
|
if (upstreamconf.worker_connections == 0) {
|
||||||
mod_config()->worker_frontend_connections =
|
upstreamconf.worker_connections = std::numeric_limits<size_t>::max();
|
||||||
std::numeric_limits<size_t>::max();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (get_config()->http2_proxy + get_config()->http2_bridge +
|
if (get_config()->http2_proxy + get_config()->http2_bridge +
|
||||||
|
@ -1879,23 +1907,23 @@ void process_options(
|
||||||
|
|
||||||
if (get_config()->client || get_config()->client_proxy) {
|
if (get_config()->client || get_config()->client_proxy) {
|
||||||
mod_config()->client_mode = true;
|
mod_config()->client_mode = true;
|
||||||
mod_config()->upstream_no_tls = true;
|
upstreamconf.no_tls = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (get_config()->client_mode || get_config()->http2_bridge) {
|
if (get_config()->client_mode || get_config()->http2_bridge) {
|
||||||
mod_config()->downstream_proto = PROTO_HTTP2;
|
downstreamconf.proto = PROTO_HTTP2;
|
||||||
} else {
|
} else {
|
||||||
mod_config()->downstream_proto = PROTO_HTTP;
|
downstreamconf.proto = PROTO_HTTP;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!get_config()->upstream_no_tls &&
|
if (!upstreamconf.no_tls &&
|
||||||
(!tlsconf.private_key_file || !tlsconf.cert_file)) {
|
(!tlsconf.private_key_file || !tlsconf.cert_file)) {
|
||||||
print_usage(std::cerr);
|
print_usage(std::cerr);
|
||||||
LOG(FATAL) << "Too few arguments";
|
LOG(FATAL) << "Too few arguments";
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!get_config()->upstream_no_tls && !tlsconf.ocsp.disabled) {
|
if (!upstreamconf.no_tls && !tlsconf.ocsp.disabled) {
|
||||||
struct stat buf;
|
struct stat buf;
|
||||||
if (stat(tlsconf.ocsp.fetch_ocsp_response_file.get(), &buf) != 0) {
|
if (stat(tlsconf.ocsp.fetch_ocsp_response_file.get(), &buf) != 0) {
|
||||||
tlsconf.ocsp.disabled = true;
|
tlsconf.ocsp.disabled = true;
|
||||||
|
@ -1905,31 +1933,31 @@ void process_options(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (get_config()->downstream_addr_groups.empty()) {
|
auto &addr_groups = downstreamconf.addr_groups;
|
||||||
|
|
||||||
|
if (addr_groups.empty()) {
|
||||||
DownstreamAddr addr;
|
DownstreamAddr addr;
|
||||||
addr.host = ImmutableString::from_lit(DEFAULT_DOWNSTREAM_HOST);
|
addr.host = ImmutableString::from_lit(DEFAULT_DOWNSTREAM_HOST);
|
||||||
addr.port = DEFAULT_DOWNSTREAM_PORT;
|
addr.port = DEFAULT_DOWNSTREAM_PORT;
|
||||||
|
|
||||||
DownstreamAddrGroup g("/");
|
DownstreamAddrGroup g("/");
|
||||||
g.addrs.push_back(std::move(addr));
|
g.addrs.push_back(std::move(addr));
|
||||||
mod_config()->router.add_route(g.pattern.get(), 1,
|
mod_config()->router.add_route(g.pattern.get(), 1, addr_groups.size());
|
||||||
get_config()->downstream_addr_groups.size());
|
addr_groups.push_back(std::move(g));
|
||||||
mod_config()->downstream_addr_groups.push_back(std::move(g));
|
|
||||||
} else if (get_config()->http2_proxy || get_config()->client_proxy) {
|
} else if (get_config()->http2_proxy || get_config()->client_proxy) {
|
||||||
// We don't support host mapping in these cases. Move all
|
// We don't support host mapping in these cases. Move all
|
||||||
// non-catch-all patterns to catch-all pattern.
|
// non-catch-all patterns to catch-all pattern.
|
||||||
DownstreamAddrGroup catch_all("/");
|
DownstreamAddrGroup catch_all("/");
|
||||||
for (auto &g : mod_config()->downstream_addr_groups) {
|
for (auto &g : addr_groups) {
|
||||||
std::move(std::begin(g.addrs), std::end(g.addrs),
|
std::move(std::begin(g.addrs), std::end(g.addrs),
|
||||||
std::back_inserter(catch_all.addrs));
|
std::back_inserter(catch_all.addrs));
|
||||||
}
|
}
|
||||||
std::vector<DownstreamAddrGroup>().swap(
|
std::vector<DownstreamAddrGroup>().swap(addr_groups);
|
||||||
mod_config()->downstream_addr_groups);
|
|
||||||
// maybe not necessary?
|
// maybe not necessary?
|
||||||
mod_config()->router = Router();
|
mod_config()->router = Router();
|
||||||
mod_config()->router.add_route(catch_all.pattern.get(), 1,
|
mod_config()->router.add_route(catch_all.pattern.get(), 1,
|
||||||
get_config()->downstream_addr_groups.size());
|
addr_groups.size());
|
||||||
mod_config()->downstream_addr_groups.push_back(std::move(catch_all));
|
addr_groups.push_back(std::move(catch_all));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (LOG_ENABLED(INFO)) {
|
if (LOG_ENABLED(INFO)) {
|
||||||
|
@ -1937,8 +1965,8 @@ void process_options(
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t catch_all_group = -1;
|
ssize_t catch_all_group = -1;
|
||||||
for (size_t i = 0; i < mod_config()->downstream_addr_groups.size(); ++i) {
|
for (size_t i = 0; i < addr_groups.size(); ++i) {
|
||||||
auto &g = mod_config()->downstream_addr_groups[i];
|
auto &g = addr_groups[i];
|
||||||
if (util::streq(g.pattern.get(), "/")) {
|
if (util::streq(g.pattern.get(), "/")) {
|
||||||
catch_all_group = i;
|
catch_all_group = i;
|
||||||
}
|
}
|
||||||
|
@ -1956,13 +1984,14 @@ void process_options(
|
||||||
LOG(FATAL) << "-b: No catch-all backend address is configured";
|
LOG(FATAL) << "-b: No catch-all backend address is configured";
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
mod_config()->downstream_addr_group_catch_all = catch_all_group;
|
|
||||||
|
downstreamconf.addr_group_catch_all = catch_all_group;
|
||||||
|
|
||||||
if (LOG_ENABLED(INFO)) {
|
if (LOG_ENABLED(INFO)) {
|
||||||
LOG(INFO) << "Catch-all pattern is group " << catch_all_group;
|
LOG(INFO) << "Catch-all pattern is group " << catch_all_group;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto &g : mod_config()->downstream_addr_groups) {
|
for (auto &g : addr_groups) {
|
||||||
for (auto &addr : g.addrs) {
|
for (auto &addr : g.addrs) {
|
||||||
|
|
||||||
if (addr.host_unix) {
|
if (addr.host_unix) {
|
||||||
|
@ -1970,7 +1999,7 @@ void process_options(
|
||||||
// hostport. This is used as Host header field to backend and
|
// hostport. This is used as Host header field to backend and
|
||||||
// not going to be passed to any syscalls.
|
// not going to be passed to any syscalls.
|
||||||
addr.hostport = ImmutableString(
|
addr.hostport = ImmutableString(
|
||||||
util::make_hostport("localhost", get_config()->port));
|
util::make_hostport("localhost", listenerconf.port));
|
||||||
|
|
||||||
auto path = addr.host.c_str();
|
auto path = addr.host.c_str();
|
||||||
auto pathlen = addr.host.size();
|
auto pathlen = addr.host.size();
|
||||||
|
@ -1997,9 +2026,9 @@ void process_options(
|
||||||
|
|
||||||
if (resolve_hostname(
|
if (resolve_hostname(
|
||||||
&addr.addr, addr.host.c_str(), addr.port,
|
&addr.addr, addr.host.c_str(), addr.port,
|
||||||
get_config()->backend_ipv4 ? AF_INET : (get_config()->backend_ipv6
|
downstreamconf.ipv4
|
||||||
? AF_INET6
|
? AF_INET
|
||||||
: AF_UNSPEC)) == -1) {
|
: (downstreamconf.ipv6 ? AF_INET6 : AF_UNSPEC)) == -1) {
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -371,16 +371,16 @@ int ClientHandler::upstream_http1_connhd_read() {
|
||||||
ClientHandler::ClientHandler(Worker *worker, int fd, SSL *ssl,
|
ClientHandler::ClientHandler(Worker *worker, int fd, SSL *ssl,
|
||||||
const char *ipaddr, const char *port)
|
const char *ipaddr, const char *port)
|
||||||
: conn_(worker->get_loop(), fd, ssl, worker->get_mcpool(),
|
: conn_(worker->get_loop(), fd, ssl, worker->get_mcpool(),
|
||||||
get_config()->upstream_write_timeout,
|
get_config()->conn.upstream.timeout.write,
|
||||||
get_config()->upstream_read_timeout, get_config()->write_rate,
|
get_config()->conn.upstream.timeout.read,
|
||||||
get_config()->write_burst, get_config()->read_rate,
|
get_config()->conn.upstream.ratelimit.write,
|
||||||
get_config()->read_burst, writecb, readcb, timeoutcb, this,
|
get_config()->conn.upstream.ratelimit.read, writecb, readcb,
|
||||||
get_config()->tls.dyn_rec.warmup_threshold,
|
timeoutcb, this, get_config()->tls.dyn_rec.warmup_threshold,
|
||||||
get_config()->tls.dyn_rec.idle_timeout),
|
get_config()->tls.dyn_rec.idle_timeout),
|
||||||
pinned_http2sessions_(
|
pinned_http2sessions_(
|
||||||
get_config()->downstream_proto == PROTO_HTTP2
|
get_config()->conn.downstream.proto == PROTO_HTTP2
|
||||||
? make_unique<std::vector<ssize_t>>(
|
? make_unique<std::vector<ssize_t>>(
|
||||||
get_config()->downstream_addr_groups.size(), -1)
|
get_config()->conn.downstream.addr_groups.size(), -1)
|
||||||
: nullptr),
|
: nullptr),
|
||||||
ipaddr_(ipaddr), port_(port), worker_(worker),
|
ipaddr_(ipaddr), port_(port), worker_(worker),
|
||||||
left_connhd_len_(NGHTTP2_CLIENT_MAGIC_LEN),
|
left_connhd_len_(NGHTTP2_CLIENT_MAGIC_LEN),
|
||||||
|
@ -395,7 +395,7 @@ 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()->accept_proxy_protocol) {
|
if (get_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;
|
||||||
|
@ -647,8 +647,9 @@ void ClientHandler::remove_downstream_connection(DownstreamConnection *dconn) {
|
||||||
std::unique_ptr<DownstreamConnection>
|
std::unique_ptr<DownstreamConnection>
|
||||||
ClientHandler::get_downstream_connection(Downstream *downstream) {
|
ClientHandler::get_downstream_connection(Downstream *downstream) {
|
||||||
size_t group;
|
size_t group;
|
||||||
auto &groups = get_config()->downstream_addr_groups;
|
auto &downstreamconf = get_config()->conn.downstream;
|
||||||
auto catch_all = get_config()->downstream_addr_group_catch_all;
|
auto &groups = downstreamconf.addr_groups;
|
||||||
|
auto catch_all = downstreamconf.addr_group_catch_all;
|
||||||
|
|
||||||
const auto &req = downstream->request();
|
const auto &req = downstream->request();
|
||||||
|
|
||||||
|
@ -693,7 +694,7 @@ ClientHandler::get_downstream_connection(Downstream *downstream) {
|
||||||
|
|
||||||
auto dconn_pool = worker_->get_dconn_pool();
|
auto dconn_pool = worker_->get_dconn_pool();
|
||||||
|
|
||||||
if (get_config()->downstream_proto == PROTO_HTTP2) {
|
if (downstreamconf.proto == PROTO_HTTP2) {
|
||||||
Http2Session *http2session;
|
Http2Session *http2session;
|
||||||
auto &pinned = (*pinned_http2sessions_)[group];
|
auto &pinned = (*pinned_http2sessions_)[group];
|
||||||
if (pinned == -1) {
|
if (pinned == -1) {
|
||||||
|
@ -857,8 +858,8 @@ void ClientHandler::write_accesslog(Downstream *downstream) {
|
||||||
std::chrono::high_resolution_clock::now(), // request_end_time
|
std::chrono::high_resolution_clock::now(), // request_end_time
|
||||||
|
|
||||||
req.http_major, req.http_minor, resp.http_status,
|
req.http_major, req.http_minor, resp.http_status,
|
||||||
downstream->response_sent_body_length, port_, get_config()->port,
|
downstream->response_sent_body_length, port_,
|
||||||
get_config()->pid,
|
get_config()->conn.listener.port, get_config()->pid,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -880,7 +881,8 @@ 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_, get_config()->port, get_config()->pid,
|
status, body_bytes_sent, port_, get_config()->conn.listener.port,
|
||||||
|
get_config()->pid,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1156,7 +1158,7 @@ const std::string &ClientHandler::get_forwarded_by() {
|
||||||
local_hostport_ += ':';
|
local_hostport_ += ':';
|
||||||
}
|
}
|
||||||
|
|
||||||
local_hostport_ += util::utos(get_config()->port);
|
local_hostport_ += util::utos(get_config()->conn.listener.port);
|
||||||
|
|
||||||
return local_hostport_;
|
return local_hostport_;
|
||||||
}
|
}
|
||||||
|
|
|
@ -594,6 +594,8 @@ void parse_mapping(const DownstreamAddr &addr, const char *src) {
|
||||||
// will append '/' to all patterns, so it becomes catch-all pattern.
|
// will append '/' to all patterns, so it becomes catch-all pattern.
|
||||||
auto mapping = util::split_config_str_list(src, ':');
|
auto mapping = util::split_config_str_list(src, ':');
|
||||||
assert(!mapping.empty());
|
assert(!mapping.empty());
|
||||||
|
auto &addr_groups = mod_config()->conn.downstream.addr_groups;
|
||||||
|
|
||||||
for (const auto &raw_pattern : mapping) {
|
for (const auto &raw_pattern : mapping) {
|
||||||
auto done = false;
|
auto done = false;
|
||||||
std::string pattern;
|
std::string pattern;
|
||||||
|
@ -608,7 +610,7 @@ void parse_mapping(const DownstreamAddr &addr, const char *src) {
|
||||||
util::inp_strlower(pattern);
|
util::inp_strlower(pattern);
|
||||||
pattern += http2::normalize_path(slash, raw_pattern.second);
|
pattern += http2::normalize_path(slash, raw_pattern.second);
|
||||||
}
|
}
|
||||||
for (auto &g : mod_config()->downstream_addr_groups) {
|
for (auto &g : addr_groups) {
|
||||||
if (g.pattern.get() == pattern) {
|
if (g.pattern.get() == pattern) {
|
||||||
g.addrs.push_back(addr);
|
g.addrs.push_back(addr);
|
||||||
done = true;
|
done = true;
|
||||||
|
@ -622,9 +624,9 @@ void parse_mapping(const DownstreamAddr &addr, const char *src) {
|
||||||
g.addrs.push_back(addr);
|
g.addrs.push_back(addr);
|
||||||
|
|
||||||
mod_config()->router.add_route(g.pattern.get(), strlen(g.pattern.get()),
|
mod_config()->router.add_route(g.pattern.get(), strlen(g.pattern.get()),
|
||||||
get_config()->downstream_addr_groups.size());
|
addr_groups.size());
|
||||||
|
|
||||||
mod_config()->downstream_addr_groups.push_back(std::move(g));
|
addr_groups.push_back(std::move(g));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -1419,11 +1421,13 @@ int parse_config(const char *opt, const char *optarg,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
case SHRPX_OPTID_FRONTEND: {
|
case SHRPX_OPTID_FRONTEND: {
|
||||||
|
auto &listenerconf = mod_config()->conn.listener;
|
||||||
|
|
||||||
if (util::istarts_with(optarg, SHRPX_UNIX_PATH_PREFIX)) {
|
if (util::istarts_with(optarg, SHRPX_UNIX_PATH_PREFIX)) {
|
||||||
auto path = optarg + str_size(SHRPX_UNIX_PATH_PREFIX);
|
auto path = optarg + str_size(SHRPX_UNIX_PATH_PREFIX);
|
||||||
mod_config()->host = strcopy(path);
|
listenerconf.host = strcopy(path);
|
||||||
mod_config()->port = 0;
|
listenerconf.port = 0;
|
||||||
mod_config()->host_unix = true;
|
listenerconf.host_unix = true;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1433,9 +1437,9 @@ int parse_config(const char *opt, const char *optarg,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
mod_config()->host = strcopy(host);
|
listenerconf.host = strcopy(host);
|
||||||
mod_config()->port = port;
|
listenerconf.port = port;
|
||||||
mod_config()->host_unix = false;
|
listenerconf.host_unix = false;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1484,20 +1488,26 @@ int parse_config(const char *opt, const char *optarg,
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
case SHRPX_OPTID_FRONTEND_HTTP2_READ_TIMEOUT:
|
case SHRPX_OPTID_FRONTEND_HTTP2_READ_TIMEOUT:
|
||||||
return parse_duration(&mod_config()->http2_upstream_read_timeout, opt,
|
return parse_duration(&mod_config()->conn.upstream.timeout.http2_read, opt,
|
||||||
optarg);
|
optarg);
|
||||||
case SHRPX_OPTID_FRONTEND_READ_TIMEOUT:
|
case SHRPX_OPTID_FRONTEND_READ_TIMEOUT:
|
||||||
return parse_duration(&mod_config()->upstream_read_timeout, opt, optarg);
|
return parse_duration(&mod_config()->conn.upstream.timeout.read, opt,
|
||||||
|
optarg);
|
||||||
case SHRPX_OPTID_FRONTEND_WRITE_TIMEOUT:
|
case SHRPX_OPTID_FRONTEND_WRITE_TIMEOUT:
|
||||||
return parse_duration(&mod_config()->upstream_write_timeout, opt, optarg);
|
return parse_duration(&mod_config()->conn.upstream.timeout.write, opt,
|
||||||
|
optarg);
|
||||||
case SHRPX_OPTID_BACKEND_READ_TIMEOUT:
|
case SHRPX_OPTID_BACKEND_READ_TIMEOUT:
|
||||||
return parse_duration(&mod_config()->downstream_read_timeout, opt, optarg);
|
return parse_duration(&mod_config()->conn.downstream.timeout.read, opt,
|
||||||
|
optarg);
|
||||||
case SHRPX_OPTID_BACKEND_WRITE_TIMEOUT:
|
case SHRPX_OPTID_BACKEND_WRITE_TIMEOUT:
|
||||||
return parse_duration(&mod_config()->downstream_write_timeout, opt, optarg);
|
return parse_duration(&mod_config()->conn.downstream.timeout.write, opt,
|
||||||
|
optarg);
|
||||||
case SHRPX_OPTID_STREAM_READ_TIMEOUT:
|
case SHRPX_OPTID_STREAM_READ_TIMEOUT:
|
||||||
return parse_duration(&mod_config()->stream_read_timeout, opt, optarg);
|
return parse_duration(&mod_config()->http2.timeout.stream_read, opt,
|
||||||
|
optarg);
|
||||||
case SHRPX_OPTID_STREAM_WRITE_TIMEOUT:
|
case SHRPX_OPTID_STREAM_WRITE_TIMEOUT:
|
||||||
return parse_duration(&mod_config()->stream_write_timeout, opt, optarg);
|
return parse_duration(&mod_config()->http2.timeout.stream_write, opt,
|
||||||
|
optarg);
|
||||||
case SHRPX_OPTID_ACCESSLOG_FILE:
|
case SHRPX_OPTID_ACCESSLOG_FILE:
|
||||||
mod_config()->logging.access.file = strcopy(optarg);
|
mod_config()->logging.access.file = strcopy(optarg);
|
||||||
|
|
||||||
|
@ -1529,12 +1539,12 @@ int parse_config(const char *opt, const char *optarg,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
mod_config()->fastopen = n;
|
mod_config()->conn.listener.fastopen = n;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
case SHRPX_OPTID_BACKEND_KEEP_ALIVE_TIMEOUT:
|
case SHRPX_OPTID_BACKEND_KEEP_ALIVE_TIMEOUT:
|
||||||
return parse_duration(&mod_config()->downstream_idle_read_timeout, opt,
|
return parse_duration(&mod_config()->conn.downstream.timeout.idle_read, opt,
|
||||||
optarg);
|
optarg);
|
||||||
case SHRPX_OPTID_FRONTEND_HTTP2_WINDOW_BITS:
|
case SHRPX_OPTID_FRONTEND_HTTP2_WINDOW_BITS:
|
||||||
case SHRPX_OPTID_BACKEND_HTTP2_WINDOW_BITS: {
|
case SHRPX_OPTID_BACKEND_HTTP2_WINDOW_BITS: {
|
||||||
|
@ -1593,11 +1603,11 @@ int parse_config(const char *opt, const char *optarg,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
case SHRPX_OPTID_FRONTEND_NO_TLS:
|
case SHRPX_OPTID_FRONTEND_NO_TLS:
|
||||||
mod_config()->upstream_no_tls = util::strieq(optarg, "yes");
|
mod_config()->conn.upstream.no_tls = util::strieq(optarg, "yes");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
case SHRPX_OPTID_BACKEND_NO_TLS:
|
case SHRPX_OPTID_BACKEND_NO_TLS:
|
||||||
mod_config()->downstream_no_tls = util::strieq(optarg, "yes");
|
mod_config()->conn.downstream.no_tls = util::strieq(optarg, "yes");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
case SHRPX_OPTID_BACKEND_TLS_SNI_FIELD:
|
case SHRPX_OPTID_BACKEND_TLS_SNI_FIELD:
|
||||||
|
@ -1676,7 +1686,7 @@ int parse_config(const char *opt, const char *optarg,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
mod_config()->backlog = n;
|
mod_config()->conn.listener.backlog = n;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1697,11 +1707,11 @@ int parse_config(const char *opt, const char *optarg,
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
case SHRPX_OPTID_BACKEND_IPV4:
|
case SHRPX_OPTID_BACKEND_IPV4:
|
||||||
mod_config()->backend_ipv4 = util::strieq(optarg, "yes");
|
mod_config()->conn.downstream.ipv4 = util::strieq(optarg, "yes");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
case SHRPX_OPTID_BACKEND_IPV6:
|
case SHRPX_OPTID_BACKEND_IPV6:
|
||||||
mod_config()->backend_ipv6 = util::strieq(optarg, "yes");
|
mod_config()->conn.downstream.ipv6 = util::strieq(optarg, "yes");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
case SHRPX_OPTID_BACKEND_HTTP_PROXY_URI: {
|
case SHRPX_OPTID_BACKEND_HTTP_PROXY_URI: {
|
||||||
|
@ -1742,25 +1752,29 @@ int parse_config(const char *opt, const char *optarg,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
case SHRPX_OPTID_READ_RATE:
|
case SHRPX_OPTID_READ_RATE:
|
||||||
return parse_uint_with_unit(&mod_config()->read_rate, opt, optarg);
|
return parse_uint_with_unit(
|
||||||
|
&mod_config()->conn.upstream.ratelimit.read.rate, opt, optarg);
|
||||||
case SHRPX_OPTID_READ_BURST:
|
case SHRPX_OPTID_READ_BURST:
|
||||||
return parse_uint_with_unit(&mod_config()->read_burst, opt, optarg);
|
return parse_uint_with_unit(
|
||||||
|
&mod_config()->conn.upstream.ratelimit.read.burst, opt, optarg);
|
||||||
case SHRPX_OPTID_WRITE_RATE:
|
case SHRPX_OPTID_WRITE_RATE:
|
||||||
return parse_uint_with_unit(&mod_config()->write_rate, opt, optarg);
|
return parse_uint_with_unit(
|
||||||
|
&mod_config()->conn.upstream.ratelimit.write.rate, opt, optarg);
|
||||||
case SHRPX_OPTID_WRITE_BURST:
|
case SHRPX_OPTID_WRITE_BURST:
|
||||||
return parse_uint_with_unit(&mod_config()->write_burst, opt, optarg);
|
return parse_uint_with_unit(
|
||||||
|
&mod_config()->conn.upstream.ratelimit.write.burst, opt, optarg);
|
||||||
case SHRPX_OPTID_WORKER_READ_RATE:
|
case SHRPX_OPTID_WORKER_READ_RATE:
|
||||||
LOG(WARN) << opt << ": not implemented yet";
|
LOG(WARN) << opt << ": not implemented yet";
|
||||||
return parse_uint_with_unit(&mod_config()->worker_read_rate, opt, optarg);
|
return 0;
|
||||||
case SHRPX_OPTID_WORKER_READ_BURST:
|
case SHRPX_OPTID_WORKER_READ_BURST:
|
||||||
LOG(WARN) << opt << ": not implemented yet";
|
LOG(WARN) << opt << ": not implemented yet";
|
||||||
return parse_uint_with_unit(&mod_config()->worker_read_burst, opt, optarg);
|
return 0;
|
||||||
case SHRPX_OPTID_WORKER_WRITE_RATE:
|
case SHRPX_OPTID_WORKER_WRITE_RATE:
|
||||||
LOG(WARN) << opt << ": not implemented yet";
|
LOG(WARN) << opt << ": not implemented yet";
|
||||||
return parse_uint_with_unit(&mod_config()->worker_write_rate, opt, optarg);
|
return 0;
|
||||||
case SHRPX_OPTID_WORKER_WRITE_BURST:
|
case SHRPX_OPTID_WORKER_WRITE_BURST:
|
||||||
LOG(WARN) << opt << ": not implemented yet";
|
LOG(WARN) << opt << ": not implemented yet";
|
||||||
return parse_uint_with_unit(&mod_config()->worker_write_burst, opt, optarg);
|
return 0;
|
||||||
case SHRPX_OPTID_NPN_LIST:
|
case SHRPX_OPTID_NPN_LIST:
|
||||||
mod_config()->tls.npn_list = util::parse_config_str_list(optarg);
|
mod_config()->tls.npn_list = util::parse_config_str_list(optarg);
|
||||||
|
|
||||||
|
@ -1867,7 +1881,8 @@ int parse_config(const char *opt, const char *optarg,
|
||||||
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()->conn.upstream.worker_connections, opt,
|
||||||
|
optarg);
|
||||||
case SHRPX_OPTID_NO_LOCATION_REWRITE:
|
case SHRPX_OPTID_NO_LOCATION_REWRITE:
|
||||||
mod_config()->http.no_location_rewrite = util::strieq(optarg, "yes");
|
mod_config()->http.no_location_rewrite = util::strieq(optarg, "yes");
|
||||||
|
|
||||||
|
@ -1892,15 +1907,16 @@ int parse_config(const char *opt, const char *optarg,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
mod_config()->downstream_connections_per_host = n;
|
mod_config()->conn.downstream.connections_per_host = n;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
case SHRPX_OPTID_BACKEND_HTTP1_CONNECTIONS_PER_FRONTEND:
|
case SHRPX_OPTID_BACKEND_HTTP1_CONNECTIONS_PER_FRONTEND:
|
||||||
return parse_uint(&mod_config()->downstream_connections_per_frontend, opt,
|
return parse_uint(&mod_config()->conn.downstream.connections_per_frontend,
|
||||||
optarg);
|
opt, optarg);
|
||||||
case SHRPX_OPTID_LISTENER_DISABLE_TIMEOUT:
|
case SHRPX_OPTID_LISTENER_DISABLE_TIMEOUT:
|
||||||
return parse_duration(&mod_config()->listener_disable_timeout, opt, optarg);
|
return parse_duration(&mod_config()->conn.listener.timeout.sleep, opt,
|
||||||
|
optarg);
|
||||||
case SHRPX_OPTID_TLS_TICKET_KEY_FILE:
|
case SHRPX_OPTID_TLS_TICKET_KEY_FILE:
|
||||||
mod_config()->tls.ticket.files.push_back(optarg);
|
mod_config()->tls.ticket.files.push_back(optarg);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1935,9 +1951,9 @@ int parse_config(const char *opt, const char *optarg,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (optid == SHRPX_OPTID_BACKEND_REQUEST_BUFFER) {
|
if (optid == SHRPX_OPTID_BACKEND_REQUEST_BUFFER) {
|
||||||
mod_config()->downstream_request_buffer_size = n;
|
mod_config()->conn.downstream.request_buffer_size = n;
|
||||||
} else {
|
} else {
|
||||||
mod_config()->downstream_response_buffer_size = n;
|
mod_config()->conn.downstream.response_buffer_size = n;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -2065,7 +2081,8 @@ int parse_config(const char *opt, const char *optarg,
|
||||||
#endif // !HAVE_MRUBY
|
#endif // !HAVE_MRUBY
|
||||||
return 0;
|
return 0;
|
||||||
case SHRPX_OPTID_ACCEPT_PROXY_PROTOCOL:
|
case SHRPX_OPTID_ACCEPT_PROXY_PROTOCOL:
|
||||||
mod_config()->accept_proxy_protocol = util::strieq(optarg, "yes");
|
mod_config()->conn.upstream.accept_proxy_protocol =
|
||||||
|
util::strieq(optarg, "yes");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
case SHRPX_OPTID_ADD_FORWARDED: {
|
case SHRPX_OPTID_ADD_FORWARDED: {
|
||||||
|
|
|
@ -429,6 +429,10 @@ struct Http2Config {
|
||||||
size_t connection_window_bits;
|
size_t connection_window_bits;
|
||||||
size_t connections_per_worker;
|
size_t connections_per_worker;
|
||||||
} downstream;
|
} downstream;
|
||||||
|
struct {
|
||||||
|
ev_tstamp stream_read;
|
||||||
|
ev_tstamp stream_write;
|
||||||
|
} timeout;
|
||||||
size_t max_concurrent_streams;
|
size_t max_concurrent_streams;
|
||||||
bool no_cookie_crumbling;
|
bool no_cookie_crumbling;
|
||||||
bool no_server_push;
|
bool no_server_push;
|
||||||
|
@ -449,26 +453,77 @@ struct LoggingConfig {
|
||||||
int syslog_facility;
|
int syslog_facility;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct RateLimitConfig {
|
||||||
|
size_t rate;
|
||||||
|
size_t burst;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ConnectionConfig {
|
||||||
|
struct {
|
||||||
|
struct {
|
||||||
|
ev_tstamp sleep;
|
||||||
|
} timeout;
|
||||||
|
// address of frontend connection. This could be a path to UNIX
|
||||||
|
// domain socket. In this case, |host_unix| must be true.
|
||||||
|
std::unique_ptr<char[]> host;
|
||||||
|
// frontend listening port. 0 if frontend listens on UNIX domain
|
||||||
|
// socket, in this case |host_unix| must be true.
|
||||||
|
uint16_t port;
|
||||||
|
// true if host contains UNIX domain socket path
|
||||||
|
bool host_unix;
|
||||||
|
int backlog;
|
||||||
|
// TCP fastopen. If this is positive, it is passed to
|
||||||
|
// setsockopt() along with TCP_FASTOPEN.
|
||||||
|
int fastopen;
|
||||||
|
} listener;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
struct {
|
||||||
|
ev_tstamp http2_read;
|
||||||
|
ev_tstamp read;
|
||||||
|
ev_tstamp write;
|
||||||
|
} timeout;
|
||||||
|
struct {
|
||||||
|
RateLimitConfig read;
|
||||||
|
RateLimitConfig write;
|
||||||
|
} ratelimit;
|
||||||
|
size_t worker_connections;
|
||||||
|
bool no_tls;
|
||||||
|
bool accept_proxy_protocol;
|
||||||
|
} upstream;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
struct {
|
||||||
|
ev_tstamp read;
|
||||||
|
ev_tstamp write;
|
||||||
|
ev_tstamp idle_read;
|
||||||
|
} timeout;
|
||||||
|
std::vector<DownstreamAddrGroup> addr_groups;
|
||||||
|
// The index of catch-all group in downstream_addr_groups.
|
||||||
|
size_t addr_group_catch_all;
|
||||||
|
size_t connections_per_host;
|
||||||
|
size_t connections_per_frontend;
|
||||||
|
size_t request_buffer_size;
|
||||||
|
size_t response_buffer_size;
|
||||||
|
// downstream protocol; this will be determined by given options.
|
||||||
|
shrpx_proto proto;
|
||||||
|
bool no_tls;
|
||||||
|
// true if IPv4 only; ipv4 and ipv6 are mutually exclusive; and
|
||||||
|
// (ipv4 && ipv6) must be false.
|
||||||
|
bool ipv4;
|
||||||
|
// true if IPv6 only
|
||||||
|
bool ipv6;
|
||||||
|
} downstream;
|
||||||
|
};
|
||||||
|
|
||||||
struct Config {
|
struct Config {
|
||||||
std::vector<DownstreamAddrGroup> downstream_addr_groups;
|
|
||||||
Router router;
|
Router router;
|
||||||
HttpProxy downstream_http_proxy;
|
HttpProxy downstream_http_proxy;
|
||||||
HttpConfig http;
|
HttpConfig http;
|
||||||
Http2Config http2;
|
Http2Config http2;
|
||||||
TLSConfig tls;
|
TLSConfig tls;
|
||||||
LoggingConfig logging;
|
LoggingConfig logging;
|
||||||
ev_tstamp http2_upstream_read_timeout;
|
ConnectionConfig conn;
|
||||||
ev_tstamp upstream_read_timeout;
|
|
||||||
ev_tstamp upstream_write_timeout;
|
|
||||||
ev_tstamp downstream_read_timeout;
|
|
||||||
ev_tstamp downstream_write_timeout;
|
|
||||||
ev_tstamp stream_read_timeout;
|
|
||||||
ev_tstamp stream_write_timeout;
|
|
||||||
ev_tstamp downstream_idle_read_timeout;
|
|
||||||
ev_tstamp listener_disable_timeout;
|
|
||||||
// address of frontend connection. This could be a path to UNIX
|
|
||||||
// domain socket. In this case, |host_unix| must be true.
|
|
||||||
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[]> user;
|
std::unique_ptr<char[]> user;
|
||||||
|
@ -477,49 +532,20 @@ struct Config {
|
||||||
char **argv;
|
char **argv;
|
||||||
char *cwd;
|
char *cwd;
|
||||||
size_t num_worker;
|
size_t num_worker;
|
||||||
size_t downstream_connections_per_host;
|
|
||||||
size_t downstream_connections_per_frontend;
|
|
||||||
size_t read_rate;
|
|
||||||
size_t read_burst;
|
|
||||||
size_t write_rate;
|
|
||||||
size_t write_burst;
|
|
||||||
size_t worker_read_rate;
|
|
||||||
size_t worker_read_burst;
|
|
||||||
size_t worker_write_rate;
|
|
||||||
size_t worker_write_burst;
|
|
||||||
size_t padding;
|
size_t padding;
|
||||||
size_t worker_frontend_connections;
|
|
||||||
size_t rlimit_nofile;
|
size_t rlimit_nofile;
|
||||||
size_t downstream_request_buffer_size;
|
|
||||||
size_t downstream_response_buffer_size;
|
|
||||||
// The index of catch-all group in downstream_addr_groups.
|
|
||||||
size_t downstream_addr_group_catch_all;
|
|
||||||
// downstream protocol; this will be determined by given options.
|
|
||||||
shrpx_proto downstream_proto;
|
|
||||||
int backlog;
|
|
||||||
int argc;
|
int argc;
|
||||||
int fastopen;
|
|
||||||
uid_t uid;
|
uid_t uid;
|
||||||
gid_t gid;
|
gid_t gid;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
// frontend listening port. 0 if frontend listens on UNIX domain
|
|
||||||
// socket, in this case |host_unix| must be true.
|
|
||||||
uint16_t 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 upstream_no_tls;
|
|
||||||
bool downstream_no_tls;
|
|
||||||
bool client;
|
bool client;
|
||||||
// true if --client or --client-proxy are enabled.
|
// true if --client or --client-proxy are enabled.
|
||||||
bool client_mode;
|
bool client_mode;
|
||||||
bool backend_ipv4;
|
|
||||||
bool backend_ipv6;
|
|
||||||
// true if host contains UNIX domain socket path
|
|
||||||
bool host_unix;
|
|
||||||
bool accept_proxy_protocol;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const Config *get_config();
|
const Config *get_config();
|
||||||
|
|
|
@ -42,15 +42,17 @@ using namespace nghttp2;
|
||||||
namespace shrpx {
|
namespace shrpx {
|
||||||
Connection::Connection(struct ev_loop *loop, int fd, SSL *ssl,
|
Connection::Connection(struct ev_loop *loop, int fd, SSL *ssl,
|
||||||
MemchunkPool *mcpool, ev_tstamp write_timeout,
|
MemchunkPool *mcpool, ev_tstamp write_timeout,
|
||||||
ev_tstamp read_timeout, size_t write_rate,
|
ev_tstamp read_timeout,
|
||||||
size_t write_burst, size_t read_rate, size_t read_burst,
|
const RateLimitConfig &write_limit,
|
||||||
IOCb writecb, IOCb readcb, TimerCb timeoutcb, void *data,
|
const RateLimitConfig &read_limit, IOCb writecb,
|
||||||
|
IOCb readcb, TimerCb timeoutcb, void *data,
|
||||||
size_t tls_dyn_rec_warmup_threshold,
|
size_t tls_dyn_rec_warmup_threshold,
|
||||||
ev_tstamp tls_dyn_rec_idle_timeout)
|
ev_tstamp tls_dyn_rec_idle_timeout)
|
||||||
: tls{DefaultMemchunks(mcpool), DefaultPeekMemchunks(mcpool)},
|
: tls{DefaultMemchunks(mcpool), DefaultPeekMemchunks(mcpool)},
|
||||||
wlimit(loop, &wev, write_rate, write_burst),
|
wlimit(loop, &wev, write_limit.rate, write_limit.burst),
|
||||||
rlimit(loop, &rev, read_rate, read_burst, this), writecb(writecb),
|
rlimit(loop, &rev, read_limit.rate, read_limit.burst, this),
|
||||||
readcb(readcb), timeoutcb(timeoutcb), loop(loop), data(data), fd(fd),
|
writecb(writecb), readcb(readcb), timeoutcb(timeoutcb), loop(loop),
|
||||||
|
data(data), fd(fd),
|
||||||
tls_dyn_rec_warmup_threshold(tls_dyn_rec_warmup_threshold),
|
tls_dyn_rec_warmup_threshold(tls_dyn_rec_warmup_threshold),
|
||||||
tls_dyn_rec_idle_timeout(tls_dyn_rec_idle_timeout) {
|
tls_dyn_rec_idle_timeout(tls_dyn_rec_idle_timeout) {
|
||||||
|
|
||||||
|
|
|
@ -73,10 +73,10 @@ using TimerCb = EVCb<ev_timer>;
|
||||||
|
|
||||||
struct Connection {
|
struct Connection {
|
||||||
Connection(struct ev_loop *loop, int fd, SSL *ssl, MemchunkPool *mcpool,
|
Connection(struct ev_loop *loop, int fd, SSL *ssl, MemchunkPool *mcpool,
|
||||||
ev_tstamp write_timeout, ev_tstamp read_timeout, size_t write_rate,
|
ev_tstamp write_timeout, ev_tstamp read_timeout,
|
||||||
size_t write_burst, size_t read_rate, size_t read_burst,
|
const RateLimitConfig &write_limit,
|
||||||
IOCb writecb, IOCb readcb, TimerCb timeoutcb, void *data,
|
const RateLimitConfig &read_limit, IOCb writecb, IOCb readcb,
|
||||||
size_t tls_dyn_rec_warmup_threshold,
|
TimerCb timeoutcb, void *data, size_t tls_dyn_rec_warmup_threshold,
|
||||||
ev_tstamp tls_dyn_rec_idle_timeout);
|
ev_tstamp tls_dyn_rec_idle_timeout);
|
||||||
~Connection();
|
~Connection();
|
||||||
|
|
||||||
|
|
|
@ -300,13 +300,13 @@ int ConnectionHandler::handle_connection(int fd, sockaddr *addr, int addrlen) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (get_config()->num_worker == 1) {
|
if (get_config()->num_worker == 1) {
|
||||||
|
auto &upstreamconf = get_config()->conn.upstream;
|
||||||
if (single_worker_->get_worker_stat()->num_connections >=
|
if (single_worker_->get_worker_stat()->num_connections >=
|
||||||
get_config()->worker_frontend_connections) {
|
upstreamconf.worker_connections) {
|
||||||
|
|
||||||
if (LOG_ENABLED(INFO)) {
|
if (LOG_ENABLED(INFO)) {
|
||||||
LLOG(INFO, this) << "Too many connections >="
|
LLOG(INFO, this) << "Too many connections >="
|
||||||
<< get_config()->worker_frontend_connections;
|
<< upstreamconf.worker_connections;
|
||||||
}
|
}
|
||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
|
@ -124,14 +124,16 @@ Downstream::Downstream(Upstream *upstream, MemchunkPool *mcpool,
|
||||||
chunked_response_(false), expect_final_response_(false),
|
chunked_response_(false), expect_final_response_(false),
|
||||||
request_pending_(false) {
|
request_pending_(false) {
|
||||||
|
|
||||||
|
auto &timeoutconf = get_config()->http2.timeout;
|
||||||
|
|
||||||
ev_timer_init(&upstream_rtimer_, &upstream_rtimeoutcb, 0.,
|
ev_timer_init(&upstream_rtimer_, &upstream_rtimeoutcb, 0.,
|
||||||
get_config()->stream_read_timeout);
|
timeoutconf.stream_read);
|
||||||
ev_timer_init(&upstream_wtimer_, &upstream_wtimeoutcb, 0.,
|
ev_timer_init(&upstream_wtimer_, &upstream_wtimeoutcb, 0.,
|
||||||
get_config()->stream_write_timeout);
|
timeoutconf.stream_write);
|
||||||
ev_timer_init(&downstream_rtimer_, &downstream_rtimeoutcb, 0.,
|
ev_timer_init(&downstream_rtimer_, &downstream_rtimeoutcb, 0.,
|
||||||
get_config()->stream_read_timeout);
|
timeoutconf.stream_read);
|
||||||
ev_timer_init(&downstream_wtimer_, &downstream_wtimeoutcb, 0.,
|
ev_timer_init(&downstream_wtimer_, &downstream_wtimeoutcb, 0.,
|
||||||
get_config()->stream_write_timeout);
|
timeoutconf.stream_write);
|
||||||
|
|
||||||
upstream_rtimer_.data = this;
|
upstream_rtimer_.data = this;
|
||||||
upstream_wtimer_.data = this;
|
upstream_wtimer_.data = this;
|
||||||
|
@ -491,7 +493,8 @@ void Downstream::set_chunked_request(bool f) { chunked_request_ = f; }
|
||||||
|
|
||||||
bool Downstream::request_buf_full() {
|
bool Downstream::request_buf_full() {
|
||||||
if (dconn_) {
|
if (dconn_) {
|
||||||
return request_buf_.rleft() >= get_config()->downstream_request_buffer_size;
|
return request_buf_.rleft() >=
|
||||||
|
get_config()->conn.downstream.request_buffer_size;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -582,7 +585,7 @@ DefaultMemchunks *Downstream::get_response_buf() { return &response_buf_; }
|
||||||
bool Downstream::response_buf_full() {
|
bool Downstream::response_buf_full() {
|
||||||
if (dconn_) {
|
if (dconn_) {
|
||||||
return response_buf_.rleft() >=
|
return response_buf_.rleft() >=
|
||||||
get_config()->downstream_response_buffer_size;
|
get_config()->conn.downstream.response_buffer_size;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -764,7 +767,7 @@ void disable_timer(struct ev_loop *loop, ev_timer *w) {
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void Downstream::reset_upstream_rtimer() {
|
void Downstream::reset_upstream_rtimer() {
|
||||||
if (get_config()->stream_read_timeout == 0.) {
|
if (get_config()->http2.timeout.stream_read == 0.) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto loop = upstream_->get_client_handler()->get_loop();
|
auto loop = upstream_->get_client_handler()->get_loop();
|
||||||
|
@ -773,16 +776,18 @@ void Downstream::reset_upstream_rtimer() {
|
||||||
|
|
||||||
void Downstream::reset_upstream_wtimer() {
|
void Downstream::reset_upstream_wtimer() {
|
||||||
auto loop = upstream_->get_client_handler()->get_loop();
|
auto loop = upstream_->get_client_handler()->get_loop();
|
||||||
if (get_config()->stream_write_timeout != 0.) {
|
auto &timeoutconf = get_config()->http2.timeout;
|
||||||
|
|
||||||
|
if (timeoutconf.stream_write != 0.) {
|
||||||
reset_timer(loop, &upstream_wtimer_);
|
reset_timer(loop, &upstream_wtimer_);
|
||||||
}
|
}
|
||||||
if (get_config()->stream_read_timeout != 0.) {
|
if (timeoutconf.stream_read != 0.) {
|
||||||
try_reset_timer(loop, &upstream_rtimer_);
|
try_reset_timer(loop, &upstream_rtimer_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Downstream::ensure_upstream_wtimer() {
|
void Downstream::ensure_upstream_wtimer() {
|
||||||
if (get_config()->stream_write_timeout == 0.) {
|
if (get_config()->http2.timeout.stream_write == 0.) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto loop = upstream_->get_client_handler()->get_loop();
|
auto loop = upstream_->get_client_handler()->get_loop();
|
||||||
|
@ -790,7 +795,7 @@ void Downstream::ensure_upstream_wtimer() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Downstream::disable_upstream_rtimer() {
|
void Downstream::disable_upstream_rtimer() {
|
||||||
if (get_config()->stream_read_timeout == 0.) {
|
if (get_config()->http2.timeout.stream_read == 0.) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto loop = upstream_->get_client_handler()->get_loop();
|
auto loop = upstream_->get_client_handler()->get_loop();
|
||||||
|
@ -798,7 +803,7 @@ void Downstream::disable_upstream_rtimer() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Downstream::disable_upstream_wtimer() {
|
void Downstream::disable_upstream_wtimer() {
|
||||||
if (get_config()->stream_write_timeout == 0.) {
|
if (get_config()->http2.timeout.stream_write == 0.) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto loop = upstream_->get_client_handler()->get_loop();
|
auto loop = upstream_->get_client_handler()->get_loop();
|
||||||
|
@ -806,7 +811,7 @@ void Downstream::disable_upstream_wtimer() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Downstream::reset_downstream_rtimer() {
|
void Downstream::reset_downstream_rtimer() {
|
||||||
if (get_config()->stream_read_timeout == 0.) {
|
if (get_config()->http2.timeout.stream_read == 0.) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto loop = upstream_->get_client_handler()->get_loop();
|
auto loop = upstream_->get_client_handler()->get_loop();
|
||||||
|
@ -815,16 +820,18 @@ void Downstream::reset_downstream_rtimer() {
|
||||||
|
|
||||||
void Downstream::reset_downstream_wtimer() {
|
void Downstream::reset_downstream_wtimer() {
|
||||||
auto loop = upstream_->get_client_handler()->get_loop();
|
auto loop = upstream_->get_client_handler()->get_loop();
|
||||||
if (get_config()->stream_write_timeout != 0.) {
|
auto &timeoutconf = get_config()->http2.timeout;
|
||||||
|
|
||||||
|
if (timeoutconf.stream_write != 0.) {
|
||||||
reset_timer(loop, &downstream_wtimer_);
|
reset_timer(loop, &downstream_wtimer_);
|
||||||
}
|
}
|
||||||
if (get_config()->stream_read_timeout != 0.) {
|
if (timeoutconf.stream_read != 0.) {
|
||||||
try_reset_timer(loop, &downstream_rtimer_);
|
try_reset_timer(loop, &downstream_rtimer_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Downstream::ensure_downstream_wtimer() {
|
void Downstream::ensure_downstream_wtimer() {
|
||||||
if (get_config()->stream_write_timeout == 0.) {
|
if (get_config()->http2.timeout.stream_write == 0.) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto loop = upstream_->get_client_handler()->get_loop();
|
auto loop = upstream_->get_client_handler()->get_loop();
|
||||||
|
@ -832,7 +839,7 @@ void Downstream::ensure_downstream_wtimer() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Downstream::disable_downstream_rtimer() {
|
void Downstream::disable_downstream_rtimer() {
|
||||||
if (get_config()->stream_read_timeout == 0.) {
|
if (get_config()->http2.timeout.stream_read == 0.) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto loop = upstream_->get_client_handler()->get_loop();
|
auto loop = upstream_->get_client_handler()->get_loop();
|
||||||
|
@ -840,7 +847,7 @@ void Downstream::disable_downstream_rtimer() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Downstream::disable_downstream_wtimer() {
|
void Downstream::disable_downstream_wtimer() {
|
||||||
if (get_config()->stream_write_timeout == 0.) {
|
if (get_config()->http2.timeout.stream_write == 0.) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto loop = upstream_->get_client_handler()->get_loop();
|
auto loop = upstream_->get_client_handler()->get_loop();
|
||||||
|
|
|
@ -47,7 +47,7 @@ std::string create_error_html(unsigned int status_code) {
|
||||||
const auto &server_name = get_config()->http.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()->conn.listener.port);
|
||||||
res += "</footer></body></html>";
|
res += "</footer></body></html>";
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
|
@ -268,7 +268,7 @@ int Http2DownstreamConnection::push_request_headers() {
|
||||||
auto addr_idx = http2session_->get_addr_idx();
|
auto addr_idx = http2session_->get_addr_idx();
|
||||||
auto group = http2session_->get_group();
|
auto group = http2session_->get_group();
|
||||||
const auto &downstream_hostport =
|
const auto &downstream_hostport =
|
||||||
get_config()->downstream_addr_groups[group].addrs[addr_idx].hostport;
|
get_config()->conn.downstream.addr_groups[group].addrs[addr_idx].hostport;
|
||||||
|
|
||||||
// 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.
|
||||||
|
|
|
@ -146,8 +146,8 @@ Http2Session::Http2Session(struct ev_loop *loop, SSL_CTX *ssl_ctx,
|
||||||
ConnectBlocker *connect_blocker, Worker *worker,
|
ConnectBlocker *connect_blocker, Worker *worker,
|
||||||
size_t group, size_t idx)
|
size_t group, size_t idx)
|
||||||
: conn_(loop, -1, nullptr, worker->get_mcpool(),
|
: conn_(loop, -1, nullptr, worker->get_mcpool(),
|
||||||
get_config()->downstream_write_timeout,
|
get_config()->conn.downstream.timeout.write,
|
||||||
get_config()->downstream_read_timeout, 0, 0, 0, 0, writecb, readcb,
|
get_config()->conn.downstream.timeout.read, {}, {}, writecb, readcb,
|
||||||
timeoutcb, this, get_config()->tls.dyn_rec.warmup_threshold,
|
timeoutcb, this, get_config()->tls.dyn_rec.warmup_threshold,
|
||||||
get_config()->tls.dyn_rec.idle_timeout),
|
get_config()->tls.dyn_rec.idle_timeout),
|
||||||
worker_(worker), connect_blocker_(connect_blocker), ssl_ctx_(ssl_ctx),
|
worker_(worker), connect_blocker_(connect_blocker), ssl_ctx_(ssl_ctx),
|
||||||
|
@ -240,13 +240,13 @@ int Http2Session::disconnect(bool hard) {
|
||||||
int Http2Session::check_cert() {
|
int Http2Session::check_cert() {
|
||||||
return ssl::check_cert(
|
return ssl::check_cert(
|
||||||
conn_.tls.ssl,
|
conn_.tls.ssl,
|
||||||
&get_config()->downstream_addr_groups[group_].addrs[addr_idx_]);
|
&get_config()->conn.downstream.addr_groups[group_].addrs[addr_idx_]);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Http2Session::initiate_connection() {
|
int Http2Session::initiate_connection() {
|
||||||
int rv = 0;
|
int rv = 0;
|
||||||
|
|
||||||
auto &addrs = get_config()->downstream_addr_groups[group_].addrs;
|
auto &addrs = get_config()->conn.downstream.addr_groups[group_].addrs;
|
||||||
|
|
||||||
if (state_ == DISCONNECTED) {
|
if (state_ == DISCONNECTED) {
|
||||||
if (connect_blocker_->blocked()) {
|
if (connect_blocker_->blocked()) {
|
||||||
|
@ -509,7 +509,7 @@ int Http2Session::downstream_connect_proxy() {
|
||||||
SSLOG(INFO, this) << "Connected to the proxy";
|
SSLOG(INFO, this) << "Connected to the proxy";
|
||||||
}
|
}
|
||||||
auto &downstream_addr =
|
auto &downstream_addr =
|
||||||
get_config()->downstream_addr_groups[group_].addrs[addr_idx_];
|
get_config()->conn.downstream.addr_groups[group_].addrs[addr_idx_];
|
||||||
|
|
||||||
std::string req = "CONNECT ";
|
std::string req = "CONNECT ";
|
||||||
req.append(downstream_addr.hostport.c_str(), downstream_addr.hostport.size());
|
req.append(downstream_addr.hostport.c_str(), downstream_addr.hostport.size());
|
||||||
|
@ -1351,7 +1351,7 @@ int Http2Session::connection_made() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto must_terminate = !get_config()->downstream_no_tls &&
|
auto must_terminate = !get_config()->conn.downstream.no_tls &&
|
||||||
!nghttp2::ssl::check_http2_requirement(conn_.tls.ssl);
|
!nghttp2::ssl::check_http2_requirement(conn_.tls.ssl);
|
||||||
|
|
||||||
if (must_terminate) {
|
if (must_terminate) {
|
||||||
|
@ -1719,7 +1719,7 @@ int Http2Session::tls_handshake() {
|
||||||
SSLOG(INFO, this) << "SSL/TLS handshake completed";
|
SSLOG(INFO, this) << "SSL/TLS handshake completed";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!get_config()->downstream_no_tls && !get_config()->tls.insecure &&
|
if (!get_config()->conn.downstream.no_tls && !get_config()->tls.insecure &&
|
||||||
check_cert() != 0) {
|
check_cert() != 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -852,9 +852,9 @@ nghttp2_session_callbacks *create_http2_upstream_callbacks() {
|
||||||
Http2Upstream::Http2Upstream(ClientHandler *handler)
|
Http2Upstream::Http2Upstream(ClientHandler *handler)
|
||||||
: downstream_queue_(
|
: downstream_queue_(
|
||||||
get_config()->http2_proxy
|
get_config()->http2_proxy
|
||||||
? get_config()->downstream_connections_per_host
|
? get_config()->conn.downstream.connections_per_host
|
||||||
: get_config()->downstream_proto == PROTO_HTTP
|
: get_config()->conn.downstream.proto == PROTO_HTTP
|
||||||
? get_config()->downstream_connections_per_frontend
|
? get_config()->conn.downstream.connections_per_frontend
|
||||||
: 0,
|
: 0,
|
||||||
!get_config()->http2_proxy),
|
!get_config()->http2_proxy),
|
||||||
pending_response_buf_(handler->get_worker()->get_mcpool()),
|
pending_response_buf_(handler->get_worker()->get_mcpool()),
|
||||||
|
@ -914,7 +914,7 @@ Http2Upstream::Http2Upstream(ClientHandler *handler)
|
||||||
ev_prepare_start(handler_->get_loop(), &prep_);
|
ev_prepare_start(handler_->get_loop(), &prep_);
|
||||||
|
|
||||||
handler_->reset_upstream_read_timeout(
|
handler_->reset_upstream_read_timeout(
|
||||||
get_config()->http2_upstream_read_timeout);
|
get_config()->conn.upstream.timeout.http2_read);
|
||||||
|
|
||||||
handler_->signal_write();
|
handler_->signal_write();
|
||||||
}
|
}
|
||||||
|
|
|
@ -113,8 +113,9 @@ void connectcb(struct ev_loop *loop, ev_io *w, int revents) {
|
||||||
HttpDownstreamConnection::HttpDownstreamConnection(
|
HttpDownstreamConnection::HttpDownstreamConnection(
|
||||||
DownstreamConnectionPool *dconn_pool, size_t group, struct ev_loop *loop)
|
DownstreamConnectionPool *dconn_pool, size_t group, struct ev_loop *loop)
|
||||||
: DownstreamConnection(dconn_pool),
|
: DownstreamConnection(dconn_pool),
|
||||||
conn_(loop, -1, nullptr, nullptr, get_config()->downstream_write_timeout,
|
conn_(loop, -1, nullptr, nullptr,
|
||||||
get_config()->downstream_read_timeout, 0, 0, 0, 0, connectcb,
|
get_config()->conn.downstream.timeout.write,
|
||||||
|
get_config()->conn.downstream.timeout.read, {}, {}, connectcb,
|
||||||
readcb, timeoutcb, this, get_config()->tls.dyn_rec.warmup_threshold,
|
readcb, timeoutcb, this, get_config()->tls.dyn_rec.warmup_threshold,
|
||||||
get_config()->tls.dyn_rec.idle_timeout),
|
get_config()->tls.dyn_rec.idle_timeout),
|
||||||
ioctrl_(&conn_.rlimit), response_htp_{0}, group_(group), addr_idx_(0),
|
ioctrl_(&conn_.rlimit), response_htp_{0}, group_(group), addr_idx_(0),
|
||||||
|
@ -127,6 +128,8 @@ int HttpDownstreamConnection::attach_downstream(Downstream *downstream) {
|
||||||
DCLOG(INFO, this) << "Attaching to DOWNSTREAM:" << downstream;
|
DCLOG(INFO, this) << "Attaching to DOWNSTREAM:" << downstream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto &downstreamconf = get_config()->conn.downstream;
|
||||||
|
|
||||||
if (conn_.fd == -1) {
|
if (conn_.fd == -1) {
|
||||||
auto connect_blocker = client_handler_->get_connect_blocker();
|
auto connect_blocker = client_handler_->get_connect_blocker();
|
||||||
|
|
||||||
|
@ -141,7 +144,7 @@ int HttpDownstreamConnection::attach_downstream(Downstream *downstream) {
|
||||||
auto worker = client_handler_->get_worker();
|
auto worker = client_handler_->get_worker();
|
||||||
auto &next_downstream = worker->get_dgrp(group_)->next;
|
auto &next_downstream = worker->get_dgrp(group_)->next;
|
||||||
auto end = next_downstream;
|
auto end = next_downstream;
|
||||||
auto &addrs = get_config()->downstream_addr_groups[group_].addrs;
|
auto &addrs = downstreamconf.addr_groups[group_].addrs;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
auto &addr = addrs[next_downstream];
|
auto &addr = addrs[next_downstream];
|
||||||
auto i = next_downstream;
|
auto i = next_downstream;
|
||||||
|
@ -196,7 +199,7 @@ int HttpDownstreamConnection::attach_downstream(Downstream *downstream) {
|
||||||
ev_timer_again(conn_.loop, &conn_.wt);
|
ev_timer_again(conn_.loop, &conn_.wt);
|
||||||
} else {
|
} else {
|
||||||
// we may set read timer cb to idle_timeoutcb. Reset again.
|
// we may set read timer cb to idle_timeoutcb. Reset again.
|
||||||
conn_.rt.repeat = get_config()->downstream_read_timeout;
|
conn_.rt.repeat = downstreamconf.timeout.read;
|
||||||
ev_set_cb(&conn_.rt, timeoutcb);
|
ev_set_cb(&conn_.rt, timeoutcb);
|
||||||
ev_timer_again(conn_.loop, &conn_.rt);
|
ev_timer_again(conn_.loop, &conn_.rt);
|
||||||
ev_set_cb(&conn_.rev, readcb);
|
ev_set_cb(&conn_.rev, readcb);
|
||||||
|
@ -211,8 +214,10 @@ int HttpDownstreamConnection::attach_downstream(Downstream *downstream) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int HttpDownstreamConnection::push_request_headers() {
|
int HttpDownstreamConnection::push_request_headers() {
|
||||||
const auto &downstream_hostport =
|
const auto &downstream_hostport = get_config()
|
||||||
get_config()->downstream_addr_groups[group_].addrs[addr_idx_].hostport;
|
->conn.downstream.addr_groups[group_]
|
||||||
|
.addrs[addr_idx_]
|
||||||
|
.hostport;
|
||||||
const auto &req = downstream_->request();
|
const auto &req = downstream_->request();
|
||||||
|
|
||||||
auto connect_method = req.method == HTTP_CONNECT;
|
auto connect_method = req.method == HTTP_CONNECT;
|
||||||
|
@ -479,7 +484,7 @@ void HttpDownstreamConnection::detach_downstream(Downstream *downstream) {
|
||||||
ev_set_cb(&conn_.rev, idle_readcb);
|
ev_set_cb(&conn_.rev, idle_readcb);
|
||||||
ioctrl_.force_resume_read();
|
ioctrl_.force_resume_read();
|
||||||
|
|
||||||
conn_.rt.repeat = get_config()->downstream_idle_read_timeout;
|
conn_.rt.repeat = get_config()->conn.downstream.timeout.idle_read;
|
||||||
ev_set_cb(&conn_.rt, idle_timeoutcb);
|
ev_set_cb(&conn_.rt, idle_timeoutcb);
|
||||||
ev_timer_again(conn_.loop, &conn_.rt);
|
ev_timer_again(conn_.loop, &conn_.rt);
|
||||||
|
|
||||||
|
@ -494,7 +499,7 @@ void HttpDownstreamConnection::pause_read(IOCtrlReason reason) {
|
||||||
int HttpDownstreamConnection::resume_read(IOCtrlReason reason,
|
int HttpDownstreamConnection::resume_read(IOCtrlReason reason,
|
||||||
size_t consumed) {
|
size_t consumed) {
|
||||||
if (downstream_->get_response_buf()->rleft() <=
|
if (downstream_->get_response_buf()->rleft() <=
|
||||||
get_config()->downstream_request_buffer_size / 2) {
|
get_config()->conn.downstream.request_buffer_size / 2) {
|
||||||
ioctrl_.resume_read(reason);
|
ioctrl_.resume_read(reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -92,7 +92,7 @@ constexpr ev_tstamp read_timeout = 10.;
|
||||||
|
|
||||||
MemcachedConnection::MemcachedConnection(const Address *addr,
|
MemcachedConnection::MemcachedConnection(const Address *addr,
|
||||||
struct ev_loop *loop)
|
struct ev_loop *loop)
|
||||||
: conn_(loop, -1, nullptr, nullptr, write_timeout, read_timeout, 0, 0, 0, 0,
|
: conn_(loop, -1, nullptr, nullptr, write_timeout, read_timeout, {}, {},
|
||||||
connectcb, readcb, timeoutcb, this, 0, 0.),
|
connectcb, readcb, timeoutcb, this, 0, 0.),
|
||||||
parse_state_{}, addr_(addr), sendsum_(0), connected_(false) {}
|
parse_state_{}, addr_(addr), sendsum_(0), connected_(false) {}
|
||||||
|
|
||||||
|
|
|
@ -494,9 +494,9 @@ uint32_t infer_upstream_rst_stream_status_code(uint32_t downstream_error_code) {
|
||||||
SpdyUpstream::SpdyUpstream(uint16_t version, ClientHandler *handler)
|
SpdyUpstream::SpdyUpstream(uint16_t version, ClientHandler *handler)
|
||||||
: downstream_queue_(
|
: downstream_queue_(
|
||||||
get_config()->http2_proxy
|
get_config()->http2_proxy
|
||||||
? get_config()->downstream_connections_per_host
|
? get_config()->conn.downstream.connections_per_host
|
||||||
: get_config()->downstream_proto == PROTO_HTTP
|
: get_config()->conn.downstream.proto == PROTO_HTTP
|
||||||
? get_config()->downstream_connections_per_frontend
|
? get_config()->conn.downstream.connections_per_frontend
|
||||||
: 0,
|
: 0,
|
||||||
!get_config()->http2_proxy),
|
!get_config()->http2_proxy),
|
||||||
handler_(handler), session_(nullptr) {
|
handler_(handler), session_(nullptr) {
|
||||||
|
@ -558,7 +558,7 @@ SpdyUpstream::SpdyUpstream(uint16_t version, ClientHandler *handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
handler_->reset_upstream_read_timeout(
|
handler_->reset_upstream_read_timeout(
|
||||||
get_config()->http2_upstream_read_timeout);
|
get_config()->conn.upstream.timeout.http2_read);
|
||||||
|
|
||||||
handler_->signal_write();
|
handler_->signal_write();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1214,7 +1214,7 @@ SSL_CTX *setup_server_ssl_context(std::vector<SSL_CTX *> &all_ssl_ctx,
|
||||||
neverbleed_t *nb
|
neverbleed_t *nb
|
||||||
#endif // HAVE_NEVERBLEED
|
#endif // HAVE_NEVERBLEED
|
||||||
) {
|
) {
|
||||||
if (get_config()->upstream_no_tls) {
|
if (get_config()->conn.upstream.no_tls) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1266,11 +1266,13 @@ SSL_CTX *setup_server_ssl_context(std::vector<SSL_CTX *> &all_ssl_ctx,
|
||||||
}
|
}
|
||||||
|
|
||||||
bool downstream_tls_enabled() {
|
bool downstream_tls_enabled() {
|
||||||
|
auto no_tls = get_config()->conn.downstream.no_tls;
|
||||||
|
|
||||||
if (get_config()->client_mode) {
|
if (get_config()->client_mode) {
|
||||||
return !get_config()->downstream_no_tls;
|
return !no_tls;
|
||||||
}
|
}
|
||||||
|
|
||||||
return get_config()->http2_bridge && !get_config()->downstream_no_tls;
|
return get_config()->http2_bridge && !no_tls;
|
||||||
}
|
}
|
||||||
|
|
||||||
SSL_CTX *setup_client_ssl_context(
|
SSL_CTX *setup_client_ssl_context(
|
||||||
|
@ -1290,7 +1292,8 @@ SSL_CTX *setup_client_ssl_context(
|
||||||
}
|
}
|
||||||
|
|
||||||
CertLookupTree *create_cert_lookup_tree() {
|
CertLookupTree *create_cert_lookup_tree() {
|
||||||
if (get_config()->upstream_no_tls || get_config()->tls.subcerts.empty()) {
|
if (get_config()->conn.upstream.no_tls ||
|
||||||
|
get_config()->tls.subcerts.empty()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return new ssl::CertLookupTree();
|
return new ssl::CertLookupTree();
|
||||||
|
|
|
@ -69,9 +69,10 @@ std::random_device rd;
|
||||||
Worker::Worker(struct ev_loop *loop, SSL_CTX *sv_ssl_ctx, SSL_CTX *cl_ssl_ctx,
|
Worker::Worker(struct ev_loop *loop, SSL_CTX *sv_ssl_ctx, SSL_CTX *cl_ssl_ctx,
|
||||||
ssl::CertLookupTree *cert_tree,
|
ssl::CertLookupTree *cert_tree,
|
||||||
const std::shared_ptr<TicketKeys> &ticket_keys)
|
const std::shared_ptr<TicketKeys> &ticket_keys)
|
||||||
: randgen_(rd()), dconn_pool_(get_config()->downstream_addr_groups.size()),
|
: randgen_(rd()),
|
||||||
worker_stat_(get_config()->downstream_addr_groups.size()),
|
dconn_pool_(get_config()->conn.downstream.addr_groups.size()),
|
||||||
dgrps_(get_config()->downstream_addr_groups.size()), loop_(loop),
|
worker_stat_(get_config()->conn.downstream.addr_groups.size()),
|
||||||
|
dgrps_(get_config()->conn.downstream.addr_groups.size()), loop_(loop),
|
||||||
sv_ssl_ctx_(sv_ssl_ctx), cl_ssl_ctx_(cl_ssl_ctx), cert_tree_(cert_tree),
|
sv_ssl_ctx_(sv_ssl_ctx), cl_ssl_ctx_(cl_ssl_ctx), cert_tree_(cert_tree),
|
||||||
ticket_keys_(ticket_keys),
|
ticket_keys_(ticket_keys),
|
||||||
connect_blocker_(make_unique<ConnectBlocker>(loop_)),
|
connect_blocker_(make_unique<ConnectBlocker>(loop_)),
|
||||||
|
@ -90,13 +91,15 @@ Worker::Worker(struct ev_loop *loop, SSL_CTX *sv_ssl_ctx, SSL_CTX *cl_ssl_ctx,
|
||||||
&session_cacheconf.memcached.addr, loop);
|
&session_cacheconf.memcached.addr, loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (get_config()->downstream_proto == PROTO_HTTP2) {
|
auto &downstreamconf = get_config()->conn.downstream;
|
||||||
|
|
||||||
|
if (downstreamconf.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;
|
||||||
if (m == 0) {
|
if (m == 0) {
|
||||||
m = get_config()->downstream_addr_groups[group].addrs.size();
|
m = downstreamconf.addr_groups[group].addrs.size();
|
||||||
}
|
}
|
||||||
for (size_t idx = 0; idx < m; ++idx) {
|
for (size_t idx = 0; idx < m; ++idx) {
|
||||||
dgrp.http2sessions.push_back(make_unique<Http2Session>(
|
dgrp.http2sessions.push_back(make_unique<Http2Session>(
|
||||||
|
@ -151,6 +154,9 @@ void Worker::process_events() {
|
||||||
std::lock_guard<std::mutex> g(m_);
|
std::lock_guard<std::mutex> g(m_);
|
||||||
q.swap(q_);
|
q.swap(q_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto worker_connections = get_config()->conn.upstream.worker_connections;
|
||||||
|
|
||||||
for (auto &wev : q) {
|
for (auto &wev : q) {
|
||||||
switch (wev.type) {
|
switch (wev.type) {
|
||||||
case NEW_CONNECTION: {
|
case NEW_CONNECTION: {
|
||||||
|
@ -159,12 +165,10 @@ void Worker::process_events() {
|
||||||
<< ", addrlen=" << wev.client_addrlen;
|
<< ", addrlen=" << wev.client_addrlen;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (worker_stat_.num_connections >=
|
if (worker_stat_.num_connections >= worker_connections) {
|
||||||
get_config()->worker_frontend_connections) {
|
|
||||||
|
|
||||||
if (LOG_ENABLED(INFO)) {
|
if (LOG_ENABLED(INFO)) {
|
||||||
WLOG(INFO, this) << "Too many connections >= "
|
WLOG(INFO, this) << "Too many connections >= " << worker_connections;
|
||||||
<< get_config()->worker_frontend_connections;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
close(wev.client_fd);
|
close(wev.client_fd);
|
||||||
|
|
|
@ -423,8 +423,10 @@ int worker_process_event_loop(WorkerProcessConfig *wpconf) {
|
||||||
|
|
||||||
#endif // HAVE_NEVERBLEED
|
#endif // HAVE_NEVERBLEED
|
||||||
|
|
||||||
|
auto &upstreamconf = get_config()->conn.upstream;
|
||||||
|
|
||||||
ev_timer renew_ticket_key_timer;
|
ev_timer renew_ticket_key_timer;
|
||||||
if (!get_config()->upstream_no_tls) {
|
if (!upstreamconf.no_tls) {
|
||||||
auto &ticketconf = get_config()->tls.ticket;
|
auto &ticketconf = get_config()->tls.ticket;
|
||||||
|
|
||||||
if (ticketconf.memcached.host) {
|
if (ticketconf.memcached.host) {
|
||||||
|
@ -514,7 +516,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 (!get_config()->upstream_no_tls && !get_config()->tls.ocsp.disabled) {
|
if (!upstreamconf.no_tls && !get_config()->tls.ocsp.disabled) {
|
||||||
conn_handler.proceed_next_cert_ocsp();
|
conn_handler.proceed_next_cert_ocsp();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue