nghttpx: Add date header field to error_reply and send_reply

This commit is contained in:
Tatsuhiro Tsujikawa 2015-09-07 23:11:23 +09:00
parent 21a3edfc60
commit 3ce1c1d39f
10 changed files with 38 additions and 1 deletions

View File

@ -28,6 +28,7 @@ HEADERS = [
"accept-language", "accept-language",
"cache-control", "cache-control",
"user-agent", "user-agent",
"date",
# disallowed h1 headers # disallowed h1 headers
'connection', 'connection',
'keep-alive', 'keep-alive',

View File

@ -414,6 +414,11 @@ int lookup_token(const uint8_t *name, size_t namelen) {
break; break;
case 4: case 4:
switch (name[3]) { switch (name[3]) {
case 'e':
if (util::streq_l("dat", name, 3)) {
return HD_DATE;
}
break;
case 'k': case 'k':
if (util::streq_l("lin", name, 3)) { if (util::streq_l("lin", name, 3)) {
return HD_LINK; return HD_LINK;

View File

@ -207,6 +207,7 @@ enum {
HD_CONNECTION, HD_CONNECTION,
HD_CONTENT_LENGTH, HD_CONTENT_LENGTH,
HD_COOKIE, HD_COOKIE,
HD_DATE,
HD_EXPECT, HD_EXPECT,
HD_HOST, HD_HOST,
HD_HTTP2_SETTINGS, HD_HTTP2_SETTINGS,

View File

@ -1238,13 +1238,17 @@ int Http2Upstream::error_reply(Downstream *downstream,
data_prd.source.ptr = downstream; data_prd.source.ptr = downstream;
data_prd.read_callback = downstream_data_read_callback; data_prd.read_callback = downstream_data_read_callback;
auto lgconf = log_config();
lgconf->update_tstamp(std::chrono::system_clock::now());
auto content_length = util::utos(html.size()); auto content_length = util::utos(html.size());
auto status_code_str = util::utos(status_code); auto status_code_str = util::utos(status_code);
auto nva = auto nva =
make_array(http2::make_nv_ls(":status", status_code_str), make_array(http2::make_nv_ls(":status", status_code_str),
http2::make_nv_ll("content-type", "text/html; charset=UTF-8"), http2::make_nv_ll("content-type", "text/html; charset=UTF-8"),
http2::make_nv_lc("server", get_config()->server_name), http2::make_nv_lc("server", get_config()->server_name),
http2::make_nv_ls("content-length", content_length)); http2::make_nv_ls("content-length", content_length),
http2::make_nv_ls("date", lgconf->time_http_str));
rv = nghttp2_submit_response(session_, downstream->get_stream_id(), rv = nghttp2_submit_response(session_, downstream->get_stream_id(),
nva.data(), nva.size(), &data_prd); nva.data(), nva.size(), &data_prd);

View File

@ -857,6 +857,11 @@ void HttpsUpstream::error_reply(unsigned int status_code) {
output->append("\r\nContent-Length: "); output->append("\r\nContent-Length: ");
auto cl = util::utos(html.size()); auto cl = util::utos(html.size());
output->append(cl.c_str(), cl.size()); output->append(cl.c_str(), cl.size());
output->append("\r\nDate: ");
auto lgconf = log_config();
lgconf->update_tstamp(std::chrono::system_clock::now());
auto &date = lgconf->time_http_str;
output->append(date.c_str(), date.size());
output->append("\r\nContent-Type: text/html; " output->append("\r\nContent-Type: text/html; "
"charset=UTF-8\r\nConnection: close\r\n\r\n"); "charset=UTF-8\r\nConnection: close\r\n\r\n");
output->append(html.c_str(), html.size()); output->append(html.c_str(), html.size());

View File

@ -64,6 +64,7 @@ LogConfig::update_tstamp(const std::chrono::system_clock::time_point &now) {
time_local_str = util::format_common_log(now); time_local_str = util::format_common_log(now);
time_iso8601_str = util::format_iso8601(now); time_iso8601_str = util::format_iso8601(now);
time_http_str = util::format_http_date(now);
} }
} // namespace shrpx } // namespace shrpx

View File

@ -35,6 +35,7 @@ struct LogConfig {
std::chrono::system_clock::time_point time_str_updated_; std::chrono::system_clock::time_point time_str_updated_;
std::string time_local_str; std::string time_local_str;
std::string time_iso8601_str; std::string time_iso8601_str;
std::string time_http_str;
int accesslog_fd; int accesslog_fd;
int errorlog_fd; int errorlog_fd;
// true if errorlog_fd is referring to a terminal. // true if errorlog_fd is referring to a terminal.

View File

@ -210,6 +210,14 @@ mrb_value response_return(mrb_state *mrb, mrb_value self) {
} }
downstream->set_response_content_length(bodylen); downstream->set_response_content_length(bodylen);
auto date = downstream->get_response_header(http2::HD_DATE);
if (!date) {
auto lgconf = log_config();
lgconf->update_tstamp(std::chrono::system_clock::now());
downstream->add_response_header("date", lgconf->time_http_str,
http2::HD_DATE);
}
auto upstream = downstream->get_upstream(); auto upstream = downstream->get_upstream();
rv = upstream->send_reply(downstream, body, bodylen); rv = upstream->send_reply(downstream, body, bodylen);

View File

@ -881,6 +881,9 @@ int SpdyUpstream::error_reply(Downstream *downstream,
data_prd.source.ptr = downstream; data_prd.source.ptr = downstream;
data_prd.read_callback = spdy_data_read_callback; data_prd.read_callback = spdy_data_read_callback;
auto lgconf = log_config();
lgconf->update_tstamp(std::chrono::system_clock::now());
std::string content_length = util::utos(html.size()); std::string content_length = util::utos(html.size());
std::string status_string = http2::get_status_string(status_code); std::string status_string = http2::get_status_string(status_code);
const char *nv[] = {":status", status_string.c_str(), const char *nv[] = {":status", status_string.c_str(),
@ -888,6 +891,7 @@ int SpdyUpstream::error_reply(Downstream *downstream,
"content-type", "text/html; charset=UTF-8", "content-type", "text/html; charset=UTF-8",
"server", get_config()->server_name, "server", get_config()->server_name,
"content-length", content_length.c_str(), "content-length", content_length.c_str(),
"date", lgconf->time_http_str.c_str(),
nullptr}; nullptr};
rv = spdylay_submit_response(session_, downstream->get_stream_id(), nv, rv = spdylay_submit_response(session_, downstream->get_stream_id(), nv,

View File

@ -588,6 +588,13 @@ template <typename T> std::string format_iso8601(const T &tp) {
return iso8601_date(t.count()); return iso8601_date(t.count());
} }
// Returns given time |tp| in HTTP date format.
template <typename T> std::string format_http_date(const T &tp) {
auto t =
std::chrono::duration_cast<std::chrono::seconds>(tp.time_since_epoch());
return http_date(t.count());
}
// Return the system precision of the template parameter |Clock| as // Return the system precision of the template parameter |Clock| as
// a nanosecond value of type |Rep| // a nanosecond value of type |Rep|
template <typename Clock, typename Rep> Rep clock_precision() { template <typename Clock, typename Rep> Rep clock_precision() {