Skip to content

Commit be42396

Browse files
Fix parsing of server DateTime
std::get_time does not claim support of time zones in the string parameter, and seems to be subject of locale set on the system. An example is a following result on linux: ParseTime(Thu, 1 Jan 1970 0:00:00 GMT)=-2209075200 ::strptime is also a subject to the time zones of locale, but it also claim support for parsing a time zone from the passed string. Thus, additional logic incorporated to offset parsed DataTime to the local timezone. Relates-To: IOTSDK-24021 Signed-off-by: Mykhailo Diachenko <ext-mykhailo.z.diachenko@here.com>
1 parent 6d25648 commit be42396

File tree

1 file changed

+30
-4
lines changed

1 file changed

+30
-4
lines changed

olp-cpp-sdk-authentication/src/AuthenticationClientUtils.cpp

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "ResponseFromJsonBuilder.h"
3333
#include "olp/core/http/NetworkResponse.h"
3434
#include "olp/core/http/NetworkUtils.h"
35+
#include "olp/core/logging/Log.h"
3536
#include "olp/core/utils/Base64.h"
3637
#include "olp/core/utils/Url.h"
3738

@@ -55,6 +56,7 @@ constexpr auto kOauthTimestamp = "oauth_timestamp";
5556
constexpr auto kOauthSignatureMethod = "oauth_signature_method";
5657
constexpr auto kVersion = "1.0";
5758
constexpr auto kHmac = "HMAC-SHA256";
59+
constexpr auto kLogTag = "AuthenticationClientUtils";
5860

5961
std::string Base64Encode(const Crypto::Sha256Digest& digest) {
6062
std::string ret = olp::utils::Base64Encode(digest.data(), digest.size());
@@ -95,16 +97,40 @@ namespace client = olp::client;
9597
constexpr auto kDate = "date";
9698

9799
#ifdef _WIN32
98-
#define timegm _mkgmtime
99-
#endif
100-
101-
std::time_t ParseTime(const std::string& value) {
100+
// Windows does not have ::strptime and ::timegm
101+
std::time_t doParseTime(const std::string& value) {
102102
std::tm tm = {};
103103
std::istringstream ss(value);
104104
ss >> std::get_time(&tm, "%a, %d %b %Y %H:%M:%S %z");
105+
return _mkgmtime(&tm);
106+
}
107+
108+
#else
109+
110+
std::time_t doParseTime(const std::string& value) {
111+
std::tm tm = {};
112+
std::istringstream ss(value);
113+
const auto format = "%a, %d %b %Y %H:%M:%S %Z";
114+
const auto parsedUntil = ::strptime(value.c_str(), format, &tm);
115+
if (parsedUntil != value.c_str() + value.size()) {
116+
OLP_SDK_LOG_WARNING(kLogTag, "Timestamp is not fully parsed" << value);
117+
}
105118
return timegm(&tm);
106119
}
107120

121+
#endif
122+
123+
std::time_t gmtEpochOffset() {
124+
const auto epochAsDateTime = "Thu, 1 Jan 1970 0:00:00 GMT";
125+
return doParseTime(epochAsDateTime);
126+
}
127+
128+
std::time_t ParseTime(const std::string& value) {
129+
const auto time = doParseTime(value);
130+
const auto offset = gmtEpochOffset();
131+
return time - offset;
132+
}
133+
108134
boost::optional<std::time_t> GetTimestampFromHeaders(
109135
const olp::http::Headers& headers) {
110136
auto it =

0 commit comments

Comments
 (0)