mirror of
https://gitee.com/openharmony/third_party_nghttp2
synced 2024-12-11 10:07:58 +00:00
Merge branch 'nghttpx-reorganize-config'
This commit is contained in:
commit
dc0f0123e9
1065
src/shrpx.cc
1065
src/shrpx.cc
File diff suppressed because it is too large
Load Diff
@ -87,7 +87,7 @@ void AcceptHandler::accept_connection() {
|
||||
case ENFILE:
|
||||
LOG(WARN) << "acceptor: running out file descriptor; disable acceptor "
|
||||
"temporarily";
|
||||
conn_hnr_->disable_acceptor_temporary(30.);
|
||||
conn_hnr_->sleep_acceptor(get_config()->conn.listener.timeout.sleep);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -371,16 +371,16 @@ int ClientHandler::upstream_http1_connhd_read() {
|
||||
ClientHandler::ClientHandler(Worker *worker, int fd, SSL *ssl,
|
||||
const char *ipaddr, const char *port)
|
||||
: conn_(worker->get_loop(), fd, ssl, worker->get_mcpool(),
|
||||
get_config()->upstream_write_timeout,
|
||||
get_config()->upstream_read_timeout, get_config()->write_rate,
|
||||
get_config()->write_burst, get_config()->read_rate,
|
||||
get_config()->read_burst, writecb, readcb, timeoutcb, this,
|
||||
get_config()->tls_dyn_rec_warmup_threshold,
|
||||
get_config()->tls_dyn_rec_idle_timeout),
|
||||
get_config()->conn.upstream.timeout.write,
|
||||
get_config()->conn.upstream.timeout.read,
|
||||
get_config()->conn.upstream.ratelimit.write,
|
||||
get_config()->conn.upstream.ratelimit.read, writecb, readcb,
|
||||
timeoutcb, this, get_config()->tls.dyn_rec.warmup_threshold,
|
||||
get_config()->tls.dyn_rec.idle_timeout),
|
||||
pinned_http2sessions_(
|
||||
get_config()->downstream_proto == PROTO_HTTP2
|
||||
get_config()->conn.downstream.proto == PROTO_HTTP2
|
||||
? make_unique<std::vector<ssize_t>>(
|
||||
get_config()->downstream_addr_groups.size(), -1)
|
||||
get_config()->conn.downstream.addr_groups.size(), -1)
|
||||
: nullptr),
|
||||
ipaddr_(ipaddr), port_(port), worker_(worker),
|
||||
left_connhd_len_(NGHTTP2_CLIENT_MAGIC_LEN),
|
||||
@ -395,7 +395,7 @@ ClientHandler::ClientHandler(Worker *worker, int fd, SSL *ssl,
|
||||
conn_.rlimit.startw();
|
||||
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;
|
||||
write_ = &ClientHandler::noop;
|
||||
on_read_ = &ClientHandler::proxy_protocol_read;
|
||||
@ -404,14 +404,16 @@ ClientHandler::ClientHandler(Worker *worker, int fd, SSL *ssl,
|
||||
setup_upstream_io_callback();
|
||||
}
|
||||
|
||||
if ((get_config()->forwarded_params & FORWARDED_FOR) &&
|
||||
get_config()->forwarded_for_node_type == FORWARDED_NODE_OBFUSCATED) {
|
||||
if (get_config()->forwarded_for_obfuscated.empty()) {
|
||||
auto &fwdconf = get_config()->http.forwarded;
|
||||
|
||||
if ((fwdconf.params & FORWARDED_FOR) &&
|
||||
fwdconf.for_node_type == FORWARDED_NODE_OBFUSCATED) {
|
||||
if (fwdconf.for_obfuscated.empty()) {
|
||||
forwarded_for_obfuscated_ = "_";
|
||||
forwarded_for_obfuscated_ += util::random_alpha_digit(
|
||||
worker_->get_randgen(), SHRPX_OBFUSCATED_NODE_LENGTH);
|
||||
} else {
|
||||
forwarded_for_obfuscated_ = get_config()->forwarded_for_obfuscated;
|
||||
forwarded_for_obfuscated_ = fwdconf.for_obfuscated;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -521,7 +523,8 @@ int ClientHandler::validate_next_proto() {
|
||||
CLOG(INFO, this) << "The negotiated next protocol: " << proto;
|
||||
}
|
||||
|
||||
if (!ssl::in_proto_list(get_config()->npn_list, next_proto, next_proto_len)) {
|
||||
if (!ssl::in_proto_list(get_config()->tls.npn_list, next_proto,
|
||||
next_proto_len)) {
|
||||
if (LOG_ENABLED(INFO)) {
|
||||
CLOG(INFO, this) << "The negotiated protocol is not supported";
|
||||
}
|
||||
@ -644,8 +647,9 @@ void ClientHandler::remove_downstream_connection(DownstreamConnection *dconn) {
|
||||
std::unique_ptr<DownstreamConnection>
|
||||
ClientHandler::get_downstream_connection(Downstream *downstream) {
|
||||
size_t group;
|
||||
auto &groups = get_config()->downstream_addr_groups;
|
||||
auto catch_all = get_config()->downstream_addr_group_catch_all;
|
||||
auto &downstreamconf = get_config()->conn.downstream;
|
||||
auto &groups = downstreamconf.addr_groups;
|
||||
auto catch_all = downstreamconf.addr_group_catch_all;
|
||||
|
||||
const auto &req = downstream->request();
|
||||
|
||||
@ -690,7 +694,7 @@ ClientHandler::get_downstream_connection(Downstream *downstream) {
|
||||
|
||||
auto dconn_pool = worker_->get_dconn_pool();
|
||||
|
||||
if (get_config()->downstream_proto == PROTO_HTTP2) {
|
||||
if (downstreamconf.proto == PROTO_HTTP2) {
|
||||
Http2Session *http2session;
|
||||
auto &pinned = (*pinned_http2sessions_)[group];
|
||||
if (pinned == -1) {
|
||||
@ -833,7 +837,7 @@ void ClientHandler::write_accesslog(Downstream *downstream) {
|
||||
const auto &resp = downstream->response();
|
||||
|
||||
upstream_accesslog(
|
||||
get_config()->accesslog_format,
|
||||
get_config()->logging.access.format,
|
||||
LogSpec{
|
||||
downstream, ipaddr_, http2::to_method_string(req.method),
|
||||
|
||||
@ -854,8 +858,8 @@ void ClientHandler::write_accesslog(Downstream *downstream) {
|
||||
std::chrono::high_resolution_clock::now(), // request_end_time
|
||||
|
||||
req.http_major, req.http_minor, resp.http_status,
|
||||
downstream->response_sent_body_length, port_, get_config()->port,
|
||||
get_config()->pid,
|
||||
downstream->response_sent_body_length, port_,
|
||||
get_config()->conn.listener.port, get_config()->pid,
|
||||
});
|
||||
}
|
||||
|
||||
@ -866,7 +870,7 @@ void ClientHandler::write_accesslog(int major, int minor, unsigned int status,
|
||||
nghttp2::ssl::TLSSessionInfo tls_info;
|
||||
|
||||
upstream_accesslog(
|
||||
get_config()->accesslog_format,
|
||||
get_config()->logging.access.format,
|
||||
LogSpec{
|
||||
nullptr, ipaddr_,
|
||||
StringRef::from_lit("-"), // method
|
||||
@ -877,7 +881,8 @@ void ClientHandler::write_accesslog(int major, int minor, unsigned int status,
|
||||
// there a better value?
|
||||
highres_now, // request_end_time
|
||||
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,
|
||||
});
|
||||
}
|
||||
|
||||
@ -1119,8 +1124,10 @@ int ClientHandler::proxy_protocol_read() {
|
||||
}
|
||||
|
||||
const std::string &ClientHandler::get_forwarded_by() {
|
||||
if (get_config()->forwarded_by_node_type == FORWARDED_NODE_OBFUSCATED) {
|
||||
return get_config()->forwarded_by_obfuscated;
|
||||
auto &fwdconf = get_config()->http.forwarded;
|
||||
|
||||
if (fwdconf.by_node_type == FORWARDED_NODE_OBFUSCATED) {
|
||||
return fwdconf.by_obfuscated;
|
||||
}
|
||||
if (!local_hostport_.empty()) {
|
||||
return local_hostport_;
|
||||
@ -1151,13 +1158,13 @@ const std::string &ClientHandler::get_forwarded_by() {
|
||||
local_hostport_ += ':';
|
||||
}
|
||||
|
||||
local_hostport_ += util::utos(get_config()->port);
|
||||
local_hostport_ += util::utos(get_config()->conn.listener.port);
|
||||
|
||||
return local_hostport_;
|
||||
}
|
||||
|
||||
const std::string &ClientHandler::get_forwarded_for() const {
|
||||
if (get_config()->forwarded_for_node_type == FORWARDED_NODE_OBFUSCATED) {
|
||||
if (get_config()->http.forwarded.for_node_type == FORWARDED_NODE_OBFUSCATED) {
|
||||
return forwarded_for_obfuscated_;
|
||||
}
|
||||
|
||||
|
@ -594,6 +594,8 @@ void parse_mapping(const DownstreamAddr &addr, const char *src) {
|
||||
// will append '/' to all patterns, so it becomes catch-all pattern.
|
||||
auto mapping = util::split_config_str_list(src, ':');
|
||||
assert(!mapping.empty());
|
||||
auto &addr_groups = mod_config()->conn.downstream.addr_groups;
|
||||
|
||||
for (const auto &raw_pattern : mapping) {
|
||||
auto done = false;
|
||||
std::string pattern;
|
||||
@ -608,7 +610,7 @@ void parse_mapping(const DownstreamAddr &addr, const char *src) {
|
||||
util::inp_strlower(pattern);
|
||||
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) {
|
||||
g.addrs.push_back(addr);
|
||||
done = true;
|
||||
@ -622,9 +624,9 @@ void parse_mapping(const DownstreamAddr &addr, const char *src) {
|
||||
g.addrs.push_back(addr);
|
||||
|
||||
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
|
||||
@ -1419,11 +1421,13 @@ int parse_config(const char *opt, const char *optarg,
|
||||
return 0;
|
||||
}
|
||||
case SHRPX_OPTID_FRONTEND: {
|
||||
auto &listenerconf = mod_config()->conn.listener;
|
||||
|
||||
if (util::istarts_with(optarg, SHRPX_UNIX_PATH_PREFIX)) {
|
||||
auto path = optarg + str_size(SHRPX_UNIX_PATH_PREFIX);
|
||||
mod_config()->host = strcopy(path);
|
||||
mod_config()->port = 0;
|
||||
mod_config()->host_unix = true;
|
||||
listenerconf.host = strcopy(path);
|
||||
listenerconf.port = 0;
|
||||
listenerconf.host_unix = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1433,9 +1437,9 @@ int parse_config(const char *opt, const char *optarg,
|
||||
return -1;
|
||||
}
|
||||
|
||||
mod_config()->host = strcopy(host);
|
||||
mod_config()->port = port;
|
||||
mod_config()->host_unix = false;
|
||||
listenerconf.host = strcopy(host);
|
||||
listenerconf.port = port;
|
||||
listenerconf.host_unix = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1447,7 +1451,7 @@ int parse_config(const char *opt, const char *optarg,
|
||||
return parse_uint(&mod_config()->num_worker, opt, optarg);
|
||||
#endif // !NOTHREADS
|
||||
case SHRPX_OPTID_HTTP2_MAX_CONCURRENT_STREAMS:
|
||||
return parse_uint(&mod_config()->http2_max_concurrent_streams, opt, optarg);
|
||||
return parse_uint(&mod_config()->http2.max_concurrent_streams, opt, optarg);
|
||||
case SHRPX_OPTID_LOG_LEVEL:
|
||||
if (Log::set_severity_level_by_name(optarg) == -1) {
|
||||
LOG(ERROR) << opt << ": Invalid severity level: " << optarg;
|
||||
@ -1472,50 +1476,56 @@ int parse_config(const char *opt, const char *optarg,
|
||||
|
||||
return 0;
|
||||
case SHRPX_OPTID_ADD_X_FORWARDED_FOR:
|
||||
mod_config()->add_x_forwarded_for = util::strieq(optarg, "yes");
|
||||
mod_config()->http.xff.add = util::strieq(optarg, "yes");
|
||||
|
||||
return 0;
|
||||
case SHRPX_OPTID_STRIP_INCOMING_X_FORWARDED_FOR:
|
||||
mod_config()->strip_incoming_x_forwarded_for = util::strieq(optarg, "yes");
|
||||
mod_config()->http.xff.strip_incoming = util::strieq(optarg, "yes");
|
||||
|
||||
return 0;
|
||||
case SHRPX_OPTID_NO_VIA:
|
||||
mod_config()->no_via = util::strieq(optarg, "yes");
|
||||
mod_config()->http.no_via = util::strieq(optarg, "yes");
|
||||
|
||||
return 0;
|
||||
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);
|
||||
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:
|
||||
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:
|
||||
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:
|
||||
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:
|
||||
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:
|
||||
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:
|
||||
mod_config()->accesslog_file = strcopy(optarg);
|
||||
mod_config()->logging.access.file = strcopy(optarg);
|
||||
|
||||
return 0;
|
||||
case SHRPX_OPTID_ACCESSLOG_SYSLOG:
|
||||
mod_config()->accesslog_syslog = util::strieq(optarg, "yes");
|
||||
mod_config()->logging.access.syslog = util::strieq(optarg, "yes");
|
||||
|
||||
return 0;
|
||||
case SHRPX_OPTID_ACCESSLOG_FORMAT:
|
||||
mod_config()->accesslog_format = parse_log_format(optarg);
|
||||
mod_config()->logging.access.format = parse_log_format(optarg);
|
||||
|
||||
return 0;
|
||||
case SHRPX_OPTID_ERRORLOG_FILE:
|
||||
mod_config()->errorlog_file = strcopy(optarg);
|
||||
mod_config()->logging.error.file = strcopy(optarg);
|
||||
|
||||
return 0;
|
||||
case SHRPX_OPTID_ERRORLOG_SYSLOG:
|
||||
mod_config()->errorlog_syslog = util::strieq(optarg, "yes");
|
||||
mod_config()->logging.error.syslog = util::strieq(optarg, "yes");
|
||||
|
||||
return 0;
|
||||
case SHRPX_OPTID_FASTOPEN: {
|
||||
@ -1529,21 +1539,21 @@ int parse_config(const char *opt, const char *optarg,
|
||||
return -1;
|
||||
}
|
||||
|
||||
mod_config()->fastopen = n;
|
||||
mod_config()->conn.listener.fastopen = n;
|
||||
|
||||
return 0;
|
||||
}
|
||||
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);
|
||||
case SHRPX_OPTID_FRONTEND_HTTP2_WINDOW_BITS:
|
||||
case SHRPX_OPTID_BACKEND_HTTP2_WINDOW_BITS: {
|
||||
size_t *resp;
|
||||
|
||||
if (optid == SHRPX_OPTID_FRONTEND_HTTP2_WINDOW_BITS) {
|
||||
resp = &mod_config()->http2_upstream_window_bits;
|
||||
resp = &mod_config()->http2.upstream.window_bits;
|
||||
} else {
|
||||
resp = &mod_config()->http2_downstream_window_bits;
|
||||
resp = &mod_config()->http2.downstream.window_bits;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
@ -1569,9 +1579,9 @@ int parse_config(const char *opt, const char *optarg,
|
||||
size_t *resp;
|
||||
|
||||
if (optid == SHRPX_OPTID_FRONTEND_HTTP2_CONNECTION_WINDOW_BITS) {
|
||||
resp = &mod_config()->http2_upstream_connection_window_bits;
|
||||
resp = &mod_config()->http2.upstream.connection_window_bits;
|
||||
} else {
|
||||
resp = &mod_config()->http2_downstream_connection_window_bits;
|
||||
resp = &mod_config()->http2.downstream.connection_window_bits;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
@ -1593,15 +1603,15 @@ int parse_config(const char *opt, const char *optarg,
|
||||
return 0;
|
||||
}
|
||||
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;
|
||||
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;
|
||||
case SHRPX_OPTID_BACKEND_TLS_SNI_FIELD:
|
||||
mod_config()->backend_tls_sni_name = optarg;
|
||||
mod_config()->tls.backend_sni_name = optarg;
|
||||
|
||||
return 0;
|
||||
case SHRPX_OPTID_PID_FILE:
|
||||
@ -1622,7 +1632,7 @@ int parse_config(const char *opt, const char *optarg,
|
||||
return 0;
|
||||
}
|
||||
case SHRPX_OPTID_PRIVATE_KEY_FILE:
|
||||
mod_config()->private_key_file = strcopy(optarg);
|
||||
mod_config()->tls.private_key_file = strcopy(optarg);
|
||||
|
||||
return 0;
|
||||
case SHRPX_OPTID_PRIVATE_KEY_PASSWD_FILE: {
|
||||
@ -1631,16 +1641,16 @@ int parse_config(const char *opt, const char *optarg,
|
||||
LOG(ERROR) << opt << ": Couldn't read key file's passwd from " << optarg;
|
||||
return -1;
|
||||
}
|
||||
mod_config()->private_key_passwd = strcopy(passwd);
|
||||
mod_config()->tls.private_key_passwd = strcopy(passwd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
case SHRPX_OPTID_CERTIFICATE_FILE:
|
||||
mod_config()->cert_file = strcopy(optarg);
|
||||
mod_config()->tls.cert_file = strcopy(optarg);
|
||||
|
||||
return 0;
|
||||
case SHRPX_OPTID_DH_PARAM_FILE:
|
||||
mod_config()->dh_param_file = strcopy(optarg);
|
||||
mod_config()->tls.dh_param_file = strcopy(optarg);
|
||||
|
||||
return 0;
|
||||
case SHRPX_OPTID_SUBCERT: {
|
||||
@ -1649,7 +1659,7 @@ int parse_config(const char *opt, const char *optarg,
|
||||
if (sp) {
|
||||
std::string keyfile(optarg, sp);
|
||||
// TODO Do we need private key for subcert?
|
||||
mod_config()->subcerts.emplace_back(keyfile, sp + 1);
|
||||
mod_config()->tls.subcerts.emplace_back(keyfile, sp + 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -1660,7 +1670,7 @@ int parse_config(const char *opt, const char *optarg,
|
||||
LOG(ERROR) << opt << ": Unknown syslog facility: " << optarg;
|
||||
return -1;
|
||||
}
|
||||
mod_config()->syslog_facility = facility;
|
||||
mod_config()->logging.syslog_facility = facility;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1676,12 +1686,12 @@ int parse_config(const char *opt, const char *optarg,
|
||||
return -1;
|
||||
}
|
||||
|
||||
mod_config()->backlog = n;
|
||||
mod_config()->conn.listener.backlog = n;
|
||||
|
||||
return 0;
|
||||
}
|
||||
case SHRPX_OPTID_CIPHERS:
|
||||
mod_config()->ciphers = strcopy(optarg);
|
||||
mod_config()->tls.ciphers = strcopy(optarg);
|
||||
|
||||
return 0;
|
||||
case SHRPX_OPTID_CLIENT:
|
||||
@ -1689,19 +1699,19 @@ int parse_config(const char *opt, const char *optarg,
|
||||
|
||||
return 0;
|
||||
case SHRPX_OPTID_INSECURE:
|
||||
mod_config()->insecure = util::strieq(optarg, "yes");
|
||||
mod_config()->tls.insecure = util::strieq(optarg, "yes");
|
||||
|
||||
return 0;
|
||||
case SHRPX_OPTID_CACERT:
|
||||
mod_config()->cacert = strcopy(optarg);
|
||||
mod_config()->tls.cacert = strcopy(optarg);
|
||||
|
||||
return 0;
|
||||
case SHRPX_OPTID_BACKEND_IPV4:
|
||||
mod_config()->backend_ipv4 = util::strieq(optarg, "yes");
|
||||
mod_config()->conn.downstream.ipv4 = util::strieq(optarg, "yes");
|
||||
|
||||
return 0;
|
||||
case SHRPX_OPTID_BACKEND_IPV6:
|
||||
mod_config()->backend_ipv6 = util::strieq(optarg, "yes");
|
||||
mod_config()->conn.downstream.ipv6 = util::strieq(optarg, "yes");
|
||||
|
||||
return 0;
|
||||
case SHRPX_OPTID_BACKEND_HTTP_PROXY_URI: {
|
||||
@ -1742,63 +1752,70 @@ int parse_config(const char *opt, const char *optarg,
|
||||
return 0;
|
||||
}
|
||||
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:
|
||||
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:
|
||||
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:
|
||||
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:
|
||||
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:
|
||||
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:
|
||||
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:
|
||||
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:
|
||||
mod_config()->npn_list = util::parse_config_str_list(optarg);
|
||||
mod_config()->tls.npn_list = util::parse_config_str_list(optarg);
|
||||
|
||||
return 0;
|
||||
case SHRPX_OPTID_TLS_PROTO_LIST:
|
||||
mod_config()->tls_proto_list = util::parse_config_str_list(optarg);
|
||||
mod_config()->tls.tls_proto_list = util::parse_config_str_list(optarg);
|
||||
|
||||
return 0;
|
||||
case SHRPX_OPTID_VERIFY_CLIENT:
|
||||
mod_config()->verify_client = util::strieq(optarg, "yes");
|
||||
mod_config()->tls.client_verify.enabled = util::strieq(optarg, "yes");
|
||||
|
||||
return 0;
|
||||
case SHRPX_OPTID_VERIFY_CLIENT_CACERT:
|
||||
mod_config()->verify_client_cacert = strcopy(optarg);
|
||||
mod_config()->tls.client_verify.cacert = strcopy(optarg);
|
||||
|
||||
return 0;
|
||||
case SHRPX_OPTID_CLIENT_PRIVATE_KEY_FILE:
|
||||
mod_config()->client_private_key_file = strcopy(optarg);
|
||||
mod_config()->tls.client.private_key_file = strcopy(optarg);
|
||||
|
||||
return 0;
|
||||
case SHRPX_OPTID_CLIENT_CERT_FILE:
|
||||
mod_config()->client_cert_file = strcopy(optarg);
|
||||
mod_config()->tls.client.cert_file = strcopy(optarg);
|
||||
|
||||
return 0;
|
||||
case SHRPX_OPTID_FRONTEND_HTTP2_DUMP_REQUEST_HEADER:
|
||||
mod_config()->http2_upstream_dump_request_header_file = strcopy(optarg);
|
||||
mod_config()->http2.upstream.debug.dump.request_header_file =
|
||||
strcopy(optarg);
|
||||
|
||||
return 0;
|
||||
case SHRPX_OPTID_FRONTEND_HTTP2_DUMP_RESPONSE_HEADER:
|
||||
mod_config()->http2_upstream_dump_response_header_file = strcopy(optarg);
|
||||
mod_config()->http2.upstream.debug.dump.response_header_file =
|
||||
strcopy(optarg);
|
||||
|
||||
return 0;
|
||||
case SHRPX_OPTID_HTTP2_NO_COOKIE_CRUMBLING:
|
||||
mod_config()->http2_no_cookie_crumbling = util::strieq(optarg, "yes");
|
||||
mod_config()->http2.no_cookie_crumbling = util::strieq(optarg, "yes");
|
||||
|
||||
return 0;
|
||||
case SHRPX_OPTID_FRONTEND_FRAME_DEBUG:
|
||||
mod_config()->upstream_frame_debug = util::strieq(optarg, "yes");
|
||||
mod_config()->http2.upstream.debug.frame_debug =
|
||||
util::strieq(optarg, "yes");
|
||||
|
||||
return 0;
|
||||
case SHRPX_OPTID_PADDING:
|
||||
@ -1845,7 +1862,7 @@ int parse_config(const char *opt, const char *optarg,
|
||||
}
|
||||
}
|
||||
|
||||
mod_config()->altsvcs.push_back(std::move(altsvc));
|
||||
mod_config()->http.altsvcs.push_back(std::move(altsvc));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1857,16 +1874,17 @@ int parse_config(const char *opt, const char *optarg,
|
||||
return -1;
|
||||
}
|
||||
if (optid == SHRPX_OPTID_ADD_REQUEST_HEADER) {
|
||||
mod_config()->add_request_headers.push_back(std::move(p));
|
||||
mod_config()->http.add_request_headers.push_back(std::move(p));
|
||||
} else {
|
||||
mod_config()->add_response_headers.push_back(std::move(p));
|
||||
mod_config()->http.add_response_headers.push_back(std::move(p));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
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:
|
||||
mod_config()->no_location_rewrite = util::strieq(optarg, "yes");
|
||||
mod_config()->http.no_location_rewrite = util::strieq(optarg, "yes");
|
||||
|
||||
return 0;
|
||||
case SHRPX_OPTID_NO_HOST_REWRITE:
|
||||
@ -1889,17 +1907,18 @@ int parse_config(const char *opt, const char *optarg,
|
||||
return -1;
|
||||
}
|
||||
|
||||
mod_config()->downstream_connections_per_host = n;
|
||||
mod_config()->conn.downstream.connections_per_host = n;
|
||||
|
||||
return 0;
|
||||
}
|
||||
case SHRPX_OPTID_BACKEND_HTTP1_CONNECTIONS_PER_FRONTEND:
|
||||
return parse_uint(&mod_config()->downstream_connections_per_frontend, opt,
|
||||
optarg);
|
||||
return parse_uint(&mod_config()->conn.downstream.connections_per_frontend,
|
||||
opt, optarg);
|
||||
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:
|
||||
mod_config()->tls_ticket_key_files.push_back(optarg);
|
||||
mod_config()->tls.ticket.files.push_back(optarg);
|
||||
return 0;
|
||||
case SHRPX_OPTID_RLIMIT_NOFILE: {
|
||||
int n;
|
||||
@ -1932,36 +1951,36 @@ int parse_config(const char *opt, const char *optarg,
|
||||
}
|
||||
|
||||
if (optid == SHRPX_OPTID_BACKEND_REQUEST_BUFFER) {
|
||||
mod_config()->downstream_request_buffer_size = n;
|
||||
mod_config()->conn.downstream.request_buffer_size = n;
|
||||
} else {
|
||||
mod_config()->downstream_response_buffer_size = n;
|
||||
mod_config()->conn.downstream.response_buffer_size = n;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
case SHRPX_OPTID_NO_SERVER_PUSH:
|
||||
mod_config()->no_server_push = util::strieq(optarg, "yes");
|
||||
mod_config()->http2.no_server_push = util::strieq(optarg, "yes");
|
||||
|
||||
return 0;
|
||||
case SHRPX_OPTID_BACKEND_HTTP2_CONNECTIONS_PER_WORKER:
|
||||
return parse_uint(&mod_config()->http2_downstream_connections_per_worker,
|
||||
return parse_uint(&mod_config()->http2.downstream.connections_per_worker,
|
||||
opt, optarg);
|
||||
case SHRPX_OPTID_FETCH_OCSP_RESPONSE_FILE:
|
||||
mod_config()->fetch_ocsp_response_file = strcopy(optarg);
|
||||
mod_config()->tls.ocsp.fetch_ocsp_response_file = strcopy(optarg);
|
||||
|
||||
return 0;
|
||||
case SHRPX_OPTID_OCSP_UPDATE_INTERVAL:
|
||||
return parse_duration(&mod_config()->ocsp_update_interval, opt, optarg);
|
||||
return parse_duration(&mod_config()->tls.ocsp.update_interval, opt, optarg);
|
||||
case SHRPX_OPTID_NO_OCSP:
|
||||
mod_config()->no_ocsp = util::strieq(optarg, "yes");
|
||||
mod_config()->tls.ocsp.disabled = util::strieq(optarg, "yes");
|
||||
|
||||
return 0;
|
||||
case SHRPX_OPTID_HEADER_FIELD_BUFFER:
|
||||
return parse_uint_with_unit(&mod_config()->header_field_buffer, opt,
|
||||
return parse_uint_with_unit(&mod_config()->http.header_field_buffer, opt,
|
||||
optarg);
|
||||
case SHRPX_OPTID_MAX_HEADER_FIELDS:
|
||||
return parse_uint(&mod_config()->max_header_fields, opt, optarg);
|
||||
return parse_uint(&mod_config()->http.max_header_fields, opt, optarg);
|
||||
case SHRPX_OPTID_INCLUDE: {
|
||||
if (included_set.count(optarg)) {
|
||||
LOG(ERROR) << opt << ": " << optarg << " has already been included";
|
||||
@ -1980,19 +1999,19 @@ int parse_config(const char *opt, const char *optarg,
|
||||
}
|
||||
case SHRPX_OPTID_TLS_TICKET_KEY_CIPHER:
|
||||
if (util::strieq(optarg, "aes-128-cbc")) {
|
||||
mod_config()->tls_ticket_key_cipher = EVP_aes_128_cbc();
|
||||
mod_config()->tls.ticket.cipher = EVP_aes_128_cbc();
|
||||
} else if (util::strieq(optarg, "aes-256-cbc")) {
|
||||
mod_config()->tls_ticket_key_cipher = EVP_aes_256_cbc();
|
||||
mod_config()->tls.ticket.cipher = EVP_aes_256_cbc();
|
||||
} else {
|
||||
LOG(ERROR) << opt
|
||||
<< ": unsupported cipher for ticket encryption: " << optarg;
|
||||
return -1;
|
||||
}
|
||||
mod_config()->tls_ticket_key_cipher_given = true;
|
||||
mod_config()->tls.ticket.cipher_given = true;
|
||||
|
||||
return 0;
|
||||
case SHRPX_OPTID_HOST_REWRITE:
|
||||
mod_config()->no_host_rewrite = !util::strieq(optarg, "yes");
|
||||
mod_config()->http.no_host_rewrite = !util::strieq(optarg, "yes");
|
||||
|
||||
return 0;
|
||||
case SHRPX_OPTID_TLS_SESSION_CACHE_MEMCACHED: {
|
||||
@ -2001,8 +2020,9 @@ int parse_config(const char *opt, const char *optarg,
|
||||
return -1;
|
||||
}
|
||||
|
||||
mod_config()->session_cache_memcached_host = strcopy(host);
|
||||
mod_config()->session_cache_memcached_port = port;
|
||||
auto &memcachedconf = mod_config()->tls.session_cache.memcached;
|
||||
memcachedconf.host = strcopy(host);
|
||||
memcachedconf.port = port;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -2012,13 +2032,14 @@ int parse_config(const char *opt, const char *optarg,
|
||||
return -1;
|
||||
}
|
||||
|
||||
mod_config()->tls_ticket_key_memcached_host = strcopy(host);
|
||||
mod_config()->tls_ticket_key_memcached_port = port;
|
||||
auto &memcachedconf = mod_config()->tls.ticket.memcached;
|
||||
memcachedconf.host = strcopy(host);
|
||||
memcachedconf.port = port;
|
||||
|
||||
return 0;
|
||||
}
|
||||
case SHRPX_OPTID_TLS_TICKET_KEY_MEMCACHED_INTERVAL:
|
||||
return parse_duration(&mod_config()->tls_ticket_key_memcached_interval, opt,
|
||||
return parse_duration(&mod_config()->tls.ticket.memcached.interval, opt,
|
||||
optarg);
|
||||
case SHRPX_OPTID_TLS_TICKET_KEY_MEMCACHED_MAX_RETRY: {
|
||||
int n;
|
||||
@ -2031,11 +2052,11 @@ int parse_config(const char *opt, const char *optarg,
|
||||
return -1;
|
||||
}
|
||||
|
||||
mod_config()->tls_ticket_key_memcached_max_retry = n;
|
||||
mod_config()->tls.ticket.memcached.max_retry = n;
|
||||
return 0;
|
||||
}
|
||||
case SHRPX_OPTID_TLS_TICKET_KEY_MEMCACHED_MAX_FAIL:
|
||||
return parse_uint(&mod_config()->tls_ticket_key_memcached_max_fail, opt,
|
||||
return parse_uint(&mod_config()->tls.ticket.memcached.max_fail, opt,
|
||||
optarg);
|
||||
case SHRPX_OPTID_TLS_DYN_REC_WARMUP_THRESHOLD: {
|
||||
size_t n;
|
||||
@ -2043,13 +2064,13 @@ int parse_config(const char *opt, const char *optarg,
|
||||
return -1;
|
||||
}
|
||||
|
||||
mod_config()->tls_dyn_rec_warmup_threshold = n;
|
||||
mod_config()->tls.dyn_rec.warmup_threshold = n;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
case SHRPX_OPTID_TLS_DYN_REC_IDLE_TIMEOUT:
|
||||
return parse_duration(&mod_config()->tls_dyn_rec_idle_timeout, opt, optarg);
|
||||
return parse_duration(&mod_config()->tls.dyn_rec.idle_timeout, opt, optarg);
|
||||
|
||||
case SHRPX_OPTID_MRUBY_FILE:
|
||||
#ifdef HAVE_MRUBY
|
||||
@ -2060,26 +2081,28 @@ int parse_config(const char *opt, const char *optarg,
|
||||
#endif // !HAVE_MRUBY
|
||||
return 0;
|
||||
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;
|
||||
case SHRPX_OPTID_ADD_FORWARDED:
|
||||
mod_config()->forwarded_params = FORWARDED_NONE;
|
||||
case SHRPX_OPTID_ADD_FORWARDED: {
|
||||
auto &fwdconf = mod_config()->http.forwarded;
|
||||
fwdconf.params = FORWARDED_NONE;
|
||||
for (const auto ¶m : util::parse_config_str_list(optarg)) {
|
||||
if (util::strieq(param, "by")) {
|
||||
mod_config()->forwarded_params |= FORWARDED_BY;
|
||||
fwdconf.params |= FORWARDED_BY;
|
||||
continue;
|
||||
}
|
||||
if (util::strieq(param, "for")) {
|
||||
mod_config()->forwarded_params |= FORWARDED_FOR;
|
||||
fwdconf.params |= FORWARDED_FOR;
|
||||
continue;
|
||||
}
|
||||
if (util::strieq(param, "host")) {
|
||||
mod_config()->forwarded_params |= FORWARDED_HOST;
|
||||
fwdconf.params |= FORWARDED_HOST;
|
||||
continue;
|
||||
}
|
||||
if (util::strieq(param, "proto")) {
|
||||
mod_config()->forwarded_params |= FORWARDED_PROTO;
|
||||
fwdconf.params |= FORWARDED_PROTO;
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -2089,8 +2112,9 @@ int parse_config(const char *opt, const char *optarg,
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
case SHRPX_OPTID_STRIP_INCOMING_FORWARDED:
|
||||
mod_config()->strip_incoming_forwarded = util::strieq(optarg, "yes");
|
||||
mod_config()->http.forwarded.strip_incoming = util::strieq(optarg, "yes");
|
||||
|
||||
return 0;
|
||||
case SHRPX_OPTID_FORWARDED_BY:
|
||||
@ -2103,23 +2127,23 @@ int parse_config(const char *opt, const char *optarg,
|
||||
return -1;
|
||||
}
|
||||
|
||||
auto &fwdconf = mod_config()->http.forwarded;
|
||||
|
||||
switch (optid) {
|
||||
case SHRPX_OPTID_FORWARDED_BY:
|
||||
mod_config()->forwarded_by_node_type =
|
||||
static_cast<shrpx_forwarded_node_type>(type);
|
||||
fwdconf.by_node_type = static_cast<shrpx_forwarded_node_type>(type);
|
||||
if (optarg[0] == '_') {
|
||||
mod_config()->forwarded_by_obfuscated = optarg;
|
||||
fwdconf.by_obfuscated = optarg;
|
||||
} else {
|
||||
mod_config()->forwarded_by_obfuscated = "";
|
||||
fwdconf.by_obfuscated = "";
|
||||
}
|
||||
break;
|
||||
case SHRPX_OPTID_FORWARDED_FOR:
|
||||
mod_config()->forwarded_for_node_type =
|
||||
static_cast<shrpx_forwarded_node_type>(type);
|
||||
fwdconf.for_node_type = static_cast<shrpx_forwarded_node_type>(type);
|
||||
if (optarg[0] == '_') {
|
||||
mod_config()->forwarded_for_obfuscated = optarg;
|
||||
fwdconf.for_obfuscated = optarg;
|
||||
} else {
|
||||
mod_config()->forwarded_for_obfuscated = "";
|
||||
fwdconf.for_obfuscated = "";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -289,178 +289,263 @@ struct HttpProxy {
|
||||
std::string host;
|
||||
// userinfo in http proxy URI, not percent-encoded form
|
||||
std::string userinfo;
|
||||
// port in http proxy URI
|
||||
uint16_t port;
|
||||
};
|
||||
|
||||
struct Config {
|
||||
struct TLSConfig {
|
||||
// RFC 5077 Session ticket related configurations
|
||||
struct {
|
||||
struct {
|
||||
Address addr;
|
||||
uint16_t port;
|
||||
std::unique_ptr<char[]> host;
|
||||
ev_tstamp interval;
|
||||
// Maximum number of retries when getting TLS ticket key from
|
||||
// mamcached, due to network error.
|
||||
size_t max_retry;
|
||||
// Maximum number of consecutive error from memcached, when this
|
||||
// limit reached, TLS ticket is disabled.
|
||||
size_t max_fail;
|
||||
} memcached;
|
||||
std::vector<std::string> files;
|
||||
const EVP_CIPHER *cipher;
|
||||
// true if --tls-ticket-key-cipher is used
|
||||
bool cipher_given;
|
||||
} ticket;
|
||||
|
||||
// Session cache related configurations
|
||||
struct {
|
||||
struct {
|
||||
Address addr;
|
||||
uint16_t port;
|
||||
std::unique_ptr<char[]> host;
|
||||
} memcached;
|
||||
} session_cache;
|
||||
|
||||
// Dynamic record sizing configurations
|
||||
struct {
|
||||
size_t warmup_threshold;
|
||||
ev_tstamp idle_timeout;
|
||||
} dyn_rec;
|
||||
|
||||
// OCSP realted configurations
|
||||
struct {
|
||||
ev_tstamp update_interval;
|
||||
std::unique_ptr<char[]> fetch_ocsp_response_file;
|
||||
bool disabled;
|
||||
} ocsp;
|
||||
|
||||
// Client verification configurations
|
||||
struct {
|
||||
// Path to file containing CA certificate solely used for client
|
||||
// certificate validation
|
||||
std::unique_ptr<char[]> cacert;
|
||||
bool enabled;
|
||||
} client_verify;
|
||||
|
||||
// Client private key and certificate used in backend connections.
|
||||
struct {
|
||||
std::unique_ptr<char[]> private_key_file;
|
||||
std::unique_ptr<char[]> cert_file;
|
||||
} client;
|
||||
|
||||
// The list of (private key file, certificate file) pair
|
||||
std::vector<std::pair<std::string, std::string>> subcerts;
|
||||
std::vector<AltSvc> altsvcs;
|
||||
std::vector<std::pair<std::string, std::string>> add_request_headers;
|
||||
std::vector<std::pair<std::string, std::string>> add_response_headers;
|
||||
std::vector<unsigned char> alpn_prefs;
|
||||
std::vector<LogFragment> accesslog_format;
|
||||
std::vector<DownstreamAddrGroup> downstream_addr_groups;
|
||||
std::vector<std::string> tls_ticket_key_files;
|
||||
// list of supported NPN/ALPN protocol strings in the order of
|
||||
// preference.
|
||||
std::vector<std::string> npn_list;
|
||||
// list of supported SSL/TLS protocol strings.
|
||||
std::vector<std::string> tls_proto_list;
|
||||
Address session_cache_memcached_addr;
|
||||
Address tls_ticket_key_memcached_addr;
|
||||
Router router;
|
||||
HttpProxy downstream_http_proxy;
|
||||
// obfuscated value used in "by" parameter of Forwarded header
|
||||
// field.
|
||||
std::string forwarded_by_obfuscated;
|
||||
// obfuscated value used in "for" parameter of Forwarded header
|
||||
// field. This is only used when user defined static obfuscated
|
||||
// string is provided.
|
||||
std::string forwarded_for_obfuscated;
|
||||
std::string backend_tls_sni_name;
|
||||
StringRef server_name;
|
||||
std::chrono::seconds tls_session_timeout;
|
||||
ev_tstamp http2_upstream_read_timeout;
|
||||
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;
|
||||
ev_tstamp ocsp_update_interval;
|
||||
ev_tstamp tls_ticket_key_memcached_interval;
|
||||
// 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;
|
||||
// Bit mask to disable SSL/TLS protocol versions. This will be
|
||||
// passed to SSL_CTX_set_options().
|
||||
long int tls_proto_mask;
|
||||
std::string backend_sni_name;
|
||||
std::chrono::seconds session_timeout;
|
||||
std::unique_ptr<char[]> private_key_file;
|
||||
std::unique_ptr<char[]> private_key_passwd;
|
||||
std::unique_ptr<char[]> cert_file;
|
||||
std::unique_ptr<char[]> dh_param_file;
|
||||
std::unique_ptr<char[]> pid_file;
|
||||
std::unique_ptr<char[]> conf_path;
|
||||
std::unique_ptr<char[]> ciphers;
|
||||
std::unique_ptr<char[]> cacert;
|
||||
std::unique_ptr<char[]> http2_upstream_dump_request_header_file;
|
||||
std::unique_ptr<char[]> http2_upstream_dump_response_header_file;
|
||||
// Path to file containing CA certificate solely used for client
|
||||
// certificate validation
|
||||
std::unique_ptr<char[]> verify_client_cacert;
|
||||
std::unique_ptr<char[]> client_private_key_file;
|
||||
std::unique_ptr<char[]> client_cert_file;
|
||||
std::unique_ptr<char[]> accesslog_file;
|
||||
std::unique_ptr<char[]> errorlog_file;
|
||||
std::unique_ptr<char[]> fetch_ocsp_response_file;
|
||||
bool insecure;
|
||||
};
|
||||
|
||||
struct HttpConfig {
|
||||
struct {
|
||||
// obfuscated value used in "by" parameter of Forwarded header
|
||||
// field.
|
||||
std::string by_obfuscated;
|
||||
// obfuscated value used in "for" parameter of Forwarded header
|
||||
// field. This is only used when user defined static obfuscated
|
||||
// string is provided.
|
||||
std::string for_obfuscated;
|
||||
// bitwise-OR of one or more of shrpx_forwarded_param values.
|
||||
uint32_t params;
|
||||
// type of value recorded in "by" parameter of Forwarded header
|
||||
// field.
|
||||
shrpx_forwarded_node_type by_node_type;
|
||||
// type of value recorded in "for" parameter of Forwarded header
|
||||
// field.
|
||||
shrpx_forwarded_node_type for_node_type;
|
||||
bool strip_incoming;
|
||||
} forwarded;
|
||||
struct {
|
||||
bool add;
|
||||
bool strip_incoming;
|
||||
} xff;
|
||||
std::vector<AltSvc> altsvcs;
|
||||
std::vector<std::pair<std::string, std::string>> add_request_headers;
|
||||
std::vector<std::pair<std::string, std::string>> add_response_headers;
|
||||
StringRef server_name;
|
||||
size_t header_field_buffer;
|
||||
size_t max_header_fields;
|
||||
bool no_via;
|
||||
bool no_location_rewrite;
|
||||
bool no_host_rewrite;
|
||||
};
|
||||
|
||||
struct Http2Config {
|
||||
struct {
|
||||
struct {
|
||||
struct {
|
||||
std::unique_ptr<char[]> request_header_file;
|
||||
std::unique_ptr<char[]> response_header_file;
|
||||
FILE *request_header;
|
||||
FILE *response_header;
|
||||
} dump;
|
||||
bool frame_debug;
|
||||
} debug;
|
||||
nghttp2_option *option;
|
||||
nghttp2_session_callbacks *callbacks;
|
||||
size_t window_bits;
|
||||
size_t connection_window_bits;
|
||||
} upstream;
|
||||
struct {
|
||||
nghttp2_option *option;
|
||||
nghttp2_session_callbacks *callbacks;
|
||||
size_t window_bits;
|
||||
size_t connection_window_bits;
|
||||
size_t connections_per_worker;
|
||||
} downstream;
|
||||
struct {
|
||||
ev_tstamp stream_read;
|
||||
ev_tstamp stream_write;
|
||||
} timeout;
|
||||
size_t max_concurrent_streams;
|
||||
bool no_cookie_crumbling;
|
||||
bool no_server_push;
|
||||
};
|
||||
|
||||
struct LoggingConfig {
|
||||
struct {
|
||||
std::vector<LogFragment> format;
|
||||
std::unique_ptr<char[]> file;
|
||||
// Send accesslog to syslog, ignoring accesslog_file.
|
||||
bool syslog;
|
||||
} access;
|
||||
struct {
|
||||
std::unique_ptr<char[]> file;
|
||||
// Send errorlog to syslog, ignoring errorlog_file.
|
||||
bool syslog;
|
||||
} error;
|
||||
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 {
|
||||
Router router;
|
||||
HttpProxy downstream_http_proxy;
|
||||
HttpConfig http;
|
||||
Http2Config http2;
|
||||
TLSConfig tls;
|
||||
LoggingConfig logging;
|
||||
ConnectionConfig conn;
|
||||
std::unique_ptr<char[]> pid_file;
|
||||
std::unique_ptr<char[]> conf_path;
|
||||
std::unique_ptr<char[]> user;
|
||||
std::unique_ptr<char[]> session_cache_memcached_host;
|
||||
std::unique_ptr<char[]> tls_ticket_key_memcached_host;
|
||||
std::unique_ptr<char[]> mruby_file;
|
||||
FILE *http2_upstream_dump_request_header;
|
||||
FILE *http2_upstream_dump_response_header;
|
||||
nghttp2_session_callbacks *http2_upstream_callbacks;
|
||||
nghttp2_session_callbacks *http2_downstream_callbacks;
|
||||
nghttp2_option *http2_option;
|
||||
nghttp2_option *http2_client_option;
|
||||
const EVP_CIPHER *tls_ticket_key_cipher;
|
||||
char **original_argv;
|
||||
char **argv;
|
||||
char *cwd;
|
||||
size_t num_worker;
|
||||
size_t http2_max_concurrent_streams;
|
||||
size_t http2_upstream_window_bits;
|
||||
size_t http2_downstream_window_bits;
|
||||
size_t http2_upstream_connection_window_bits;
|
||||
size_t http2_downstream_connection_window_bits;
|
||||
size_t http2_downstream_connections_per_worker;
|
||||
size_t downstream_connections_per_host;
|
||||
size_t downstream_connections_per_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 worker_frontend_connections;
|
||||
size_t rlimit_nofile;
|
||||
size_t downstream_request_buffer_size;
|
||||
size_t downstream_response_buffer_size;
|
||||
size_t header_field_buffer;
|
||||
size_t max_header_fields;
|
||||
// The index of catch-all group in downstream_addr_groups.
|
||||
size_t downstream_addr_group_catch_all;
|
||||
// Maximum number of retries when getting TLS ticket key from
|
||||
// mamcached, due to network error.
|
||||
size_t tls_ticket_key_memcached_max_retry;
|
||||
// Maximum number of consecutive error from memcached, when this
|
||||
// limit reached, TLS ticket is disabled.
|
||||
size_t tls_ticket_key_memcached_max_fail;
|
||||
// Bit mask to disable SSL/TLS protocol versions. This will be
|
||||
// passed to SSL_CTX_set_options().
|
||||
long int tls_proto_mask;
|
||||
// downstream protocol; this will be determined by given options.
|
||||
shrpx_proto downstream_proto;
|
||||
// bitwise-OR of one or more of shrpx_forwarded_param values.
|
||||
uint32_t forwarded_params;
|
||||
// type of value recorded in "by" parameter of Forwarded header
|
||||
// field.
|
||||
shrpx_forwarded_node_type forwarded_by_node_type;
|
||||
// type of value recorded in "for" parameter of Forwarded header
|
||||
// field.
|
||||
shrpx_forwarded_node_type forwarded_for_node_type;
|
||||
int syslog_facility;
|
||||
int backlog;
|
||||
int argc;
|
||||
int fastopen;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
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;
|
||||
// port in http proxy URI
|
||||
uint16_t downstream_http_proxy_port;
|
||||
uint16_t session_cache_memcached_port;
|
||||
uint16_t tls_ticket_key_memcached_port;
|
||||
bool verbose;
|
||||
bool daemon;
|
||||
bool verify_client;
|
||||
bool http2_proxy;
|
||||
bool http2_bridge;
|
||||
bool client_proxy;
|
||||
bool add_x_forwarded_for;
|
||||
bool strip_incoming_x_forwarded_for;
|
||||
bool strip_incoming_forwarded;
|
||||
bool no_via;
|
||||
bool upstream_no_tls;
|
||||
bool downstream_no_tls;
|
||||
// Send accesslog to syslog, ignoring accesslog_file.
|
||||
bool accesslog_syslog;
|
||||
// Send errorlog to syslog, ignoring errorlog_file.
|
||||
bool errorlog_syslog;
|
||||
bool client;
|
||||
// true if --client or --client-proxy are enabled.
|
||||
bool client_mode;
|
||||
bool insecure;
|
||||
bool backend_ipv4;
|
||||
bool backend_ipv6;
|
||||
bool http2_no_cookie_crumbling;
|
||||
bool upstream_frame_debug;
|
||||
bool no_location_rewrite;
|
||||
bool no_host_rewrite;
|
||||
bool no_server_push;
|
||||
// true if host contains UNIX domain socket path
|
||||
bool host_unix;
|
||||
bool no_ocsp;
|
||||
// true if --tls-ticket-key-cipher is used
|
||||
bool tls_ticket_key_cipher_given;
|
||||
bool accept_proxy_protocol;
|
||||
size_t tls_dyn_rec_warmup_threshold;
|
||||
ev_tstamp tls_dyn_rec_idle_timeout;
|
||||
};
|
||||
|
||||
const Config *get_config();
|
||||
|
@ -42,15 +42,17 @@ using namespace nghttp2;
|
||||
namespace shrpx {
|
||||
Connection::Connection(struct ev_loop *loop, int fd, SSL *ssl,
|
||||
MemchunkPool *mcpool, ev_tstamp write_timeout,
|
||||
ev_tstamp read_timeout, size_t write_rate,
|
||||
size_t write_burst, size_t read_rate, size_t read_burst,
|
||||
IOCb writecb, IOCb readcb, TimerCb timeoutcb, void *data,
|
||||
ev_tstamp read_timeout,
|
||||
const RateLimitConfig &write_limit,
|
||||
const RateLimitConfig &read_limit, IOCb writecb,
|
||||
IOCb readcb, TimerCb timeoutcb, void *data,
|
||||
size_t tls_dyn_rec_warmup_threshold,
|
||||
ev_tstamp tls_dyn_rec_idle_timeout)
|
||||
: tls{DefaultMemchunks(mcpool), DefaultPeekMemchunks(mcpool)},
|
||||
wlimit(loop, &wev, write_rate, write_burst),
|
||||
rlimit(loop, &rev, read_rate, read_burst, this), writecb(writecb),
|
||||
readcb(readcb), timeoutcb(timeoutcb), loop(loop), data(data), fd(fd),
|
||||
wlimit(loop, &wev, write_limit.rate, write_limit.burst),
|
||||
rlimit(loop, &rev, read_limit.rate, read_limit.burst, this),
|
||||
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_idle_timeout(tls_dyn_rec_idle_timeout) {
|
||||
|
||||
|
@ -73,10 +73,10 @@ using TimerCb = EVCb<ev_timer>;
|
||||
|
||||
struct Connection {
|
||||
Connection(struct ev_loop *loop, int fd, SSL *ssl, MemchunkPool *mcpool,
|
||||
ev_tstamp write_timeout, ev_tstamp read_timeout, size_t write_rate,
|
||||
size_t write_burst, size_t read_rate, size_t read_burst,
|
||||
IOCb writecb, IOCb readcb, TimerCb timeoutcb, void *data,
|
||||
size_t tls_dyn_rec_warmup_threshold,
|
||||
ev_tstamp write_timeout, ev_tstamp read_timeout,
|
||||
const RateLimitConfig &write_limit,
|
||||
const RateLimitConfig &read_limit, IOCb writecb, IOCb readcb,
|
||||
TimerCb timeoutcb, void *data, size_t tls_dyn_rec_warmup_threshold,
|
||||
ev_tstamp tls_dyn_rec_idle_timeout);
|
||||
~Connection();
|
||||
|
||||
|
@ -300,13 +300,13 @@ int ConnectionHandler::handle_connection(int fd, sockaddr *addr, int addrlen) {
|
||||
}
|
||||
|
||||
if (get_config()->num_worker == 1) {
|
||||
|
||||
auto &upstreamconf = get_config()->conn.upstream;
|
||||
if (single_worker_->get_worker_stat()->num_connections >=
|
||||
get_config()->worker_frontend_connections) {
|
||||
upstreamconf.worker_connections) {
|
||||
|
||||
if (LOG_ENABLED(INFO)) {
|
||||
LLOG(INFO, this) << "Too many connections >="
|
||||
<< get_config()->worker_frontend_connections;
|
||||
<< upstreamconf.worker_connections;
|
||||
}
|
||||
|
||||
close(fd);
|
||||
@ -385,7 +385,7 @@ void ConnectionHandler::disable_acceptor() {
|
||||
}
|
||||
}
|
||||
|
||||
void ConnectionHandler::disable_acceptor_temporary(ev_tstamp t) {
|
||||
void ConnectionHandler::sleep_acceptor(ev_tstamp t) {
|
||||
if (t == 0. || ev_is_active(&disable_acceptor_timer_)) {
|
||||
return;
|
||||
}
|
||||
@ -450,7 +450,7 @@ int ConnectionHandler::start_ocsp_update(const char *cert_file) {
|
||||
assert(!ev_is_active(&ocsp_.chldev));
|
||||
|
||||
char *const argv[] = {
|
||||
const_cast<char *>(get_config()->fetch_ocsp_response_file.get()),
|
||||
const_cast<char *>(get_config()->tls.ocsp.fetch_ocsp_response_file.get()),
|
||||
const_cast<char *>(cert_file), nullptr};
|
||||
char *const envp[] = {nullptr};
|
||||
|
||||
@ -634,7 +634,7 @@ void ConnectionHandler::proceed_next_cert_ocsp() {
|
||||
if (ocsp_.next == all_ssl_ctx_.size()) {
|
||||
ocsp_.next = 0;
|
||||
// We have updated all ocsp response, and schedule next update.
|
||||
ev_timer_set(&ocsp_timer_, get_config()->ocsp_update_interval, 0.);
|
||||
ev_timer_set(&ocsp_timer_, get_config()->tls.ocsp.update_interval, 0.);
|
||||
ev_timer_start(loop_, &ocsp_timer_);
|
||||
return;
|
||||
}
|
||||
@ -673,7 +673,7 @@ ConnectionHandler::get_tls_ticket_key_memcached_dispatcher() const {
|
||||
|
||||
void ConnectionHandler::on_tls_ticket_key_network_error(ev_timer *w) {
|
||||
if (++tls_ticket_key_memcached_get_retry_count_ >=
|
||||
get_config()->tls_ticket_key_memcached_max_retry) {
|
||||
get_config()->tls.ticket.memcached.max_retry) {
|
||||
LOG(WARN) << "Memcached: tls ticket get retry all failed "
|
||||
<< tls_ticket_key_memcached_get_retry_count_ << " times.";
|
||||
|
||||
@ -697,7 +697,7 @@ void ConnectionHandler::on_tls_ticket_key_not_found(ev_timer *w) {
|
||||
tls_ticket_key_memcached_get_retry_count_ = 0;
|
||||
|
||||
if (++tls_ticket_key_memcached_fail_count_ >=
|
||||
get_config()->tls_ticket_key_memcached_max_fail) {
|
||||
get_config()->tls.ticket.memcached.max_fail) {
|
||||
LOG(WARN) << "Memcached: could not get tls ticket; disable tls ticket";
|
||||
|
||||
tls_ticket_key_memcached_fail_count_ = 0;
|
||||
@ -742,7 +742,7 @@ void ConnectionHandler::on_tls_ticket_key_get_success(
|
||||
|
||||
void ConnectionHandler::schedule_next_tls_ticket_key_memcached_get(
|
||||
ev_timer *w) {
|
||||
ev_timer_set(w, get_config()->tls_ticket_key_memcached_interval, 0.);
|
||||
ev_timer_set(w, get_config()->tls.ticket.memcached.interval, 0.);
|
||||
ev_timer_start(loop_, w);
|
||||
}
|
||||
|
||||
|
@ -98,7 +98,7 @@ public:
|
||||
AcceptHandler *get_acceptor6() const;
|
||||
void enable_acceptor();
|
||||
void disable_acceptor();
|
||||
void disable_acceptor_temporary(ev_tstamp t);
|
||||
void sleep_acceptor(ev_tstamp t);
|
||||
void accept_pending_connection();
|
||||
void graceful_shutdown_worker();
|
||||
void set_graceful_shutdown(bool f);
|
||||
|
@ -124,14 +124,16 @@ Downstream::Downstream(Upstream *upstream, MemchunkPool *mcpool,
|
||||
chunked_response_(false), expect_final_response_(false),
|
||||
request_pending_(false) {
|
||||
|
||||
auto &timeoutconf = get_config()->http2.timeout;
|
||||
|
||||
ev_timer_init(&upstream_rtimer_, &upstream_rtimeoutcb, 0.,
|
||||
get_config()->stream_read_timeout);
|
||||
timeoutconf.stream_read);
|
||||
ev_timer_init(&upstream_wtimer_, &upstream_wtimeoutcb, 0.,
|
||||
get_config()->stream_write_timeout);
|
||||
timeoutconf.stream_write);
|
||||
ev_timer_init(&downstream_rtimer_, &downstream_rtimeoutcb, 0.,
|
||||
get_config()->stream_read_timeout);
|
||||
timeoutconf.stream_read);
|
||||
ev_timer_init(&downstream_wtimer_, &downstream_wtimeoutcb, 0.,
|
||||
get_config()->stream_write_timeout);
|
||||
timeoutconf.stream_write);
|
||||
|
||||
upstream_rtimer_.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() {
|
||||
if (dconn_) {
|
||||
return request_buf_.rleft() >= get_config()->downstream_request_buffer_size;
|
||||
return request_buf_.rleft() >=
|
||||
get_config()->conn.downstream.request_buffer_size;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
@ -582,7 +585,7 @@ DefaultMemchunks *Downstream::get_response_buf() { return &response_buf_; }
|
||||
bool Downstream::response_buf_full() {
|
||||
if (dconn_) {
|
||||
return response_buf_.rleft() >=
|
||||
get_config()->downstream_response_buffer_size;
|
||||
get_config()->conn.downstream.response_buffer_size;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
@ -764,7 +767,7 @@ void disable_timer(struct ev_loop *loop, ev_timer *w) {
|
||||
} // namespace
|
||||
|
||||
void Downstream::reset_upstream_rtimer() {
|
||||
if (get_config()->stream_read_timeout == 0.) {
|
||||
if (get_config()->http2.timeout.stream_read == 0.) {
|
||||
return;
|
||||
}
|
||||
auto loop = upstream_->get_client_handler()->get_loop();
|
||||
@ -773,16 +776,18 @@ void Downstream::reset_upstream_rtimer() {
|
||||
|
||||
void Downstream::reset_upstream_wtimer() {
|
||||
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_);
|
||||
}
|
||||
if (get_config()->stream_read_timeout != 0.) {
|
||||
if (timeoutconf.stream_read != 0.) {
|
||||
try_reset_timer(loop, &upstream_rtimer_);
|
||||
}
|
||||
}
|
||||
|
||||
void Downstream::ensure_upstream_wtimer() {
|
||||
if (get_config()->stream_write_timeout == 0.) {
|
||||
if (get_config()->http2.timeout.stream_write == 0.) {
|
||||
return;
|
||||
}
|
||||
auto loop = upstream_->get_client_handler()->get_loop();
|
||||
@ -790,7 +795,7 @@ void Downstream::ensure_upstream_wtimer() {
|
||||
}
|
||||
|
||||
void Downstream::disable_upstream_rtimer() {
|
||||
if (get_config()->stream_read_timeout == 0.) {
|
||||
if (get_config()->http2.timeout.stream_read == 0.) {
|
||||
return;
|
||||
}
|
||||
auto loop = upstream_->get_client_handler()->get_loop();
|
||||
@ -798,7 +803,7 @@ void Downstream::disable_upstream_rtimer() {
|
||||
}
|
||||
|
||||
void Downstream::disable_upstream_wtimer() {
|
||||
if (get_config()->stream_write_timeout == 0.) {
|
||||
if (get_config()->http2.timeout.stream_write == 0.) {
|
||||
return;
|
||||
}
|
||||
auto loop = upstream_->get_client_handler()->get_loop();
|
||||
@ -806,7 +811,7 @@ void Downstream::disable_upstream_wtimer() {
|
||||
}
|
||||
|
||||
void Downstream::reset_downstream_rtimer() {
|
||||
if (get_config()->stream_read_timeout == 0.) {
|
||||
if (get_config()->http2.timeout.stream_read == 0.) {
|
||||
return;
|
||||
}
|
||||
auto loop = upstream_->get_client_handler()->get_loop();
|
||||
@ -815,16 +820,18 @@ void Downstream::reset_downstream_rtimer() {
|
||||
|
||||
void Downstream::reset_downstream_wtimer() {
|
||||
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_);
|
||||
}
|
||||
if (get_config()->stream_read_timeout != 0.) {
|
||||
if (timeoutconf.stream_read != 0.) {
|
||||
try_reset_timer(loop, &downstream_rtimer_);
|
||||
}
|
||||
}
|
||||
|
||||
void Downstream::ensure_downstream_wtimer() {
|
||||
if (get_config()->stream_write_timeout == 0.) {
|
||||
if (get_config()->http2.timeout.stream_write == 0.) {
|
||||
return;
|
||||
}
|
||||
auto loop = upstream_->get_client_handler()->get_loop();
|
||||
@ -832,7 +839,7 @@ void Downstream::ensure_downstream_wtimer() {
|
||||
}
|
||||
|
||||
void Downstream::disable_downstream_rtimer() {
|
||||
if (get_config()->stream_read_timeout == 0.) {
|
||||
if (get_config()->http2.timeout.stream_read == 0.) {
|
||||
return;
|
||||
}
|
||||
auto loop = upstream_->get_client_handler()->get_loop();
|
||||
@ -840,7 +847,7 @@ void Downstream::disable_downstream_rtimer() {
|
||||
}
|
||||
|
||||
void Downstream::disable_downstream_wtimer() {
|
||||
if (get_config()->stream_write_timeout == 0.) {
|
||||
if (get_config()->http2.timeout.stream_write == 0.) {
|
||||
return;
|
||||
}
|
||||
auto loop = upstream_->get_client_handler()->get_loop();
|
||||
|
@ -44,10 +44,10 @@ std::string create_error_html(unsigned int status_code) {
|
||||
res += "</title><body><h1>";
|
||||
res += status;
|
||||
res += "</h1><footer>";
|
||||
const auto &server_name = get_config()->server_name;
|
||||
const auto &server_name = get_config()->http.server_name;
|
||||
res.append(server_name.c_str(), server_name.size());
|
||||
res += " at port ";
|
||||
res += util::utos(get_config()->port);
|
||||
res += util::utos(get_config()->conn.listener.port);
|
||||
res += "</footer></body></html>";
|
||||
return res;
|
||||
}
|
||||
|
@ -256,8 +256,11 @@ int Http2DownstreamConnection::push_request_headers() {
|
||||
|
||||
const auto &req = downstream_->request();
|
||||
|
||||
auto &httpconf = get_config()->http;
|
||||
auto &http2conf = get_config()->http2;
|
||||
|
||||
auto no_host_rewrite =
|
||||
get_config()->no_host_rewrite || get_config()->http2_proxy ||
|
||||
httpconf.no_host_rewrite || get_config()->http2_proxy ||
|
||||
get_config()->client_proxy || req.method == HTTP_CONNECT;
|
||||
|
||||
// http2session_ has already in CONNECTED state, so we can get
|
||||
@ -265,7 +268,7 @@ int Http2DownstreamConnection::push_request_headers() {
|
||||
auto addr_idx = http2session_->get_addr_idx();
|
||||
auto group = http2session_->get_group();
|
||||
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
|
||||
// case, we use backend server's host nonetheless.
|
||||
@ -278,7 +281,7 @@ int Http2DownstreamConnection::push_request_headers() {
|
||||
downstream_->set_request_downstream_host(authority.str());
|
||||
|
||||
size_t num_cookies = 0;
|
||||
if (!get_config()->http2_no_cookie_crumbling) {
|
||||
if (!http2conf.no_cookie_crumbling) {
|
||||
num_cookies = downstream_->count_crumble_request_cookie();
|
||||
}
|
||||
|
||||
@ -294,7 +297,7 @@ int Http2DownstreamConnection::push_request_headers() {
|
||||
// 9. forwarded (optional)
|
||||
auto nva = std::vector<nghttp2_nv>();
|
||||
nva.reserve(req.fs.headers().size() + 9 + num_cookies +
|
||||
get_config()->add_request_headers.size());
|
||||
httpconf.add_request_headers.size());
|
||||
|
||||
nva.push_back(
|
||||
http2::make_nv_lc_nocopy(":method", http2::to_method_string(req.method)));
|
||||
@ -328,7 +331,7 @@ int Http2DownstreamConnection::push_request_headers() {
|
||||
chunked_encoding = true;
|
||||
}
|
||||
|
||||
if (!get_config()->http2_no_cookie_crumbling) {
|
||||
if (!http2conf.no_cookie_crumbling) {
|
||||
downstream_->crumble_request_cookie(nva);
|
||||
}
|
||||
|
||||
@ -337,12 +340,13 @@ int Http2DownstreamConnection::push_request_headers() {
|
||||
|
||||
std::string forwarded_value;
|
||||
|
||||
auto fwd = get_config()->strip_incoming_forwarded
|
||||
? nullptr
|
||||
: req.fs.header(http2::HD_FORWARDED);
|
||||
auto &fwdconf = httpconf.forwarded;
|
||||
|
||||
if (get_config()->forwarded_params) {
|
||||
auto params = get_config()->forwarded_params;
|
||||
auto fwd =
|
||||
fwdconf.strip_incoming ? nullptr : req.fs.header(http2::HD_FORWARDED);
|
||||
|
||||
if (fwdconf.params) {
|
||||
auto params = fwdconf.params;
|
||||
|
||||
if (get_config()->http2_proxy || get_config()->client_proxy ||
|
||||
req.method == HTTP_CONNECT) {
|
||||
@ -370,12 +374,14 @@ int Http2DownstreamConnection::push_request_headers() {
|
||||
forwarded_value = fwd->value;
|
||||
}
|
||||
|
||||
std::string xff_value;
|
||||
auto xff = get_config()->strip_incoming_x_forwarded_for
|
||||
? nullptr
|
||||
: req.fs.header(http2::HD_X_FORWARDED_FOR);
|
||||
auto &xffconf = httpconf.xff;
|
||||
|
||||
if (get_config()->add_x_forwarded_for) {
|
||||
auto xff = xffconf.strip_incoming ? nullptr
|
||||
: req.fs.header(http2::HD_X_FORWARDED_FOR);
|
||||
|
||||
std::string xff_value;
|
||||
|
||||
if (xffconf.add) {
|
||||
if (xff) {
|
||||
xff_value = (*xff).value;
|
||||
xff_value += ", ";
|
||||
@ -394,7 +400,7 @@ int Http2DownstreamConnection::push_request_headers() {
|
||||
|
||||
std::string via_value;
|
||||
auto via = req.fs.header(http2::HD_VIA);
|
||||
if (get_config()->no_via) {
|
||||
if (httpconf.no_via) {
|
||||
if (via) {
|
||||
nva.push_back(http2::make_nv_ls_nocopy("via", (*via).value));
|
||||
}
|
||||
@ -415,7 +421,7 @@ int Http2DownstreamConnection::push_request_headers() {
|
||||
nva.push_back(http2::make_nv_ll("te", "trailers"));
|
||||
}
|
||||
|
||||
for (auto &p : get_config()->add_request_headers) {
|
||||
for (auto &p : httpconf.add_request_headers) {
|
||||
nva.push_back(http2::make_nv_nocopy(p.first, p.second));
|
||||
}
|
||||
|
||||
|
@ -146,10 +146,10 @@ Http2Session::Http2Session(struct ev_loop *loop, SSL_CTX *ssl_ctx,
|
||||
ConnectBlocker *connect_blocker, Worker *worker,
|
||||
size_t group, size_t idx)
|
||||
: conn_(loop, -1, nullptr, worker->get_mcpool(),
|
||||
get_config()->downstream_write_timeout,
|
||||
get_config()->downstream_read_timeout, 0, 0, 0, 0, writecb, readcb,
|
||||
timeoutcb, this, get_config()->tls_dyn_rec_warmup_threshold,
|
||||
get_config()->tls_dyn_rec_idle_timeout),
|
||||
get_config()->conn.downstream.timeout.write,
|
||||
get_config()->conn.downstream.timeout.read, {}, {}, writecb, readcb,
|
||||
timeoutcb, this, get_config()->tls.dyn_rec.warmup_threshold,
|
||||
get_config()->tls.dyn_rec.idle_timeout),
|
||||
worker_(worker), connect_blocker_(connect_blocker), ssl_ctx_(ssl_ctx),
|
||||
session_(nullptr), data_pending_(nullptr), data_pendinglen_(0),
|
||||
addr_idx_(0), group_(group), index_(idx), state_(DISCONNECTED),
|
||||
@ -240,13 +240,13 @@ int Http2Session::disconnect(bool hard) {
|
||||
int Http2Session::check_cert() {
|
||||
return ssl::check_cert(
|
||||
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 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 (connect_blocker_->blocked()) {
|
||||
@ -331,8 +331,8 @@ int Http2Session::initiate_connection() {
|
||||
conn_.set_ssl(ssl);
|
||||
}
|
||||
|
||||
StringRef sni_name = !get_config()->backend_tls_sni_name.empty()
|
||||
? get_config()->backend_tls_sni_name
|
||||
StringRef sni_name = !get_config()->tls.backend_sni_name.empty()
|
||||
? get_config()->tls.backend_sni_name
|
||||
: downstream_addr.host;
|
||||
|
||||
if (!util::numeric_host(sni_name.c_str())) {
|
||||
@ -509,7 +509,7 @@ int Http2Session::downstream_connect_proxy() {
|
||||
SSLOG(INFO, this) << "Connected to the proxy";
|
||||
}
|
||||
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 ";
|
||||
req.append(downstream_addr.hostport.c_str(), downstream_addr.hostport.size());
|
||||
@ -1309,9 +1309,10 @@ int Http2Session::connection_made() {
|
||||
}
|
||||
}
|
||||
|
||||
rv = nghttp2_session_client_new2(&session_,
|
||||
get_config()->http2_downstream_callbacks,
|
||||
this, get_config()->http2_client_option);
|
||||
auto &http2conf = get_config()->http2;
|
||||
|
||||
rv = nghttp2_session_client_new2(&session_, http2conf.downstream.callbacks,
|
||||
this, http2conf.downstream.option);
|
||||
|
||||
if (rv != 0) {
|
||||
return -1;
|
||||
@ -1322,12 +1323,12 @@ int Http2Session::connection_made() {
|
||||
std::array<nghttp2_settings_entry, 3> entry;
|
||||
size_t nentry = 2;
|
||||
entry[0].settings_id = NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS;
|
||||
entry[0].value = get_config()->http2_max_concurrent_streams;
|
||||
entry[0].value = http2conf.max_concurrent_streams;
|
||||
|
||||
entry[1].settings_id = NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE;
|
||||
entry[1].value = (1 << get_config()->http2_downstream_window_bits) - 1;
|
||||
entry[1].value = (1 << http2conf.downstream.window_bits) - 1;
|
||||
|
||||
if (get_config()->no_server_push || get_config()->http2_proxy ||
|
||||
if (http2conf.no_server_push || get_config()->http2_proxy ||
|
||||
get_config()->client_proxy) {
|
||||
entry[nentry].settings_id = NGHTTP2_SETTINGS_ENABLE_PUSH;
|
||||
entry[nentry].value = 0;
|
||||
@ -1340,17 +1341,17 @@ int Http2Session::connection_made() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (get_config()->http2_downstream_connection_window_bits > 16) {
|
||||
int32_t delta =
|
||||
(1 << get_config()->http2_downstream_connection_window_bits) - 1 -
|
||||
NGHTTP2_INITIAL_CONNECTION_WINDOW_SIZE;
|
||||
auto connection_window_bits = http2conf.downstream.connection_window_bits;
|
||||
if (connection_window_bits > 16) {
|
||||
int32_t delta = (1 << connection_window_bits) - 1 -
|
||||
NGHTTP2_INITIAL_CONNECTION_WINDOW_SIZE;
|
||||
rv = nghttp2_submit_window_update(session_, NGHTTP2_FLAG_NONE, 0, delta);
|
||||
if (rv != 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if (must_terminate) {
|
||||
@ -1718,7 +1719,7 @@ int Http2Session::tls_handshake() {
|
||||
SSLOG(INFO, this) << "SSL/TLS handshake completed";
|
||||
}
|
||||
|
||||
if (!get_config()->downstream_no_tls && !get_config()->insecure &&
|
||||
if (!get_config()->conn.downstream.no_tls && !get_config()->tls.insecure &&
|
||||
check_cert() != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -154,7 +154,7 @@ int on_header_callback(nghttp2_session *session, const nghttp2_frame *frame,
|
||||
const uint8_t *name, size_t namelen,
|
||||
const uint8_t *value, size_t valuelen, uint8_t flags,
|
||||
void *user_data) {
|
||||
if (get_config()->upstream_frame_debug) {
|
||||
if (get_config()->http2.upstream.debug.frame_debug) {
|
||||
verbose_on_header_callback(session, frame, name, namelen, value, valuelen,
|
||||
flags, user_data);
|
||||
}
|
||||
@ -170,9 +170,11 @@ int on_header_callback(nghttp2_session *session, const nghttp2_frame *frame,
|
||||
|
||||
auto &req = downstream->request();
|
||||
|
||||
auto &httpconf = get_config()->http;
|
||||
|
||||
if (req.fs.buffer_size() + namelen + valuelen >
|
||||
get_config()->header_field_buffer ||
|
||||
req.fs.num_fields() >= get_config()->max_header_fields) {
|
||||
httpconf.header_field_buffer ||
|
||||
req.fs.num_fields() >= httpconf.max_header_fields) {
|
||||
if (downstream->get_response_state() == Downstream::MSG_COMPLETE) {
|
||||
return 0;
|
||||
}
|
||||
@ -263,8 +265,10 @@ int Http2Upstream::on_request_headers(Downstream *downstream,
|
||||
<< downstream->get_stream_id() << "\n" << ss.str();
|
||||
}
|
||||
|
||||
if (get_config()->http2_upstream_dump_request_header) {
|
||||
http2::dump_nv(get_config()->http2_upstream_dump_request_header, nva);
|
||||
auto &dump = get_config()->http2.upstream.debug.dump;
|
||||
|
||||
if (dump.request_header) {
|
||||
http2::dump_nv(dump.request_header, nva);
|
||||
}
|
||||
|
||||
auto content_length = req.fs.header(http2::HD_CONTENT_LENGTH);
|
||||
@ -398,7 +402,7 @@ void Http2Upstream::initiate_downstream(Downstream *downstream) {
|
||||
namespace {
|
||||
int on_frame_recv_callback(nghttp2_session *session, const nghttp2_frame *frame,
|
||||
void *user_data) {
|
||||
if (get_config()->upstream_frame_debug) {
|
||||
if (get_config()->http2.upstream.debug.frame_debug) {
|
||||
verbose_on_frame_recv_callback(session, frame, user_data);
|
||||
}
|
||||
auto upstream = static_cast<Http2Upstream *>(user_data);
|
||||
@ -500,7 +504,7 @@ int on_data_chunk_recv_callback(nghttp2_session *session, uint8_t flags,
|
||||
namespace {
|
||||
int on_frame_send_callback(nghttp2_session *session, const nghttp2_frame *frame,
|
||||
void *user_data) {
|
||||
if (get_config()->upstream_frame_debug) {
|
||||
if (get_config()->http2.upstream.debug.frame_debug) {
|
||||
verbose_on_frame_send_callback(session, frame, user_data);
|
||||
}
|
||||
auto upstream = static_cast<Http2Upstream *>(user_data);
|
||||
@ -848,9 +852,9 @@ nghttp2_session_callbacks *create_http2_upstream_callbacks() {
|
||||
Http2Upstream::Http2Upstream(ClientHandler *handler)
|
||||
: downstream_queue_(
|
||||
get_config()->http2_proxy
|
||||
? get_config()->downstream_connections_per_host
|
||||
: get_config()->downstream_proto == PROTO_HTTP
|
||||
? get_config()->downstream_connections_per_frontend
|
||||
? get_config()->conn.downstream.connections_per_host
|
||||
: get_config()->conn.downstream.proto == PROTO_HTTP
|
||||
? get_config()->conn.downstream.connections_per_frontend
|
||||
: 0,
|
||||
!get_config()->http2_proxy),
|
||||
pending_response_buf_(handler->get_worker()->get_mcpool()),
|
||||
@ -860,9 +864,10 @@ Http2Upstream::Http2Upstream(ClientHandler *handler)
|
||||
|
||||
int rv;
|
||||
|
||||
rv = nghttp2_session_server_new2(&session_,
|
||||
get_config()->http2_upstream_callbacks, this,
|
||||
get_config()->http2_option);
|
||||
auto &http2conf = get_config()->http2;
|
||||
|
||||
rv = nghttp2_session_server_new2(&session_, http2conf.upstream.callbacks,
|
||||
this, http2conf.upstream.option);
|
||||
|
||||
assert(rv == 0);
|
||||
|
||||
@ -871,10 +876,10 @@ Http2Upstream::Http2Upstream(ClientHandler *handler)
|
||||
// TODO Maybe call from outside?
|
||||
std::array<nghttp2_settings_entry, 2> entry;
|
||||
entry[0].settings_id = NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS;
|
||||
entry[0].value = get_config()->http2_max_concurrent_streams;
|
||||
entry[0].value = http2conf.max_concurrent_streams;
|
||||
|
||||
entry[1].settings_id = NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE;
|
||||
entry[1].value = (1 << get_config()->http2_upstream_window_bits) - 1;
|
||||
entry[1].value = (1 << http2conf.upstream.window_bits) - 1;
|
||||
|
||||
rv = nghttp2_submit_settings(session_, NGHTTP2_FLAG_NONE, entry.data(),
|
||||
entry.size());
|
||||
@ -883,9 +888,9 @@ Http2Upstream::Http2Upstream(ClientHandler *handler)
|
||||
<< nghttp2_strerror(rv);
|
||||
}
|
||||
|
||||
if (get_config()->http2_upstream_connection_window_bits > 16) {
|
||||
int32_t delta = (1 << get_config()->http2_upstream_connection_window_bits) -
|
||||
1 - NGHTTP2_INITIAL_CONNECTION_WINDOW_SIZE;
|
||||
if (http2conf.upstream.connection_window_bits > 16) {
|
||||
int32_t delta = (1 << http2conf.upstream.connection_window_bits) - 1 -
|
||||
NGHTTP2_INITIAL_CONNECTION_WINDOW_SIZE;
|
||||
rv = nghttp2_submit_window_update(session_, NGHTTP2_FLAG_NONE, 0, delta);
|
||||
|
||||
if (rv != 0) {
|
||||
@ -909,7 +914,7 @@ Http2Upstream::Http2Upstream(ClientHandler *handler)
|
||||
ev_prepare_start(handler_->get_loop(), &prep_);
|
||||
|
||||
handler_->reset_upstream_read_timeout(
|
||||
get_config()->http2_upstream_read_timeout);
|
||||
get_config()->conn.upstream.timeout.http2_read);
|
||||
|
||||
handler_->signal_write();
|
||||
}
|
||||
@ -1337,7 +1342,7 @@ int Http2Upstream::send_reply(Downstream *downstream, const uint8_t *body,
|
||||
|
||||
if (!resp.fs.header(http2::HD_SERVER)) {
|
||||
nva.push_back(
|
||||
http2::make_nv_ls_nocopy("server", get_config()->server_name));
|
||||
http2::make_nv_ls_nocopy("server", get_config()->http.server_name));
|
||||
}
|
||||
|
||||
rv = nghttp2_submit_response(session_, downstream->get_stream_id(),
|
||||
@ -1386,7 +1391,7 @@ int Http2Upstream::error_reply(Downstream *downstream,
|
||||
: http2::make_nv_ls(":status",
|
||||
(status_code_str = util::utos(status_code))),
|
||||
http2::make_nv_ll("content-type", "text/html; charset=UTF-8"),
|
||||
http2::make_nv_ls_nocopy("server", get_config()->server_name),
|
||||
http2::make_nv_ls_nocopy("server", get_config()->http.server_name),
|
||||
http2::make_nv_ls("content-length", content_length),
|
||||
http2::make_nv_ls("date", lgconf->time_http_str));
|
||||
|
||||
@ -1442,8 +1447,10 @@ int Http2Upstream::on_downstream_header_complete(Downstream *downstream) {
|
||||
}
|
||||
}
|
||||
|
||||
auto &httpconf = get_config()->http;
|
||||
|
||||
if (!get_config()->http2_proxy && !get_config()->client_proxy &&
|
||||
!get_config()->no_location_rewrite) {
|
||||
!httpconf.no_location_rewrite) {
|
||||
downstream->rewrite_location_response_header(req.scheme);
|
||||
}
|
||||
|
||||
@ -1470,7 +1477,7 @@ int Http2Upstream::on_downstream_header_complete(Downstream *downstream) {
|
||||
// 4 means :status and possible server, via and x-http2-push header
|
||||
// field.
|
||||
nva.reserve(resp.fs.headers().size() + 4 +
|
||||
get_config()->add_response_headers.size());
|
||||
httpconf.add_response_headers.size());
|
||||
std::string via_value;
|
||||
std::string response_status;
|
||||
|
||||
@ -1506,8 +1513,7 @@ int Http2Upstream::on_downstream_header_complete(Downstream *downstream) {
|
||||
http2::copy_headers_to_nva_nocopy(nva, resp.fs.headers());
|
||||
|
||||
if (!get_config()->http2_proxy && !get_config()->client_proxy) {
|
||||
nva.push_back(
|
||||
http2::make_nv_ls_nocopy("server", get_config()->server_name));
|
||||
nva.push_back(http2::make_nv_ls_nocopy("server", httpconf.server_name));
|
||||
} else {
|
||||
auto server = resp.fs.header(http2::HD_SERVER);
|
||||
if (server) {
|
||||
@ -1516,7 +1522,7 @@ int Http2Upstream::on_downstream_header_complete(Downstream *downstream) {
|
||||
}
|
||||
|
||||
auto via = resp.fs.header(http2::HD_VIA);
|
||||
if (get_config()->no_via) {
|
||||
if (httpconf.no_via) {
|
||||
if (via) {
|
||||
nva.push_back(http2::make_nv_ls_nocopy("via", (*via).value));
|
||||
}
|
||||
@ -1530,7 +1536,7 @@ int Http2Upstream::on_downstream_header_complete(Downstream *downstream) {
|
||||
nva.push_back(http2::make_nv_ls("via", via_value));
|
||||
}
|
||||
|
||||
for (auto &p : get_config()->add_response_headers) {
|
||||
for (auto &p : httpconf.add_response_headers) {
|
||||
nva.push_back(http2::make_nv_nocopy(p.first, p.second));
|
||||
}
|
||||
|
||||
@ -1544,9 +1550,11 @@ int Http2Upstream::on_downstream_header_complete(Downstream *downstream) {
|
||||
log_response_headers(downstream, nva);
|
||||
}
|
||||
|
||||
if (get_config()->http2_upstream_dump_response_header) {
|
||||
http2::dump_nv(get_config()->http2_upstream_dump_response_header,
|
||||
nva.data(), nva.size());
|
||||
auto &http2conf = get_config()->http2;
|
||||
|
||||
if (http2conf.upstream.debug.dump.response_header) {
|
||||
http2::dump_nv(http2conf.upstream.debug.dump.response_header, nva.data(),
|
||||
nva.size());
|
||||
}
|
||||
|
||||
nghttp2_data_provider data_prd;
|
||||
@ -1574,7 +1582,7 @@ int Http2Upstream::on_downstream_header_complete(Downstream *downstream) {
|
||||
// * We requires GET or POST for associated resource. Probably we
|
||||
// don't want to push for HEAD request. Not sure other methods
|
||||
// are also eligible for push.
|
||||
if (!get_config()->no_server_push &&
|
||||
if (!http2conf.no_server_push &&
|
||||
nghttp2_session_get_remote_settings(session_,
|
||||
NGHTTP2_SETTINGS_ENABLE_PUSH) == 1 &&
|
||||
!get_config()->http2_proxy && !get_config()->client_proxy &&
|
||||
@ -1875,7 +1883,7 @@ int Http2Upstream::submit_push_promise(const std::string &scheme,
|
||||
}
|
||||
|
||||
bool Http2Upstream::push_enabled() const {
|
||||
return !(get_config()->no_server_push ||
|
||||
return !(get_config()->http2.no_server_push ||
|
||||
nghttp2_session_get_remote_settings(
|
||||
session_, NGHTTP2_SETTINGS_ENABLE_PUSH) == 0 ||
|
||||
get_config()->http2_proxy || get_config()->client_proxy);
|
||||
|
@ -113,10 +113,11 @@ void connectcb(struct ev_loop *loop, ev_io *w, int revents) {
|
||||
HttpDownstreamConnection::HttpDownstreamConnection(
|
||||
DownstreamConnectionPool *dconn_pool, size_t group, struct ev_loop *loop)
|
||||
: DownstreamConnection(dconn_pool),
|
||||
conn_(loop, -1, nullptr, nullptr, get_config()->downstream_write_timeout,
|
||||
get_config()->downstream_read_timeout, 0, 0, 0, 0, connectcb,
|
||||
readcb, timeoutcb, this, get_config()->tls_dyn_rec_warmup_threshold,
|
||||
get_config()->tls_dyn_rec_idle_timeout),
|
||||
conn_(loop, -1, nullptr, nullptr,
|
||||
get_config()->conn.downstream.timeout.write,
|
||||
get_config()->conn.downstream.timeout.read, {}, {}, connectcb,
|
||||
readcb, timeoutcb, this, get_config()->tls.dyn_rec.warmup_threshold,
|
||||
get_config()->tls.dyn_rec.idle_timeout),
|
||||
ioctrl_(&conn_.rlimit), response_htp_{0}, group_(group), addr_idx_(0),
|
||||
connected_(false) {}
|
||||
|
||||
@ -127,6 +128,8 @@ int HttpDownstreamConnection::attach_downstream(Downstream *downstream) {
|
||||
DCLOG(INFO, this) << "Attaching to DOWNSTREAM:" << downstream;
|
||||
}
|
||||
|
||||
auto &downstreamconf = get_config()->conn.downstream;
|
||||
|
||||
if (conn_.fd == -1) {
|
||||
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 &next_downstream = worker->get_dgrp(group_)->next;
|
||||
auto end = next_downstream;
|
||||
auto &addrs = get_config()->downstream_addr_groups[group_].addrs;
|
||||
auto &addrs = downstreamconf.addr_groups[group_].addrs;
|
||||
for (;;) {
|
||||
auto &addr = addrs[next_downstream];
|
||||
auto i = next_downstream;
|
||||
@ -196,7 +199,7 @@ int HttpDownstreamConnection::attach_downstream(Downstream *downstream) {
|
||||
ev_timer_again(conn_.loop, &conn_.wt);
|
||||
} else {
|
||||
// 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_timer_again(conn_.loop, &conn_.rt);
|
||||
ev_set_cb(&conn_.rev, readcb);
|
||||
@ -211,16 +214,20 @@ int HttpDownstreamConnection::attach_downstream(Downstream *downstream) {
|
||||
}
|
||||
|
||||
int HttpDownstreamConnection::push_request_headers() {
|
||||
const auto &downstream_hostport =
|
||||
get_config()->downstream_addr_groups[group_].addrs[addr_idx_].hostport;
|
||||
const auto &downstream_hostport = get_config()
|
||||
->conn.downstream.addr_groups[group_]
|
||||
.addrs[addr_idx_]
|
||||
.hostport;
|
||||
const auto &req = downstream_->request();
|
||||
|
||||
auto connect_method = req.method == HTTP_CONNECT;
|
||||
|
||||
auto &httpconf = get_config()->http;
|
||||
|
||||
// For HTTP/1.0 request, there is no authority in request. In that
|
||||
// case, we use backend server's host nonetheless.
|
||||
auto authority = StringRef(downstream_hostport);
|
||||
auto no_host_rewrite = get_config()->no_host_rewrite ||
|
||||
auto no_host_rewrite = httpconf.no_host_rewrite ||
|
||||
get_config()->http2_proxy ||
|
||||
get_config()->client_proxy || connect_method;
|
||||
|
||||
@ -296,11 +303,13 @@ int HttpDownstreamConnection::push_request_headers() {
|
||||
auto upstream = downstream_->get_upstream();
|
||||
auto handler = upstream->get_client_handler();
|
||||
|
||||
auto fwd = get_config()->strip_incoming_forwarded
|
||||
? nullptr
|
||||
: req.fs.header(http2::HD_FORWARDED);
|
||||
if (get_config()->forwarded_params) {
|
||||
auto params = get_config()->forwarded_params;
|
||||
auto &fwdconf = httpconf.forwarded;
|
||||
|
||||
auto fwd =
|
||||
fwdconf.strip_incoming ? nullptr : req.fs.header(http2::HD_FORWARDED);
|
||||
|
||||
if (fwdconf.params) {
|
||||
auto params = fwdconf.params;
|
||||
|
||||
if (get_config()->http2_proxy || get_config()->client_proxy ||
|
||||
connect_method) {
|
||||
@ -328,11 +337,12 @@ int HttpDownstreamConnection::push_request_headers() {
|
||||
buf->append("\r\n");
|
||||
}
|
||||
|
||||
auto xff = get_config()->strip_incoming_x_forwarded_for
|
||||
? nullptr
|
||||
: req.fs.header(http2::HD_X_FORWARDED_FOR);
|
||||
auto &xffconf = httpconf.xff;
|
||||
|
||||
if (get_config()->add_x_forwarded_for) {
|
||||
auto xff = xffconf.strip_incoming ? nullptr
|
||||
: req.fs.header(http2::HD_X_FORWARDED_FOR);
|
||||
|
||||
if (xffconf.add) {
|
||||
buf->append("X-Forwarded-For: ");
|
||||
if (xff) {
|
||||
buf->append((*xff).value);
|
||||
@ -353,7 +363,7 @@ int HttpDownstreamConnection::push_request_headers() {
|
||||
buf->append("\r\n");
|
||||
}
|
||||
auto via = req.fs.header(http2::HD_VIA);
|
||||
if (get_config()->no_via) {
|
||||
if (httpconf.no_via) {
|
||||
if (via) {
|
||||
buf->append("Via: ");
|
||||
buf->append((*via).value);
|
||||
@ -369,7 +379,7 @@ int HttpDownstreamConnection::push_request_headers() {
|
||||
buf->append("\r\n");
|
||||
}
|
||||
|
||||
for (auto &p : get_config()->add_request_headers) {
|
||||
for (auto &p : httpconf.add_request_headers) {
|
||||
buf->append(p.first);
|
||||
buf->append(": ");
|
||||
buf->append(p.second);
|
||||
@ -474,7 +484,7 @@ void HttpDownstreamConnection::detach_downstream(Downstream *downstream) {
|
||||
ev_set_cb(&conn_.rev, idle_readcb);
|
||||
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_timer_again(conn_.loop, &conn_.rt);
|
||||
|
||||
@ -489,7 +499,7 @@ void HttpDownstreamConnection::pause_read(IOCtrlReason reason) {
|
||||
int HttpDownstreamConnection::resume_read(IOCtrlReason reason,
|
||||
size_t consumed) {
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -88,7 +88,7 @@ int htp_uricb(http_parser *htp, const char *data, size_t len) {
|
||||
// We happen to have the same value for method token.
|
||||
req.method = htp->method;
|
||||
|
||||
if (req.fs.buffer_size() + len > get_config()->header_field_buffer) {
|
||||
if (req.fs.buffer_size() + len > get_config()->http.header_field_buffer) {
|
||||
if (LOG_ENABLED(INFO)) {
|
||||
ULOG(INFO, upstream) << "Too large URI size="
|
||||
<< req.fs.buffer_size() + len;
|
||||
@ -115,8 +115,9 @@ int htp_hdr_keycb(http_parser *htp, const char *data, size_t len) {
|
||||
auto upstream = static_cast<HttpsUpstream *>(htp->data);
|
||||
auto downstream = upstream->get_downstream();
|
||||
auto &req = downstream->request();
|
||||
auto &httpconf = get_config()->http;
|
||||
|
||||
if (req.fs.buffer_size() + len > get_config()->header_field_buffer) {
|
||||
if (req.fs.buffer_size() + len > httpconf.header_field_buffer) {
|
||||
if (LOG_ENABLED(INFO)) {
|
||||
ULOG(INFO, upstream) << "Too large header block size="
|
||||
<< req.fs.buffer_size() + len;
|
||||
@ -130,7 +131,7 @@ int htp_hdr_keycb(http_parser *htp, const char *data, size_t len) {
|
||||
if (req.fs.header_key_prev()) {
|
||||
req.fs.append_last_header_key(data, len);
|
||||
} else {
|
||||
if (req.fs.num_fields() >= get_config()->max_header_fields) {
|
||||
if (req.fs.num_fields() >= httpconf.max_header_fields) {
|
||||
if (LOG_ENABLED(INFO)) {
|
||||
ULOG(INFO, upstream)
|
||||
<< "Too many header field num=" << req.fs.num_fields() + 1;
|
||||
@ -146,7 +147,7 @@ int htp_hdr_keycb(http_parser *htp, const char *data, size_t len) {
|
||||
if (req.fs.trailer_key_prev()) {
|
||||
req.fs.append_last_trailer_key(data, len);
|
||||
} else {
|
||||
if (req.fs.num_fields() >= get_config()->max_header_fields) {
|
||||
if (req.fs.num_fields() >= httpconf.max_header_fields) {
|
||||
if (LOG_ENABLED(INFO)) {
|
||||
ULOG(INFO, upstream)
|
||||
<< "Too many header field num=" << req.fs.num_fields() + 1;
|
||||
@ -166,7 +167,7 @@ int htp_hdr_valcb(http_parser *htp, const char *data, size_t len) {
|
||||
auto downstream = upstream->get_downstream();
|
||||
auto &req = downstream->request();
|
||||
|
||||
if (req.fs.buffer_size() + len > get_config()->header_field_buffer) {
|
||||
if (req.fs.buffer_size() + len > get_config()->http.header_field_buffer) {
|
||||
if (LOG_ENABLED(INFO)) {
|
||||
ULOG(INFO, upstream) << "Too large header block size="
|
||||
<< req.fs.buffer_size() + len;
|
||||
@ -802,7 +803,7 @@ int HttpsUpstream::send_reply(Downstream *downstream, const uint8_t *body,
|
||||
|
||||
if (!resp.fs.header(http2::HD_SERVER)) {
|
||||
output->append("Server: ");
|
||||
output->append(get_config()->server_name);
|
||||
output->append(get_config()->http.server_name);
|
||||
output->append("\r\n");
|
||||
}
|
||||
|
||||
@ -839,8 +840,7 @@ void HttpsUpstream::error_reply(unsigned int status_code) {
|
||||
auto status_str = http2::get_status_string(status_code);
|
||||
output->append(status_str);
|
||||
output->append("\r\nServer: ");
|
||||
const auto &server_name = get_config()->server_name;
|
||||
output->append(server_name);
|
||||
output->append(get_config()->http.server_name);
|
||||
output->append("\r\nContent-Length: ");
|
||||
auto cl = util::utos(html.size());
|
||||
output->append(cl);
|
||||
@ -927,8 +927,10 @@ int HttpsUpstream::on_downstream_header_complete(Downstream *downstream) {
|
||||
buf->append(http2::get_status_string(resp.http_status));
|
||||
buf->append("\r\n");
|
||||
|
||||
auto &httpconf = get_config()->http;
|
||||
|
||||
if (!get_config()->http2_proxy && !get_config()->client_proxy &&
|
||||
!get_config()->no_location_rewrite) {
|
||||
!httpconf.no_location_rewrite) {
|
||||
downstream->rewrite_location_response_header(
|
||||
get_client_handler()->get_upstream_scheme());
|
||||
}
|
||||
@ -984,10 +986,10 @@ int HttpsUpstream::on_downstream_header_complete(Downstream *downstream) {
|
||||
|
||||
if (!resp.fs.header(http2::HD_ALT_SVC)) {
|
||||
// We won't change or alter alt-svc from backend for now
|
||||
if (!get_config()->altsvcs.empty()) {
|
||||
if (!httpconf.altsvcs.empty()) {
|
||||
buf->append("Alt-Svc: ");
|
||||
|
||||
auto &altsvcs = get_config()->altsvcs;
|
||||
auto &altsvcs = httpconf.altsvcs;
|
||||
write_altsvc(buf, altsvcs[0]);
|
||||
for (size_t i = 1; i < altsvcs.size(); ++i) {
|
||||
buf->append(", ");
|
||||
@ -999,7 +1001,7 @@ int HttpsUpstream::on_downstream_header_complete(Downstream *downstream) {
|
||||
|
||||
if (!get_config()->http2_proxy && !get_config()->client_proxy) {
|
||||
buf->append("Server: ");
|
||||
buf->append(get_config()->server_name);
|
||||
buf->append(httpconf.server_name);
|
||||
buf->append("\r\n");
|
||||
} else {
|
||||
auto server = resp.fs.header(http2::HD_SERVER);
|
||||
@ -1011,7 +1013,7 @@ int HttpsUpstream::on_downstream_header_complete(Downstream *downstream) {
|
||||
}
|
||||
|
||||
auto via = resp.fs.header(http2::HD_VIA);
|
||||
if (get_config()->no_via) {
|
||||
if (httpconf.no_via) {
|
||||
if (via) {
|
||||
buf->append("Via: ");
|
||||
buf->append((*via).value);
|
||||
@ -1028,7 +1030,7 @@ int HttpsUpstream::on_downstream_header_complete(Downstream *downstream) {
|
||||
buf->append("\r\n");
|
||||
}
|
||||
|
||||
for (auto &p : get_config()->add_response_headers) {
|
||||
for (auto &p : httpconf.add_response_headers) {
|
||||
buf->append(p.first);
|
||||
buf->append(": ");
|
||||
buf->append(p.second);
|
||||
|
@ -109,12 +109,14 @@ Log::~Log() {
|
||||
|
||||
auto lgconf = log_config();
|
||||
|
||||
auto &errorconf = get_config()->logging.error;
|
||||
|
||||
if (!log_enabled(severity_) ||
|
||||
(lgconf->errorlog_fd == -1 && !get_config()->errorlog_syslog)) {
|
||||
(lgconf->errorlog_fd == -1 && !errorconf.syslog)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (get_config()->errorlog_syslog) {
|
||||
if (errorconf.syslog) {
|
||||
if (severity_ == NOTICE) {
|
||||
syslog(severity_to_syslog_level(severity_), "[%s] %s",
|
||||
SEVERITY_STR[severity_], stream_.str().c_str());
|
||||
@ -219,8 +221,9 @@ std::pair<OutputIterator, size_t> copy_hex_low(const uint8_t *src,
|
||||
void upstream_accesslog(const std::vector<LogFragment> &lfv,
|
||||
const LogSpec &lgsp) {
|
||||
auto lgconf = log_config();
|
||||
auto &accessconf = get_config()->logging.access;
|
||||
|
||||
if (lgconf->accesslog_fd == -1 && !get_config()->accesslog_syslog) {
|
||||
if (lgconf->accesslog_fd == -1 && !accessconf.syslog) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -360,7 +363,7 @@ void upstream_accesslog(const std::vector<LogFragment> &lfv,
|
||||
|
||||
*p = '\0';
|
||||
|
||||
if (get_config()->accesslog_syslog) {
|
||||
if (accessconf.syslog) {
|
||||
syslog(LOG_INFO, "%s", buf);
|
||||
|
||||
return;
|
||||
@ -379,29 +382,27 @@ int reopen_log_files() {
|
||||
int new_errorlog_fd = -1;
|
||||
|
||||
auto lgconf = log_config();
|
||||
auto &accessconf = get_config()->logging.access;
|
||||
auto &errorconf = get_config()->logging.error;
|
||||
|
||||
if (!get_config()->accesslog_syslog && get_config()->accesslog_file) {
|
||||
|
||||
new_accesslog_fd = util::open_log_file(get_config()->accesslog_file.get());
|
||||
if (!accessconf.syslog && accessconf.file) {
|
||||
new_accesslog_fd = util::open_log_file(accessconf.file.get());
|
||||
|
||||
if (new_accesslog_fd == -1) {
|
||||
LOG(ERROR) << "Failed to open accesslog file "
|
||||
<< get_config()->accesslog_file.get();
|
||||
LOG(ERROR) << "Failed to open accesslog file " << accessconf.file.get();
|
||||
res = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!get_config()->errorlog_syslog && get_config()->errorlog_file) {
|
||||
|
||||
new_errorlog_fd = util::open_log_file(get_config()->errorlog_file.get());
|
||||
if (!errorconf.syslog && errorconf.file) {
|
||||
new_errorlog_fd = util::open_log_file(errorconf.file.get());
|
||||
|
||||
if (new_errorlog_fd == -1) {
|
||||
if (lgconf->errorlog_fd != -1) {
|
||||
LOG(ERROR) << "Failed to open errorlog file "
|
||||
<< get_config()->errorlog_file.get();
|
||||
LOG(ERROR) << "Failed to open errorlog file " << errorconf.file.get();
|
||||
} else {
|
||||
std::cerr << "Failed to open errorlog file "
|
||||
<< get_config()->errorlog_file.get() << std::endl;
|
||||
std::cerr << "Failed to open errorlog file " << errorconf.file.get()
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
res = -1;
|
||||
@ -444,8 +445,9 @@ void log_chld(pid_t pid, int rstatus, const char *msg) {
|
||||
|
||||
void redirect_stderr_to_errorlog() {
|
||||
auto lgconf = log_config();
|
||||
auto &errorconf = get_config()->logging.error;
|
||||
|
||||
if (get_config()->errorlog_syslog || lgconf->errorlog_fd == -1) {
|
||||
if (errorconf.syslog || lgconf->errorlog_fd == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -92,7 +92,7 @@ constexpr ev_tstamp read_timeout = 10.;
|
||||
|
||||
MemcachedConnection::MemcachedConnection(const Address *addr,
|
||||
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.),
|
||||
parse_state_{}, addr_(addr), sendsum_(0), connected_(false) {}
|
||||
|
||||
|
@ -173,10 +173,12 @@ void on_ctrl_recv_callback(spdylay_session *session, spdylay_frame_type type,
|
||||
header_buffer += strlen(nv[i]) + strlen(nv[i + 1]);
|
||||
}
|
||||
|
||||
auto &httpconf = get_config()->http;
|
||||
|
||||
// spdy does not define usage of trailer fields, and we ignores
|
||||
// them.
|
||||
if (header_buffer > get_config()->header_field_buffer ||
|
||||
num_headers > get_config()->max_header_fields) {
|
||||
if (header_buffer > httpconf.header_field_buffer ||
|
||||
num_headers > httpconf.max_header_fields) {
|
||||
upstream->rst_stream(downstream, SPDYLAY_INTERNAL_ERROR);
|
||||
return;
|
||||
}
|
||||
@ -370,31 +372,33 @@ void on_data_chunk_recv_callback(spdylay_session *session, uint8_t flags,
|
||||
return;
|
||||
}
|
||||
|
||||
auto &http2conf = get_config()->http2;
|
||||
|
||||
// If connection-level window control is not enabled (e.g,
|
||||
// spdy/3), spdylay_session_get_recv_data_length() is always
|
||||
// returns 0.
|
||||
if (spdylay_session_get_recv_data_length(session) >
|
||||
std::max(SPDYLAY_INITIAL_WINDOW_SIZE,
|
||||
1 << get_config()->http2_upstream_connection_window_bits)) {
|
||||
1 << http2conf.upstream.connection_window_bits)) {
|
||||
if (LOG_ENABLED(INFO)) {
|
||||
ULOG(INFO, upstream)
|
||||
<< "Flow control error on connection: "
|
||||
<< "recv_window_size="
|
||||
<< spdylay_session_get_recv_data_length(session) << ", window_size="
|
||||
<< (1 << get_config()->http2_upstream_connection_window_bits);
|
||||
ULOG(INFO, upstream) << "Flow control error on connection: "
|
||||
<< "recv_window_size="
|
||||
<< spdylay_session_get_recv_data_length(session)
|
||||
<< ", window_size="
|
||||
<< (1 << http2conf.upstream.connection_window_bits);
|
||||
}
|
||||
spdylay_session_fail_session(session, SPDYLAY_GOAWAY_PROTOCOL_ERROR);
|
||||
return;
|
||||
}
|
||||
if (spdylay_session_get_stream_recv_data_length(session, stream_id) >
|
||||
std::max(SPDYLAY_INITIAL_WINDOW_SIZE,
|
||||
1 << get_config()->http2_upstream_window_bits)) {
|
||||
1 << http2conf.upstream.window_bits)) {
|
||||
if (LOG_ENABLED(INFO)) {
|
||||
ULOG(INFO, upstream) << "Flow control error: recv_window_size="
|
||||
<< spdylay_session_get_stream_recv_data_length(
|
||||
session, stream_id)
|
||||
<< ", initial_window_size="
|
||||
<< (1 << get_config()->http2_upstream_window_bits);
|
||||
<< (1 << http2conf.upstream.window_bits);
|
||||
}
|
||||
upstream->rst_stream(downstream, SPDYLAY_FLOW_CONTROL_ERROR);
|
||||
return;
|
||||
@ -490,9 +494,9 @@ uint32_t infer_upstream_rst_stream_status_code(uint32_t downstream_error_code) {
|
||||
SpdyUpstream::SpdyUpstream(uint16_t version, ClientHandler *handler)
|
||||
: downstream_queue_(
|
||||
get_config()->http2_proxy
|
||||
? get_config()->downstream_connections_per_host
|
||||
: get_config()->downstream_proto == PROTO_HTTP
|
||||
? get_config()->downstream_connections_per_frontend
|
||||
? get_config()->conn.downstream.connections_per_host
|
||||
: get_config()->conn.downstream.proto == PROTO_HTTP
|
||||
? get_config()->conn.downstream.connections_per_frontend
|
||||
: 0,
|
||||
!get_config()->http2_proxy),
|
||||
handler_(handler), session_(nullptr) {
|
||||
@ -518,10 +522,12 @@ SpdyUpstream::SpdyUpstream(uint16_t version, ClientHandler *handler)
|
||||
&max_buffer, sizeof(max_buffer));
|
||||
assert(rv == 0);
|
||||
|
||||
auto &http2conf = get_config()->http2;
|
||||
|
||||
if (version >= SPDYLAY_PROTO_SPDY3) {
|
||||
int val = 1;
|
||||
flow_control_ = true;
|
||||
initial_window_size_ = 1 << get_config()->http2_upstream_window_bits;
|
||||
initial_window_size_ = 1 << http2conf.upstream.window_bits;
|
||||
rv = spdylay_session_set_option(
|
||||
session_, SPDYLAY_OPT_NO_AUTO_WINDOW_UPDATE2, &val, sizeof(val));
|
||||
assert(rv == 0);
|
||||
@ -532,7 +538,7 @@ SpdyUpstream::SpdyUpstream(uint16_t version, ClientHandler *handler)
|
||||
// TODO Maybe call from outside?
|
||||
std::array<spdylay_settings_entry, 2> entry;
|
||||
entry[0].settings_id = SPDYLAY_SETTINGS_MAX_CONCURRENT_STREAMS;
|
||||
entry[0].value = get_config()->http2_max_concurrent_streams;
|
||||
entry[0].value = http2conf.max_concurrent_streams;
|
||||
entry[0].flags = SPDYLAY_ID_FLAG_SETTINGS_NONE;
|
||||
|
||||
entry[1].settings_id = SPDYLAY_SETTINGS_INITIAL_WINDOW_SIZE;
|
||||
@ -544,15 +550,15 @@ SpdyUpstream::SpdyUpstream(uint16_t version, ClientHandler *handler)
|
||||
assert(rv == 0);
|
||||
|
||||
if (version >= SPDYLAY_PROTO_SPDY3_1 &&
|
||||
get_config()->http2_upstream_connection_window_bits > 16) {
|
||||
int32_t delta = (1 << get_config()->http2_upstream_connection_window_bits) -
|
||||
http2conf.upstream.connection_window_bits > 16) {
|
||||
int32_t delta = (1 << http2conf.upstream.connection_window_bits) -
|
||||
SPDYLAY_INITIAL_WINDOW_SIZE;
|
||||
rv = spdylay_submit_window_update(session_, 0, delta);
|
||||
assert(rv == 0);
|
||||
}
|
||||
|
||||
handler_->reset_upstream_read_timeout(
|
||||
get_config()->http2_upstream_read_timeout);
|
||||
get_config()->conn.upstream.timeout.http2_read);
|
||||
|
||||
handler_->signal_write();
|
||||
}
|
||||
@ -875,7 +881,7 @@ int SpdyUpstream::send_reply(Downstream *downstream, const uint8_t *body,
|
||||
|
||||
if (!resp.fs.header(http2::HD_SERVER)) {
|
||||
nva.push_back("server");
|
||||
nva.push_back(get_config()->server_name.c_str());
|
||||
nva.push_back(get_config()->http.server_name.c_str());
|
||||
}
|
||||
|
||||
nva.push_back(nullptr);
|
||||
@ -919,7 +925,7 @@ int SpdyUpstream::error_reply(Downstream *downstream,
|
||||
std::string status_string = http2::get_status_string(status_code);
|
||||
const char *nv[] = {":status", status_string.c_str(), ":version", "http/1.1",
|
||||
"content-type", "text/html; charset=UTF-8", "server",
|
||||
get_config()->server_name.c_str(), "content-length",
|
||||
get_config()->http.server_name.c_str(), "content-length",
|
||||
content_length.c_str(), "date",
|
||||
lgconf->time_http_str.c_str(), nullptr};
|
||||
|
||||
@ -997,15 +1003,17 @@ int SpdyUpstream::on_downstream_header_complete(Downstream *downstream) {
|
||||
DLOG(INFO, downstream) << "HTTP response header completed";
|
||||
}
|
||||
|
||||
auto &httpconf = get_config()->http;
|
||||
|
||||
if (!get_config()->http2_proxy && !get_config()->client_proxy &&
|
||||
!get_config()->no_location_rewrite) {
|
||||
!httpconf.no_location_rewrite) {
|
||||
downstream->rewrite_location_response_header(req.scheme);
|
||||
}
|
||||
|
||||
// 8 means server, :status, :version and possible via header field.
|
||||
auto nv = make_unique<const char *[]>(
|
||||
resp.fs.headers().size() * 2 + 8 +
|
||||
get_config()->add_response_headers.size() * 2 + 1);
|
||||
auto nv =
|
||||
make_unique<const char *[]>(resp.fs.headers().size() * 2 + 8 +
|
||||
httpconf.add_response_headers.size() * 2 + 1);
|
||||
|
||||
size_t hdidx = 0;
|
||||
std::string via_value;
|
||||
@ -1034,7 +1042,7 @@ int SpdyUpstream::on_downstream_header_complete(Downstream *downstream) {
|
||||
|
||||
if (!get_config()->http2_proxy && !get_config()->client_proxy) {
|
||||
nv[hdidx++] = "server";
|
||||
nv[hdidx++] = get_config()->server_name.c_str();
|
||||
nv[hdidx++] = httpconf.server_name.c_str();
|
||||
} else {
|
||||
auto server = resp.fs.header(http2::HD_SERVER);
|
||||
if (server) {
|
||||
@ -1044,7 +1052,7 @@ int SpdyUpstream::on_downstream_header_complete(Downstream *downstream) {
|
||||
}
|
||||
|
||||
auto via = resp.fs.header(http2::HD_VIA);
|
||||
if (get_config()->no_via) {
|
||||
if (httpconf.no_via) {
|
||||
if (via) {
|
||||
nv[hdidx++] = "via";
|
||||
nv[hdidx++] = via->value.c_str();
|
||||
@ -1060,7 +1068,7 @@ int SpdyUpstream::on_downstream_header_complete(Downstream *downstream) {
|
||||
nv[hdidx++] = via_value.c_str();
|
||||
}
|
||||
|
||||
for (auto &p : get_config()->add_response_headers) {
|
||||
for (auto &p : httpconf.add_response_headers) {
|
||||
nv[hdidx++] = p.first.c_str();
|
||||
nv[hdidx++] = p.second.c_str();
|
||||
}
|
||||
|
109
src/shrpx_ssl.cc
109
src/shrpx_ssl.cc
@ -70,7 +70,7 @@ namespace ssl {
|
||||
namespace {
|
||||
int next_proto_cb(SSL *s, const unsigned char **data, unsigned int *len,
|
||||
void *arg) {
|
||||
auto &prefs = get_config()->alpn_prefs;
|
||||
auto &prefs = get_config()->tls.alpn_prefs;
|
||||
*data = prefs.data();
|
||||
*len = prefs.size();
|
||||
return SSL_TLSEXT_ERR_OK;
|
||||
@ -124,13 +124,13 @@ set_alpn_prefs(const std::vector<std::string> &protos) {
|
||||
namespace {
|
||||
int ssl_pem_passwd_cb(char *buf, int size, int rwflag, void *user_data) {
|
||||
auto config = static_cast<Config *>(user_data);
|
||||
int len = (int)strlen(config->private_key_passwd.get());
|
||||
int len = (int)strlen(config->tls.private_key_passwd.get());
|
||||
if (size < len + 1) {
|
||||
LOG(ERROR) << "ssl_pem_passwd_cb: buf is too small " << size;
|
||||
return 0;
|
||||
}
|
||||
// Copy string including last '\0'.
|
||||
memcpy(buf, config->private_key_passwd.get(), len + 1);
|
||||
memcpy(buf, config->tls.private_key_passwd.get(), len + 1);
|
||||
return len;
|
||||
}
|
||||
} // namespace
|
||||
@ -346,7 +346,7 @@ int ticket_key_cb(SSL *ssl, unsigned char *key_name, unsigned char *iv,
|
||||
|
||||
std::copy(std::begin(key.data.name), std::end(key.data.name), key_name);
|
||||
|
||||
EVP_EncryptInit_ex(ctx, get_config()->tls_ticket_key_cipher, nullptr,
|
||||
EVP_EncryptInit_ex(ctx, get_config()->tls.ticket.cipher, nullptr,
|
||||
key.data.enc_key.data(), iv);
|
||||
HMAC_Init_ex(hctx, key.data.hmac_key.data(), key.hmac_keylen, key.hmac,
|
||||
nullptr);
|
||||
@ -411,7 +411,7 @@ int alpn_select_proto_cb(SSL *ssl, const unsigned char **out,
|
||||
// We assume that get_config()->npn_list contains ALPN protocol
|
||||
// identifier sorted by preference order. So we just break when we
|
||||
// found the first overlap.
|
||||
for (const auto &target_proto_id : get_config()->npn_list) {
|
||||
for (const auto &target_proto_id : get_config()->tls.npn_list) {
|
||||
for (auto p = in, end = in + inlen; p < end;) {
|
||||
auto proto_id = p + 1;
|
||||
auto proto_len = *p;
|
||||
@ -477,22 +477,24 @@ 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_SINGLE_DH_USE | SSL_OP_CIPHER_SERVER_PREFERENCE;
|
||||
|
||||
SSL_CTX_set_options(ssl_ctx, ssl_opts | get_config()->tls_proto_mask);
|
||||
auto &tlsconf = get_config()->tls;
|
||||
|
||||
SSL_CTX_set_options(ssl_ctx, ssl_opts | tlsconf.tls_proto_mask);
|
||||
|
||||
const unsigned char sid_ctx[] = "shrpx";
|
||||
SSL_CTX_set_session_id_context(ssl_ctx, sid_ctx, sizeof(sid_ctx) - 1);
|
||||
SSL_CTX_set_session_cache_mode(ssl_ctx, SSL_SESS_CACHE_SERVER);
|
||||
|
||||
if (get_config()->session_cache_memcached_host) {
|
||||
if (tlsconf.session_cache.memcached.host) {
|
||||
SSL_CTX_sess_set_new_cb(ssl_ctx, tls_session_new_cb);
|
||||
SSL_CTX_sess_set_get_cb(ssl_ctx, tls_session_get_cb);
|
||||
}
|
||||
|
||||
SSL_CTX_set_timeout(ssl_ctx, get_config()->tls_session_timeout.count());
|
||||
SSL_CTX_set_timeout(ssl_ctx, tlsconf.session_timeout.count());
|
||||
|
||||
const char *ciphers;
|
||||
if (get_config()->ciphers) {
|
||||
ciphers = get_config()->ciphers.get();
|
||||
if (tlsconf.ciphers) {
|
||||
ciphers = tlsconf.ciphers.get();
|
||||
} else {
|
||||
ciphers = nghttp2::ssl::DEFAULT_CIPHER_LIST;
|
||||
}
|
||||
@ -525,9 +527,9 @@ SSL_CTX *create_ssl_context(const char *private_key_file, const char *cert_file
|
||||
|
||||
#endif // OPENSSL_NO_EC
|
||||
|
||||
if (get_config()->dh_param_file) {
|
||||
if (tlsconf.dh_param_file) {
|
||||
// Read DH parameters from file
|
||||
auto bio = BIO_new_file(get_config()->dh_param_file.get(), "r");
|
||||
auto bio = BIO_new_file(tlsconf.dh_param_file.get(), "r");
|
||||
if (bio == nullptr) {
|
||||
LOG(FATAL) << "BIO_new_file() failed: "
|
||||
<< ERR_error_string(ERR_get_error(), nullptr);
|
||||
@ -546,7 +548,7 @@ SSL_CTX *create_ssl_context(const char *private_key_file, const char *cert_file
|
||||
|
||||
SSL_CTX_set_mode(ssl_ctx, SSL_MODE_AUTO_RETRY);
|
||||
SSL_CTX_set_mode(ssl_ctx, SSL_MODE_RELEASE_BUFFERS);
|
||||
if (get_config()->private_key_passwd) {
|
||||
if (tlsconf.private_key_passwd) {
|
||||
SSL_CTX_set_default_passwd_cb(ssl_ctx, ssl_pem_passwd_cb);
|
||||
SSL_CTX_set_default_passwd_cb_userdata(ssl_ctx, (void *)get_config());
|
||||
}
|
||||
@ -576,14 +578,13 @@ SSL_CTX *create_ssl_context(const char *private_key_file, const char *cert_file
|
||||
<< ERR_error_string(ERR_get_error(), nullptr);
|
||||
DIE();
|
||||
}
|
||||
if (get_config()->verify_client) {
|
||||
if (get_config()->verify_client_cacert) {
|
||||
if (tlsconf.client_verify.enabled) {
|
||||
if (tlsconf.client_verify.cacert) {
|
||||
if (SSL_CTX_load_verify_locations(
|
||||
ssl_ctx, get_config()->verify_client_cacert.get(), nullptr) !=
|
||||
1) {
|
||||
ssl_ctx, tlsconf.client_verify.cacert.get(), nullptr) != 1) {
|
||||
|
||||
LOG(FATAL) << "Could not load trusted ca certificates from "
|
||||
<< get_config()->verify_client_cacert.get() << ": "
|
||||
<< tlsconf.client_verify.cacert.get() << ": "
|
||||
<< ERR_error_string(ERR_get_error(), nullptr);
|
||||
DIE();
|
||||
}
|
||||
@ -591,11 +592,10 @@ SSL_CTX *create_ssl_context(const char *private_key_file, const char *cert_file
|
||||
// error even though it returns success. See
|
||||
// http://forum.nginx.org/read.php?29,242540
|
||||
ERR_clear_error();
|
||||
auto list =
|
||||
SSL_load_client_CA_file(get_config()->verify_client_cacert.get());
|
||||
auto list = SSL_load_client_CA_file(tlsconf.client_verify.cacert.get());
|
||||
if (!list) {
|
||||
LOG(FATAL) << "Could not load ca certificates from "
|
||||
<< get_config()->verify_client_cacert.get() << ": "
|
||||
<< tlsconf.client_verify.cacert.get() << ": "
|
||||
<< ERR_error_string(ERR_get_error(), nullptr);
|
||||
DIE();
|
||||
}
|
||||
@ -656,11 +656,13 @@ SSL_CTX *create_ssl_client_context(
|
||||
SSL_OP_NO_COMPRESSION |
|
||||
SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION;
|
||||
|
||||
SSL_CTX_set_options(ssl_ctx, ssl_opts | get_config()->tls_proto_mask);
|
||||
auto &tlsconf = get_config()->tls;
|
||||
|
||||
SSL_CTX_set_options(ssl_ctx, ssl_opts | tlsconf.tls_proto_mask);
|
||||
|
||||
const char *ciphers;
|
||||
if (get_config()->ciphers) {
|
||||
ciphers = get_config()->ciphers.get();
|
||||
if (tlsconf.ciphers) {
|
||||
ciphers = tlsconf.ciphers.get();
|
||||
} else {
|
||||
ciphers = nghttp2::ssl::DEFAULT_CIPHER_LIST;
|
||||
}
|
||||
@ -678,44 +680,44 @@ SSL_CTX *create_ssl_client_context(
|
||||
<< ERR_error_string(ERR_get_error(), nullptr);
|
||||
}
|
||||
|
||||
if (get_config()->cacert) {
|
||||
if (SSL_CTX_load_verify_locations(ssl_ctx, get_config()->cacert.get(),
|
||||
nullptr) != 1) {
|
||||
if (tlsconf.cacert) {
|
||||
if (SSL_CTX_load_verify_locations(ssl_ctx, tlsconf.cacert.get(), nullptr) !=
|
||||
1) {
|
||||
|
||||
LOG(FATAL) << "Could not load trusted ca certificates from "
|
||||
<< get_config()->cacert.get() << ": "
|
||||
<< tlsconf.cacert.get() << ": "
|
||||
<< ERR_error_string(ERR_get_error(), nullptr);
|
||||
DIE();
|
||||
}
|
||||
}
|
||||
|
||||
if (get_config()->client_private_key_file) {
|
||||
if (tlsconf.client.private_key_file) {
|
||||
#ifndef HAVE_NEVERBLEED
|
||||
if (SSL_CTX_use_PrivateKey_file(ssl_ctx,
|
||||
get_config()->client_private_key_file.get(),
|
||||
tlsconf.client.private_key_file.get(),
|
||||
SSL_FILETYPE_PEM) != 1) {
|
||||
LOG(FATAL) << "Could not load client private key from "
|
||||
<< get_config()->client_private_key_file.get() << ": "
|
||||
<< tlsconf.client.private_key_file.get() << ": "
|
||||
<< ERR_error_string(ERR_get_error(), nullptr);
|
||||
DIE();
|
||||
}
|
||||
#else // HAVE_NEVERBLEED
|
||||
std::array<char, NEVERBLEED_ERRBUF_SIZE> errbuf;
|
||||
if (neverbleed_load_private_key_file(
|
||||
nb, ssl_ctx, get_config()->client_private_key_file.get(),
|
||||
errbuf.data()) != 1) {
|
||||
if (neverbleed_load_private_key_file(nb, ssl_ctx,
|
||||
tlsconf.client.private_key_file.get(),
|
||||
errbuf.data()) != 1) {
|
||||
LOG(FATAL) << "neverbleed_load_private_key_file failed: "
|
||||
<< errbuf.data();
|
||||
DIE();
|
||||
}
|
||||
#endif // HAVE_NEVERBLEED
|
||||
}
|
||||
if (get_config()->client_cert_file) {
|
||||
if (tlsconf.client.cert_file) {
|
||||
if (SSL_CTX_use_certificate_chain_file(
|
||||
ssl_ctx, get_config()->client_cert_file.get()) != 1) {
|
||||
ssl_ctx, tlsconf.client.cert_file.get()) != 1) {
|
||||
|
||||
LOG(FATAL) << "Could not load client certificate from "
|
||||
<< get_config()->client_cert_file.get() << ": "
|
||||
<< tlsconf.client.cert_file.get() << ": "
|
||||
<< ERR_error_string(ERR_get_error(), nullptr);
|
||||
DIE();
|
||||
}
|
||||
@ -971,9 +973,11 @@ int check_cert(SSL *ssl, const DownstreamAddr *addr) {
|
||||
<< X509_verify_cert_error_string(verify_res);
|
||||
return -1;
|
||||
}
|
||||
auto hostname = !get_config()->backend_tls_sni_name.empty()
|
||||
? StringRef(get_config()->backend_tls_sni_name)
|
||||
: StringRef(addr->host);
|
||||
|
||||
auto &backend_sni_name = get_config()->tls.backend_sni_name;
|
||||
|
||||
auto hostname = !backend_sni_name.empty() ? StringRef(backend_sni_name)
|
||||
: StringRef(addr->host);
|
||||
if (verify_hostname(cert, hostname.c_str(), hostname.size(), &addr->addr) !=
|
||||
0) {
|
||||
LOG(ERROR) << "Certificate verification failed: hostname does not match";
|
||||
@ -1210,12 +1214,14 @@ SSL_CTX *setup_server_ssl_context(std::vector<SSL_CTX *> &all_ssl_ctx,
|
||||
neverbleed_t *nb
|
||||
#endif // HAVE_NEVERBLEED
|
||||
) {
|
||||
if (get_config()->upstream_no_tls) {
|
||||
if (get_config()->conn.upstream.no_tls) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto ssl_ctx = ssl::create_ssl_context(get_config()->private_key_file.get(),
|
||||
get_config()->cert_file.get()
|
||||
auto &tlsconf = get_config()->tls;
|
||||
|
||||
auto ssl_ctx = ssl::create_ssl_context(tlsconf.private_key_file.get(),
|
||||
tlsconf.cert_file.get()
|
||||
#ifdef HAVE_NEVERBLEED
|
||||
,
|
||||
nb
|
||||
@ -1224,7 +1230,7 @@ SSL_CTX *setup_server_ssl_context(std::vector<SSL_CTX *> &all_ssl_ctx,
|
||||
|
||||
all_ssl_ctx.push_back(ssl_ctx);
|
||||
|
||||
if (get_config()->subcerts.empty()) {
|
||||
if (tlsconf.subcerts.empty()) {
|
||||
return ssl_ctx;
|
||||
}
|
||||
|
||||
@ -1234,7 +1240,7 @@ SSL_CTX *setup_server_ssl_context(std::vector<SSL_CTX *> &all_ssl_ctx,
|
||||
return ssl_ctx;
|
||||
}
|
||||
|
||||
for (auto &keycert : get_config()->subcerts) {
|
||||
for (auto &keycert : tlsconf.subcerts) {
|
||||
auto ssl_ctx =
|
||||
ssl::create_ssl_context(keycert.first.c_str(), keycert.second.c_str()
|
||||
#ifdef HAVE_NEVERBLEED
|
||||
@ -1250,8 +1256,8 @@ SSL_CTX *setup_server_ssl_context(std::vector<SSL_CTX *> &all_ssl_ctx,
|
||||
}
|
||||
}
|
||||
|
||||
if (ssl::cert_lookup_tree_add_cert_from_file(
|
||||
cert_tree, ssl_ctx, get_config()->cert_file.get()) == -1) {
|
||||
if (ssl::cert_lookup_tree_add_cert_from_file(cert_tree, ssl_ctx,
|
||||
tlsconf.cert_file.get()) == -1) {
|
||||
LOG(FATAL) << "Failed to add default certificate.";
|
||||
DIE();
|
||||
}
|
||||
@ -1260,11 +1266,13 @@ SSL_CTX *setup_server_ssl_context(std::vector<SSL_CTX *> &all_ssl_ctx,
|
||||
}
|
||||
|
||||
bool downstream_tls_enabled() {
|
||||
auto no_tls = get_config()->conn.downstream.no_tls;
|
||||
|
||||
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(
|
||||
@ -1284,7 +1292,8 @@ SSL_CTX *setup_client_ssl_context(
|
||||
}
|
||||
|
||||
CertLookupTree *create_cert_lookup_tree() {
|
||||
if (get_config()->upstream_no_tls || get_config()->subcerts.empty()) {
|
||||
if (get_config()->conn.upstream.no_tls ||
|
||||
get_config()->tls.subcerts.empty()) {
|
||||
return nullptr;
|
||||
}
|
||||
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,
|
||||
ssl::CertLookupTree *cert_tree,
|
||||
const std::shared_ptr<TicketKeys> &ticket_keys)
|
||||
: randgen_(rd()), dconn_pool_(get_config()->downstream_addr_groups.size()),
|
||||
worker_stat_(get_config()->downstream_addr_groups.size()),
|
||||
dgrps_(get_config()->downstream_addr_groups.size()), loop_(loop),
|
||||
: randgen_(rd()),
|
||||
dconn_pool_(get_config()->conn.downstream.addr_groups.size()),
|
||||
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),
|
||||
ticket_keys_(ticket_keys),
|
||||
connect_blocker_(make_unique<ConnectBlocker>(loop_)),
|
||||
@ -83,18 +84,22 @@ Worker::Worker(struct ev_loop *loop, SSL_CTX *sv_ssl_ctx, SSL_CTX *cl_ssl_ctx,
|
||||
ev_timer_init(&mcpool_clear_timer_, mcpool_clear_cb, 0., 0.);
|
||||
mcpool_clear_timer_.data = this;
|
||||
|
||||
if (get_config()->session_cache_memcached_host) {
|
||||
auto &session_cacheconf = get_config()->tls.session_cache;
|
||||
|
||||
if (session_cacheconf.memcached.host) {
|
||||
session_cache_memcached_dispatcher_ = make_unique<MemcachedDispatcher>(
|
||||
&get_config()->session_cache_memcached_addr, loop);
|
||||
&session_cacheconf.memcached.addr, loop);
|
||||
}
|
||||
|
||||
if (get_config()->downstream_proto == PROTO_HTTP2) {
|
||||
auto n = get_config()->http2_downstream_connections_per_worker;
|
||||
auto &downstreamconf = get_config()->conn.downstream;
|
||||
|
||||
if (downstreamconf.proto == PROTO_HTTP2) {
|
||||
auto n = get_config()->http2.downstream.connections_per_worker;
|
||||
size_t group = 0;
|
||||
for (auto &dgrp : dgrps_) {
|
||||
auto m = n;
|
||||
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) {
|
||||
dgrp.http2sessions.push_back(make_unique<Http2Session>(
|
||||
@ -149,6 +154,9 @@ void Worker::process_events() {
|
||||
std::lock_guard<std::mutex> g(m_);
|
||||
q.swap(q_);
|
||||
}
|
||||
|
||||
auto worker_connections = get_config()->conn.upstream.worker_connections;
|
||||
|
||||
for (auto &wev : q) {
|
||||
switch (wev.type) {
|
||||
case NEW_CONNECTION: {
|
||||
@ -157,12 +165,10 @@ void Worker::process_events() {
|
||||
<< ", addrlen=" << wev.client_addrlen;
|
||||
}
|
||||
|
||||
if (worker_stat_.num_connections >=
|
||||
get_config()->worker_frontend_connections) {
|
||||
if (worker_stat_.num_connections >= worker_connections) {
|
||||
|
||||
if (LOG_ENABLED(INFO)) {
|
||||
WLOG(INFO, this) << "Too many connections >= "
|
||||
<< get_config()->worker_frontend_connections;
|
||||
WLOG(INFO, this) << "Too many connections >= " << worker_connections;
|
||||
}
|
||||
|
||||
close(wev.client_fd);
|
||||
|
@ -170,7 +170,7 @@ void ipc_readcb(struct ev_loop *loop, ev_io *w, int revents) {
|
||||
|
||||
namespace {
|
||||
int generate_ticket_key(TicketKey &ticket_key) {
|
||||
ticket_key.cipher = get_config()->tls_ticket_key_cipher;
|
||||
ticket_key.cipher = get_config()->tls.ticket.cipher;
|
||||
ticket_key.hmac = EVP_sha256();
|
||||
ticket_key.hmac_keylen = EVP_MD_size(ticket_key.hmac);
|
||||
|
||||
@ -217,7 +217,7 @@ void renew_ticket_key_cb(struct ev_loop *loop, ev_timer *w, int revents) {
|
||||
|
||||
auto max_tickets =
|
||||
static_cast<size_t>(std::chrono::duration_cast<std::chrono::hours>(
|
||||
get_config()->tls_session_timeout).count());
|
||||
get_config()->tls.session_timeout).count());
|
||||
|
||||
new_keys.resize(std::min(max_tickets, old_keys.size() + 1));
|
||||
std::copy_n(std::begin(old_keys), new_keys.size() - 1,
|
||||
@ -297,14 +297,16 @@ void memcached_get_ticket_key_cb(struct ev_loop *loop, ev_timer *w,
|
||||
auto end = p + value.size();
|
||||
p += 4;
|
||||
|
||||
auto &ticketconf = get_config()->tls.ticket;
|
||||
|
||||
size_t expectedlen;
|
||||
size_t enc_keylen;
|
||||
size_t hmac_keylen;
|
||||
if (get_config()->tls_ticket_key_cipher == EVP_aes_128_cbc()) {
|
||||
if (ticketconf.cipher == EVP_aes_128_cbc()) {
|
||||
expectedlen = 48;
|
||||
enc_keylen = 16;
|
||||
hmac_keylen = 16;
|
||||
} else if (get_config()->tls_ticket_key_cipher == EVP_aes_256_cbc()) {
|
||||
} else if (ticketconf.cipher == EVP_aes_256_cbc()) {
|
||||
expectedlen = 80;
|
||||
enc_keylen = 32;
|
||||
hmac_keylen = 32;
|
||||
@ -335,7 +337,7 @@ void memcached_get_ticket_key_cb(struct ev_loop *loop, ev_timer *w,
|
||||
return;
|
||||
}
|
||||
auto key = TicketKey();
|
||||
key.cipher = get_config()->tls_ticket_key_cipher;
|
||||
key.cipher = ticketconf.cipher;
|
||||
key.hmac = EVP_sha256();
|
||||
key.hmac_keylen = hmac_keylen;
|
||||
|
||||
@ -421,12 +423,15 @@ int worker_process_event_loop(WorkerProcessConfig *wpconf) {
|
||||
|
||||
#endif // HAVE_NEVERBLEED
|
||||
|
||||
auto &upstreamconf = get_config()->conn.upstream;
|
||||
|
||||
ev_timer renew_ticket_key_timer;
|
||||
if (!get_config()->upstream_no_tls) {
|
||||
if (get_config()->tls_ticket_key_memcached_host) {
|
||||
if (!upstreamconf.no_tls) {
|
||||
auto &ticketconf = get_config()->tls.ticket;
|
||||
|
||||
if (ticketconf.memcached.host) {
|
||||
conn_handler.set_tls_ticket_key_memcached_dispatcher(
|
||||
make_unique<MemcachedDispatcher>(
|
||||
&get_config()->tls_ticket_key_memcached_addr, loop));
|
||||
make_unique<MemcachedDispatcher>(&ticketconf.memcached.addr, loop));
|
||||
|
||||
ev_timer_init(&renew_ticket_key_timer, memcached_get_ticket_key_cb, 0.,
|
||||
0.);
|
||||
@ -435,8 +440,8 @@ int worker_process_event_loop(WorkerProcessConfig *wpconf) {
|
||||
memcached_get_ticket_key_cb(loop, &renew_ticket_key_timer, 0);
|
||||
} else {
|
||||
bool auto_tls_ticket_key = true;
|
||||
if (!get_config()->tls_ticket_key_files.empty()) {
|
||||
if (!get_config()->tls_ticket_key_cipher_given) {
|
||||
if (!ticketconf.files.empty()) {
|
||||
if (!ticketconf.cipher_given) {
|
||||
LOG(WARN)
|
||||
<< "It is strongly recommended to specify "
|
||||
"--tls-ticket-key-cipher=aes-128-cbc (or "
|
||||
@ -446,8 +451,7 @@ int worker_process_event_loop(WorkerProcessConfig *wpconf) {
|
||||
"becomes aes-256-cbc";
|
||||
}
|
||||
auto ticket_keys = read_tls_ticket_key_file(
|
||||
get_config()->tls_ticket_key_files,
|
||||
get_config()->tls_ticket_key_cipher, EVP_sha256());
|
||||
ticketconf.files, ticketconf.cipher, EVP_sha256());
|
||||
if (!ticket_keys) {
|
||||
LOG(WARN) << "Use internal session ticket key generator";
|
||||
} else {
|
||||
@ -512,7 +516,7 @@ int worker_process_event_loop(WorkerProcessConfig *wpconf) {
|
||||
ipcev.data = &conn_handler;
|
||||
ev_io_start(loop, &ipcev);
|
||||
|
||||
if (!get_config()->upstream_no_tls && !get_config()->no_ocsp) {
|
||||
if (!upstreamconf.no_tls && !get_config()->tls.ocsp.disabled) {
|
||||
conn_handler.proceed_next_cert_ocsp();
|
||||
}
|
||||
|
||||
|
@ -171,10 +171,18 @@ constexpr unsigned long long operator"" _g(unsigned long long g) {
|
||||
|
||||
// User-defined literals for time, converted into double in seconds
|
||||
|
||||
// hours
|
||||
constexpr double operator"" _h(unsigned long long h) { return h * 60 * 60; }
|
||||
|
||||
// minutes
|
||||
constexpr double operator"" _min(unsigned long long min) { return min * 60; }
|
||||
|
||||
// seconds
|
||||
constexpr double operator"" _s(unsigned long long s) { return s; }
|
||||
|
||||
// milliseconds
|
||||
constexpr double operator"" _ms(unsigned long long ms) { return ms / 1000.; }
|
||||
|
||||
// Returns a copy of NULL-terminated string [first, last).
|
||||
template <typename InputIt>
|
||||
std::unique_ptr<char[]> strcopy(InputIt first, InputIt last) {
|
||||
|
Loading…
Reference in New Issue
Block a user