wsd: extract wopi upload response handling
This is in preparation for asynchronous uploading. Change-Id: Ibd0ff0fa8edfc08ad2755a45227891ed40e09d1c Signed-off-by: Ashod Nakashian <ashod.nakashian@collabora.co.uk>
This commit is contained in:
parent
a6cadbcba3
commit
06a45e6db9
2 changed files with 78 additions and 26 deletions
|
@ -1011,7 +1011,6 @@ WopiStorage::saveLocalFileToStorage(const Authorization& auth, const std::string
|
|||
LOG_INF("Uploading " << size << " bytes from [" << filePathAnonym << "] to URI via WOPI ["
|
||||
<< uriAnonym << "].");
|
||||
|
||||
StorageBase::SaveResult saveResult(StorageBase::SaveResult::Result::FAILED);
|
||||
const auto startTime = std::chrono::steady_clock::now();
|
||||
try
|
||||
{
|
||||
|
@ -1100,12 +1099,41 @@ WopiStorage::saveLocalFileToStorage(const Authorization& auth, const std::string
|
|||
|
||||
_wopiSaveDuration = std::chrono::steady_clock::now() - startTime;
|
||||
|
||||
WopiUploadDetails details
|
||||
= { filePathAnonym, uriAnonym, response.getReason(), response.getStatus(), size,
|
||||
isSaveAs, isRename };
|
||||
|
||||
std::ostringstream oss;
|
||||
Poco::StreamCopier::copyStream(rs, oss);
|
||||
std::string responseString = oss.str();
|
||||
return handleUploadToStorageResponse(details, oss.str());
|
||||
}
|
||||
catch (const Poco::Exception& pexc)
|
||||
{
|
||||
LOG_ERR("Cannot save file to WOPI storage uri [" << uriAnonym << "]. Error: " <<
|
||||
pexc.displayText() << (pexc.nested() ? " (" + pexc.nested()->displayText() + ')' : ""));
|
||||
}
|
||||
catch (const BadRequestException& exc)
|
||||
{
|
||||
LOG_ERR("Cannot save file to WOPI storage uri [" + uriAnonym + "]. Error: " << exc.what());
|
||||
}
|
||||
|
||||
return StorageBase::SaveResult::Result::FAILED;
|
||||
}
|
||||
|
||||
StorageBase::SaveResult WopiStorage::handleUploadToStorageResponse(const WopiUploadDetails& details,
|
||||
std::string responseString)
|
||||
{
|
||||
// Assume we failed, unless we have confirmation of success.
|
||||
StorageBase::SaveResult saveResult(StorageBase::SaveResult::Result::FAILED);
|
||||
try
|
||||
{
|
||||
const std::string origResponseString = responseString;
|
||||
|
||||
saveResult.setErrorMsg(responseString);
|
||||
|
||||
const std::string wopiLog(isSaveAs ? "WOPI::PutRelativeFile" : (isRename ? "WOPI::RenameFile":"WOPI::PutFile"));
|
||||
const std::string wopiLog(details.isSaveAs
|
||||
? "WOPI::PutRelativeFile"
|
||||
: (details.isRename ? "WOPI::RenameFile" : "WOPI::PutFile"));
|
||||
|
||||
if (Log::infoEnabled())
|
||||
{
|
||||
|
@ -1117,14 +1145,15 @@ WopiStorage::saveLocalFileToStorage(const Authorization& auth, const std::string
|
|||
// Anonymize the filename
|
||||
std::string url;
|
||||
std::string filename;
|
||||
if (JsonUtil::findJSONValue(object, "Url", url) &&
|
||||
JsonUtil::findJSONValue(object, "Name", filename))
|
||||
if (JsonUtil::findJSONValue(object, "Url", url)
|
||||
&& JsonUtil::findJSONValue(object, "Name", filename))
|
||||
{
|
||||
// Get the FileId form the URL, which we use as the anonymized filename.
|
||||
std::string decodedUrl;
|
||||
Poco::URI::decode(url, decodedUrl);
|
||||
const std::string obfuscatedFileId = Util::getFilenameFromURL(decodedUrl);
|
||||
Util::mapAnonymized(obfuscatedFileId, obfuscatedFileId); // Identity, to avoid re-anonymizing.
|
||||
Util::mapAnonymized(obfuscatedFileId,
|
||||
obfuscatedFileId); // Identity, to avoid re-anonymizing.
|
||||
|
||||
const std::string filenameOnly = Util::getFilenameFromURL(filename);
|
||||
Util::mapAnonymized(filenameOnly, obfuscatedFileId);
|
||||
|
@ -1138,22 +1167,25 @@ WopiStorage::saveLocalFileToStorage(const Authorization& auth, const std::string
|
|||
}
|
||||
}
|
||||
|
||||
LOG_INF(wopiLog << " uploaded " << size << " bytes from [" << filePathAnonym << "] -> ["
|
||||
<< uriAnonym << "]: " << response.getStatus() << ' '
|
||||
<< response.getReason() << ": " << responseString);
|
||||
LOG_INF(wopiLog << " uploaded " << details.size << " bytes from ["
|
||||
<< details.filePathAnonym << "] -> [" << details.uriAnonym
|
||||
<< "]: " << details.httpResponseCode << ' '
|
||||
<< details.httpResponseReason << ": " << responseString);
|
||||
}
|
||||
|
||||
if (response.getStatus() == Poco::Net::HTTPResponse::HTTP_OK)
|
||||
if (details.httpResponseCode == Poco::Net::HTTPResponse::HTTP_OK)
|
||||
{
|
||||
saveResult.setResult(StorageBase::SaveResult::Result::OK);
|
||||
Poco::JSON::Object::Ptr object;
|
||||
if (JsonUtil::parseJSON(oss.str(), object))
|
||||
if (JsonUtil::parseJSON(origResponseString, object))
|
||||
{
|
||||
const std::string lastModifiedTime = JsonUtil::getJSONValue<std::string>(object, "LastModifiedTime");
|
||||
const std::string lastModifiedTime
|
||||
= JsonUtil::getJSONValue<std::string>(object, "LastModifiedTime");
|
||||
LOG_TRC(wopiLog << " returns LastModifiedTime [" << lastModifiedTime << "].");
|
||||
getFileInfo().setModifiedTime(Util::iso8601ToTimestamp(lastModifiedTime, "LastModifiedTime"));
|
||||
getFileInfo().setModifiedTime(
|
||||
Util::iso8601ToTimestamp(lastModifiedTime, "LastModifiedTime"));
|
||||
|
||||
if (isSaveAs || isRename)
|
||||
if (details.isSaveAs || details.isRename)
|
||||
{
|
||||
const std::string name = JsonUtil::getJSONValue<std::string>(object, "Name");
|
||||
LOG_TRC(wopiLog << " returns Name [" << LOOLWSD::anonymizeUrl(name) << "].");
|
||||
|
@ -1172,22 +1204,23 @@ WopiStorage::saveLocalFileToStorage(const Authorization& auth, const std::string
|
|||
LOG_WRN("Invalid or missing JSON in " << wopiLog << " HTTP_OK response.");
|
||||
}
|
||||
}
|
||||
else if (response.getStatus() == Poco::Net::HTTPResponse::HTTP_REQUESTENTITYTOOLARGE)
|
||||
else if (details.httpResponseCode == Poco::Net::HTTPResponse::HTTP_REQUEST_ENTITY_TOO_LARGE)
|
||||
{
|
||||
saveResult.setResult(StorageBase::SaveResult::Result::DISKFULL);
|
||||
}
|
||||
else if (response.getStatus() == Poco::Net::HTTPResponse::HTTP_UNAUTHORIZED ||
|
||||
response.getStatus() == Poco::Net::HTTPResponse::HTTP_FORBIDDEN)
|
||||
else if (details.httpResponseCode == Poco::Net::HTTPResponse::HTTP_UNAUTHORIZED
|
||||
|| details.httpResponseCode == Poco::Net::HTTPResponse::HTTP_FORBIDDEN)
|
||||
{
|
||||
saveResult.setResult(StorageBase::SaveResult::Result::UNAUTHORIZED);
|
||||
}
|
||||
else if (response.getStatus() == Poco::Net::HTTPResponse::HTTP_CONFLICT)
|
||||
else if (details.httpResponseCode == Poco::Net::HTTPResponse::HTTP_CONFLICT)
|
||||
{
|
||||
saveResult.setResult(StorageBase::SaveResult::Result::CONFLICT);
|
||||
Poco::JSON::Object::Ptr object;
|
||||
if (JsonUtil::parseJSON(oss.str(), object))
|
||||
if (JsonUtil::parseJSON(origResponseString, object))
|
||||
{
|
||||
const unsigned loolStatusCode = JsonUtil::getJSONValue<unsigned>(object, "LOOLStatusCode");
|
||||
const unsigned loolStatusCode
|
||||
= JsonUtil::getJSONValue<unsigned>(object, "LOOLStatusCode");
|
||||
if (loolStatusCode == static_cast<unsigned>(LOOLStatusCode::DOC_CHANGED))
|
||||
{
|
||||
saveResult.setResult(StorageBase::SaveResult::Result::DOC_CHANGED);
|
||||
|
@ -1202,21 +1235,24 @@ WopiStorage::saveLocalFileToStorage(const Authorization& auth, const std::string
|
|||
{
|
||||
// Internal server error, and other failures.
|
||||
LOG_ERR("Unexpected response to "
|
||||
<< wopiLog << ". Cannot upload file to WOPI storage uri [" << uriAnonym
|
||||
<< "]: " << response.getStatus() << ' ' << response.getReason() << ": "
|
||||
<< responseString);
|
||||
<< wopiLog << ". Cannot upload file to WOPI storage uri [" << details.uriAnonym
|
||||
<< "]: " << details.httpResponseCode << ' ' << details.httpResponseReason
|
||||
<< ": " << responseString);
|
||||
saveResult.setResult(StorageBase::SaveResult::Result::FAILED);
|
||||
}
|
||||
}
|
||||
catch (const Poco::Exception& pexc)
|
||||
{
|
||||
LOG_ERR("Cannot save file to WOPI storage uri [" << uriAnonym << "]. Error: " <<
|
||||
pexc.displayText() << (pexc.nested() ? " (" + pexc.nested()->displayText() + ')' : ""));
|
||||
LOG_ERR("Cannot save file to WOPI storage uri ["
|
||||
<< details.uriAnonym << "]. Error: " << pexc.displayText()
|
||||
<< (pexc.nested() ? " (" + pexc.nested()->displayText() + ')' : ""));
|
||||
saveResult.setResult(StorageBase::SaveResult::Result::FAILED);
|
||||
}
|
||||
catch (const BadRequestException& exc)
|
||||
{
|
||||
LOG_ERR("Cannot save file to WOPI storage uri [" + uriAnonym + "]. Error: " << exc.what());
|
||||
LOG_ERR("Cannot save file to WOPI storage uri [" + details.uriAnonym + "]. Error: "
|
||||
<< exc.what());
|
||||
saveResult.setResult(StorageBase::SaveResult::Result::FAILED);
|
||||
}
|
||||
|
||||
return saveResult;
|
||||
|
|
|
@ -525,6 +525,22 @@ public:
|
|||
std::chrono::duration<double> getWopiLoadDuration() const { return _wopiLoadDuration; }
|
||||
std::chrono::duration<double> getWopiSaveDuration() const { return _wopiSaveDuration; }
|
||||
|
||||
protected:
|
||||
struct WopiUploadDetails
|
||||
{
|
||||
const std::string filePathAnonym;
|
||||
const std::string uriAnonym;
|
||||
const std::string httpResponseReason;
|
||||
const long httpResponseCode;
|
||||
const std::size_t size;
|
||||
const bool isSaveAs;
|
||||
const bool isRename;
|
||||
};
|
||||
|
||||
/// Handles the response from the server when uploading the document.
|
||||
SaveResult handleUploadToStorageResponse(const WopiUploadDetails& details,
|
||||
std::string responseString);
|
||||
|
||||
private:
|
||||
/// Initialize an HTTPRequest instance with the common settings and headers.
|
||||
/// Older Poco versions don't support copying HTTPRequest objects, so we can't generate them.
|
||||
|
|
Loading…
Reference in a new issue