nghttpx: Allow log variable to be enclosed by curly braces

This commit is contained in:
Tatsuhiro Tsujikawa 2015-07-14 22:25:52 +09:00
parent 7c301defbd
commit 7f7b6d641d
3 changed files with 93 additions and 34 deletions

View File

@ -1407,6 +1407,9 @@ Logging:
* $ssl_session_reused: "r" if SSL/TLS session was * $ssl_session_reused: "r" if SSL/TLS session was
reused. Otherwise, "." reused. Otherwise, "."
The variable can be enclosed by "{" and "}" for
disambiguation (e.g., ${remote_addr}).
Default: )" << DEFAULT_ACCESSLOG_FORMAT << R"( Default: )" << DEFAULT_ACCESSLOG_FORMAT << R"(
--errorlog-file=<PATH> --errorlog-file=<PATH>
Set path to write error log. To reopen file, send USR1 Set path to write error log. To reopen file, send USR1

View File

@ -370,52 +370,69 @@ std::vector<LogFragment> parse_log_format(const char *optarg) {
++p; ++p;
const char *var_name;
size_t var_namelen;
if (p != eop && *p == '{') {
var_name = ++p;
for (; p != eop && var_token(*p); ++p) for (; p != eop && var_token(*p); ++p)
; ;
auto varlen = p - var_start; if (p == eop || *p != '}') {
LOG(WARN) << "Missing '}' after " << std::string(var_start, p);
continue;
}
var_namelen = p - var_name;
++p;
} else {
var_name = p;
for (; p != eop && var_token(*p); ++p)
;
var_namelen = p - var_name;
}
auto type = SHRPX_LOGF_NONE; auto type = SHRPX_LOGF_NONE;
const char *value = nullptr; const char *value = nullptr;
size_t valuelen = 0; size_t valuelen = 0;
if (util::strieq_l("$remote_addr", var_start, varlen)) { if (util::strieq_l("remote_addr", var_name, var_namelen)) {
type = SHRPX_LOGF_REMOTE_ADDR; type = SHRPX_LOGF_REMOTE_ADDR;
} else if (util::strieq_l("$time_local", var_start, varlen)) { } else if (util::strieq_l("time_local", var_name, var_namelen)) {
type = SHRPX_LOGF_TIME_LOCAL; type = SHRPX_LOGF_TIME_LOCAL;
} else if (util::strieq_l("$time_iso8601", var_start, varlen)) { } else if (util::strieq_l("time_iso8601", var_name, var_namelen)) {
type = SHRPX_LOGF_TIME_ISO8601; type = SHRPX_LOGF_TIME_ISO8601;
} else if (util::strieq_l("$request", var_start, varlen)) { } else if (util::strieq_l("request", var_name, var_namelen)) {
type = SHRPX_LOGF_REQUEST; type = SHRPX_LOGF_REQUEST;
} else if (util::strieq_l("$status", var_start, varlen)) { } else if (util::strieq_l("status", var_name, var_namelen)) {
type = SHRPX_LOGF_STATUS; type = SHRPX_LOGF_STATUS;
} else if (util::strieq_l("$body_bytes_sent", var_start, varlen)) { } else if (util::strieq_l("body_bytes_sent", var_name, var_namelen)) {
type = SHRPX_LOGF_BODY_BYTES_SENT; type = SHRPX_LOGF_BODY_BYTES_SENT;
} else if (util::istartsWith(var_start, varlen, "$http_")) { } else if (util::istartsWith(var_name, var_namelen, "http_")) {
type = SHRPX_LOGF_HTTP; type = SHRPX_LOGF_HTTP;
value = var_start + sizeof("$http_") - 1; value = var_name + sizeof("http_") - 1;
valuelen = varlen - (sizeof("$http_") - 1); valuelen = var_namelen - (sizeof("http_") - 1);
} else if (util::strieq_l("$remote_port", var_start, varlen)) { } else if (util::strieq_l("remote_port", var_name, var_namelen)) {
type = SHRPX_LOGF_REMOTE_PORT; type = SHRPX_LOGF_REMOTE_PORT;
} else if (util::strieq_l("$server_port", var_start, varlen)) { } else if (util::strieq_l("server_port", var_name, var_namelen)) {
type = SHRPX_LOGF_SERVER_PORT; type = SHRPX_LOGF_SERVER_PORT;
} else if (util::strieq_l("$request_time", var_start, varlen)) { } else if (util::strieq_l("request_time", var_name, var_namelen)) {
type = SHRPX_LOGF_REQUEST_TIME; type = SHRPX_LOGF_REQUEST_TIME;
} else if (util::strieq_l("$pid", var_start, varlen)) { } else if (util::strieq_l("pid", var_name, var_namelen)) {
type = SHRPX_LOGF_PID; type = SHRPX_LOGF_PID;
} else if (util::strieq_l("$alpn", var_start, varlen)) { } else if (util::strieq_l("alpn", var_name, var_namelen)) {
type = SHRPX_LOGF_ALPN; type = SHRPX_LOGF_ALPN;
} else if (util::strieq_l("$ssl_cipher", var_start, varlen)) { } else if (util::strieq_l("ssl_cipher", var_name, var_namelen)) {
type = SHRPX_LOGF_SSL_CIPHER; type = SHRPX_LOGF_SSL_CIPHER;
} else if (util::strieq_l("$ssl_protocol", var_start, varlen)) { } else if (util::strieq_l("ssl_protocol", var_name, var_namelen)) {
type = SHRPX_LOGF_SSL_PROTOCOL; type = SHRPX_LOGF_SSL_PROTOCOL;
} else if (util::strieq_l("$ssl_session_id", var_start, varlen)) { } else if (util::strieq_l("ssl_session_id", var_name, var_namelen)) {
type = SHRPX_LOGF_SSL_SESSION_ID; type = SHRPX_LOGF_SSL_SESSION_ID;
} else if (util::strieq_l("$ssl_session_reused", var_start, varlen)) { } else if (util::strieq_l("ssl_session_reused", var_name, var_namelen)) {
type = SHRPX_LOGF_SSL_SESSION_REUSED; type = SHRPX_LOGF_SSL_SESSION_REUSED;
} else { } else {
LOG(WARN) << "Unrecognized log format variable: " LOG(WARN) << "Unrecognized log format variable: "
<< std::string(var_start, varlen); << std::string(var_name, var_namelen);
continue; continue;
} }
@ -425,9 +442,13 @@ std::vector<LogFragment> parse_log_format(const char *optarg) {
strcopy(literal_start, var_start - literal_start))); strcopy(literal_start, var_start - literal_start)));
} }
literal_start = p;
if (value == nullptr) { if (value == nullptr) {
res.push_back(make_log_fragment(type)); res.push_back(make_log_fragment(type));
} else { continue;
}
res.push_back(make_log_fragment(type, strcopy(value, valuelen))); res.push_back(make_log_fragment(type, strcopy(value, valuelen)));
auto &v = res.back().value; auto &v = res.back().value;
for (size_t i = 0; v[i]; ++i) { for (size_t i = 0; v[i]; ++i) {
@ -437,9 +458,6 @@ std::vector<LogFragment> parse_log_format(const char *optarg) {
} }
} }
literal_start = var_start + varlen;
}
if (literal_start != eop) { if (literal_start != eop) {
res.push_back(make_log_fragment( res.push_back(make_log_fragment(
SHRPX_LOGF_LITERAL, strcopy(literal_start, eop - literal_start))); SHRPX_LOGF_LITERAL, strcopy(literal_start, eop - literal_start)));

View File

@ -95,9 +95,9 @@ 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("$remote_addr - $remote_user [$time_local] " auto res = parse_log_format(R"($remote_addr - $remote_user [$time_local] )"
"\"$request\" $status $body_bytes_sent " R"("$request" $status $body_bytes_sent )"
"\"$http_referer\" \"$http_user_agent\""); R"("${http_referer}" "$http_user_agent")");
CU_ASSERT(14 == res.size()); CU_ASSERT(14 == res.size());
CU_ASSERT(SHRPX_LOGF_REMOTE_ADDR == res[0].type); CU_ASSERT(SHRPX_LOGF_REMOTE_ADDR == res[0].type);
@ -136,6 +136,44 @@ void test_shrpx_config_parse_log_format(void) {
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()));
res = parse_log_format("$");
CU_ASSERT(1 == res.size());
CU_ASSERT(SHRPX_LOGF_LITERAL == res[0].type);
CU_ASSERT(0 == strcmp("$", res[0].value.get()));
res = parse_log_format("${");
CU_ASSERT(1 == res.size());
CU_ASSERT(SHRPX_LOGF_LITERAL == res[0].type);
CU_ASSERT(0 == strcmp("${", res[0].value.get()));
res = parse_log_format("${a");
CU_ASSERT(1 == res.size());
CU_ASSERT(SHRPX_LOGF_LITERAL == res[0].type);
CU_ASSERT(0 == strcmp("${a", res[0].value.get()));
res = parse_log_format("${a ");
CU_ASSERT(1 == res.size());
CU_ASSERT(SHRPX_LOGF_LITERAL == res[0].type);
CU_ASSERT(0 == strcmp("${a ", res[0].value.get()));
res = parse_log_format("$$remote_addr");
CU_ASSERT(2 == res.size());
CU_ASSERT(SHRPX_LOGF_LITERAL == res[0].type);
CU_ASSERT(0 == strcmp("$", res[0].value.get()));
CU_ASSERT(SHRPX_LOGF_REMOTE_ADDR == res[1].type);
CU_ASSERT(nullptr == res[1].value.get());
} }
void test_shrpx_config_read_tls_ticket_key_file(void) { void test_shrpx_config_read_tls_ticket_key_file(void) {