diff --git a/src/libsync/owncloudpropagator.cpp b/src/libsync/owncloudpropagator.cpp index 8741de22c692d..730010026aef1 100644 --- a/src/libsync/owncloudpropagator.cpp +++ b/src/libsync/owncloudpropagator.cpp @@ -358,7 +358,12 @@ void PropagateItemJob::reportClientStatuses() propagator()->account()->reportClientStatus(ClientStatusReporting::Status::DownloadError_ConflictInvalidCharacters); } else if (_item->_httpErrorCode != 0 && _item->_httpErrorCode != 200 && _item->_httpErrorCode != 201 && _item->_httpErrorCode != 204) { if (_item->_direction == SyncFileItem::Up) { - propagator()->account()->reportClientStatus(ClientStatusReporting::Status::UploadError_ServerError); + if (_item->_httpErrorCode == 503 && !_item->_errorException.isEmpty() + && _item->_errorException.contains(QStringLiteral("UnsupportedMediaType")) && _item->_errorString.contains(QStringLiteral("virus"), Qt::CaseInsensitive)) { + propagator()->account()->reportClientStatus(ClientStatusReporting::Status::UploadError_Virus_Detected); + } else { + propagator()->account()->reportClientStatus(ClientStatusReporting::Status::UploadError_ServerError); + } } else { propagator()->account()->reportClientStatus(ClientStatusReporting::Status::DownloadError_ServerError); } diff --git a/src/libsync/owncloudpropagator_p.h b/src/libsync/owncloudpropagator_p.h index 6337b2f3cfb9c..485f52a88240b 100644 --- a/src/libsync/owncloudpropagator_p.h +++ b/src/libsync/owncloudpropagator_p.h @@ -48,6 +48,7 @@ inline bool fileIsStillChanging(const OCC::SyncFileItem &item) namespace OCC { + inline QByteArray getEtagFromReply(QNetworkReply *reply) { QByteArray ocEtag = parseEtag(reply->rawHeader("OC-ETag")); @@ -62,6 +63,30 @@ inline QByteArray getEtagFromReply(QNetworkReply *reply) return ret; } +inline QByteArray getExceptionFromReply(QNetworkReply *reply) +{ + Q_ASSERT(reply); + if (!reply) { + qCDebug(lcPropagator) << "Could not parse null reply"; + return {}; + } + + if (reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() != 503) { + return {}; + } + + const auto replyBody = reply->readAll(); + reply->reset(); + + auto exceptionStartIndex = replyBody.indexOf(QByteArrayLiteral("")); + if (exceptionStartIndex != -1) { + exceptionStartIndex += QByteArrayLiteral("").size(); + const auto exceptionEndIndex = replyBody.indexOf('<', exceptionStartIndex); + return replyBody.mid(exceptionStartIndex, exceptionEndIndex - exceptionStartIndex); + } + return {}; +} + /** * Given an error from the network, map to a SyncFileItem::Status error */ diff --git a/src/libsync/propagateupload.cpp b/src/libsync/propagateupload.cpp index ca08042eeaf20..52629612b622a 100644 --- a/src/libsync/propagateupload.cpp +++ b/src/libsync/propagateupload.cpp @@ -112,6 +112,7 @@ bool PollJob::finished() _item->_requestId = requestId(); _item->_status = classifyError(err, _item->_httpErrorCode); _item->_errorString = errorString(); + _item->_errorException = getExceptionFromReply(reply()); if (_item->_status == SyncFileItem::FatalError || _item->_httpErrorCode >= 400) { if (_item->_status != SyncFileItem::FatalError diff --git a/src/libsync/syncfileitem.h b/src/libsync/syncfileitem.h index eb263f3424bfc..af1a5a2011fa9 100644 --- a/src/libsync/syncfileitem.h +++ b/src/libsync/syncfileitem.h @@ -285,6 +285,7 @@ class OWNCLOUDSYNC_EXPORT SyncFileItem quint16 _httpErrorCode = 0; RemotePermissions _remotePerm; QString _errorString; // Contains a string only in case of error + QString _errorException; // Contains a server exception string only in case of error QByteArray _responseTimeStamp; QByteArray _requestId; // X-Request-Id of the failed request quint32 _affectedItems = 1; // the number of affected items by the operation on this item.