Skip to content

Commit 21f5f8f

Browse files
Fix parsing of server DateTime (#1499)
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 e343dc1 commit 21f5f8f

File tree

1 file changed

+29
-4
lines changed

1 file changed

+29
-4
lines changed

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

Lines changed: 29 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,39 @@ 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+
const auto format = "%a, %d %b %Y %H:%M:%S %Z";
113+
const auto parsed_until = ::strptime(value.c_str(), format, &tm);
114+
if (parsed_until != value.c_str() + value.size()) {
115+
OLP_SDK_LOG_WARNING(kLogTag, "Timestamp is not fully parsed" << value);
116+
}
105117
return timegm(&tm);
106118
}
107119

120+
#endif
121+
122+
std::time_t GmtEpochOffset() {
123+
const auto epoch_as_date_time = "Thu, 1 Jan 1970 0:00:00 GMT";
124+
return DoParseTime(epoch_as_date_time);
125+
}
126+
127+
std::time_t ParseTime(const std::string& value) {
128+
const auto time = DoParseTime(value);
129+
const auto offset = GmtEpochOffset();
130+
return time - offset;
131+
}
132+
108133
boost::optional<std::time_t> GetTimestampFromHeaders(
109134
const olp::http::Headers& headers) {
110135
auto it =

0 commit comments

Comments
 (0)