diff options
author | Kitsune Ral <Kitsune-Ral@users.sf.net> | 2018-04-29 18:29:56 +0900 |
---|---|---|
committer | Kitsune Ral <Kitsune-Ral@users.sf.net> | 2018-04-29 18:29:56 +0900 |
commit | b5d962b0f5dcd3497db8a4b3bada46bb666d08e1 (patch) | |
tree | 10d6e3add6b73cf9e4cecdeca08c72b490c50f7a /lib/jobs/basejob.cpp | |
parent | 4ced9792f27ed3d891c1f7772ae30d9fe452dd79 (diff) | |
parent | f5af25428212f139c59941bb294a184242c8b5e0 (diff) | |
download | libquotient-b5d962b0f5dcd3497db8a4b3bada46bb666d08e1.tar.gz libquotient-b5d962b0f5dcd3497db8a4b3bada46bb666d08e1.zip |
Merge branch 'master' into kitsune-gtad
Diffstat (limited to 'lib/jobs/basejob.cpp')
-rw-r--r-- | lib/jobs/basejob.cpp | 73 |
1 files changed, 42 insertions, 31 deletions
diff --git a/lib/jobs/basejob.cpp b/lib/jobs/basejob.cpp index 696861fb..2d41650a 100644 --- a/lib/jobs/basejob.cpp +++ b/lib/jobs/basejob.cpp @@ -336,39 +336,50 @@ bool checkContentType(const QByteArray& type, const QByteArrayList& patterns) BaseJob::Status BaseJob::doCheckReply(QNetworkReply* reply) const { - const auto httpCode = - reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); - - if (httpCode == 429) // Qt doesn't know about it yet - return { TooManyRequestsError, tr("Too many requests") }; - - // Should we check httpCode instead? Maybe even use it in BaseJob::Status? - // That would make codes in logs slightly more readable. - switch( reply->error() ) + // QNetworkReply error codes seem to be flawed when it comes to HTTP; + // see, e.g., https://github.com/QMatrixClient/libqmatrixclient/issues/200 + // so check genuine HTTP codes. The below processing is based on + // https://en.wikipedia.org/wiki/List_of_HTTP_status_codes + const auto httpCodeHeader = + reply->attribute(QNetworkRequest::HttpStatusCodeAttribute); + if (!httpCodeHeader.isValid()) // Woah, we didn't even get HTTP headers + return { NetworkError, reply->errorString() }; + + const auto httpCode = httpCodeHeader.toInt(); + if (httpCode / 100 == 2) // 2xx { - case QNetworkReply::NoError: - if (checkContentType(reply->rawHeader("Content-Type"), - d->expectedContentTypes)) - return NoError; - else // A warning in the logs might be more proper instead - return { IncorrectResponseError, - "Incorrect content type of the response" }; - - case QNetworkReply::AuthenticationRequiredError: - case QNetworkReply::ContentAccessDenied: - case QNetworkReply::ContentOperationNotPermittedError: - return { ContentAccessError, reply->errorString() }; - - case QNetworkReply::ProtocolInvalidOperationError: - case QNetworkReply::UnknownContentError: - return { IncorrectRequestError, reply->errorString() }; - - case QNetworkReply::ContentNotFoundError: - return { NotFoundError, reply->errorString() }; - - default: - return { NetworkError, reply->errorString() }; + if (checkContentType(reply->rawHeader("Content-Type"), + d->expectedContentTypes)) + return NoError; + else // A warning in the logs might be more proper instead + return { UnexpectedResponseTypeWarning, + "Unexpected content type of the response" }; } + + return { [httpCode]() -> StatusCode { + if (httpCode / 10 == 41) + return httpCode == 410 ? IncorrectRequestError : NotFoundError; + switch (httpCode) + { + case 401: case 403: case 407: + return ContentAccessError; + case 404: + return NotFoundError; + case 400: case 405: case 406: case 426: case 428: + case 505: + case 494: // Unofficial nginx "Request header too large" + case 497: // Unofficial nginx "HTTP request sent to HTTPS port" + return IncorrectRequestError; + case 429: + return TooManyRequestsError; + case 501: case 510: + return RequestNotImplementedError; + case 511: + return NetworkAuthRequiredError; + default: + return NetworkError; + } + }(), reply->errorString() }; } BaseJob::Status BaseJob::parseReply(QNetworkReply* reply) |