CLOUD: Simplify OneDriveTokenRefresher

It now just extends CurlJsonRequest, not wraps one.
This commit is contained in:
Alexander Tkachev 2016-05-27 19:32:35 +06:00
parent dcbaeb57c4
commit 6c01edc57a
3 changed files with 44 additions and 94 deletions

View file

@ -23,10 +23,7 @@
#include "backends/cloud/onedrive/onedrivetokenrefresher.h" #include "backends/cloud/onedrive/onedrivetokenrefresher.h"
#include "backends/cloud/onedrive/onedrivestorage.h" #include "backends/cloud/onedrive/onedrivestorage.h"
#include "backends/networking/curl/connectionmanager.h"
#include "backends/networking/curl/curljsonrequest.h"
#include "backends/networking/curl/networkreadstream.h" #include "backends/networking/curl/networkreadstream.h"
#include "common/config-manager.h"
#include "common/debug.h" #include "common/debug.h"
#include "common/json.h" #include "common/json.h"
#include <curl/curl.h> #include <curl/curl.h>
@ -35,50 +32,10 @@ namespace Cloud {
namespace OneDrive { namespace OneDrive {
OneDriveTokenRefresher::OneDriveTokenRefresher(OneDriveStorage *parent, Networking::JsonCallback callback, const char *url): OneDriveTokenRefresher::OneDriveTokenRefresher(OneDriveStorage *parent, Networking::JsonCallback callback, const char *url):
CurlJsonRequest(0, url), CurlJsonRequest(callback, url), _parentStorage(parent) {}
_parentStorage(parent),
_innerRequest(
new CurlJsonRequest(
new Common::Callback<OneDriveTokenRefresher, Networking::JsonResponse>(this, &OneDriveTokenRefresher::innerRequestCallback),
url
)
), _jsonCallback(callback), _retryRequest(nullptr), _started(false) {}
OneDriveTokenRefresher::~OneDriveTokenRefresher() {} OneDriveTokenRefresher::~OneDriveTokenRefresher() {}
void OneDriveTokenRefresher::innerRequestCallback(Networking::JsonResponse pair) {
if (!pair.value) {
//notify user of failure
warning("OneDriveTokenRefresher: got NULL instead of JSON");
finish();
return;
}
Common::JSONObject result = pair.value->asObject();
if (result.contains("error")) {
//new token needed => request token & then retry original request
CurlJsonRequest *streamRequest = (CurlJsonRequest *)pair.request;
if (streamRequest) {
const Networking::NetworkReadStream *stream = streamRequest->getNetworkReadStream();
if (stream) {
debug("code %ld", stream->httpResponseCode());
}
}
Common::JSONObject error = result.getVal("error")->asObject();
debug("code = %s", error.getVal("code")->asString().c_str());
debug("message = %s", error.getVal("message")->asString().c_str());
if (pair.request) pair.request->pause();
_retryRequest = pair.request;
delete pair.value;
_parentStorage->getAccessToken(new Common::Callback<OneDriveTokenRefresher, Storage::BoolResponse>(this, &OneDriveTokenRefresher::tokenRefreshed));
return;
}
//notify user of success
finishJson(pair.value);
}
void OneDriveTokenRefresher::tokenRefreshed(Storage::BoolResponse pair) { void OneDriveTokenRefresher::tokenRefreshed(Storage::BoolResponse pair) {
if (!pair.value) { if (!pair.value) {
//failed to refresh token, notify user with NULL in original callback //failed to refresh token, notify user with NULL in original callback
@ -87,53 +44,54 @@ void OneDriveTokenRefresher::tokenRefreshed(Storage::BoolResponse pair) {
return; return;
} }
//successfully received refreshed token, can restart the original request now
if (_retryRequest) _retryRequest->retry(1);
//update headers: first change header with token, then pass those to request //update headers: first change header with token, then pass those to request
for (uint32 i = 0; i < _headers.size(); ++i) { for (uint32 i = 0; i < _headers.size(); ++i) {
if (_headers[i].contains("Authorization")) { if (_headers[i].contains("Authorization")) {
_headers[i] = "Authorization: bearer " + _parentStorage->accessToken(); _headers[i] = "Authorization: bearer " + _parentStorage->accessToken();
} }
} }
CurlJsonRequest *retryRequest = (CurlJsonRequest *)_retryRequest; setHeaders(_headers);
if (retryRequest) retryRequest->setHeaders(_headers);
}
void OneDriveTokenRefresher::handle() { //successfully received refreshed token, can restart the original request now
if (!_started) { retry(0);
for (uint32 i = 0; i < _headers.size(); ++i)
_innerRequest->addHeader(_headers[i]);
_started = true;
ConnMan.addRequest(_innerRequest);
}
}
void OneDriveTokenRefresher::restart() {
//can't restart as all headers were passed to _innerRequest which is probably dead now
warning("OneDriveTokenRefresher: cannot be restarted");
finish();
}
void OneDriveTokenRefresher::finish() {
finishJson(0);
} }
void OneDriveTokenRefresher::finishJson(Common::JSONValue *json) { void OneDriveTokenRefresher::finishJson(Common::JSONValue *json) {
Request::finish(); if (!json) {
if (_jsonCallback) (*_jsonCallback)(Networking::JsonResponse(this, json)); //notify user of failure
warning("OneDriveTokenRefresher: got NULL instead of JSON");
CurlJsonRequest::finish();
return;
} }
Networking::NetworkReadStreamResponse OneDriveTokenRefresher::execute() { Common::JSONObject result = json->asObject();
if (!_started) { if (result.contains("error")) {
for (uint32 i = 0; i < _headers.size(); ++i) //new token needed => request token & then retry original request
_innerRequest->addHeader(_headers[i]); if (_stream) {
_started = true; debug("code %ld", _stream->httpResponseCode());
} else {
warning("OneDriveTokenRefresher: inner Request is already started");
} }
return _innerRequest->execute();
Common::JSONObject error = result.getVal("error")->asObject();
debug("code = %s", error.getVal("code")->asString().c_str());
debug("message = %s", error.getVal("message")->asString().c_str());
pause();
delete json;
_parentStorage->getAccessToken(new Common::Callback<OneDriveTokenRefresher, Storage::BoolResponse>(this, &OneDriveTokenRefresher::tokenRefreshed));
return;
} }
//notify user of success
CurlJsonRequest::finishJson(json);
}
void OneDriveTokenRefresher::setHeaders(Common::Array<Common::String> &headers) {
_headers = headers;
curl_slist_free_all(_headersList);
_headersList = 0;
for (uint32 i = 0; i < headers.size(); ++i)
CurlJsonRequest::addHeader(headers[i]);
}
} //end of namespace OneDrive } //end of namespace OneDrive
} //end of namespace Cloud } //end of namespace Cloud

View file

@ -24,7 +24,6 @@
#define BACKENDS_CLOUD_ONEDRIVE_ONEDRIVETOKENREFRESHER_H #define BACKENDS_CLOUD_ONEDRIVE_ONEDRIVETOKENREFRESHER_H
#include "backends/cloud/storage.h" #include "backends/cloud/storage.h"
#include "common/callback.h"
#include "backends/networking/curl/curljsonrequest.h" #include "backends/networking/curl/curljsonrequest.h"
namespace Cloud { namespace Cloud {
@ -35,12 +34,7 @@ class OneDriveStorage;
class OneDriveTokenRefresher: public Networking::CurlJsonRequest { class OneDriveTokenRefresher: public Networking::CurlJsonRequest {
OneDriveStorage *_parentStorage; OneDriveStorage *_parentStorage;
Common::Array<Common::String> _headers; Common::Array<Common::String> _headers;
CurlJsonRequest *_innerRequest;
Networking::JsonCallback _jsonCallback;
Request *_retryRequest;
bool _started;
void innerRequestCallback(Networking::JsonResponse pair);
void tokenRefreshed(Storage::BoolResponse pair); void tokenRefreshed(Storage::BoolResponse pair);
virtual void finishJson(Common::JSONValue *json); virtual void finishJson(Common::JSONValue *json);
@ -48,14 +42,12 @@ public:
OneDriveTokenRefresher(OneDriveStorage *parent, Networking::JsonCallback callback, const char *url); OneDriveTokenRefresher(OneDriveStorage *parent, Networking::JsonCallback callback, const char *url);
virtual ~OneDriveTokenRefresher(); virtual ~OneDriveTokenRefresher();
virtual void handle(); virtual void setHeaders(Common::Array<Common::String> &headers);
virtual void restart();
virtual void finish();
virtual void setHeaders(Common::Array<Common::String> &headers) { _headers = headers; } virtual void addHeader(Common::String header) {
virtual void addHeader(Common::String header) { _headers.push_back(header); } _headers.push_back(header);
virtual void addPostField(Common::String field) { _innerRequest->addPostField(field); } CurlJsonRequest::addHeader(header);
virtual Networking::NetworkReadStreamResponse execute(); }
}; };
} //end of namespace OneDrive } //end of namespace OneDrive

View file

@ -33,13 +33,13 @@ typedef Response<Common::JSONValue *> JsonResponse;
typedef Common::BaseCallback<JsonResponse> *JsonCallback; typedef Common::BaseCallback<JsonResponse> *JsonCallback;
class CurlJsonRequest: public CurlRequest { class CurlJsonRequest: public CurlRequest {
protected:
JsonCallback _jsonCallback; JsonCallback _jsonCallback;
Common::MemoryWriteStreamDynamic _contentsStream; Common::MemoryWriteStreamDynamic _contentsStream;
/** Prepares raw bytes from _contentsStream to be parsed with Common::JSON::parse(). */ /** Prepares raw bytes from _contentsStream to be parsed with Common::JSON::parse(). */
char *getPreparedContents(); char *getPreparedContents();
protected:
/** Sets FINISHED state and passes the JSONValue * into user's callback in JsonResponse. */ /** Sets FINISHED state and passes the JSONValue * into user's callback in JsonResponse. */
virtual void finishJson(Common::JSONValue *json); virtual void finishJson(Common::JSONValue *json);