Merge branch 'master' into http2-debug-state-api
This commit is contained in:
commit
69aa70086a
1
AUTHORS
1
AUTHORS
|
@ -71,6 +71,7 @@ Tomasz Buchert
|
|||
Vernon Tang
|
||||
Viacheslav Biriukov
|
||||
Viktor Szépe
|
||||
Wenfeng Liu
|
||||
Xiaoguang Sun
|
||||
Zhuoyun Wei
|
||||
acesso
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
# XXX using 1.8.90 instead of 1.9.0-DEV
|
||||
project(nghttp2 VERSION 1.13.90)
|
||||
project(nghttp2 VERSION 1.14.90)
|
||||
|
||||
# See versioning rule:
|
||||
# http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
# script to extract commit author's name from standard input. The
|
||||
# input should be <AUTHOR>:<EMAIL>, one per line.
|
||||
# This script expects the input is created by git-log command:
|
||||
#
|
||||
# git log --format=%aN:%aE
|
||||
#
|
||||
# This script removes duplicates based on email address, breaking a
|
||||
# tie with longer author name. Among the all author names extract the
|
||||
# previous step, we remove duplicate by case-insensitive match.
|
||||
#
|
||||
# So we can do this in one line:
|
||||
#
|
||||
# git log --format=%aN:%aE | sort | uniq | ./author.py > authors
|
||||
|
||||
import sys
|
||||
|
||||
edict = {}
|
||||
|
||||
for line in sys.stdin:
|
||||
author, email = line.strip().split(':', 1)
|
||||
if email in edict:
|
||||
an = edict[email]
|
||||
if len(an) < len(author) or an > author:
|
||||
sys.stderr.write(
|
||||
'eliminated {} in favor of {}\n'.format(an, author))
|
||||
edict[email] = author
|
||||
else:
|
||||
sys.stderr.write(
|
||||
'eliminated {} in favor of {}\n'.format(author, an))
|
||||
else:
|
||||
edict[email] = author
|
||||
|
||||
names = list(sorted(edict.values()))
|
||||
|
||||
ndict = {}
|
||||
|
||||
for name in names:
|
||||
lowname = name.lower()
|
||||
if lowname in ndict:
|
||||
an = ndict[lowname]
|
||||
if an > name:
|
||||
sys.stderr.write('eliminated {} in favor of {}\n'.format(an, name))
|
||||
ndict[lowname] = name
|
||||
else:
|
||||
sys.stderr.write('eliminated {} in favor of {}\n'.format(name, an))
|
||||
else:
|
||||
ndict[lowname] = name
|
||||
|
||||
for name in sorted(ndict.values()):
|
||||
print name
|
|
@ -25,7 +25,7 @@ dnl Do not change user variables!
|
|||
dnl http://www.gnu.org/software/automake/manual/html_node/Flag-Variables-Ordering.html
|
||||
|
||||
AC_PREREQ(2.61)
|
||||
AC_INIT([nghttp2], [1.14.0-DEV], [t-tujikawa@users.sourceforge.net])
|
||||
AC_INIT([nghttp2], [1.15.0-DEV], [t-tujikawa@users.sourceforge.net])
|
||||
AC_CONFIG_AUX_DIR([.])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
|
@ -44,9 +44,9 @@ m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
|
|||
|
||||
dnl See versioning rule:
|
||||
dnl http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
|
||||
AC_SUBST(LT_CURRENT, 23)
|
||||
AC_SUBST(LT_CURRENT, 24)
|
||||
AC_SUBST(LT_REVISION, 0)
|
||||
AC_SUBST(LT_AGE, 9)
|
||||
AC_SUBST(LT_AGE, 10)
|
||||
|
||||
major=`echo $PACKAGE_VERSION |cut -d. -f1 | sed -e "s/[^0-9]//g"`
|
||||
minor=`echo $PACKAGE_VERSION |cut -d. -f2 | sed -e "s/[^0-9]//g"`
|
||||
|
|
|
@ -37,6 +37,7 @@ APIDOCS= \
|
|||
nghttp2_hd_deflate_get_num_table_entries.rst \
|
||||
nghttp2_hd_deflate_get_table_entry.rst \
|
||||
nghttp2_hd_deflate_hd.rst \
|
||||
nghttp2_hd_deflate_hd_vec.rst \
|
||||
nghttp2_hd_deflate_new.rst \
|
||||
nghttp2_hd_deflate_new2.rst \
|
||||
nghttp2_hd_inflate_change_table_size.rst \
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
.\" Man page generated from reStructuredText.
|
||||
.
|
||||
.TH "H2LOAD" "1" "Jul 31, 2016" "1.14.0-DEV" "nghttp2"
|
||||
.TH "H2LOAD" "1" "Aug 25, 2016" "1.14.0" "nghttp2"
|
||||
.SH NAME
|
||||
h2load \- HTTP/2 benchmarking tool
|
||||
.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
.\" Man page generated from reStructuredText.
|
||||
.
|
||||
.TH "NGHTTP" "1" "Jul 31, 2016" "1.14.0-DEV" "nghttp2"
|
||||
.TH "NGHTTP" "1" "Aug 25, 2016" "1.14.0" "nghttp2"
|
||||
.SH NAME
|
||||
nghttp \- HTTP/2 client
|
||||
.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
.\" Man page generated from reStructuredText.
|
||||
.
|
||||
.TH "NGHTTPD" "1" "Jul 31, 2016" "1.14.0-DEV" "nghttp2"
|
||||
.TH "NGHTTPD" "1" "Aug 25, 2016" "1.14.0" "nghttp2"
|
||||
.SH NAME
|
||||
nghttpd \- HTTP/2 server
|
||||
.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
.\" Man page generated from reStructuredText.
|
||||
.
|
||||
.TH "NGHTTPX" "1" "Jul 31, 2016" "1.14.0-DEV" "nghttp2"
|
||||
.TH "NGHTTPX" "1" "Aug 25, 2016" "1.14.0" "nghttp2"
|
||||
.SH NAME
|
||||
nghttpx \- HTTP/2 proxy
|
||||
.
|
||||
|
@ -938,6 +938,12 @@ $ssl_session_id: session ID for SSL/TLS connection.
|
|||
.IP \(bu 2
|
||||
$ssl_session_reused: "r" if SSL/TLS session was
|
||||
reused. Otherwise, "."
|
||||
.IP \(bu 2
|
||||
$backend_host: backend host used to fulfill the
|
||||
request. "\-" if backend host is not available.
|
||||
.IP \(bu 2
|
||||
$backend_port: backend port used to fulfill the
|
||||
request. "\-" if backend host is not available.
|
||||
.UNINDENT
|
||||
.sp
|
||||
The variable can be enclosed by "{" and "}" for
|
||||
|
|
|
@ -847,6 +847,10 @@ Logging
|
|||
* $ssl_session_id: session ID for SSL/TLS connection.
|
||||
* $ssl_session_reused: "r" if SSL/TLS session was
|
||||
reused. Otherwise, "."
|
||||
* $backend_host: backend host used to fulfill the
|
||||
request. "-" if backend host is not available.
|
||||
* $backend_port: backend port used to fulfill the
|
||||
request. "-" if backend host is not available.
|
||||
|
||||
The variable can be enclosed by "{" and "}" for
|
||||
disambiguation (e.g., ${remote_addr}).
|
||||
|
|
|
@ -134,6 +134,7 @@ OPTIONS = [
|
|||
"backend-http2-settings-timeout",
|
||||
"api-max-request-body",
|
||||
"backend-max-backoff",
|
||||
"server-name",
|
||||
]
|
||||
|
||||
LOGVARS = [
|
||||
|
|
|
@ -768,14 +768,12 @@ static size_t entry_room(size_t namelen, size_t valuelen) {
|
|||
return NGHTTP2_HD_ENTRY_OVERHEAD + namelen + valuelen;
|
||||
}
|
||||
|
||||
static int emit_header(nghttp2_hd_nv *nv_out, nghttp2_hd_nv *nv) {
|
||||
static void emit_header(nghttp2_hd_nv *nv_out, nghttp2_hd_nv *nv) {
|
||||
DEBUGF(fprintf(stderr, "inflatehd: header emission: %s: %s\n", nv->name->base,
|
||||
nv->value->base));
|
||||
/* ent->ref may be 0. This happens if the encoder emits literal
|
||||
block larger than header table capacity with indexing. */
|
||||
*nv_out = *nv;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static size_t count_encoded_length(size_t n, size_t prefix) {
|
||||
|
|
|
@ -503,7 +503,7 @@ const request *session_impl::submit(boost::system::error_code &ec,
|
|||
}
|
||||
|
||||
auto nva = std::vector<nghttp2_nv>();
|
||||
nva.reserve(3 + h.size());
|
||||
nva.reserve(4 + h.size());
|
||||
nva.push_back(http2::make_nv_ls(":method", method));
|
||||
nva.push_back(http2::make_nv_ls(":scheme", uref.scheme));
|
||||
nva.push_back(http2::make_nv_ls(":path", path));
|
||||
|
|
|
@ -178,6 +178,9 @@ template <typename Memchunk> struct Memchunks {
|
|||
}
|
||||
size_t append(const std::string &s) { return append(s.c_str(), s.size()); }
|
||||
size_t append(const StringRef &s) { return append(s.c_str(), s.size()); }
|
||||
size_t append(const ImmutableString &s) {
|
||||
return append(s.c_str(), s.size());
|
||||
}
|
||||
size_t remove(void *dest, size_t count) {
|
||||
if (!tail || count == 0) {
|
||||
return 0;
|
||||
|
|
36
src/shrpx.cc
36
src/shrpx.cc
|
@ -574,7 +574,7 @@ int create_unix_domain_server_socket(UpstreamAddr &faddr,
|
|||
<< (faddr.tls ? ", tls" : "");
|
||||
(*found).used = true;
|
||||
faddr.fd = (*found).fd;
|
||||
faddr.hostport = "localhost";
|
||||
faddr.hostport = ImmutableString::from_lit("localhost");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -639,7 +639,7 @@ int create_unix_domain_server_socket(UpstreamAddr &faddr,
|
|||
<< (faddr.tls ? ", tls" : "");
|
||||
|
||||
faddr.fd = fd;
|
||||
faddr.hostport = "localhost";
|
||||
faddr.hostport = ImmutableString::from_lit("localhost");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -791,7 +791,8 @@ int create_tcp_server_socket(UpstreamAddr &faddr,
|
|||
}
|
||||
|
||||
faddr.fd = fd;
|
||||
faddr.hostport = util::make_http_hostport(StringRef{host.data()}, faddr.port);
|
||||
faddr.hostport = ImmutableString{
|
||||
util::make_http_hostport(StringRef{host.data()}, faddr.port)};
|
||||
|
||||
LOG(NOTICE) << "Listening on " << faddr.hostport
|
||||
<< (faddr.tls ? ", tls" : "");
|
||||
|
@ -855,7 +856,7 @@ get_inherited_addr_from_config(const Config *config) {
|
|||
continue;
|
||||
}
|
||||
|
||||
iaddr.host = host.data();
|
||||
iaddr.host = ImmutableString{host.data()};
|
||||
}
|
||||
|
||||
return iaddrs;
|
||||
|
@ -947,7 +948,7 @@ std::vector<InheritedAddr> get_inherited_addr_from_env() {
|
|||
}
|
||||
|
||||
InheritedAddr addr{};
|
||||
addr.host = path;
|
||||
addr.host = ImmutableString{path};
|
||||
addr.host_unix = true;
|
||||
addr.fd = static_cast<int>(fd);
|
||||
iaddrs.push_back(std::move(addr));
|
||||
|
@ -1001,7 +1002,7 @@ std::vector<InheritedAddr> get_inherited_addr_from_env() {
|
|||
}
|
||||
|
||||
InheritedAddr addr{};
|
||||
addr.host = host.data();
|
||||
addr.host = ImmutableString{host.data()};
|
||||
addr.port = static_cast<uint16_t>(port);
|
||||
addr.fd = static_cast<int>(fd);
|
||||
iaddrs.push_back(std::move(addr));
|
||||
|
@ -1272,10 +1273,8 @@ constexpr auto DEFAULT_ACCESSLOG_FORMAT = StringRef::from_lit(
|
|||
|
||||
namespace {
|
||||
void fill_default_config(Config *config) {
|
||||
*config = {};
|
||||
|
||||
config->num_worker = 1;
|
||||
config->conf_path = "/etc/nghttpx/nghttpx.conf";
|
||||
config->conf_path = ImmutableString::from_lit("/etc/nghttpx/nghttpx.conf");
|
||||
config->pid = getpid();
|
||||
|
||||
if (ev_supported_backends() & ~ev_recommended_backends() & EVBACKEND_KQUEUE) {
|
||||
|
@ -1306,7 +1305,8 @@ void fill_default_config(Config *config) {
|
|||
auto &ocspconf = tlsconf.ocsp;
|
||||
// ocsp update interval = 14400 secs = 4 hours, borrowed from h2o
|
||||
ocspconf.update_interval = 4_h;
|
||||
ocspconf.fetch_ocsp_response_file = PKGDATADIR "/fetch-ocsp-response";
|
||||
ocspconf.fetch_ocsp_response_file =
|
||||
ImmutableString::from_lit(PKGDATADIR "/fetch-ocsp-response");
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -1319,7 +1319,7 @@ void fill_default_config(Config *config) {
|
|||
|
||||
auto &httpconf = config->http;
|
||||
httpconf.server_name =
|
||||
StringRef::from_lit("nghttpx nghttp2/" NGHTTP2_VERSION);
|
||||
ImmutableString::from_lit("nghttpx nghttp2/" NGHTTP2_VERSION);
|
||||
httpconf.no_host_rewrite = true;
|
||||
httpconf.request_header_field_buffer = 64_k;
|
||||
httpconf.max_request_header_fields = 100;
|
||||
|
@ -1377,7 +1377,7 @@ void fill_default_config(Config *config) {
|
|||
accessconf.format = parse_log_format(DEFAULT_ACCESSLOG_FORMAT);
|
||||
|
||||
auto &errorconf = loggingconf.error;
|
||||
errorconf.file = "/dev/stderr";
|
||||
errorconf.file = ImmutableString::from_lit("/dev/stderr");
|
||||
}
|
||||
|
||||
loggingconf.syslog_facility = LOG_DAEMON;
|
||||
|
@ -2205,6 +2205,9 @@ HTTP:
|
|||
599. If "*" is used instead of <CODE>, it matches all
|
||||
HTTP status code. If error status code comes from
|
||||
backend server, the custom error pages are not used.
|
||||
--server-name=<NAME>
|
||||
Change server response header field value to <NAME>.
|
||||
Default: )" << get_config()->http.server_name << R"(
|
||||
|
||||
API:
|
||||
--api-max-request-body=<SIZE>
|
||||
|
@ -2396,7 +2399,7 @@ int process_options(Config *config,
|
|||
|
||||
if (listenerconf.addrs.empty()) {
|
||||
UpstreamAddr addr{};
|
||||
addr.host = "*";
|
||||
addr.host = ImmutableString::from_lit("*");
|
||||
addr.port = 3000;
|
||||
addr.tls = true;
|
||||
addr.family = AF_INET;
|
||||
|
@ -2833,6 +2836,7 @@ int main(int argc, char **argv) {
|
|||
&flag, 125},
|
||||
{SHRPX_OPT_API_MAX_REQUEST_BODY.c_str(), required_argument, &flag, 126},
|
||||
{SHRPX_OPT_BACKEND_MAX_BACKOFF.c_str(), required_argument, &flag, 127},
|
||||
{SHRPX_OPT_SERVER_NAME.c_str(), required_argument, &flag, 128},
|
||||
{nullptr, 0, nullptr, 0}};
|
||||
|
||||
int option_index = 0;
|
||||
|
@ -2935,7 +2939,7 @@ int main(int argc, char **argv) {
|
|||
break;
|
||||
case 12:
|
||||
// --conf
|
||||
mod_config()->conf_path = optarg;
|
||||
mod_config()->conf_path = ImmutableString{optarg};
|
||||
break;
|
||||
case 14:
|
||||
// --syslog-facility
|
||||
|
@ -3430,6 +3434,10 @@ int main(int argc, char **argv) {
|
|||
// --backend-max-backoff
|
||||
cmdcfgs.emplace_back(SHRPX_OPT_BACKEND_MAX_BACKOFF, StringRef{optarg});
|
||||
break;
|
||||
case 128:
|
||||
// --server-name
|
||||
cmdcfgs.emplace_back(SHRPX_OPT_SERVER_NAME, StringRef{optarg});
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -1127,6 +1127,11 @@ int option_lookup_token(const char *name, size_t namelen) {
|
|||
break;
|
||||
case 11:
|
||||
switch (name[10]) {
|
||||
case 'e':
|
||||
if (util::strieq_l("server-nam", name, 10)) {
|
||||
return SHRPX_OPTID_SERVER_NAME;
|
||||
}
|
||||
break;
|
||||
case 's':
|
||||
if (util::strieq_l("backend-tl", name, 10)) {
|
||||
return SHRPX_OPTID_BACKEND_TLS;
|
||||
|
@ -2027,7 +2032,7 @@ int parse_config(Config *config, int optid, const StringRef &opt,
|
|||
<< strerror(errno);
|
||||
return -1;
|
||||
}
|
||||
config->user = pwd->pw_name;
|
||||
config->user = ImmutableString{pwd->pw_name};
|
||||
config->uid = pwd->pw_uid;
|
||||
config->gid = pwd->pw_gid;
|
||||
|
||||
|
@ -2044,7 +2049,7 @@ int parse_config(Config *config, int optid, const StringRef &opt,
|
|||
LOG(ERROR) << opt << ": Couldn't read key file's passwd from " << optarg;
|
||||
return -1;
|
||||
}
|
||||
config->tls.private_key_passwd = passwd;
|
||||
config->tls.private_key_passwd = ImmutableString{passwd};
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -2479,14 +2484,14 @@ int parse_config(Config *config, int optid, const StringRef &opt,
|
|||
switch (optid) {
|
||||
case SHRPX_OPTID_TLS_SESSION_CACHE_MEMCACHED: {
|
||||
auto &memcachedconf = config->tls.session_cache.memcached;
|
||||
memcachedconf.host = host;
|
||||
memcachedconf.host = ImmutableString{host};
|
||||
memcachedconf.port = port;
|
||||
memcachedconf.tls = params.tls;
|
||||
break;
|
||||
}
|
||||
case SHRPX_OPTID_TLS_TICKET_KEY_MEMCACHED: {
|
||||
auto &memcachedconf = config->tls.ticket.memcached;
|
||||
memcachedconf.host = host;
|
||||
memcachedconf.host = ImmutableString{host};
|
||||
memcachedconf.port = port;
|
||||
memcachedconf.tls = params.tls;
|
||||
break;
|
||||
|
@ -2673,6 +2678,11 @@ int parse_config(Config *config, int optid, const StringRef &opt,
|
|||
case SHRPX_OPTID_BACKEND_MAX_BACKOFF:
|
||||
return parse_duration(&config->conn.downstream->timeout.max_backoff, opt,
|
||||
optarg);
|
||||
case SHRPX_OPTID_SERVER_NAME:
|
||||
config->http.server_name =
|
||||
ImmutableString{std::begin(optarg), std::end(optarg)};
|
||||
|
||||
return 0;
|
||||
case SHRPX_OPTID_CONF:
|
||||
LOG(WARN) << "conf: ignored";
|
||||
|
||||
|
@ -2948,7 +2958,7 @@ int configure_downstream_group(Config *config, bool http2_proxy,
|
|||
auto &sni = tlsconf.backend_sni_name;
|
||||
for (auto &addr_group : addr_groups) {
|
||||
for (auto &addr : addr_group.addrs) {
|
||||
addr.sni = sni;
|
||||
addr.sni = ImmutableString{sni};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2995,7 +3005,7 @@ int configure_downstream_group(Config *config, bool http2_proxy,
|
|||
// for AF_UNIX socket, we use "localhost" as host for backend
|
||||
// hostport. This is used as Host header field to backend and
|
||||
// not going to be passed to any syscalls.
|
||||
addr.hostport = "localhost";
|
||||
addr.hostport = ImmutableString::from_lit("localhost");
|
||||
|
||||
auto path = addr.host.c_str();
|
||||
auto pathlen = addr.host.size();
|
||||
|
|
|
@ -284,6 +284,7 @@ constexpr auto SHRPX_OPT_API_MAX_REQUEST_BODY =
|
|||
StringRef::from_lit("api-max-request-body");
|
||||
constexpr auto SHRPX_OPT_BACKEND_MAX_BACKOFF =
|
||||
StringRef::from_lit("backend-max-backoff");
|
||||
constexpr auto SHRPX_OPT_SERVER_NAME = StringRef::from_lit("server-name");
|
||||
|
||||
constexpr size_t SHRPX_OBFUSCATED_NODE_LENGTH = 8;
|
||||
|
||||
|
@ -552,7 +553,7 @@ struct HttpConfig {
|
|||
std::vector<ErrorPage> error_pages;
|
||||
Headers add_request_headers;
|
||||
Headers add_response_headers;
|
||||
StringRef server_name;
|
||||
ImmutableString server_name;
|
||||
size_t request_header_field_buffer;
|
||||
size_t max_request_header_fields;
|
||||
size_t response_header_field_buffer;
|
||||
|
@ -706,8 +707,14 @@ struct APIConfig {
|
|||
};
|
||||
|
||||
struct Config {
|
||||
Config() = default;
|
||||
~Config();
|
||||
|
||||
Config(Config &&) = delete;
|
||||
Config(const Config &&) = delete;
|
||||
Config &operator=(Config &&) = delete;
|
||||
Config &operator=(const Config &&) = delete;
|
||||
|
||||
HttpProxy downstream_http_proxy;
|
||||
HttpConfig http;
|
||||
Http2Config http2;
|
||||
|
@ -837,6 +844,7 @@ enum {
|
|||
SHRPX_OPTID_REQUEST_HEADER_FIELD_BUFFER,
|
||||
SHRPX_OPTID_RESPONSE_HEADER_FIELD_BUFFER,
|
||||
SHRPX_OPTID_RLIMIT_NOFILE,
|
||||
SHRPX_OPTID_SERVER_NAME,
|
||||
SHRPX_OPTID_STREAM_READ_TIMEOUT,
|
||||
SHRPX_OPTID_STREAM_WRITE_TIMEOUT,
|
||||
SHRPX_OPTID_STRIP_INCOMING_FORWARDED,
|
||||
|
|
|
@ -51,7 +51,7 @@ StringRef create_error_html(BlockAllocator &balloc, unsigned int http_status) {
|
|||
return concat_string_ref(
|
||||
balloc, StringRef::from_lit(R"(<!DOCTYPE html><html lang="en"><title>)"),
|
||||
status_string, StringRef::from_lit("</title><body><h1>"), status_string,
|
||||
StringRef::from_lit("</h1><footer>"), server_name,
|
||||
StringRef::from_lit("</h1><footer>"), StringRef{server_name},
|
||||
StringRef::from_lit("</footer></body></html>"));
|
||||
}
|
||||
|
||||
|
|
|
@ -1806,9 +1806,11 @@ int Http2Session::read_noop(const uint8_t *data, size_t datalen) { return 0; }
|
|||
int Http2Session::write_noop() { return 0; }
|
||||
|
||||
int Http2Session::connected() {
|
||||
if (!util::check_socket_connected(conn_.fd)) {
|
||||
auto sock_error = util::get_socket_error(conn_.fd);
|
||||
if (sock_error != 0) {
|
||||
SSLOG(WARN, this) << "Backend connect failed; addr="
|
||||
<< util::to_numeric_addr(&addr_->addr);
|
||||
<< util::to_numeric_addr(&addr_->addr)
|
||||
<< ": errno=" << sock_error;
|
||||
|
||||
downstream_failure(addr_);
|
||||
|
||||
|
|
|
@ -1307,8 +1307,8 @@ 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()->http.server_name));
|
||||
nva.push_back(http2::make_nv_ls_nocopy(
|
||||
"server", StringRef{get_config()->http.server_name}));
|
||||
}
|
||||
|
||||
for (auto &p : httpconf.add_response_headers) {
|
||||
|
@ -1359,7 +1359,8 @@ int Http2Upstream::error_reply(Downstream *downstream,
|
|||
auto nva = std::array<nghttp2_nv, 5>{
|
||||
{http2::make_nv_ls_nocopy(":status", response_status),
|
||||
http2::make_nv_ll("content-type", "text/html; charset=UTF-8"),
|
||||
http2::make_nv_ls_nocopy("server", get_config()->http.server_name),
|
||||
http2::make_nv_ls_nocopy("server",
|
||||
StringRef{get_config()->http.server_name}),
|
||||
http2::make_nv_ls_nocopy("content-length", content_length),
|
||||
http2::make_nv_ls_nocopy("date", date)}};
|
||||
|
||||
|
@ -1506,7 +1507,8 @@ int Http2Upstream::on_downstream_header_complete(Downstream *downstream) {
|
|||
http2::copy_headers_to_nva_nocopy(nva, resp.fs.headers());
|
||||
|
||||
if (!get_config()->http2_proxy) {
|
||||
nva.push_back(http2::make_nv_ls_nocopy("server", httpconf.server_name));
|
||||
nva.push_back(
|
||||
http2::make_nv_ls_nocopy("server", StringRef{httpconf.server_name}));
|
||||
} else {
|
||||
auto server = resp.fs.header(http2::HD_SERVER);
|
||||
if (server) {
|
||||
|
|
|
@ -994,6 +994,8 @@ int HttpDownstreamConnection::tls_handshake() {
|
|||
|
||||
auto &connect_blocker = addr_->connect_blocker;
|
||||
|
||||
do_signal_write_ = &HttpDownstreamConnection::actual_signal_write;
|
||||
|
||||
connect_blocker->on_success();
|
||||
|
||||
ev_set_cb(&conn_.rt, timeoutcb);
|
||||
|
@ -1141,11 +1143,13 @@ int HttpDownstreamConnection::process_input(const uint8_t *data,
|
|||
int HttpDownstreamConnection::connected() {
|
||||
auto &connect_blocker = addr_->connect_blocker;
|
||||
|
||||
if (!util::check_socket_connected(conn_.fd)) {
|
||||
auto sock_error = util::get_socket_error(conn_.fd);
|
||||
if (sock_error != 0) {
|
||||
conn_.wlimit.stopw();
|
||||
|
||||
DCLOG(WARN, this) << "Backend connect failed; addr="
|
||||
<< util::to_numeric_addr(&addr_->addr);
|
||||
<< util::to_numeric_addr(&addr_->addr)
|
||||
<< ": errno=" << sock_error;
|
||||
|
||||
downstream_failure(addr_);
|
||||
|
||||
|
@ -1160,8 +1164,6 @@ int HttpDownstreamConnection::connected() {
|
|||
|
||||
ev_set_cb(&conn_.wev, writecb);
|
||||
|
||||
do_signal_write_ = &HttpDownstreamConnection::actual_signal_write;
|
||||
|
||||
if (conn_.tls.ssl) {
|
||||
do_read_ = &HttpDownstreamConnection::tls_handshake;
|
||||
do_write_ = &HttpDownstreamConnection::tls_handshake;
|
||||
|
@ -1169,6 +1171,8 @@ int HttpDownstreamConnection::connected() {
|
|||
return 0;
|
||||
}
|
||||
|
||||
do_signal_write_ = &HttpDownstreamConnection::actual_signal_write;
|
||||
|
||||
connect_blocker->on_success();
|
||||
|
||||
ev_set_cb(&conn_.rt, timeoutcb);
|
||||
|
|
|
@ -259,10 +259,12 @@ int LiveCheck::initiate_connection() {
|
|||
}
|
||||
|
||||
int LiveCheck::connected() {
|
||||
if (!util::check_socket_connected(conn_.fd)) {
|
||||
auto sock_error = util::get_socket_error(conn_.fd);
|
||||
if (sock_error != 0) {
|
||||
if (LOG_ENABLED(INFO)) {
|
||||
LOG(INFO) << "Backend connect failed; addr="
|
||||
<< util::to_numeric_addr(&addr_->addr);
|
||||
<< util::to_numeric_addr(&addr_->addr)
|
||||
<< ": errno=" << sock_error;
|
||||
}
|
||||
|
||||
return -1;
|
||||
|
|
|
@ -203,15 +203,16 @@ int MemcachedConnection::initiate_connection() {
|
|||
}
|
||||
|
||||
int MemcachedConnection::connected() {
|
||||
if (!util::check_socket_connected(conn_.fd)) {
|
||||
auto sock_error = util::get_socket_error(conn_.fd);
|
||||
if (sock_error != 0) {
|
||||
MCLOG(WARN, this) << "memcached connect failed; addr="
|
||||
<< util::to_numeric_addr(addr_)
|
||||
<< ": errno=" << sock_error;
|
||||
|
||||
connect_blocker_.on_failure();
|
||||
|
||||
conn_.wlimit.stopw();
|
||||
|
||||
if (LOG_ENABLED(INFO)) {
|
||||
MCLOG(INFO, this) << "memcached connect failed";
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -255,8 +255,9 @@ public:
|
|||
ImmutableString() : len(0), base("") {}
|
||||
ImmutableString(const char *s, size_t slen)
|
||||
: len(slen), base(copystr(s, s + len)) {}
|
||||
ImmutableString(const char *s) : len(strlen(s)), base(copystr(s, s + len)) {}
|
||||
ImmutableString(const std::string &s)
|
||||
explicit ImmutableString(const char *s)
|
||||
: len(strlen(s)), base(copystr(s, s + len)) {}
|
||||
explicit ImmutableString(const std::string &s)
|
||||
: len(s.size()), base(copystr(std::begin(s), std::end(s))) {}
|
||||
template <typename InputIt>
|
||||
ImmutableString(InputIt first, InputIt last)
|
||||
|
|
|
@ -156,7 +156,7 @@ void test_template_string_ref(void) {
|
|||
CU_ASSERT(5 == from_lit.size());
|
||||
|
||||
// from ImmutableString
|
||||
ImmutableString im = "bravo";
|
||||
auto im = ImmutableString::from_lit("bravo");
|
||||
|
||||
StringRef imref(im);
|
||||
|
||||
|
|
10
src/util.cc
10
src/util.cc
|
@ -893,6 +893,16 @@ bool check_socket_connected(int fd) {
|
|||
return error == 0;
|
||||
}
|
||||
|
||||
int get_socket_error(int fd) {
|
||||
int error;
|
||||
socklen_t len = sizeof(error);
|
||||
if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
bool ipv6_numeric_addr(const char *host) {
|
||||
uint8_t dst[16];
|
||||
return inet_pton(AF_INET6, host, dst) == 1;
|
||||
|
|
|
@ -574,6 +574,11 @@ int create_nonblock_socket(int family);
|
|||
|
||||
bool check_socket_connected(int fd);
|
||||
|
||||
// Returns the error code (errno) by inspecting SO_ERROR of given
|
||||
// |fd|. This function returns the error code if it succeeds, or -1.
|
||||
// Returning 0 means no error.
|
||||
int get_socket_error(int fd);
|
||||
|
||||
// Returns true if |host| is IPv6 numeric address (e.g., ::1)
|
||||
bool ipv6_numeric_addr(const char *host);
|
||||
|
||||
|
|
Loading…
Reference in New Issue