コード例 #1
0
bool GoogleDriveUploadRequest::handleHttp308(const Networking::NetworkReadStream *stream) {
	//308 Resume Incomplete, with Range: X-Y header
	if (!stream)
		return false;
	if (stream->httpResponseCode() != 308)
		return false; //seriously

	Common::String headers = stream->responseHeaders();
	const char *cstr = headers.c_str();
	for (int rangeTry = 0; rangeTry < 2; ++rangeTry) {
		const char *needle = (rangeTry == 0 ? "Range: 0-" : "Range: bytes=0-");
		uint32 needleLength = (rangeTry == 0 ? 9 : 15);

		const char *position = strstr(cstr, needle); //if it lost the first part, I refuse to talk with it

		if (position) {
			Common::String result = "";
			char c;
			for (const char *i = position + needleLength; c = *i, c != 0; ++i) {
				if (c == '\n' || c == '\r')
					break;
				result += c;
			}
			_serverReceivedBytes = result.asUint64() + 1;
			uploadNextPart();
			return true;
		}
	}

	return false;
}
コード例 #2
0
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;
}
コード例 #3
0
void OneDriveUploadRequest::start() {
	_ignoreCallback = true;
	if (_workingRequest)
		_workingRequest->finish();
	if (_contentsStream == nullptr) {
		warning("OneDriveUploadRequest: cannot restart because no stream given");
		finishError(Networking::ErrorResponse(this, false, true, "No stream given", -1));
		return;
	}
	if (!_contentsStream->seek(0)) {
		warning("OneDriveUploadRequest: cannot restart because stream couldn't seek(0)");
		finishError(Networking::ErrorResponse(this, false, true, "", -1));
		return;
	}
	_ignoreCallback = false;

	uploadNextPart();
}
コード例 #4
0
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);
}
コード例 #5
0
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;
}