Merge branch 'nghttpx-accesslog-write-early'
This commit is contained in:
commit
91af4ed70d
|
@ -157,6 +157,7 @@ OPTIONS = [
|
||||||
"client-psk-secrets",
|
"client-psk-secrets",
|
||||||
"client-no-http2-cipher-black-list",
|
"client-no-http2-cipher-black-list",
|
||||||
"client-ciphers",
|
"client-ciphers",
|
||||||
|
"accesslog-write-early",
|
||||||
]
|
]
|
||||||
|
|
||||||
LOGVARS = [
|
LOGVARS = [
|
||||||
|
|
10
src/shrpx.cc
10
src/shrpx.cc
|
@ -2307,6 +2307,10 @@ Logging:
|
||||||
|
|
||||||
Default: )"
|
Default: )"
|
||||||
<< DEFAULT_ACCESSLOG_FORMAT << R"(
|
<< DEFAULT_ACCESSLOG_FORMAT << R"(
|
||||||
|
--accesslog-write-early
|
||||||
|
Write access log when response header fields are
|
||||||
|
received from backend rather than when request
|
||||||
|
transaction finishes.
|
||||||
--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
|
||||||
signal to nghttpx. stderr will be redirected to the
|
signal to nghttpx. stderr will be redirected to the
|
||||||
|
@ -3126,6 +3130,7 @@ int main(int argc, char **argv) {
|
||||||
{SHRPX_OPT_CLIENT_NO_HTTP2_CIPHER_BLACK_LIST.c_str(), no_argument,
|
{SHRPX_OPT_CLIENT_NO_HTTP2_CIPHER_BLACK_LIST.c_str(), no_argument,
|
||||||
&flag, 149},
|
&flag, 149},
|
||||||
{SHRPX_OPT_CLIENT_CIPHERS.c_str(), required_argument, &flag, 150},
|
{SHRPX_OPT_CLIENT_CIPHERS.c_str(), required_argument, &flag, 150},
|
||||||
|
{SHRPX_OPT_ACCESSLOG_WRITE_EARLY.c_str(), no_argument, &flag, 151},
|
||||||
{nullptr, 0, nullptr, 0}};
|
{nullptr, 0, nullptr, 0}};
|
||||||
|
|
||||||
int option_index = 0;
|
int option_index = 0;
|
||||||
|
@ -3833,6 +3838,11 @@ int main(int argc, char **argv) {
|
||||||
// --client-ciphers
|
// --client-ciphers
|
||||||
cmdcfgs.emplace_back(SHRPX_OPT_CLIENT_CIPHERS, StringRef{optarg});
|
cmdcfgs.emplace_back(SHRPX_OPT_CLIENT_CIPHERS, StringRef{optarg});
|
||||||
break;
|
break;
|
||||||
|
case 151:
|
||||||
|
// --accesslog-write-early
|
||||||
|
cmdcfgs.emplace_back(SHRPX_OPT_ACCESSLOG_WRITE_EARLY,
|
||||||
|
StringRef::from_lit("yes"));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1786,6 +1786,11 @@ int option_lookup_token(const char *name, size_t namelen) {
|
||||||
return SHRPX_OPTID_FRONTEND_READ_TIMEOUT;
|
return SHRPX_OPTID_FRONTEND_READ_TIMEOUT;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'y':
|
||||||
|
if (util::strieq_l("accesslog-write-earl", name, 20)) {
|
||||||
|
return SHRPX_OPTID_ACCESSLOG_WRITE_EARLY;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 22:
|
case 22:
|
||||||
|
@ -3290,6 +3295,10 @@ int parse_config(Config *config, int optid, const StringRef &opt,
|
||||||
case SHRPX_OPTID_CLIENT_CIPHERS:
|
case SHRPX_OPTID_CLIENT_CIPHERS:
|
||||||
config->tls.client.ciphers = make_string_ref(config->balloc, optarg);
|
config->tls.client.ciphers = make_string_ref(config->balloc, optarg);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
case SHRPX_OPTID_ACCESSLOG_WRITE_EARLY:
|
||||||
|
config->logging.access.write_early = util::strieq_l("yes", optarg);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
case SHRPX_OPTID_CONF:
|
case SHRPX_OPTID_CONF:
|
||||||
LOG(WARN) << "conf: ignored";
|
LOG(WARN) << "conf: ignored";
|
||||||
|
|
|
@ -325,6 +325,8 @@ constexpr auto SHRPX_OPT_CLIENT_PSK_SECRETS =
|
||||||
constexpr auto SHRPX_OPT_CLIENT_NO_HTTP2_CIPHER_BLACK_LIST =
|
constexpr auto SHRPX_OPT_CLIENT_NO_HTTP2_CIPHER_BLACK_LIST =
|
||||||
StringRef::from_lit("client-no-http2-cipher-black-list");
|
StringRef::from_lit("client-no-http2-cipher-black-list");
|
||||||
constexpr auto SHRPX_OPT_CLIENT_CIPHERS = StringRef::from_lit("client-ciphers");
|
constexpr auto SHRPX_OPT_CLIENT_CIPHERS = StringRef::from_lit("client-ciphers");
|
||||||
|
constexpr auto SHRPX_OPT_ACCESSLOG_WRITE_EARLY =
|
||||||
|
StringRef::from_lit("accesslog-write-early");
|
||||||
|
|
||||||
constexpr size_t SHRPX_OBFUSCATED_NODE_LENGTH = 8;
|
constexpr size_t SHRPX_OBFUSCATED_NODE_LENGTH = 8;
|
||||||
|
|
||||||
|
@ -686,6 +688,9 @@ struct LoggingConfig {
|
||||||
StringRef file;
|
StringRef file;
|
||||||
// Send accesslog to syslog, ignoring accesslog_file.
|
// Send accesslog to syslog, ignoring accesslog_file.
|
||||||
bool syslog;
|
bool syslog;
|
||||||
|
// Write accesslog when response headers are received from
|
||||||
|
// backend, rather than response body is received and sent.
|
||||||
|
bool write_early;
|
||||||
} access;
|
} access;
|
||||||
struct {
|
struct {
|
||||||
StringRef file;
|
StringRef file;
|
||||||
|
@ -888,6 +893,7 @@ enum {
|
||||||
SHRPX_OPTID_ACCESSLOG_FILE,
|
SHRPX_OPTID_ACCESSLOG_FILE,
|
||||||
SHRPX_OPTID_ACCESSLOG_FORMAT,
|
SHRPX_OPTID_ACCESSLOG_FORMAT,
|
||||||
SHRPX_OPTID_ACCESSLOG_SYSLOG,
|
SHRPX_OPTID_ACCESSLOG_SYSLOG,
|
||||||
|
SHRPX_OPTID_ACCESSLOG_WRITE_EARLY,
|
||||||
SHRPX_OPTID_ADD_FORWARDED,
|
SHRPX_OPTID_ADD_FORWARDED,
|
||||||
SHRPX_OPTID_ADD_REQUEST_HEADER,
|
SHRPX_OPTID_ADD_REQUEST_HEADER,
|
||||||
SHRPX_OPTID_ADD_RESPONSE_HEADER,
|
SHRPX_OPTID_ADD_RESPONSE_HEADER,
|
||||||
|
|
|
@ -138,7 +138,8 @@ Downstream::Downstream(Upstream *upstream, MemchunkPool *mcpool,
|
||||||
chunked_response_(false),
|
chunked_response_(false),
|
||||||
expect_final_response_(false),
|
expect_final_response_(false),
|
||||||
request_pending_(false),
|
request_pending_(false),
|
||||||
request_header_sent_(false) {
|
request_header_sent_(false),
|
||||||
|
accesslog_written_(false) {
|
||||||
|
|
||||||
auto &timeoutconf = get_config()->http2.timeout;
|
auto &timeoutconf = get_config()->http2.timeout;
|
||||||
|
|
||||||
|
@ -906,7 +907,9 @@ void Downstream::disable_downstream_wtimer() {
|
||||||
disable_timer(loop, &downstream_wtimer_);
|
disable_timer(loop, &downstream_wtimer_);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Downstream::accesslog_ready() const { return resp_.http_status > 0; }
|
bool Downstream::accesslog_ready() const {
|
||||||
|
return !accesslog_written_ && resp_.http_status > 0;
|
||||||
|
}
|
||||||
|
|
||||||
void Downstream::add_retry() { ++num_retry_; }
|
void Downstream::add_retry() { ++num_retry_; }
|
||||||
|
|
||||||
|
@ -985,4 +988,6 @@ void Downstream::set_addr(const DownstreamAddr *addr) { addr_ = addr; }
|
||||||
|
|
||||||
const DownstreamAddr *Downstream::get_addr() const { return addr_; }
|
const DownstreamAddr *Downstream::get_addr() const { return addr_; }
|
||||||
|
|
||||||
|
void Downstream::set_accesslog_written(bool f) { accesslog_written_ = f; }
|
||||||
|
|
||||||
} // namespace shrpx
|
} // namespace shrpx
|
||||||
|
|
|
@ -406,6 +406,8 @@ public:
|
||||||
|
|
||||||
const DownstreamAddr *get_addr() const;
|
const DownstreamAddr *get_addr() const;
|
||||||
|
|
||||||
|
void set_accesslog_written(bool f);
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
EVENT_ERROR = 0x1,
|
EVENT_ERROR = 0x1,
|
||||||
EVENT_TIMEOUT = 0x2,
|
EVENT_TIMEOUT = 0x2,
|
||||||
|
@ -489,6 +491,8 @@ private:
|
||||||
bool request_pending_;
|
bool request_pending_;
|
||||||
// true if downstream request header is considered to be sent.
|
// true if downstream request header is considered to be sent.
|
||||||
bool request_header_sent_;
|
bool request_header_sent_;
|
||||||
|
// true if access.log has been written.
|
||||||
|
bool accesslog_written_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace shrpx
|
} // namespace shrpx
|
||||||
|
|
|
@ -1090,11 +1090,15 @@ int on_response_headers(Http2Session *http2session, Downstream *downstream,
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
auto upstream = downstream->get_upstream();
|
auto upstream = downstream->get_upstream();
|
||||||
|
auto handler = upstream->get_client_handler();
|
||||||
const auto &req = downstream->request();
|
const auto &req = downstream->request();
|
||||||
auto &resp = downstream->response();
|
auto &resp = downstream->response();
|
||||||
|
|
||||||
auto &nva = resp.fs.headers();
|
auto &nva = resp.fs.headers();
|
||||||
|
|
||||||
|
auto config = get_config();
|
||||||
|
auto &loggingconf = config->logging;
|
||||||
|
|
||||||
downstream->set_expect_final_response(false);
|
downstream->set_expect_final_response(false);
|
||||||
|
|
||||||
auto status = resp.fs.header(http2::HD__STATUS);
|
auto status = resp.fs.header(http2::HD__STATUS);
|
||||||
|
@ -1147,7 +1151,7 @@ int on_response_headers(Http2Session *http2session, Downstream *downstream,
|
||||||
// On upgrade sucess, both ends can send data
|
// On upgrade sucess, both ends can send data
|
||||||
if (upstream->resume_read(SHRPX_NO_BUFFER, downstream, 0) != 0) {
|
if (upstream->resume_read(SHRPX_NO_BUFFER, downstream, 0) != 0) {
|
||||||
// If resume_read fails, just drop connection. Not ideal.
|
// If resume_read fails, just drop connection. Not ideal.
|
||||||
delete upstream->get_client_handler();
|
delete handler;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
downstream->set_request_state(Downstream::HEADER_COMPLETE);
|
downstream->set_request_state(Downstream::HEADER_COMPLETE);
|
||||||
|
@ -1184,6 +1188,11 @@ int on_response_headers(Http2Session *http2session, Downstream *downstream,
|
||||||
resp.headers_only = true;
|
resp.headers_only = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (loggingconf.access.write_early && downstream->accesslog_ready()) {
|
||||||
|
handler->write_accesslog(downstream);
|
||||||
|
downstream->set_accesslog_written(true);
|
||||||
|
}
|
||||||
|
|
||||||
rv = upstream->on_downstream_header_complete(downstream);
|
rv = upstream->on_downstream_header_complete(downstream);
|
||||||
if (rv != 0) {
|
if (rv != 0) {
|
||||||
// Handling early return (in other words, response was hijacked by
|
// Handling early return (in other words, response was hijacked by
|
||||||
|
|
|
@ -822,10 +822,14 @@ namespace {
|
||||||
int htp_hdrs_completecb(http_parser *htp) {
|
int htp_hdrs_completecb(http_parser *htp) {
|
||||||
auto downstream = static_cast<Downstream *>(htp->data);
|
auto downstream = static_cast<Downstream *>(htp->data);
|
||||||
auto upstream = downstream->get_upstream();
|
auto upstream = downstream->get_upstream();
|
||||||
|
auto handler = upstream->get_client_handler();
|
||||||
const auto &req = downstream->request();
|
const auto &req = downstream->request();
|
||||||
auto &resp = downstream->response();
|
auto &resp = downstream->response();
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
|
auto config = get_config();
|
||||||
|
auto &loggingconf = config->logging;
|
||||||
|
|
||||||
resp.http_status = htp->status_code;
|
resp.http_status = htp->status_code;
|
||||||
resp.http_major = htp->http_major;
|
resp.http_major = htp->http_major;
|
||||||
resp.http_minor = htp->http_minor;
|
resp.http_minor = htp->http_minor;
|
||||||
|
@ -911,6 +915,11 @@ int htp_hdrs_completecb(http_parser *htp) {
|
||||||
downstream->set_chunked_response(false);
|
downstream->set_chunked_response(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (loggingconf.access.write_early && downstream->accesslog_ready()) {
|
||||||
|
handler->write_accesslog(downstream);
|
||||||
|
downstream->set_accesslog_written(true);
|
||||||
|
}
|
||||||
|
|
||||||
if (upstream->on_downstream_header_complete(downstream) != 0) {
|
if (upstream->on_downstream_header_complete(downstream) != 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue