src: Always use our own faster simpler timegm, use it to calculate gmtoff
This commit is contained in:
parent
515c313073
commit
51ef646678
|
@ -152,6 +152,10 @@ int main(int argc, char *argv[]) {
|
||||||
shrpx::test_util_format_duration) ||
|
shrpx::test_util_format_duration) ||
|
||||||
!CU_add_test(pSuite, "util_starts_with", shrpx::test_util_starts_with) ||
|
!CU_add_test(pSuite, "util_starts_with", shrpx::test_util_starts_with) ||
|
||||||
!CU_add_test(pSuite, "util_ends_with", shrpx::test_util_ends_with) ||
|
!CU_add_test(pSuite, "util_ends_with", shrpx::test_util_ends_with) ||
|
||||||
|
!CU_add_test(pSuite, "util_parse_http_date",
|
||||||
|
shrpx::test_util_parse_http_date) ||
|
||||||
|
!CU_add_test(pSuite, "util_localtime_date",
|
||||||
|
shrpx::test_util_localtime_date) ||
|
||||||
!CU_add_test(pSuite, "gzip_inflate", test_nghttp2_gzip_inflate) ||
|
!CU_add_test(pSuite, "gzip_inflate", test_nghttp2_gzip_inflate) ||
|
||||||
!CU_add_test(pSuite, "buffer_write", nghttp2::test_buffer_write) ||
|
!CU_add_test(pSuite, "buffer_write", nghttp2::test_buffer_write) ||
|
||||||
!CU_add_test(pSuite, "pool_recycle", nghttp2::test_pool_recycle) ||
|
!CU_add_test(pSuite, "pool_recycle", nghttp2::test_pool_recycle) ||
|
||||||
|
|
19
src/timegm.c
19
src/timegm.c
|
@ -24,8 +24,6 @@
|
||||||
*/
|
*/
|
||||||
#include "timegm.h"
|
#include "timegm.h"
|
||||||
|
|
||||||
#ifndef HAVE_TIMEGM
|
|
||||||
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
|
||||||
/* Counter the number of leap year in the range [0, y). The |y| is the
|
/* Counter the number of leap year in the range [0, y). The |y| is the
|
||||||
|
@ -35,15 +33,6 @@ static int count_leap_year(int y) {
|
||||||
return y / 4 - y / 100 + y / 400;
|
return y / 4 - y / 100 + y / 400;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Returns nonzero if the |y| is the leap year. The |y| is the year,
|
|
||||||
including century (e.g., 2012) */
|
|
||||||
static int is_leap_year(int y) {
|
|
||||||
return y % 4 == 0 && (y % 100 != 0 || y % 400 == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The number of days before ith month begins */
|
|
||||||
static int daysum[] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
|
|
||||||
|
|
||||||
/* Based on the algorithm of Python 2.7 calendar.timegm. */
|
/* Based on the algorithm of Python 2.7 calendar.timegm. */
|
||||||
time_t timegm(struct tm *tm) {
|
time_t timegm(struct tm *tm) {
|
||||||
int days;
|
int days;
|
||||||
|
@ -53,11 +42,7 @@ time_t timegm(struct tm *tm) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
num_leap_year = count_leap_year(tm->tm_year + 1900) - count_leap_year(1970);
|
num_leap_year = count_leap_year(tm->tm_year + 1900) - count_leap_year(1970);
|
||||||
days = (tm->tm_year - 70) * 365 + num_leap_year + daysum[tm->tm_mon] +
|
days = (tm->tm_year - 70) * 365 + num_leap_year + tm->tm_yday;
|
||||||
tm->tm_mday - 1;
|
|
||||||
if (tm->tm_mon >= 2 && is_leap_year(tm->tm_year + 1900)) {
|
|
||||||
++days;
|
|
||||||
}
|
|
||||||
t = ((int64_t)days * 24 + tm->tm_hour) * 3600 + tm->tm_min * 60 + tm->tm_sec;
|
t = ((int64_t)days * 24 + tm->tm_hour) * 3600 + tm->tm_min * 60 + tm->tm_sec;
|
||||||
if (sizeof(time_t) == 4) {
|
if (sizeof(time_t) == 4) {
|
||||||
if (t < INT32_MIN || t > INT32_MAX) {
|
if (t < INT32_MIN || t > INT32_MAX) {
|
||||||
|
@ -66,5 +51,3 @@ time_t timegm(struct tm *tm) {
|
||||||
}
|
}
|
||||||
return (time_t)t;
|
return (time_t)t;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* !HAVE_TIMEGM */
|
|
||||||
|
|
|
@ -37,12 +37,8 @@ extern "C" {
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#endif // HAVE_TIME_H
|
#endif // HAVE_TIME_H
|
||||||
|
|
||||||
#ifndef HAVE_TIMEGM
|
|
||||||
|
|
||||||
time_t timegm(struct tm *tm);
|
time_t timegm(struct tm *tm);
|
||||||
|
|
||||||
#endif /* HAVE_TIMEGM */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
40
src/util.cc
40
src/util.cc
|
@ -254,7 +254,6 @@ std::string common_log_date(time_t t) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_STRUCT_TM_TM_GMTOFF
|
|
||||||
// Format data like this:
|
// Format data like this:
|
||||||
// 03/Jul/2014:00:19:38 +0900
|
// 03/Jul/2014:00:19:38 +0900
|
||||||
std::string res;
|
std::string res;
|
||||||
|
@ -276,7 +275,11 @@ std::string common_log_date(time_t t) {
|
||||||
p = cpydig(p, tms.tm_sec, 2);
|
p = cpydig(p, tms.tm_sec, 2);
|
||||||
*p++ = ' ';
|
*p++ = ' ';
|
||||||
|
|
||||||
|
#ifdef HAVE_STRUCT_TM_TM_GMTOFF
|
||||||
auto gmtoff = tms.tm_gmtoff;
|
auto gmtoff = tms.tm_gmtoff;
|
||||||
|
#else // !HAVE_STRUCT_TM_TM_GMTOFF
|
||||||
|
auto gmtoff = timegm(&tms) - t;
|
||||||
|
#endif // !HAVE_STRUCT_TM_TM_GMTOFF
|
||||||
if (gmtoff >= 0) {
|
if (gmtoff >= 0) {
|
||||||
*p++ = '+';
|
*p++ = '+';
|
||||||
} else {
|
} else {
|
||||||
|
@ -288,13 +291,6 @@ std::string common_log_date(time_t t) {
|
||||||
p = cpydig(p, (gmtoff % 3600) / 60, 2);
|
p = cpydig(p, (gmtoff % 3600) / 60, 2);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
#else // !HAVE_STRUCT_TM_TM_GMTOFF
|
|
||||||
char buf[32];
|
|
||||||
|
|
||||||
strftime(buf, sizeof(buf), "%d/%b/%Y:%T %z", &tms);
|
|
||||||
|
|
||||||
return buf;
|
|
||||||
#endif // !HAVE_STRUCT_TM_TM_GMTOFF
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string iso8601_date(int64_t ms) {
|
std::string iso8601_date(int64_t ms) {
|
||||||
|
@ -305,7 +301,6 @@ std::string iso8601_date(int64_t ms) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_STRUCT_TM_TM_GMTOFF
|
|
||||||
// Format data like this:
|
// Format data like this:
|
||||||
// 2014-11-15T12:58:24.741Z
|
// 2014-11-15T12:58:24.741Z
|
||||||
// 2014-11-15T12:58:24.741+09:00
|
// 2014-11-15T12:58:24.741+09:00
|
||||||
|
@ -328,7 +323,11 @@ std::string iso8601_date(int64_t ms) {
|
||||||
*p++ = '.';
|
*p++ = '.';
|
||||||
p = cpydig(p, ms % 1000, 3);
|
p = cpydig(p, ms % 1000, 3);
|
||||||
|
|
||||||
|
#ifdef HAVE_STRUCT_TM_TM_GMTOFF
|
||||||
auto gmtoff = tms.tm_gmtoff;
|
auto gmtoff = tms.tm_gmtoff;
|
||||||
|
#else // !HAVE_STRUCT_TM_TM_GMTOFF
|
||||||
|
auto gmtoff = timegm(&tms) - sec;
|
||||||
|
#endif // !HAVE_STRUCT_TM_TM_GMTOFF
|
||||||
if (gmtoff == 0) {
|
if (gmtoff == 0) {
|
||||||
*p++ = 'Z';
|
*p++ = 'Z';
|
||||||
} else {
|
} else {
|
||||||
|
@ -346,29 +345,6 @@ std::string iso8601_date(int64_t ms) {
|
||||||
res.resize(p - std::begin(res));
|
res.resize(p - std::begin(res));
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
#else // !HAVE_STRUCT_TM_TM_GMTOFF
|
|
||||||
char buf[128];
|
|
||||||
|
|
||||||
auto nwrite = strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%S", &tms);
|
|
||||||
nwrite += snprintf(&buf[nwrite], sizeof(buf) - nwrite, ".%03d",
|
|
||||||
static_cast<int>(ms % 1000));
|
|
||||||
auto nzone = strftime(&buf[nwrite], sizeof(buf) - nwrite, "%z", &tms);
|
|
||||||
|
|
||||||
// %z of strftime writes +hhmm or -hhmm not Z, +hh:mm or -hh:mm. Do
|
|
||||||
// %nothing if nzone is not 5. we don't know how to cope with this.
|
|
||||||
if (nzone == 5) {
|
|
||||||
if (memcmp(&buf[nwrite], "+0000", 5) == 0) {
|
|
||||||
// 0000 should be Z
|
|
||||||
memcpy(&buf[nwrite], "Z", 2);
|
|
||||||
} else {
|
|
||||||
// Move mm part to right by 1 including terminal \0
|
|
||||||
memmove(&buf[nwrite + 4], &buf[nwrite + 3], 3);
|
|
||||||
// Insert ':' between hh and mm
|
|
||||||
buf[nwrite + 3] = ':';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return buf;
|
|
||||||
#endif // !HAVE_STRUCT_TM_TM_GMTOFF
|
|
||||||
}
|
}
|
||||||
|
|
||||||
time_t parse_http_date(const std::string &s) {
|
time_t parse_http_date(const std::string &s) {
|
||||||
|
|
|
@ -367,4 +367,30 @@ void test_util_ends_with(void) {
|
||||||
CU_ASSERT(!util::iendsWith("ofoo", "fo"));
|
CU_ASSERT(!util::iendsWith("ofoo", "fo"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_util_parse_http_date(void) {
|
||||||
|
CU_ASSERT(1001939696 ==
|
||||||
|
util::parse_http_date("Mon, 1 Oct 2001 12:34:56 GMT"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_util_localtime_date(void) {
|
||||||
|
auto tz = getenv("TZ");
|
||||||
|
if (tz) {
|
||||||
|
tz = strdup(tz);
|
||||||
|
}
|
||||||
|
setenv("TZ", ":Pacific/Auckland", 1);
|
||||||
|
tzset();
|
||||||
|
|
||||||
|
CU_ASSERT_STRING_EQUAL("02/Oct/2001:00:34:56 +1200",
|
||||||
|
util::common_log_date(1001939696).c_str());
|
||||||
|
CU_ASSERT_STRING_EQUAL("2001-10-02T00:34:56.123+12:00",
|
||||||
|
util::iso8601_date(1001939696000LL + 123).c_str());
|
||||||
|
|
||||||
|
if (tz) {
|
||||||
|
setenv("TZ", tz, 1);
|
||||||
|
} else {
|
||||||
|
unsetenv("TZ");
|
||||||
|
}
|
||||||
|
tzset();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace shrpx
|
} // namespace shrpx
|
||||||
|
|
|
@ -53,6 +53,8 @@ void test_util_duration_str(void);
|
||||||
void test_util_format_duration(void);
|
void test_util_format_duration(void);
|
||||||
void test_util_starts_with(void);
|
void test_util_starts_with(void);
|
||||||
void test_util_ends_with(void);
|
void test_util_ends_with(void);
|
||||||
|
void test_util_parse_http_date(void);
|
||||||
|
void test_util_localtime_date(void);
|
||||||
|
|
||||||
} // namespace shrpx
|
} // namespace shrpx
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue