nghttpx: Log :authority as $http_host if available
This commit is contained in:
parent
b915c24704
commit
d9f73c36c3
|
@ -515,8 +515,16 @@ std::vector<LogFragment> parse_log_format(const char *optarg) {
|
||||||
|
|
||||||
if (type == SHRPX_LOGF_NONE) {
|
if (type == SHRPX_LOGF_NONE) {
|
||||||
if (util::istartsWith(var_name, var_namelen, "http_")) {
|
if (util::istartsWith(var_name, var_namelen, "http_")) {
|
||||||
|
if (util::streq("host", var_name + str_size("http_"),
|
||||||
|
var_namelen - str_size("http_"))) {
|
||||||
|
// Special handling of host header field. We will use
|
||||||
|
// :authority header field if host header is missing. This
|
||||||
|
// is a typical case in HTTP/2.
|
||||||
|
type = SHRPX_LOGF_AUTHORITY;
|
||||||
|
} else {
|
||||||
type = SHRPX_LOGF_HTTP;
|
type = SHRPX_LOGF_HTTP;
|
||||||
value = var_name + str_size("http_");
|
value = var_name + str_size("http_");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
LOG(WARN) << "Unrecognized log format variable: "
|
LOG(WARN) << "Unrecognized log format variable: "
|
||||||
<< std::string(var_name, var_namelen);
|
<< std::string(var_name, var_namelen);
|
||||||
|
|
|
@ -62,10 +62,11 @@ void test_shrpx_config_parse_header(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_shrpx_config_parse_log_format(void) {
|
void test_shrpx_config_parse_log_format(void) {
|
||||||
auto res = parse_log_format(R"($remote_addr - $remote_user [$time_local] )"
|
auto res =
|
||||||
|
parse_log_format(R"($remote_addr - $remote_user [$time_local] )"
|
||||||
R"("$request" $status $body_bytes_sent )"
|
R"("$request" $status $body_bytes_sent )"
|
||||||
R"("${http_referer}" "$http_user_agent")");
|
R"("${http_referer}" $http_host "$http_user_agent")");
|
||||||
CU_ASSERT(14 == res.size());
|
CU_ASSERT(16 == res.size());
|
||||||
|
|
||||||
CU_ASSERT(SHRPX_LOGF_REMOTE_ADDR == res[0].type);
|
CU_ASSERT(SHRPX_LOGF_REMOTE_ADDR == res[0].type);
|
||||||
|
|
||||||
|
@ -96,14 +97,19 @@ void test_shrpx_config_parse_log_format(void) {
|
||||||
CU_ASSERT(0 == strcmp("referer", res[10].value.get()));
|
CU_ASSERT(0 == strcmp("referer", res[10].value.get()));
|
||||||
|
|
||||||
CU_ASSERT(SHRPX_LOGF_LITERAL == res[11].type);
|
CU_ASSERT(SHRPX_LOGF_LITERAL == res[11].type);
|
||||||
CU_ASSERT(0 == strcmp("\" \"", res[11].value.get()));
|
CU_ASSERT(0 == strcmp("\" ", res[11].value.get()));
|
||||||
|
|
||||||
CU_ASSERT(SHRPX_LOGF_HTTP == res[12].type);
|
CU_ASSERT(SHRPX_LOGF_AUTHORITY == res[12].type);
|
||||||
CU_ASSERT(0 == strcmp("user-agent", res[12].value.get()));
|
|
||||||
|
|
||||||
CU_ASSERT(SHRPX_LOGF_LITERAL == res[13].type);
|
CU_ASSERT(SHRPX_LOGF_LITERAL == res[13].type);
|
||||||
CU_ASSERT(0 == strcmp(" \"", res[13].value.get()));
|
CU_ASSERT(0 == strcmp(" \"", res[13].value.get()));
|
||||||
|
|
||||||
|
CU_ASSERT(SHRPX_LOGF_HTTP == res[14].type);
|
||||||
|
CU_ASSERT(0 == strcmp("user-agent", res[14].value.get()));
|
||||||
|
|
||||||
|
CU_ASSERT(SHRPX_LOGF_LITERAL == res[15].type);
|
||||||
|
CU_ASSERT(0 == strcmp("\"", res[15].value.get()));
|
||||||
|
|
||||||
res = parse_log_format("$");
|
res = parse_log_format("$");
|
||||||
|
|
||||||
CU_ASSERT(1 == res.size());
|
CU_ASSERT(1 == res.size());
|
||||||
|
|
|
@ -158,14 +158,38 @@ Log::~Log() {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
template <typename OutputIterator>
|
template <typename OutputIterator>
|
||||||
std::pair<OutputIterator, size_t> copy(const char *src, size_t avail,
|
std::pair<OutputIterator, size_t> copy(const char *src, size_t srclen,
|
||||||
OutputIterator oitr) {
|
size_t avail, OutputIterator oitr) {
|
||||||
auto nwrite = std::min(strlen(src), avail);
|
auto nwrite = std::min(srclen, avail);
|
||||||
auto noitr = std::copy_n(src, nwrite, oitr);
|
auto noitr = std::copy_n(src, nwrite, oitr);
|
||||||
return std::make_pair(noitr, avail - nwrite);
|
return std::make_pair(noitr, avail - nwrite);
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
template <typename OutputIterator>
|
||||||
|
std::pair<OutputIterator, size_t> copy(const char *src, size_t avail,
|
||||||
|
OutputIterator oitr) {
|
||||||
|
return copy(src, strlen(src), avail, oitr);
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
template <typename OutputIterator>
|
||||||
|
std::pair<OutputIterator, size_t> copy(const std::string &src, size_t avail,
|
||||||
|
OutputIterator oitr) {
|
||||||
|
return copy(src.c_str(), src.size(), avail, oitr);
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
template <size_t N, typename OutputIterator>
|
||||||
|
std::pair<OutputIterator, size_t> copy_l(const char (&src)[N], size_t avail,
|
||||||
|
OutputIterator oitr) {
|
||||||
|
return copy(src, N - 1, avail, oitr);
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
const char LOWER_XDIGITS[] = "0123456789abcdef";
|
const char LOWER_XDIGITS[] = "0123456789abcdef";
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -212,46 +236,57 @@ void upstream_accesslog(const std::vector<LogFragment> &lfv,
|
||||||
std::tie(p, avail) = copy(lgsp.remote_addr, avail, p);
|
std::tie(p, avail) = copy(lgsp.remote_addr, avail, p);
|
||||||
break;
|
break;
|
||||||
case SHRPX_LOGF_TIME_LOCAL:
|
case SHRPX_LOGF_TIME_LOCAL:
|
||||||
std::tie(p, avail) = copy(time_local.c_str(), avail, p);
|
std::tie(p, avail) = copy(time_local, avail, p);
|
||||||
break;
|
break;
|
||||||
case SHRPX_LOGF_TIME_ISO8601:
|
case SHRPX_LOGF_TIME_ISO8601:
|
||||||
std::tie(p, avail) = copy(time_iso8601.c_str(), avail, p);
|
std::tie(p, avail) = copy(time_iso8601, avail, p);
|
||||||
break;
|
break;
|
||||||
case SHRPX_LOGF_REQUEST:
|
case SHRPX_LOGF_REQUEST:
|
||||||
std::tie(p, avail) = copy(lgsp.method, avail, p);
|
std::tie(p, avail) = copy(lgsp.method, avail, p);
|
||||||
std::tie(p, avail) = copy(" ", avail, p);
|
std::tie(p, avail) = copy_l(" ", avail, p);
|
||||||
std::tie(p, avail) = copy(lgsp.path, avail, p);
|
std::tie(p, avail) = copy(lgsp.path, avail, p);
|
||||||
std::tie(p, avail) = copy(" HTTP/", avail, p);
|
std::tie(p, avail) = copy_l(" HTTP/", avail, p);
|
||||||
std::tie(p, avail) = copy(util::utos(lgsp.major).c_str(), avail, p);
|
std::tie(p, avail) = copy(util::utos(lgsp.major), avail, p);
|
||||||
if (lgsp.major < 2) {
|
if (lgsp.major < 2) {
|
||||||
std::tie(p, avail) = copy(".", avail, p);
|
std::tie(p, avail) = copy_l(".", avail, p);
|
||||||
std::tie(p, avail) = copy(util::utos(lgsp.minor).c_str(), avail, p);
|
std::tie(p, avail) = copy(util::utos(lgsp.minor), avail, p);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SHRPX_LOGF_STATUS:
|
case SHRPX_LOGF_STATUS:
|
||||||
std::tie(p, avail) = copy(util::utos(lgsp.status).c_str(), avail, p);
|
std::tie(p, avail) = copy(util::utos(lgsp.status), avail, p);
|
||||||
break;
|
break;
|
||||||
case SHRPX_LOGF_BODY_BYTES_SENT:
|
case SHRPX_LOGF_BODY_BYTES_SENT:
|
||||||
std::tie(p, avail) =
|
std::tie(p, avail) = copy(util::utos(lgsp.body_bytes_sent), avail, p);
|
||||||
copy(util::utos(lgsp.body_bytes_sent).c_str(), avail, p);
|
|
||||||
break;
|
break;
|
||||||
case SHRPX_LOGF_HTTP:
|
case SHRPX_LOGF_HTTP:
|
||||||
if (downstream) {
|
if (downstream) {
|
||||||
auto hd = downstream->get_request_header(lf.value.get());
|
auto hd = downstream->get_request_header(lf.value.get());
|
||||||
if (hd) {
|
if (hd) {
|
||||||
std::tie(p, avail) = copy((*hd).value.c_str(), avail, p);
|
std::tie(p, avail) = copy((*hd).value, avail, p);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::tie(p, avail) = copy("-", avail, p);
|
std::tie(p, avail) = copy_l("-", avail, p);
|
||||||
|
|
||||||
|
break;
|
||||||
|
case SHRPX_LOGF_AUTHORITY:
|
||||||
|
if (downstream) {
|
||||||
|
auto &authority = downstream->get_request_http2_authority();
|
||||||
|
if (!authority.empty()) {
|
||||||
|
std::tie(p, avail) = copy(authority, avail, p);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::tie(p, avail) = copy_l("-", avail, p);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case SHRPX_LOGF_REMOTE_PORT:
|
case SHRPX_LOGF_REMOTE_PORT:
|
||||||
std::tie(p, avail) = copy(lgsp.remote_port, avail, p);
|
std::tie(p, avail) = copy(lgsp.remote_port, avail, p);
|
||||||
break;
|
break;
|
||||||
case SHRPX_LOGF_SERVER_PORT:
|
case SHRPX_LOGF_SERVER_PORT:
|
||||||
std::tie(p, avail) = copy(util::utos(lgsp.server_port).c_str(), avail, p);
|
std::tie(p, avail) = copy(util::utos(lgsp.server_port), avail, p);
|
||||||
break;
|
break;
|
||||||
case SHRPX_LOGF_REQUEST_TIME: {
|
case SHRPX_LOGF_REQUEST_TIME: {
|
||||||
auto t = std::chrono::duration_cast<std::chrono::milliseconds>(
|
auto t = std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||||
|
@ -265,31 +300,31 @@ void upstream_accesslog(const std::vector<LogFragment> &lfv,
|
||||||
sec += ".";
|
sec += ".";
|
||||||
sec += frac;
|
sec += frac;
|
||||||
|
|
||||||
std::tie(p, avail) = copy(sec.c_str(), avail, p);
|
std::tie(p, avail) = copy(sec, avail, p);
|
||||||
} break;
|
} break;
|
||||||
case SHRPX_LOGF_PID:
|
case SHRPX_LOGF_PID:
|
||||||
std::tie(p, avail) = copy(util::utos(lgsp.pid).c_str(), avail, p);
|
std::tie(p, avail) = copy(util::utos(lgsp.pid), avail, p);
|
||||||
break;
|
break;
|
||||||
case SHRPX_LOGF_ALPN:
|
case SHRPX_LOGF_ALPN:
|
||||||
std::tie(p, avail) = copy(lgsp.alpn, avail, p);
|
std::tie(p, avail) = copy(lgsp.alpn, avail, p);
|
||||||
break;
|
break;
|
||||||
case SHRPX_LOGF_SSL_CIPHER:
|
case SHRPX_LOGF_SSL_CIPHER:
|
||||||
if (!lgsp.tls_info) {
|
if (!lgsp.tls_info) {
|
||||||
std::tie(p, avail) = copy("-", avail, p);
|
std::tie(p, avail) = copy_l("-", avail, p);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
std::tie(p, avail) = copy(lgsp.tls_info->cipher, avail, p);
|
std::tie(p, avail) = copy(lgsp.tls_info->cipher, avail, p);
|
||||||
break;
|
break;
|
||||||
case SHRPX_LOGF_SSL_PROTOCOL:
|
case SHRPX_LOGF_SSL_PROTOCOL:
|
||||||
if (!lgsp.tls_info) {
|
if (!lgsp.tls_info) {
|
||||||
std::tie(p, avail) = copy("-", avail, p);
|
std::tie(p, avail) = copy_l("-", avail, p);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
std::tie(p, avail) = copy(lgsp.tls_info->protocol, avail, p);
|
std::tie(p, avail) = copy(lgsp.tls_info->protocol, avail, p);
|
||||||
break;
|
break;
|
||||||
case SHRPX_LOGF_SSL_SESSION_ID:
|
case SHRPX_LOGF_SSL_SESSION_ID:
|
||||||
if (!lgsp.tls_info || lgsp.tls_info->session_id_length == 0) {
|
if (!lgsp.tls_info || lgsp.tls_info->session_id_length == 0) {
|
||||||
std::tie(p, avail) = copy("-", avail, p);
|
std::tie(p, avail) = copy_l("-", avail, p);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
std::tie(p, avail) =
|
std::tie(p, avail) =
|
||||||
|
@ -298,11 +333,11 @@ void upstream_accesslog(const std::vector<LogFragment> &lfv,
|
||||||
break;
|
break;
|
||||||
case SHRPX_LOGF_SSL_SESSION_REUSED:
|
case SHRPX_LOGF_SSL_SESSION_REUSED:
|
||||||
if (!lgsp.tls_info) {
|
if (!lgsp.tls_info) {
|
||||||
std::tie(p, avail) = copy("-", avail, p);
|
std::tie(p, avail) = copy_l("-", avail, p);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
std::tie(p, avail) =
|
std::tie(p, avail) =
|
||||||
copy(lgsp.tls_info->session_reused ? "r" : ".", avail, p);
|
copy_l(lgsp.tls_info->session_reused ? "r" : ".", avail, p);
|
||||||
break;
|
break;
|
||||||
case SHRPX_LOGF_NONE:
|
case SHRPX_LOGF_NONE:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -118,6 +118,7 @@ enum LogFragmentType {
|
||||||
SHRPX_LOGF_STATUS,
|
SHRPX_LOGF_STATUS,
|
||||||
SHRPX_LOGF_BODY_BYTES_SENT,
|
SHRPX_LOGF_BODY_BYTES_SENT,
|
||||||
SHRPX_LOGF_HTTP,
|
SHRPX_LOGF_HTTP,
|
||||||
|
SHRPX_LOGF_AUTHORITY,
|
||||||
SHRPX_LOGF_REMOTE_PORT,
|
SHRPX_LOGF_REMOTE_PORT,
|
||||||
SHRPX_LOGF_SERVER_PORT,
|
SHRPX_LOGF_SERVER_PORT,
|
||||||
SHRPX_LOGF_REQUEST_TIME,
|
SHRPX_LOGF_REQUEST_TIME,
|
||||||
|
|
Loading…
Reference in New Issue