From 7f7b6d641d35083f4ed66c11d5c031dc7060a107 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Tue, 14 Jul 2015 22:25:52 +0900 Subject: [PATCH] nghttpx: Allow log variable to be enclosed by curly braces --- src/shrpx.cc | 3 ++ src/shrpx_config.cc | 80 ++++++++++++++++++++++++---------------- src/shrpx_config_test.cc | 44 ++++++++++++++++++++-- 3 files changed, 93 insertions(+), 34 deletions(-) diff --git a/src/shrpx.cc b/src/shrpx.cc index 7160bf6c..d458ed68 100644 --- a/src/shrpx.cc +++ b/src/shrpx.cc @@ -1407,6 +1407,9 @@ Logging: * $ssl_session_reused: "r" if SSL/TLS session was reused. Otherwise, "." + The variable can be enclosed by "{" and "}" for + disambiguation (e.g., ${remote_addr}). + Default: )" << DEFAULT_ACCESSLOG_FORMAT << R"( --errorlog-file= Set path to write error log. To reopen file, send USR1 diff --git a/src/shrpx_config.cc b/src/shrpx_config.cc index 6a978b1c..c1501dff 100644 --- a/src/shrpx_config.cc +++ b/src/shrpx_config.cc @@ -370,52 +370,69 @@ std::vector parse_log_format(const char *optarg) { ++p; - for (; p != eop && var_token(*p); ++p) - ; + const char *var_name; + size_t var_namelen; + if (p != eop && *p == '{') { + var_name = ++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; const char *value = nullptr; 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; - } 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; - } 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; - } else if (util::strieq_l("$request", var_start, varlen)) { + } else if (util::strieq_l("request", var_name, var_namelen)) { 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; - } 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; - } else if (util::istartsWith(var_start, varlen, "$http_")) { + } else if (util::istartsWith(var_name, var_namelen, "http_")) { type = SHRPX_LOGF_HTTP; - value = var_start + sizeof("$http_") - 1; - valuelen = varlen - (sizeof("$http_") - 1); - } else if (util::strieq_l("$remote_port", var_start, varlen)) { + value = var_name + sizeof("http_") - 1; + valuelen = var_namelen - (sizeof("http_") - 1); + } else if (util::strieq_l("remote_port", var_name, var_namelen)) { 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; - } 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; - } else if (util::strieq_l("$pid", var_start, varlen)) { + } else if (util::strieq_l("pid", var_name, var_namelen)) { 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; - } 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; - } 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; - } 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; - } 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; } else { LOG(WARN) << "Unrecognized log format variable: " - << std::string(var_start, varlen); + << std::string(var_name, var_namelen); continue; } @@ -425,19 +442,20 @@ std::vector parse_log_format(const char *optarg) { strcopy(literal_start, var_start - literal_start))); } + literal_start = p; + if (value == nullptr) { res.push_back(make_log_fragment(type)); - } else { - res.push_back(make_log_fragment(type, strcopy(value, valuelen))); - auto &v = res.back().value; - for (size_t i = 0; v[i]; ++i) { - if (v[i] == '_') { - v[i] = '-'; - } - } + continue; } - literal_start = var_start + varlen; + res.push_back(make_log_fragment(type, strcopy(value, valuelen))); + auto &v = res.back().value; + for (size_t i = 0; v[i]; ++i) { + if (v[i] == '_') { + v[i] = '-'; + } + } } if (literal_start != eop) { diff --git a/src/shrpx_config_test.cc b/src/shrpx_config_test.cc index ab6a0f27..c5116294 100644 --- a/src/shrpx_config_test.cc +++ b/src/shrpx_config_test.cc @@ -95,9 +95,9 @@ void test_shrpx_config_parse_header(void) { } void test_shrpx_config_parse_log_format(void) { - auto res = parse_log_format("$remote_addr - $remote_user [$time_local] " - "\"$request\" $status $body_bytes_sent " - "\"$http_referer\" \"$http_user_agent\""); + auto res = parse_log_format(R"($remote_addr - $remote_user [$time_local] )" + R"("$request" $status $body_bytes_sent )" + R"("${http_referer}" "$http_user_agent")"); CU_ASSERT(14 == res.size()); 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(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) {