diff --git a/webcc/request_builder.cc b/webcc/request_builder.cc index 583ba95..dc826d5 100644 --- a/webcc/request_builder.cc +++ b/webcc/request_builder.cc @@ -104,7 +104,7 @@ RequestBuilder& RequestBuilder::AuthToken(const std::string& token) { RequestBuilder& RequestBuilder::Date() { headers_.push_back(headers::kDate); - headers_.push_back(utility::GetTimestamp()); + headers_.push_back(utility::HttpDate()); return *this; } diff --git a/webcc/response_builder.cc b/webcc/response_builder.cc index 50c62dd..9316266 100644 --- a/webcc/response_builder.cc +++ b/webcc/response_builder.cc @@ -57,7 +57,7 @@ ResponseBuilder& ResponseBuilder::File(const std::filesystem::path& path, ResponseBuilder& ResponseBuilder::Date() { headers_.push_back(headers::kDate); - headers_.push_back(utility::GetTimestamp()); + headers_.push_back(utility::HttpDate()); return *this; } diff --git a/webcc/utility.cc b/webcc/utility.cc index 936d226..2a2127f 100644 --- a/webcc/utility.cc +++ b/webcc/utility.cc @@ -15,15 +15,38 @@ namespace webcc { namespace utility { const std::string& UserAgent() { - static auto s_user_agent = std::string("Webcc/") + WEBCC_VERSION; + static const std::string s_user_agent = std::string("Webcc/") + WEBCC_VERSION; return s_user_agent; } -std::string GetTimestamp() { +std::string HttpDate() { std::time_t t = std::time(nullptr); - std::stringstream ss; - ss << std::put_time(std::gmtime(&t), "%a, %d %b %Y %H:%M:%S") << " GMT"; - return ss.str(); + tm* gmt = std::gmtime(&t); + + // Either put_time() or strftime() could format the date as expected, but they + // are both locale dependent! + // + // std::stringstream ss; + // ss << std::put_time(gmt, "%a, %d %b %Y %H:%M:%S") << " GMT"; + // return ss.str(); + // + // char buf[26]; + // std::strftime(buf, 26, "%a, %d %b %Y %H:%M:%S", gmt); + + static const char* const kDays[7] = { "Sun", "Mon", "Tue", "Wed", + "Thu", "Fri", "Sat" }; + + static const char* const kMonths[12] = { "Jan", "Feb", "Mar", "Apr", + "May", "Jun", "Jul", "Aug", + "Sep", "Oct", "Nov", "Dec" }; + + char buf[26]; + + std::snprintf(buf, 26, "%s, %.2i %s %i %.2i:%.2i:%.2i", kDays[gmt->tm_wday], + gmt->tm_mday, kMonths[gmt->tm_mon], gmt->tm_year + 1900, + gmt->tm_hour, gmt->tm_min, gmt->tm_sec); + + return std::string(buf) + " GMT"; } std::size_t TellSize(const std::filesystem::path& path) { diff --git a/webcc/utility.h b/webcc/utility.h index 036a296..7544578 100644 --- a/webcc/utility.h +++ b/webcc/utility.h @@ -24,7 +24,7 @@ const std::string& UserAgent(); // Get the timestamp for HTTP Date header field. // E.g., Wed, 21 Oct 2015 07:28:00 GMT // See: https://tools.ietf.org/html/rfc7231#section-7.1.1.2 -std::string GetTimestamp(); +std::string HttpDate(); // Tell the size in bytes of the given file. // Return kInvalidLength (-1) on failure.