Skip to content

Commit 3e944d2

Browse files
authored
Fixed issues created by the date string being localized (#2217)
1 parent 1765223 commit 3e944d2

File tree

7 files changed

+46
-8
lines changed

7 files changed

+46
-8
lines changed

.github/workflows/cmake.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,12 @@ jobs:
173173
sudo apt-get install -y libjsoncpp-dev uuid-dev libssl-dev zlib1g-dev libsqlite3-dev
174174
sudo apt-get install -y ninja-build libbrotli-dev
175175
sudo apt-get install -y libspdlog-dev
176+
177+
- name: Install and update locales
178+
run: |
179+
sudo apt-get install -y locales
180+
sudo locale-gen en_US && sudo locale-gen en_US.UTF-8
181+
sudo update-locale LC_ALL=en_US.UTF-8
176182
177183
- name: Install postgresql
178184
run: |

lib/inc/drogon/utils/Utilities.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,12 @@ DROGON_EXPORT std::string brotliDecompress(const char *data,
301301
DROGON_EXPORT char *getHttpFullDate(
302302
const trantor::Date &date = trantor::Date::now());
303303

304+
DROGON_EXPORT const std::string &getHttpFullDateStr(
305+
const trantor::Date &date = trantor::Date::now());
306+
307+
DROGON_EXPORT void dateToCustomFormattedString(const std::string &fmtStr,
308+
std::string &str,
309+
const trantor::Date &date);
304310
/// Get the trantor::Date object according to the http full date string
305311
/**
306312
* Returns trantor::Date(std::numeric_limits<int64_t>::max()) upon failure.

lib/src/Cookie.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ std::string Cookie::cookieString() const
3030
expiresDate_.microSecondsSinceEpoch() >= 0)
3131
{
3232
ret.append("Expires=")
33-
.append(utils::getHttpFullDate(expiresDate_))
33+
.append(utils::getHttpFullDateStr(expiresDate_))
3434
.append("; ");
3535
}
3636
if (maxAge_.has_value())

lib/src/HttpResponseImpl.cc

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -632,8 +632,7 @@ void HttpResponseImpl::renderToBuffer(trantor::MsgBuffer &buffer)
632632
drogon::HttpAppFrameworkImpl::instance().sendDateHeader())
633633
{
634634
buffer.append("date: ");
635-
buffer.append(utils::getHttpFullDate(trantor::Date::date()),
636-
httpFullDateStringLength);
635+
buffer.append(utils::getHttpFullDateStr(trantor::Date::date()));
637636
buffer.append("\r\n\r\n");
638637
}
639638
else
@@ -706,8 +705,7 @@ std::shared_ptr<trantor::MsgBuffer> HttpResponseImpl::renderToBuffer()
706705
{
707706
httpString->append("date: ");
708707
auto datePos = httpString->readableBytes();
709-
httpString->append(utils::getHttpFullDate(trantor::Date::date()),
710-
httpFullDateStringLength);
708+
httpString->append(utils::getHttpFullDateStr(trantor::Date::date()));
711709
httpString->append("\r\n\r\n");
712710
datePos_ = datePos;
713711
}

lib/src/Utilities.cc

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1034,6 +1034,35 @@ char *getHttpFullDate(const trantor::Date &date)
10341034
return lastTimeString;
10351035
}
10361036

1037+
void dateToCustomFormattedString(const std::string &fmtStr,
1038+
std::string &str,
1039+
const trantor::Date &date)
1040+
{
1041+
auto nowSecond = date.microSecondsSinceEpoch() / MICRO_SECONDS_PRE_SEC;
1042+
time_t seconds = static_cast<time_t>(nowSecond);
1043+
struct tm tm_LValue = date.tmStruct();
1044+
std::stringstream Out;
1045+
Out.imbue(std::locale{"en_US"});
1046+
Out << std::put_time(&tm_LValue, fmtStr.c_str());
1047+
str = Out.str();
1048+
}
1049+
1050+
const std::string &getHttpFullDateStr(const trantor::Date &date)
1051+
{
1052+
static thread_local int64_t lastSecond = 0;
1053+
static thread_local std::string lastTimeString(128, 0);
1054+
auto nowSecond = date.microSecondsSinceEpoch() / MICRO_SECONDS_PRE_SEC;
1055+
if (nowSecond == lastSecond)
1056+
{
1057+
return lastTimeString;
1058+
}
1059+
lastSecond = nowSecond;
1060+
dateToCustomFormattedString("%a, %d %b %Y %H:%M:%S GMT",
1061+
lastTimeString,
1062+
date);
1063+
return lastTimeString;
1064+
}
1065+
10371066
trantor::Date getHttpDate(const std::string &httpFullDateString)
10381067
{
10391068
static const std::array<const char *, 4> formats = {

lib/tests/integration_test/server/main.cc

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -408,8 +408,7 @@ int main()
408408
app().registerCustomExtensionMime("md", "text/markdown");
409409
app().setFileTypes({"md", "html", "jpg", "cc", "txt"});
410410
std::cout << "Date: "
411-
<< std::string{drogon::utils::getHttpFullDate(
412-
trantor::Date::now())}
411+
<< drogon::utils::getHttpFullDateStr(trantor::Date::now())
413412
<< std::endl;
414413

415414
app().registerBeginningAdvice(

lib/tests/unittests/HttpFullDateTest.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ using namespace drogon;
77

88
DROGON_TEST(HttpFullDateTest)
99
{
10-
auto str = utils::getHttpFullDate();
10+
auto str = utils::getHttpFullDateStr();
1111
auto date = utils::getHttpDate(str);
1212
CHECK(utils::getHttpFullDate(date) == str);
1313
}

0 commit comments

Comments
 (0)