CLOUD: Make OneDriveStorage::download() work fine
Well, it takes two API calls instead of one now, but there are no problems with expired token because of it. This commit changes Storage::streamFile() to pass NetworkReadStream * through callback.
This commit is contained in:
parent
24007c029b
commit
83b349a033
13 changed files with 77 additions and 36 deletions
|
@ -27,25 +27,39 @@
|
||||||
|
|
||||||
namespace Cloud {
|
namespace Cloud {
|
||||||
|
|
||||||
DownloadRequest::DownloadRequest(Storage::BoolCallback callback, Networking::NetworkReadStream *stream, Common::DumpFile *dumpFile):
|
DownloadRequest::DownloadRequest(Storage *storage, Storage::BoolCallback callback, Common::String remoteFile, Common::DumpFile *dumpFile):
|
||||||
Request(0), _boolCallback(callback), _remoteFileStream(stream), _localFile(dumpFile) {}
|
Request(0), _boolCallback(callback), _remoteFileStream(0), _localFile(dumpFile) {
|
||||||
|
storage->streamFile(remoteFile, new Common::Callback<DownloadRequest, Storage::RequestReadStreamPair>(this, &DownloadRequest::streamCallback));
|
||||||
|
}
|
||||||
|
|
||||||
void DownloadRequest::handle() {
|
void DownloadRequest::streamCallback(Storage::RequestReadStreamPair pair) {
|
||||||
if (!_remoteFileStream) {
|
if (!pair.value) {
|
||||||
warning("DownloadRequest: no stream to read");
|
warning("DownloadRequest: no ReadStream passed");
|
||||||
ConnMan.getRequestInfo(_id).state = Networking::FINISHED;
|
ConnMan.getRequestInfo(_id).state = Networking::FINISHED;
|
||||||
|
if (_boolCallback) (*_boolCallback)(Storage::RequestBoolPair(_id, false));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_remoteFileStream = (Networking::NetworkReadStream *)pair.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DownloadRequest::handle() {
|
||||||
if (!_localFile) {
|
if (!_localFile) {
|
||||||
warning("DownloadRequest: no file to write");
|
warning("DownloadRequest: no file to write");
|
||||||
ConnMan.getRequestInfo(_id).state = Networking::FINISHED;
|
ConnMan.getRequestInfo(_id).state = Networking::FINISHED;
|
||||||
|
if (_boolCallback) (*_boolCallback)(Storage::RequestBoolPair(_id, false));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_localFile->isOpen()) {
|
if (!_localFile->isOpen()) {
|
||||||
warning("DownloadRequest: failed to open file to write");
|
warning("DownloadRequest: failed to open file to write");
|
||||||
ConnMan.getRequestInfo(_id).state = Networking::FINISHED;
|
ConnMan.getRequestInfo(_id).state = Networking::FINISHED;
|
||||||
|
if (_boolCallback) (*_boolCallback)(Storage::RequestBoolPair(_id, false));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_remoteFileStream) {
|
||||||
|
//waiting for callback
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,8 +35,9 @@ class DownloadRequest: public Networking::Request {
|
||||||
Networking::NetworkReadStream *_remoteFileStream;
|
Networking::NetworkReadStream *_remoteFileStream;
|
||||||
Common::DumpFile *_localFile;
|
Common::DumpFile *_localFile;
|
||||||
|
|
||||||
|
void streamCallback(Storage::RequestReadStreamPair pair);
|
||||||
public:
|
public:
|
||||||
DownloadRequest(Storage::BoolCallback callback, Networking::NetworkReadStream *stream, Common::DumpFile *dumpFile);
|
DownloadRequest(Storage *storage, Storage::BoolCallback callback, Common::String remoteFile, Common::DumpFile *dumpFile);
|
||||||
virtual ~DownloadRequest() { delete _localFile; }
|
virtual ~DownloadRequest() { delete _localFile; }
|
||||||
|
|
||||||
virtual void handle();
|
virtual void handle();
|
||||||
|
|
|
@ -88,7 +88,7 @@ int32 DropboxStorage::listDirectory(Common::String path, FileArrayCallback outer
|
||||||
return ConnMan.addRequest(new DropboxListDirectoryRequest(_token, path, outerCallback, recursive));
|
return ConnMan.addRequest(new DropboxListDirectoryRequest(_token, path, outerCallback, recursive));
|
||||||
}
|
}
|
||||||
|
|
||||||
Networking::NetworkReadStream *DropboxStorage::streamFile(Common::String path) {
|
int32 DropboxStorage::streamFile(Common::String path, ReadStreamCallback callback) {
|
||||||
Common::JSONObject jsonRequestParameters;
|
Common::JSONObject jsonRequestParameters;
|
||||||
jsonRequestParameters.setVal("path", new Common::JSONValue(path));
|
jsonRequestParameters.setVal("path", new Common::JSONValue(path));
|
||||||
Common::JSONValue value(jsonRequestParameters);
|
Common::JSONValue value(jsonRequestParameters);
|
||||||
|
@ -98,7 +98,9 @@ Networking::NetworkReadStream *DropboxStorage::streamFile(Common::String path) {
|
||||||
request->addHeader("Dropbox-API-Arg: " + Common::JSON::stringify(&value));
|
request->addHeader("Dropbox-API-Arg: " + Common::JSON::stringify(&value));
|
||||||
request->addHeader("Content-Type: "); //required to be empty (as we do POST, it's usually app/form-url-encoded)
|
request->addHeader("Content-Type: "); //required to be empty (as we do POST, it's usually app/form-url-encoded)
|
||||||
|
|
||||||
return request->execute();
|
RequestReadStreamPair pair = request->execute();
|
||||||
|
if (callback) (*callback)(pair);
|
||||||
|
return pair.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 DropboxStorage::download(Common::String remotePath, Common::String localPath, BoolCallback callback) {
|
int32 DropboxStorage::download(Common::String remotePath, Common::String localPath, BoolCallback callback) {
|
||||||
|
@ -110,7 +112,7 @@ int32 DropboxStorage::download(Common::String remotePath, Common::String localPa
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ConnMan.addRequest(new DownloadRequest(callback, streamFile(remotePath), f));
|
return ConnMan.addRequest(new DownloadRequest(this, callback, remotePath, f));
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 DropboxStorage::syncSaves(BoolCallback callback) {
|
int32 DropboxStorage::syncSaves(BoolCallback callback) {
|
||||||
|
|
|
@ -71,7 +71,7 @@ public:
|
||||||
virtual int32 upload(Common::String path, Common::ReadStream *contents, BoolCallback callback) { return -1; } //TODO
|
virtual int32 upload(Common::String path, Common::ReadStream *contents, BoolCallback callback) { return -1; } //TODO
|
||||||
|
|
||||||
/** Returns pointer to Networking::NetworkReadStream. */
|
/** Returns pointer to Networking::NetworkReadStream. */
|
||||||
virtual Networking::NetworkReadStream *streamFile(Common::String path);
|
virtual int32 streamFile(Common::String path, ReadStreamCallback callback);
|
||||||
|
|
||||||
/** Calls the callback when finished. */
|
/** Calls the callback when finished. */
|
||||||
virtual int32 download(Common::String remotePath, Common::String localPath, BoolCallback callback);
|
virtual int32 download(Common::String remotePath, Common::String localPath, BoolCallback callback);
|
||||||
|
|
|
@ -126,14 +126,35 @@ void OneDriveStorage::printJson(Networking::RequestJsonPair pair) {
|
||||||
delete json;
|
delete json;
|
||||||
}
|
}
|
||||||
|
|
||||||
Networking::NetworkReadStream *OneDriveStorage::streamFile(Common::String path) {
|
void OneDriveStorage::fileInfoCallback(ReadStreamCallback outerCallback, Networking::RequestJsonPair pair) {
|
||||||
Common::String url = "https://api.onedrive.com/v1.0/drive/special/approot:/" + path + ":/content";
|
if (!pair.value) {
|
||||||
//NOT USING OneDriveTokenRefresher, because it's CurlJsonRequest, which saves all contents in memory to parse as JSON
|
warning("fileInfoCallback: NULL");
|
||||||
//we actually don't even need a token if the download is "pre-authenticated" (whatever it means)
|
if (outerCallback) (*outerCallback)(RequestReadStreamPair(pair.id, 0));
|
||||||
//still, we'd have to know direct URL (might be found in Item's "@content.downloadUrl", received from the server)
|
return;
|
||||||
Networking::CurlRequest *request = new Networking::CurlRequest(0, url.c_str());
|
}
|
||||||
|
|
||||||
|
Common::JSONObject result = pair.value->asObject();
|
||||||
|
if (result.contains("@content.downloadUrl")) {
|
||||||
|
const char *url = result.getVal("@content.downloadUrl")->asString().c_str();
|
||||||
|
if (outerCallback)
|
||||||
|
(*outerCallback)(RequestReadStreamPair(
|
||||||
|
pair.id,
|
||||||
|
new Networking::NetworkReadStream(url, 0, "")
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
warning("downloadUrl not found in passed JSON");
|
||||||
|
debug("%s", pair.value->stringify().c_str());
|
||||||
|
if (outerCallback) (*outerCallback)(RequestReadStreamPair(pair.id, 0));
|
||||||
|
}
|
||||||
|
delete pair.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 OneDriveStorage::streamFile(Common::String path, ReadStreamCallback outerCallback) {
|
||||||
|
Common::String url = "https://api.onedrive.com/v1.0/drive/special/approot:/" + path + ":/";
|
||||||
|
Networking::JsonCallback innerCallback = new Common::CallbackBridge<OneDriveStorage, RequestReadStreamPair, Networking::RequestJsonPair>(this, &OneDriveStorage::fileInfoCallback, outerCallback);
|
||||||
|
Networking::CurlJsonRequest *request = new OneDriveTokenRefresher(this, innerCallback, url.c_str());
|
||||||
request->addHeader("Authorization: Bearer " + _token);
|
request->addHeader("Authorization: Bearer " + _token);
|
||||||
return request->execute();
|
return ConnMan.addRequest(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 OneDriveStorage::download(Common::String remotePath, Common::String localPath, BoolCallback callback) {
|
int32 OneDriveStorage::download(Common::String remotePath, Common::String localPath, BoolCallback callback) {
|
||||||
|
@ -145,7 +166,7 @@ int32 OneDriveStorage::download(Common::String remotePath, Common::String localP
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ConnMan.addRequest(new DownloadRequest(callback, streamFile(remotePath), f));
|
return ConnMan.addRequest(new DownloadRequest(this, callback, remotePath, f));
|
||||||
}
|
}
|
||||||
|
|
||||||
void OneDriveStorage::fileDownloaded(RequestBoolPair pair) {
|
void OneDriveStorage::fileDownloaded(RequestBoolPair pair) {
|
||||||
|
|
|
@ -49,6 +49,8 @@ class OneDriveStorage: public Cloud::Storage {
|
||||||
|
|
||||||
void printJson(Networking::RequestJsonPair pair);
|
void printJson(Networking::RequestJsonPair pair);
|
||||||
void fileDownloaded(RequestBoolPair pair);
|
void fileDownloaded(RequestBoolPair pair);
|
||||||
|
|
||||||
|
void fileInfoCallback(ReadStreamCallback outerCallback, Networking::RequestJsonPair pair);
|
||||||
public:
|
public:
|
||||||
virtual ~OneDriveStorage();
|
virtual ~OneDriveStorage();
|
||||||
|
|
||||||
|
@ -75,7 +77,7 @@ public:
|
||||||
virtual int32 upload(Common::String path, Common::ReadStream *contents, BoolCallback callback) { return -1; } //TODO
|
virtual int32 upload(Common::String path, Common::ReadStream *contents, BoolCallback callback) { return -1; } //TODO
|
||||||
|
|
||||||
/** Returns pointer to Networking::NetworkReadStream. */
|
/** Returns pointer to Networking::NetworkReadStream. */
|
||||||
virtual int32 streamFile(Common::String path);
|
virtual int32 streamFile(Common::String path, ReadStreamCallback callback);
|
||||||
|
|
||||||
/** Calls the callback when finished. */
|
/** Calls the callback when finished. */
|
||||||
virtual int32 download(Common::String remotePath, Common::String localPath, BoolCallback callback);
|
virtual int32 download(Common::String remotePath, Common::String localPath, BoolCallback callback);
|
||||||
|
|
|
@ -109,7 +109,7 @@ void OneDriveTokenRefresher::restart() {
|
||||||
if (_jsonCallback) (*_jsonCallback)(Networking::RequestJsonPair(_id, 0));
|
if (_jsonCallback) (*_jsonCallback)(Networking::RequestJsonPair(_id, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
Networking::NetworkReadStream *OneDriveTokenRefresher::execute() {
|
Cloud::Storage::RequestReadStreamPair OneDriveTokenRefresher::execute() {
|
||||||
if (!_started) {
|
if (!_started) {
|
||||||
for (uint32 i = 0; i < _headers.size(); ++i)
|
for (uint32 i = 0; i < _headers.size(); ++i)
|
||||||
_innerRequest->addHeader(_headers[i]);
|
_innerRequest->addHeader(_headers[i]);
|
||||||
|
|
|
@ -52,7 +52,7 @@ public:
|
||||||
virtual void setHeaders(Common::Array<Common::String> &headers) { _headers = headers; }
|
virtual void setHeaders(Common::Array<Common::String> &headers) { _headers = headers; }
|
||||||
virtual void addHeader(Common::String header) { _headers.push_back(header); }
|
virtual void addHeader(Common::String header) { _headers.push_back(header); }
|
||||||
virtual void addPostField(Common::String field) { _innerRequest->addPostField(field); }
|
virtual void addPostField(Common::String field) { _innerRequest->addPostField(field); }
|
||||||
virtual Networking::NetworkReadStream *execute();
|
virtual Cloud::Storage::RequestReadStreamPair execute();
|
||||||
};
|
};
|
||||||
|
|
||||||
} //end of namespace OneDrive
|
} //end of namespace OneDrive
|
||||||
|
|
|
@ -37,7 +37,7 @@ namespace Cloud {
|
||||||
class Storage {
|
class Storage {
|
||||||
public:
|
public:
|
||||||
typedef Networking::RequestIdPair<Common::Array<StorageFile>&> RequestFileArrayPair;
|
typedef Networking::RequestIdPair<Common::Array<StorageFile>&> RequestFileArrayPair;
|
||||||
typedef Networking::RequestIdPair<Common::ReadStream *> RequestReadStreamPair;
|
typedef Networking::RequestIdPair<Networking::NetworkReadStream *> RequestReadStreamPair;
|
||||||
typedef Networking::RequestIdPair<StorageInfo> RequestStorageInfoPair;
|
typedef Networking::RequestIdPair<StorageInfo> RequestStorageInfoPair;
|
||||||
typedef Networking::RequestIdPair<bool> RequestBoolPair;
|
typedef Networking::RequestIdPair<bool> RequestBoolPair;
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ public:
|
||||||
virtual int32 upload(Common::String path, Common::ReadStream *contents, BoolCallback callback) = 0;
|
virtual int32 upload(Common::String path, Common::ReadStream *contents, BoolCallback callback) = 0;
|
||||||
|
|
||||||
/** Returns pointer to Networking::NetworkReadStream. */
|
/** Returns pointer to Networking::NetworkReadStream. */
|
||||||
virtual Networking::NetworkReadStream *streamFile(Common::String path) = 0; //TODO: return int32 somehow
|
virtual int32 streamFile(Common::String path, ReadStreamCallback callback) = 0;
|
||||||
|
|
||||||
/** Calls the callback when finished. */
|
/** Calls the callback when finished. */
|
||||||
virtual int32 download(Common::String remotePath, Common::String localPath, BoolCallback callback) = 0;
|
virtual int32 download(Common::String remotePath, Common::String localPath, BoolCallback callback) = 0;
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
|
|
||||||
namespace Networking {
|
namespace Networking {
|
||||||
|
|
||||||
CurlJsonRequest::CurlJsonRequest(JsonCallback cb, const char *url):
|
CurlJsonRequest::CurlJsonRequest(JsonCallback cb, Common::String url):
|
||||||
CurlRequest(0, url), _jsonCallback(cb), _contentsStream(DisposeAfterUse::YES) {}
|
CurlRequest(0, url), _jsonCallback(cb), _contentsStream(DisposeAfterUse::YES) {}
|
||||||
|
|
||||||
CurlJsonRequest::~CurlJsonRequest() {}
|
CurlJsonRequest::~CurlJsonRequest() {}
|
||||||
|
@ -55,7 +55,7 @@ char *CurlJsonRequest::getPreparedContents() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CurlJsonRequest::handle() {
|
void CurlJsonRequest::handle() {
|
||||||
if (!_stream) _stream = new NetworkReadStream(_url, _headersList, _postFields);
|
if (!_stream) _stream = new NetworkReadStream(_url.c_str(), _headersList, _postFields);
|
||||||
|
|
||||||
if (_stream) {
|
if (_stream) {
|
||||||
const int kBufSize = 16*1024;
|
const int kBufSize = 16*1024;
|
||||||
|
|
|
@ -42,7 +42,7 @@ class CurlJsonRequest: public CurlRequest {
|
||||||
char *getPreparedContents();
|
char *getPreparedContents();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CurlJsonRequest(JsonCallback cb, const char *url);
|
CurlJsonRequest(JsonCallback cb, Common::String url);
|
||||||
virtual ~CurlJsonRequest();
|
virtual ~CurlJsonRequest();
|
||||||
|
|
||||||
virtual void handle();
|
virtual void handle();
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
|
|
||||||
namespace Networking {
|
namespace Networking {
|
||||||
|
|
||||||
CurlRequest::CurlRequest(DataCallback cb, const char *url):
|
CurlRequest::CurlRequest(DataCallback cb, Common::String url):
|
||||||
Request(cb), _url(url), _stream(0), _headersList(0) {}
|
Request(cb), _url(url), _stream(0), _headersList(0) {}
|
||||||
|
|
||||||
CurlRequest::~CurlRequest() {
|
CurlRequest::~CurlRequest() {
|
||||||
|
@ -38,7 +38,7 @@ CurlRequest::~CurlRequest() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CurlRequest::handle() {
|
void CurlRequest::handle() {
|
||||||
if (!_stream) _stream = new NetworkReadStream(_url, _headersList, _postFields);
|
if (!_stream) _stream = new NetworkReadStream(_url.c_str(), _headersList, _postFields);
|
||||||
|
|
||||||
if (_stream && _stream->eos()) {
|
if (_stream && _stream->eos()) {
|
||||||
if (_stream->httpResponseCode() != 200)
|
if (_stream->httpResponseCode() != 200)
|
||||||
|
@ -71,13 +71,13 @@ void CurlRequest::addPostField(Common::String keyValuePair) {
|
||||||
_postFields += "&" + keyValuePair;
|
_postFields += "&" + keyValuePair;
|
||||||
}
|
}
|
||||||
|
|
||||||
NetworkReadStream *CurlRequest::execute() {
|
Cloud::Storage::RequestReadStreamPair CurlRequest::execute() {
|
||||||
if (!_stream) {
|
if (!_stream) {
|
||||||
_stream = new NetworkReadStream(_url, _headersList, _postFields);
|
_stream = new NetworkReadStream(_url.c_str(), _headersList, _postFields);
|
||||||
ConnMan.addRequest(this);
|
ConnMan.addRequest(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
return _stream;
|
return Cloud::Storage::RequestReadStreamPair(_id, _stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
} //end of namespace Networking
|
} //end of namespace Networking
|
||||||
|
|
|
@ -24,8 +24,9 @@
|
||||||
#define BACKENDS_NETWORKING_CURL_CURLREQUEST_H
|
#define BACKENDS_NETWORKING_CURL_CURLREQUEST_H
|
||||||
|
|
||||||
#include "backends/networking/curl/request.h"
|
#include "backends/networking/curl/request.h"
|
||||||
|
#include "backends/cloud/storage.h"
|
||||||
#include "common/str.h"
|
#include "common/str.h"
|
||||||
#include <common/array.h>
|
#include "common/array.h"
|
||||||
|
|
||||||
struct curl_slist;
|
struct curl_slist;
|
||||||
|
|
||||||
|
@ -35,13 +36,13 @@ class NetworkReadStream;
|
||||||
|
|
||||||
class CurlRequest: public Request {
|
class CurlRequest: public Request {
|
||||||
protected:
|
protected:
|
||||||
const char *_url;
|
Common::String _url;
|
||||||
NetworkReadStream *_stream;
|
NetworkReadStream *_stream;
|
||||||
curl_slist *_headersList;
|
curl_slist *_headersList;
|
||||||
Common::String _postFields;
|
Common::String _postFields;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CurlRequest(DataCallback cb, const char *url);
|
CurlRequest(DataCallback cb, Common::String url);
|
||||||
virtual ~CurlRequest();
|
virtual ~CurlRequest();
|
||||||
|
|
||||||
virtual void handle();
|
virtual void handle();
|
||||||
|
@ -51,8 +52,8 @@ public:
|
||||||
virtual void addHeader(Common::String header);
|
virtual void addHeader(Common::String header);
|
||||||
virtual void addPostField(Common::String field);
|
virtual void addPostField(Common::String field);
|
||||||
|
|
||||||
/** Start this Request with ConnMan. Returns its ReadStream. */
|
/** Start this Request with ConnMan. Returns its ReadStream and request id. */
|
||||||
virtual NetworkReadStream *execute();
|
virtual Cloud::Storage::RequestReadStreamPair execute();
|
||||||
};
|
};
|
||||||
|
|
||||||
} //end of namespace Networking
|
} //end of namespace Networking
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue