diff --git a/src/shrpx-unittest.cc b/src/shrpx-unittest.cc index 0de07c3d..42998acf 100644 --- a/src/shrpx-unittest.cc +++ b/src/shrpx-unittest.cc @@ -123,6 +123,7 @@ int main(int argc, char* argv[]) !CU_add_test(pSuite, "util_quote_string", shrpx::test_util_quote_string) || !CU_add_test(pSuite, "util_utox", shrpx::test_util_utox) || + !CU_add_test(pSuite, "util_http_date", shrpx::test_util_http_date) || !CU_add_test(pSuite, "gzip_inflate", test_nghttp2_gzip_inflate)) { CU_cleanup_registry(); return CU_get_error(); diff --git a/src/util.cc b/src/util.cc index 8be0a949..14d58af6 100644 --- a/src/util.cc +++ b/src/util.cc @@ -163,17 +163,62 @@ std::string quote_string(const std::string& target) return res; } +namespace { +template +Iterator cpydig(Iterator d, int n, size_t len) +{ + auto p = d + len - 1; + + do { + *p-- = (n % 10) + '0'; + n /= 10; + } while(p >= d); + + return d + len; +} +} // namespace + +namespace { +const char *MONTH[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; +const char *DAY_OF_WEEK[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", + "Sat" }; +} // namespace + std::string http_date(time_t t) { - char buf[32]; - tm tms; + struct tm tms; + std::string res; if(gmtime_r(&t, &tms) == nullptr) { - return ""; + return res; } - auto rv = strftime(buf, sizeof(buf), "%a, %d %b %Y %H:%M:%S GMT", &tms); - return std::string(&buf[0], &buf[rv]); + /* Sat, 27 Sep 2014 06:31:15 GMT */ + res.resize(29); + + auto p = std::begin(res); + + auto s = DAY_OF_WEEK[tms.tm_wday]; + p = std::copy(s, s + 3, p); + *p++ = ','; + *p++ = ' '; + p = cpydig(p, tms.tm_mday, 2); + *p++ = ' '; + s = MONTH[tms.tm_mon]; + p = std::copy(s, s + 3, p); + *p++ = ' '; + p = cpydig(p, tms.tm_year + 1900, 4); + *p++ = ' '; + p = cpydig(p, tms.tm_hour, 2); + *p++ = ':'; + p = cpydig(p, tms.tm_min, 2); + *p++ = ':'; + p = cpydig(p, tms.tm_sec, 2); + s = " GMT"; + p = std::copy(s, s + 4, p); + + return res; } time_t parse_http_date(const std::string& s) diff --git a/src/util_test.cc b/src/util_test.cc index bc301399..54b18f92 100644 --- a/src/util_test.cc +++ b/src/util_test.cc @@ -118,4 +118,10 @@ void test_util_utox(void) CU_ASSERT("100000000" == util::utox(1LL << 32)); } +void test_util_http_date(void) +{ + CU_ASSERT("Thu, 01 Jan 1970 00:00:00 GMT" == util::http_date(0)); + CU_ASSERT("Wed, 29 Feb 2012 09:15:16 GMT" == util::http_date(1330506916)); +} + } // namespace shrpx diff --git a/src/util_test.h b/src/util_test.h index d0220a88..f4ffefc5 100644 --- a/src/util_test.h +++ b/src/util_test.h @@ -34,6 +34,7 @@ void test_util_to_base64(void); void test_util_percent_encode_token(void); void test_util_quote_string(void); void test_util_utox(void); +void test_util_http_date(void); } // namespace shrpx