From b2272af3cb63d09ec56033b983249657411e7d8a Mon Sep 17 00:00:00 2001 From: Aaron McConnell Date: Fri, 5 Jun 2026 11:14:01 -0400 Subject: [PATCH] Use strftime_l with C locale and gmtime for X-Duo-Date header Replace locale-dependent strftime(localtime()) with strftime_l(gmtime()) using an explicit C locale. This fixes three issues: - #366/#355: strftime %a and %b produce localized day/month names when the system locale is non-English, breaking HMAC signature verification - #363: strftime %z on AIX produces a timezone name ("EST") instead of a numeric offset ("-0500"), also breaking signatures The fix uses gmtime() with a hardcoded "+0000" UTC offset (matching the Python client's default behavior) and strftime_l() with a C locale to guarantee English day/month abbreviations regardless of environment. Resolves #366, #355, #363 Co-Authored-By: Claude Opus 4.6 --- lib/https.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/https.c b/lib/https.c index 6a229fe..e982883 100644 --- a/lib/https.c +++ b/lib/https.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -929,11 +930,18 @@ https_send(struct https_request *req, const char *method, const char *uri, char *qs, *p, date[128]; int i, n, is_get; time_t t; + locale_t c_locale; req->done = 0; t = time(NULL) + time_offset; /* adjust time by offset */ - strftime(date, sizeof date, "%a, %d %b %Y %T %z", localtime(&t)); + c_locale = newlocale(LC_TIME_MASK, "C", (locale_t)0); + if (c_locale == (locale_t)0) { + ctx.errstr = "Failed to create C locale"; + return (HTTPS_ERR_LIB); + } + strftime_l(date, sizeof date, "%a, %d %b %Y %T +0000", gmtime(&t), c_locale); + freelocale(c_locale); /* Generate query string and canonical request to sign */ if ((qs = _argv_to_qs(argc, argv)) == NULL) {