Commit 3ce1c1d3 authored by Tatsuhiro Tsujikawa's avatar Tatsuhiro Tsujikawa

nghttpx: Add date header field to error_reply and send_reply

parent 21a3edfc
......@@ -28,6 +28,7 @@ HEADERS = [
"accept-language",
"cache-control",
"user-agent",
"date",
# disallowed h1 headers
'connection',
'keep-alive',
......
......@@ -414,6 +414,11 @@ int lookup_token(const uint8_t *name, size_t namelen) {
break;
case 4:
switch (name[3]) {
case 'e':
if (util::streq_l("dat", name, 3)) {
return HD_DATE;
}
break;
case 'k':
if (util::streq_l("lin", name, 3)) {
return HD_LINK;
......
......@@ -207,6 +207,7 @@ enum {
HD_CONNECTION,
HD_CONTENT_LENGTH,
HD_COOKIE,
HD_DATE,
HD_EXPECT,
HD_HOST,
HD_HTTP2_SETTINGS,
......
......@@ -1238,13 +1238,17 @@ int Http2Upstream::error_reply(Downstream *downstream,
data_prd.source.ptr = downstream;
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 status_code_str = util::utos(status_code);
auto nva =
make_array(http2::make_nv_ls(":status", status_code_str),
http2::make_nv_ll("content-type", "text/html; charset=UTF-8"),
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(),
nva.data(), nva.size(), &data_prd);
......
......@@ -857,6 +857,11 @@ void HttpsUpstream::error_reply(unsigned int status_code) {
output->append("\r\nContent-Length: ");
auto cl = util::utos(html.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; "
"charset=UTF-8\r\nConnection: close\r\n\r\n");
output->append(html.c_str(), html.size());
......
......@@ -64,6 +64,7 @@ LogConfig::update_tstamp(const std::chrono::system_clock::time_point &now) {
time_local_str = util::format_common_log(now);
time_iso8601_str = util::format_iso8601(now);
time_http_str = util::format_http_date(now);
}
} // namespace shrpx
......@@ -35,6 +35,7 @@ struct LogConfig {
std::chrono::system_clock::time_point time_str_updated_;
std::string time_local_str;
std::string time_iso8601_str;
std::string time_http_str;
int accesslog_fd;
int errorlog_fd;
// true if errorlog_fd is referring to a terminal.
......
......@@ -210,6 +210,14 @@ mrb_value response_return(mrb_state *mrb, mrb_value self) {
}
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();
rv = upstream->send_reply(downstream, body, bodylen);
......
......@@ -881,6 +881,9 @@ int SpdyUpstream::error_reply(Downstream *downstream,
data_prd.source.ptr = downstream;
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 status_string = http2::get_status_string(status_code);
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",
"server", get_config()->server_name,
"content-length", content_length.c_str(),
"date", lgconf->time_http_str.c_str(),
nullptr};
rv = spdylay_submit_response(session_, downstream->get_stream_id(), nv,
......
......@@ -588,6 +588,13 @@ template <typename T> std::string format_iso8601(const T &tp) {
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
// a nanosecond value of type |Rep|
template <typename Clock, typename Rep> Rep clock_precision() {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment