@@ -2999,19 +2999,31 @@ inline std::string file_mtime_to_http_date(time_t mtime) {
29992999// Parse HTTP-date (RFC 7231) to time_t. Returns -1 on failure.
30003000inline time_t parse_http_date (const std::string &date_str) {
30013001 struct tm tm_buf;
3002- memset (&tm_buf, 0 , sizeof (tm_buf));
30033002
3004- // Try RFC 7231 preferred format: "Sun, 06 Nov 1994 08:49:37 GMT"
3005- const char *p = strptime (date_str.c_str (), " %a, %d %b %Y %H:%M:%S" , &tm_buf);
3006- if (!p) {
3007- // Try RFC 850 format: "Sunday, 06-Nov-94 08:49:37 GMT"
3008- p = strptime (date_str.c_str (), " %A, %d-%b-%y %H:%M:%S" , &tm_buf);
3009- }
3010- if (!p) {
3011- // Try asctime format: "Sun Nov 6 08:49:37 1994"
3012- p = strptime (date_str.c_str (), " %a %b %d %H:%M:%S %Y" , &tm_buf);
3003+ // Create a classic locale object once for all parsing attempts
3004+ const std::locale classic_locale = std::locale::classic ();
3005+
3006+ // Try to parse using std::get_time (C++11, cross-platform)
3007+ auto try_parse = [&](const char *fmt) -> bool {
3008+ std::istringstream ss (date_str);
3009+ ss.imbue (classic_locale);
3010+
3011+ memset (&tm_buf, 0 , sizeof (tm_buf));
3012+ ss >> std::get_time (&tm_buf, fmt);
3013+
3014+ return !ss.fail ();
3015+ };
3016+
3017+ // RFC 7231 preferred format: "Sun, 06 Nov 1994 08:49:37 GMT"
3018+ if (!try_parse (" %a, %d %b %Y %H:%M:%S" )) {
3019+ // RFC 850 format: "Sunday, 06-Nov-94 08:49:37 GMT"
3020+ if (!try_parse (" %A, %d-%b-%y %H:%M:%S" )) {
3021+ // asctime format: "Sun Nov 6 08:49:37 1994"
3022+ if (!try_parse (" %a %b %d %H:%M:%S %Y" )) {
3023+ return static_cast <time_t >(-1 );
3024+ }
3025+ }
30133026 }
3014- if (!p) { return static_cast <time_t >(-1 ); }
30153027
30163028#ifdef _WIN32
30173029 return _mkgmtime (&tm_buf);
0 commit comments