void OneDriveListDirectoryRequest::makeRequest(Common::String url) { Networking::JsonCallback callback = new Common::Callback<OneDriveListDirectoryRequest, Networking::JsonResponse>(this, &OneDriveListDirectoryRequest::listedDirectoryCallback); Networking::ErrorCallback failureCallback = new Common::Callback<OneDriveListDirectoryRequest, Networking::ErrorResponse>(this, &OneDriveListDirectoryRequest::listedDirectoryErrorCallback); Networking::CurlJsonRequest *request = new OneDriveTokenRefresher(_storage, callback, failureCallback, url.c_str()); request->addHeader("Authorization: Bearer " + _storage->accessToken()); _workingRequest = ConnMan.addRequest(request); }
Networking::Request *OneDriveStorage::streamFileById(Common::String path, Networking::NetworkReadStreamCallback outerCallback, Networking::ErrorCallback errorCallback) { Common::String url = ONEDRIVE_API_SPECIAL_APPROOT_ID + ConnMan.urlEncode(path); Networking::JsonCallback innerCallback = new Common::CallbackBridge<OneDriveStorage, Networking::NetworkReadStreamResponse, Networking::JsonResponse>(this, &OneDriveStorage::fileInfoCallback, outerCallback); Networking::CurlJsonRequest *request = new OneDriveTokenRefresher(this, innerCallback, errorCallback, url.c_str()); request->addHeader("Authorization: Bearer " + _token); return addRequest(request); }
Networking::Request *GoogleDriveStorage::info(StorageInfoCallback callback, Networking::ErrorCallback errorCallback) { if (!callback) callback = new Common::Callback<GoogleDriveStorage, StorageInfoResponse>(this, &GoogleDriveStorage::printInfo); Networking::JsonCallback innerCallback = new Common::CallbackBridge<GoogleDriveStorage, StorageInfoResponse, Networking::JsonResponse>(this, &GoogleDriveStorage::infoInnerCallback, callback); Networking::CurlJsonRequest *request = new GoogleDriveTokenRefresher(this, innerCallback, errorCallback, GOOGLEDRIVE_API_ABOUT); request->addHeader("Authorization: Bearer " + _token); return addRequest(request); }
void GoogleDriveStorage::getAccessToken(BoolCallback callback, Networking::ErrorCallback errorCallback, Common::String code) { if (!KEY || !SECRET) loadKeyAndSecret(); bool codeFlow = (code != ""); if (!codeFlow && _refreshToken == "") { warning("GoogleDriveStorage: no refresh token available to get new access token."); if (callback) (*callback)(BoolResponse(nullptr, false)); return; } Networking::JsonCallback innerCallback = new Common::CallbackBridge<GoogleDriveStorage, BoolResponse, Networking::JsonResponse>(this, &GoogleDriveStorage::tokenRefreshed, callback); if (errorCallback == nullptr) errorCallback = getErrorPrintingCallback(); Networking::CurlJsonRequest *request = new Networking::CurlJsonRequest(innerCallback, errorCallback, GOOGLEDRIVE_OAUTH2_TOKEN); if (codeFlow) { request->addPostField("code=" + code); request->addPostField("grant_type=authorization_code"); } else { request->addPostField("refresh_token=" + _refreshToken); request->addPostField("grant_type=refresh_token"); } request->addPostField("client_id=" + Common::String(KEY)); request->addPostField("client_secret=" + Common::String(SECRET)); if (Cloud::CloudManager::couldUseLocalServer()) { request->addPostField("&redirect_uri=http%3A%2F%2Flocalhost%3A12345"); } else { request->addPostField("&redirect_uri=https%3A%2F%2Fwww.scummvm.org/c/code"); } addRequest(request); }
void OneDriveUploadRequest::partUploadedCallback(Networking::JsonResponse response) { _workingRequest = nullptr; if (_ignoreCallback) return; Networking::ErrorResponse error(this, false, true, "", -1); Networking::CurlJsonRequest *rq = (Networking::CurlJsonRequest *)response.request; if (rq && rq->getNetworkReadStream()) error.httpResponseCode = rq->getNetworkReadStream()->httpResponseCode(); Common::JSONValue *json = response.value; if (json == nullptr) { error.response = "Failed to parse JSON, null passed!"; finishError(error); return; } if (json->isObject()) { Common::JSONObject object = json->asObject(); if (object.contains("error")) { warning("OneDriveUploadRequest: error: %s", json->stringify(true).c_str()); error.response = json->stringify(true); finishError(error); delete json; return; } if (Networking::CurlJsonRequest::jsonContainsString(object, "id", "OneDriveUploadRequest") && Networking::CurlJsonRequest::jsonContainsString(object, "name", "OneDriveUploadRequest") && Networking::CurlJsonRequest::jsonContainsIntegerNumber(object, "size", "OneDriveUploadRequest") && Networking::CurlJsonRequest::jsonContainsString(object, "lastModifiedDateTime", "OneDriveUploadRequest")) { //finished Common::String path = _savePath; uint32 size = object.getVal("size")->asIntegerNumber(); uint32 timestamp = ISO8601::convertToTimestamp(object.getVal("lastModifiedDateTime")->asString()); finishUpload(StorageFile(path, size, timestamp, false)); return; } if (_uploadUrl == "") { if (Networking::CurlJsonRequest::jsonContainsString(object, "uploadUrl", "OneDriveUploadRequest")) _uploadUrl = object.getVal("uploadUrl")->asString(); } } if (_contentsStream->eos() || _contentsStream->pos() >= _contentsStream->size() - 1) { warning("OneDriveUploadRequest: no file info to return"); finishUpload(StorageFile(_savePath, 0, 0, false)); } else { uploadNextPart(); } delete json; }
void GoogleDriveUploadRequest::partUploadedErrorCallback(Networking::ErrorResponse error) { _workingRequest = nullptr; if (_ignoreCallback) return; Networking::CurlJsonRequest *rq = (Networking::CurlJsonRequest *)error.request; if (rq) { const Networking::NetworkReadStream *stream = rq->getNetworkReadStream(); if (stream) { long code = stream->httpResponseCode(); if (code == 308 && handleHttp308(stream)) { return; } } } finishError(error); }
void GoogleDriveUploadRequest::uploadNextPart() { const uint32 UPLOAD_PER_ONE_REQUEST = 10 * 1024 * 1024; Common::String url = _uploadUrl; Networking::JsonCallback callback = new Common::Callback<GoogleDriveUploadRequest, Networking::JsonResponse>(this, &GoogleDriveUploadRequest::partUploadedCallback); Networking::ErrorCallback failureCallback = new Common::Callback<GoogleDriveUploadRequest, Networking::ErrorResponse>(this, &GoogleDriveUploadRequest::partUploadedErrorCallback); Networking::CurlJsonRequest *request = new GoogleDriveTokenRefresher(_storage, callback, failureCallback, url.c_str()); request->addHeader("Authorization: Bearer " + _storage->accessToken()); request->usePut(); uint32 oldPos = _contentsStream->pos(); if (oldPos != _serverReceivedBytes) { if (!_contentsStream->seek(_serverReceivedBytes)) { warning("GoogleDriveUploadRequest: cannot upload because stream couldn't seek(%lu)", _serverReceivedBytes); finishError(Networking::ErrorResponse(this, false, true, "", -1)); return; } oldPos = _serverReceivedBytes; } byte *buffer = new byte[UPLOAD_PER_ONE_REQUEST]; uint32 size = _contentsStream->read(buffer, UPLOAD_PER_ONE_REQUEST); if (size != 0) request->setBuffer(buffer, size); if (_uploadUrl != "") { if (_contentsStream->pos() == 0) request->addHeader(Common::String::format("Content-Length: 0")); else request->addHeader(Common::String::format("Content-Range: bytes %u-%u/%u", oldPos, _contentsStream->pos() - 1, _contentsStream->size())); } _workingRequest = ConnMan.addRequest(request); }
void GoogleDriveUploadRequest::startUploadCallback(Networking::JsonResponse response) { _workingRequest = nullptr; if (_ignoreCallback) return; Networking::ErrorResponse error(this, false, true, "", -1); Networking::CurlJsonRequest *rq = (Networking::CurlJsonRequest *)response.request; if (rq) { const Networking::NetworkReadStream *stream = rq->getNetworkReadStream(); if (stream) { long code = stream->httpResponseCode(); Common::String headers = stream->responseHeaders(); if (code == 200) { const char *cstr = headers.c_str(); const char *position = strstr(cstr, "Location: "); if (position) { Common::String result = ""; char c; for (const char *i = position + 10; c = *i, c != 0; ++i) { if (c == '\n' || c == '\r') break; result += c; } _uploadUrl = result; uploadNextPart(); return; } } error.httpResponseCode = code; } } Common::JSONValue *json = response.value; delete json; finishError(error); }
Networking::Request *BoxStorage::createDirectoryWithParentId(Common::String parentId, Common::String name, BoolCallback callback, Networking::ErrorCallback errorCallback) { if (!errorCallback) errorCallback = getErrorPrintingCallback(); Common::String url = BOX_API_FOLDERS; Networking::JsonCallback innerCallback = new Common::CallbackBridge<BoxStorage, BoolResponse, Networking::JsonResponse>(this, &BoxStorage::createDirectoryInnerCallback, callback); Networking::CurlJsonRequest *request = new BoxTokenRefresher(this, innerCallback, errorCallback, url.c_str()); request->addHeader("Authorization: Bearer " + accessToken()); request->addHeader("Content-Type: application/json"); Common::JSONObject parentObject; parentObject.setVal("id", new Common::JSONValue(parentId)); Common::JSONObject jsonRequestParameters; jsonRequestParameters.setVal("name", new Common::JSONValue(name)); jsonRequestParameters.setVal("parent", new Common::JSONValue(parentObject)); Common::JSONValue value(jsonRequestParameters); request->addPostField(Common::JSON::stringify(&value)); return addRequest(request); }
Networking::Request *GoogleDriveStorage::createDirectoryWithParentId(Common::String parentId, Common::String name, BoolCallback callback, Networking::ErrorCallback errorCallback) { if (!errorCallback) errorCallback = getErrorPrintingCallback(); Common::String url = GOOGLEDRIVE_API_FILES; Networking::JsonCallback innerCallback = new Common::CallbackBridge<GoogleDriveStorage, BoolResponse, Networking::JsonResponse>(this, &GoogleDriveStorage::createDirectoryInnerCallback, callback); Networking::CurlJsonRequest *request = new GoogleDriveTokenRefresher(this, innerCallback, errorCallback, url.c_str()); request->addHeader("Authorization: Bearer " + accessToken()); request->addHeader("Content-Type: application/json"); Common::JSONArray parentsArray; parentsArray.push_back(new Common::JSONValue(parentId)); Common::JSONObject jsonRequestParameters; jsonRequestParameters.setVal("mimeType", new Common::JSONValue("application/vnd.google-apps.folder")); jsonRequestParameters.setVal("name", new Common::JSONValue(name)); jsonRequestParameters.setVal("parents", new Common::JSONValue(parentsArray)); Common::JSONValue value(jsonRequestParameters); request->addPostField(Common::JSON::stringify(&value)); return addRequest(request); }
void GoogleDriveUploadRequest::startUpload() { Common::String name = _savePath; for (uint32 i = name.size(); i > 0; --i) { if (name[i - 1] == '/' || name[i - 1] == '\\') { name.erase(0, i); break; } } Common::String url = GOOGLEDRIVE_API_FILES; if (_resolvedId != "") url += "/" + ConnMan.urlEncode(_resolvedId); url += "?uploadType=resumable&fields=id,mimeType,modifiedTime,name,size"; Networking::JsonCallback callback = new Common::Callback<GoogleDriveUploadRequest, Networking::JsonResponse>(this, &GoogleDriveUploadRequest::startUploadCallback); Networking::ErrorCallback failureCallback = new Common::Callback<GoogleDriveUploadRequest, Networking::ErrorResponse>(this, &GoogleDriveUploadRequest::startUploadErrorCallback); Networking::CurlJsonRequest *request = new GoogleDriveTokenRefresher(_storage, callback, failureCallback, url.c_str()); request->addHeader("Authorization: Bearer " + _storage->accessToken()); request->addHeader("Content-Type: application/json"); if (_resolvedId != "") request->usePatch(); Common::JSONObject jsonRequestParameters; if (_resolvedId != "") { jsonRequestParameters.setVal("id", new Common::JSONValue(_resolvedId)); } else { Common::JSONArray parentsArray; parentsArray.push_back(new Common::JSONValue(_parentId)); jsonRequestParameters.setVal("parents", new Common::JSONValue(parentsArray)); } jsonRequestParameters.setVal("name", new Common::JSONValue(name)); Common::JSONValue value(jsonRequestParameters); request->addPostField(Common::JSON::stringify(&value)); _workingRequest = ConnMan.addRequest(request); }
void OneDriveUploadRequest::uploadNextPart() { const uint32 UPLOAD_PER_ONE_REQUEST = 10 * 1024 * 1024; if (_uploadUrl == "" && (uint32)_contentsStream->size() > UPLOAD_PER_ONE_REQUEST) { Common::String url = Common::String::format(ONEDRIVE_API_SPECIAL_APPROOT_UPLOAD, ConnMan.urlEncode(_savePath).c_str()); //folder must exist Networking::JsonCallback callback = new Common::Callback<OneDriveUploadRequest, Networking::JsonResponse>(this, &OneDriveUploadRequest::partUploadedCallback); Networking::ErrorCallback failureCallback = new Common::Callback<OneDriveUploadRequest, Networking::ErrorResponse>(this, &OneDriveUploadRequest::partUploadedErrorCallback); Networking::CurlJsonRequest *request = new OneDriveTokenRefresher(_storage, callback, failureCallback, url.c_str()); request->addHeader("Authorization: Bearer " + _storage->accessToken()); request->setBuffer(new byte[1], 0); //use POST _workingRequest = ConnMan.addRequest(request); return; } Common::String url; if (_uploadUrl == "") { url = Common::String::format(ONEDRIVE_API_SPECIAL_APPROOT_CONTENT, ConnMan.urlEncode(_savePath).c_str()); } else { url = _uploadUrl; } Networking::JsonCallback callback = new Common::Callback<OneDriveUploadRequest, Networking::JsonResponse>(this, &OneDriveUploadRequest::partUploadedCallback); Networking::ErrorCallback failureCallback = new Common::Callback<OneDriveUploadRequest, Networking::ErrorResponse>(this, &OneDriveUploadRequest::partUploadedErrorCallback); Networking::CurlJsonRequest *request = new OneDriveTokenRefresher(_storage, callback, failureCallback, url.c_str()); request->addHeader("Authorization: Bearer " + _storage->accessToken()); request->usePut(); uint32 oldPos = _contentsStream->pos(); byte *buffer = new byte[UPLOAD_PER_ONE_REQUEST]; uint32 size = _contentsStream->read(buffer, UPLOAD_PER_ONE_REQUEST); request->setBuffer(buffer, size); if (_uploadUrl != "") { request->addHeader(Common::String::format("Content-Range: bytes %u-%u/%u", oldPos, _contentsStream->pos() - 1, _contentsStream->size())); } else if (_contentsStream->size() == 0) { warning("\"Sorry, OneDrive can't upload empty files\""); finishUpload(StorageFile(_savePath, 0, 0, false)); delete request; return; } _workingRequest = ConnMan.addRequest(request); }
void DropboxStorage::getAccessToken(Common::String code) { if (!KEY || !SECRET) loadKeyAndSecret(); Networking::JsonCallback callback = new Common::Callback<DropboxStorage, Networking::JsonResponse>(this, &DropboxStorage::codeFlowComplete); Networking::ErrorCallback errorCallback = new Common::Callback<DropboxStorage, Networking::ErrorResponse>(this, &DropboxStorage::codeFlowFailed); Networking::CurlJsonRequest *request = new Networking::CurlJsonRequest(callback, errorCallback, DROPBOX_OAUTH2_TOKEN); request->addPostField("code=" + code); request->addPostField("grant_type=authorization_code"); request->addPostField("client_id=" + Common::String(KEY)); request->addPostField("client_secret=" + Common::String(SECRET)); if (Cloud::CloudManager::couldUseLocalServer()) { request->addPostField("&redirect_uri=http%3A%2F%2Flocalhost%3A12345%2F"); } else { request->addPostField("&redirect_uri=https%3A%2F%2Fwww.scummvm.org/c/code"); } addRequest(request); }
Networking::Request *BoxStorage::info(StorageInfoCallback callback, Networking::ErrorCallback errorCallback) { Networking::JsonCallback innerCallback = new Common::CallbackBridge<BoxStorage, StorageInfoResponse, Networking::JsonResponse>(this, &BoxStorage::infoInnerCallback, callback); Networking::CurlJsonRequest *request = new BoxTokenRefresher(this, innerCallback, errorCallback, BOX_API_USERS_ME); request->addHeader("Authorization: Bearer " + _token); return addRequest(request); }
void GoogleDriveUploadRequest::partUploadedCallback(Networking::JsonResponse response) { _workingRequest = nullptr; if (_ignoreCallback) return; Networking::ErrorResponse error(this, false, true, "", -1); Networking::CurlJsonRequest *rq = (Networking::CurlJsonRequest *)response.request; if (rq) { const Networking::NetworkReadStream *stream = rq->getNetworkReadStream(); if (stream) { long code = stream->httpResponseCode(); error.httpResponseCode = code; if (code == 308 && handleHttp308(stream)) { delete (Common::JSONValue *)response.value; return; } } } Common::JSONValue *json = response.value; if (json == nullptr) { error.response = "Failed to parse JSON, null passed!"; finishError(error); return; } if (json->isObject()) { Common::JSONObject object = json->asObject(); if (object.contains("error")) { warning("GoogleDrive returned error: %s", json->stringify(true).c_str()); error.response = json->stringify(true); finishError(error); delete json; return; } if (Networking::CurlJsonRequest::jsonContainsString(object, "id", "GoogleDriveUploadRequest") && Networking::CurlJsonRequest::jsonContainsString(object, "name", "GoogleDriveUploadRequest") && Networking::CurlJsonRequest::jsonContainsString(object, "mimeType", "GoogleDriveUploadRequest")) { //finished Common::String id = object.getVal("id")->asString(); Common::String name = object.getVal("name")->asString(); bool isDirectory = (object.getVal("mimeType")->asString() == "application/vnd.google-apps.folder"); uint32 size = 0, timestamp = 0; if (Networking::CurlJsonRequest::jsonContainsString(object, "size", "GoogleDriveUploadRequest", true)) size = object.getVal("size")->asString().asUint64(); if (Networking::CurlJsonRequest::jsonContainsString(object, "modifiedTime", "GoogleDriveUploadRequest", true)) timestamp = ISO8601::convertToTimestamp(object.getVal("modifiedTime")->asString()); finishUpload(StorageFile(id, _savePath, name, size, timestamp, isDirectory)); return; } } if (_contentsStream->eos() || _contentsStream->pos() >= _contentsStream->size() - 1) { warning("GoogleDriveUploadRequest: no file info to return"); finishUpload(StorageFile(_savePath, 0, 0, false)); } else { uploadNextPart(); } delete json; }
void OneDriveListDirectoryRequest::listedDirectoryCallback(Networking::JsonResponse response) { _workingRequest = nullptr; Common::JSONValue *json = response.value; if (_ignoreCallback) { delete json; return; } if (response.request) _date = response.request->date(); Networking::ErrorResponse error(this); Networking::CurlJsonRequest *rq = (Networking::CurlJsonRequest *)response.request; if (rq && rq->getNetworkReadStream()) error.httpResponseCode = rq->getNetworkReadStream()->httpResponseCode(); if (json == nullptr) { error.response = "Failed to parse JSON, null passed!"; finishError(error); return; } if (!json->isObject()) { error.response = "Passed JSON is not an object!"; finishError(error); delete json; return; } Common::JSONObject object = json->asObject(); //check that ALL keys exist AND HAVE RIGHT TYPE to avoid segfaults if (!Networking::CurlJsonRequest::jsonContainsArray(object, "value", "OneDriveListDirectoryRequest")) { error.response = "\"value\" not found or that's not an array!"; finishError(error); delete json; return; } Common::JSONArray items = object.getVal("value")->asArray(); for (uint32 i = 0; i < items.size(); ++i) { if (!Networking::CurlJsonRequest::jsonIsObject(items[i], "OneDriveListDirectoryRequest")) continue; Common::JSONObject item = items[i]->asObject(); if (!Networking::CurlJsonRequest::jsonContainsAttribute(item, "folder", "OneDriveListDirectoryRequest", true)) continue; if (!Networking::CurlJsonRequest::jsonContainsString(item, "name", "OneDriveListDirectoryRequest")) continue; if (!Networking::CurlJsonRequest::jsonContainsIntegerNumber(item, "size", "OneDriveListDirectoryRequest")) continue; if (!Networking::CurlJsonRequest::jsonContainsString(item, "lastModifiedDateTime", "OneDriveListDirectoryRequest")) continue; Common::String path = _currentDirectory + item.getVal("name")->asString(); bool isDirectory = item.contains("folder"); uint32 size = item.getVal("size")->asIntegerNumber(); uint32 timestamp = ISO8601::convertToTimestamp(item.getVal("lastModifiedDateTime")->asString()); StorageFile file(path, size, timestamp, isDirectory); _files.push_back(file); if (_requestedRecursive && file.isDirectory()) { _directoriesQueue.push_back(file.path()); } } bool hasMore = object.contains("@odata.nextLink"); if (hasMore) { if (!Networking::CurlJsonRequest::jsonContainsString(object, "@odata.nextLink", "OneDriveListDirectoryRequest")) { error.response = "\"@odata.nextLink\" is not a string!"; finishError(error); delete json; return; } makeRequest(object.getVal("@odata.nextLink")->asString()); } else { listNextDirectory(); } delete json; }
Networking::Request *OneDriveStorage::info(StorageInfoCallback callback, Networking::ErrorCallback errorCallback) { Networking::JsonCallback innerCallback = new Common::CallbackBridge<OneDriveStorage, StorageInfoResponse, Networking::JsonResponse>(this, &OneDriveStorage::infoInnerCallback, callback); Networking::CurlJsonRequest *request = new OneDriveTokenRefresher(this, innerCallback, errorCallback, ONEDRIVE_API_SPECIAL_APPROOT); request->addHeader("Authorization: bearer " + _token); return addRequest(request); }