Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/map
diff options
context:
space:
mode:
authorDaria Volvenkova <d.volvenkova@corp.mail.ru>2018-09-18 20:03:22 +0300
committerRoman Kuznetsov <r.kuznetsow@gmail.com>2018-09-18 20:41:11 +0300
commitfccd6c01204ab3b95d1af494bd610efc3a5afa2b (patch)
tree418d5f20918a11dbaeb3e58fe10968dd6cc5de1a /map
parente0d62d7c72111656ca854c2498a9114e69c6c83a (diff)
Use several attempts to verify purchase.
Diffstat (limited to 'map')
-rw-r--r--map/purchase.cpp102
-rw-r--r--map/purchase.hpp3
2 files changed, 66 insertions, 39 deletions
diff --git a/map/purchase.cpp b/map/purchase.cpp
index 8bbdb46b70..9fcc3976b7 100644
--- a/map/purchase.cpp
+++ b/map/purchase.cpp
@@ -30,6 +30,10 @@ std::string const kReceiptType = "google";
std::string const kReceiptType {};
#endif
+uint32_t constexpr kFirstWaitingTimeInSec = 1;
+uint32_t constexpr kWaitingTimeScaleFactor = 2;
+uint8_t constexpr kMaxAttemptIndex = 2;
+
std::string GetClientIdHash()
{
return coding::SHA1::CalculateBase64ForString(GetPlatform().UniqueClientId());
@@ -167,59 +171,79 @@ void Purchase::Validate(ValidationInfo const & validationInfo, std::string const
GetPlatform().RunTask(Platform::Thread::Network, [this, url, validationInfo, accessToken]()
{
- platform::HttpClient request(url);
- request.SetRawHeader("Accept", "application/json");
- request.SetRawHeader("User-Agent", GetPlatform().GetAppUserAgent());
- if (!accessToken.empty())
- request.SetRawHeader("Authorization", "Bearer " + accessToken);
+ ValidateImpl(url, validationInfo, accessToken, 0 /* attemptIndex */, kFirstWaitingTimeInSec);
+ });
+}
- std::string jsonStr;
+void Purchase::ValidateImpl(std::string const & url, ValidationInfo const & validationInfo,
+ std::string const & accessToken, uint8_t attemptIndex, uint32_t waitingTimeInSeconds)
+{
+ platform::HttpClient request(url);
+ request.SetRawHeader("Accept", "application/json");
+ request.SetRawHeader("User-Agent", GetPlatform().GetAppUserAgent());
+ if (!accessToken.empty())
+ request.SetRawHeader("Authorization", "Bearer " + accessToken);
+
+ std::string jsonStr;
+ {
+ using Sink = MemWriter<std::string>;
+ Sink sink(jsonStr);
+ coding::SerializerJson<Sink> serializer(sink);
+ serializer(ValidationData(validationInfo, kReceiptType, GetDeviceId()));
+ }
+ request.SetBodyData(std::move(jsonStr), "application/json");
+
+ ValidationCode code = ValidationCode::ServerError;
+ if (request.RunHttpRequest())
+ {
+ auto const resultCode = request.ErrorCode();
+ if (resultCode >= 200 && resultCode < 300)
{
- using Sink = MemWriter<std::string>;
- Sink sink(jsonStr);
- coding::SerializerJson<Sink> serializer(sink);
- serializer(ValidationData(validationInfo, kReceiptType, GetDeviceId()));
+ code = ValidationCode::Verified;
}
- request.SetBodyData(std::move(jsonStr), "application/json");
-
- ValidationCode code = ValidationCode::ServerError;
- if (request.RunHttpRequest())
+ else if (resultCode >= 400 && resultCode < 500)
{
- auto const resultCode = request.ErrorCode();
- if (resultCode >= 200 && resultCode < 300)
- {
- code = ValidationCode::Verified;
- }
- else if (resultCode >= 400 && resultCode < 500)
- {
- code = ValidationCode::NotVerified;
-
- ValidationResult result;
- try
- {
- coding::DeserializerJson deserializer(request.ServerResponse());
- deserializer(result);
- }
- catch(coding::DeserializerJson::Exception const &) {}
-
- if (!result.m_reason.empty())
- LOG(LWARNING, ("Validation error:", result.m_reason));
- }
- else
+ code = ValidationCode::NotVerified;
+
+ ValidationResult result;
+ try
{
- LOG(LWARNING, ("Unexpected validation error. Code =", resultCode,
- request.ServerResponse()));
+ coding::DeserializerJson deserializer(request.ServerResponse());
+ deserializer(result);
}
+ catch(coding::DeserializerJson::Exception const &) {}
+
+ if (!result.m_reason.empty())
+ LOG(LWARNING, ("Validation error:", result.m_reason));
}
else
{
- LOG(LWARNING, ("Validation request failed."));
+ LOG(LWARNING, ("Unexpected validation error. Code =", resultCode,
+ request.ServerResponse()));
}
+ }
+ else
+ {
+ LOG(LWARNING, ("Validation request failed."));
+ }
+ if (code == ValidationCode::ServerError && attemptIndex < kMaxAttemptIndex)
+ {
+ auto const delayTime = std::chrono::seconds(waitingTimeInSeconds);
+ ++attemptIndex;
+ waitingTimeInSeconds *= kWaitingTimeScaleFactor;
+ GetPlatform().RunDelayedTask(Platform::Thread::Network, delayTime,
+ [this, url, validationInfo, accessToken, attemptIndex, waitingTimeInSeconds]()
+ {
+ ValidateImpl(url, validationInfo, accessToken, attemptIndex, waitingTimeInSeconds);
+ });
+ }
+ else
+ {
GetPlatform().RunTask(Platform::Thread::Gui, [this, code, validationInfo]()
{
if (m_validationCallback)
m_validationCallback(code, validationInfo);
});
- });
+ }
}
diff --git a/map/purchase.hpp b/map/purchase.hpp
index f52a2884b4..1d31ef5614 100644
--- a/map/purchase.hpp
+++ b/map/purchase.hpp
@@ -51,6 +51,9 @@ public:
void Validate(ValidationInfo const & validationInfo, std::string const & accessToken);
private:
+ void ValidateImpl(std::string const & url, ValidationInfo const & validationInfo,
+ std::string const & accessToken, uint8_t attemptIndex, uint32_t waitingTimeInSeconds);
+
struct RemoveAdsSubscriptionData
{
std::atomic<bool> m_isActive;