Privacy policyContactsAbout siteOpinionsGitHubDonate
© EVILEG 2015-2018
Recommend hosting
TIMEWEB

Qt/C++ - Lesson 065. The correspondence of HTTP errors to server response errors in QNetworkAccessManager

QNetworkAccessManager, QNetworkReply, QNetworkError

In one of the lessons, I worked with QNetworkAccessManager to get the content of the page from the site via the http protocol. There was made a check for errors, but no explanation was given as to what errors might be. For this, the QNetworkReply class provides an enum NetworkError , which lists the possible error codes.

If successful, NoError is returned, which is 0.

Otherwise, an error code is returned from the codes below:

Constant Value Description
QNetworkReply::ConnectionRefusedError 1 the remote server refused the connection (the server is not accepting requests)
QNetworkReply::RemoteHostClosedError 2 the remote server closed the connection prematurely, before the entire reply was received and processed
QNetworkReply::HostNotFoundError 3 the remote host name was not found (invalid hostname)
QNetworkReply::TimeoutError 4 the connection to the remote server timed out
QNetworkReply::OperationCanceledError 5 the operation was canceled via calls to abort() or close() before it was finished.
QNetworkReply::SslHandshakeFailedError 6 the SSL/TLS handshake failed and the encrypted channel could not be established. The sslErrors() signal should have been emitted.
QNetworkReply::TemporaryNetworkFailureError 7 the connection was broken due to disconnection from the network, however the system has initiated roaming to another access point. The request should be resubmitted and will be processed as soon as the connection is re-established.
QNetworkReply::NetworkSessionFailedError 8 the connection was broken due to disconnection from the network or failure to start the network.
QNetworkReply::BackgroundRequestNotAllowedError 9 the background request is not currently allowed due to platform policy.
QNetworkReply::TooManyRedirectsError 10 while following redirects, the maximum limit was reached. The limit is by default set to 50 or as set by QNetworkRequest::setMaxRedirectsAllowed(). (This value was introduced in 5.6.)
QNetworkReply::InsecureRedirectError 11 while following redirects, the network access API detected a redirect from a encrypted protocol (https) to an unencrypted one (http). (This value was introduced in 5.6.)
QNetworkReply::ProxyConnectionRefusedError 101 the connection to the proxy server was refused (the proxy server is not accepting requests)
QNetworkReply::ProxyConnectionClosedError 102 the proxy server closed the connection prematurely, before the entire reply was received and processed
QNetworkReply::ProxyNotFoundError 103 the proxy host name was not found (invalid proxy hostname)
QNetworkReply::ProxyTimeoutError 104 the connection to the proxy timed out or the proxy did not reply in time to the request sent
QNetworkReply::ProxyAuthenticationRequiredError 105 the proxy requires authentication in order to honour the request but did not accept any credentials offered (if any)
QNetworkReply::ContentAccessDenied 201 the access to the remote content was denied (similar to HTTP error 401)
QNetworkReply::ContentOperationNotPermittedError 202 the operation requested on the remote content is not permitted
QNetworkReply::ContentNotFoundError 203 the remote content was not found at the server (similar to HTTP error 404)
QNetworkReply::AuthenticationRequiredError 204 the remote server requires authentication to serve the content but the credentials provided were not accepted (if any)
QNetworkReply::ContentReSendError 205 the request needed to be sent again, but this failed for example because the upload data could not be read a second time.
QNetworkReply::ContentConflictError 206 the request could not be completed due to a conflict with the current state of the resource.
QNetworkReply::ContentGoneError 207 the requested resource is no longer available at the server.
QNetworkReply::InternalServerError 401 the server encountered an unexpected condition which prevented it from fulfilling the request.
QNetworkReply::OperationNotImplementedError 402 the server does not support the functionality required to fulfill the request.
QNetworkReply::ServiceUnavailableError 403 the server is unable to handle the request at this time.
QNetworkReply::ProtocolUnknownError 301 the Network Access API cannot honor the request because the protocol is not known
QNetworkReply::ProtocolInvalidOperationError 302 the requested operation is invalid for this protocol
QNetworkReply::UnknownNetworkError 99 an unknown network-related error was detected
QNetworkReply::UnknownProxyError 199 an unknown proxy-related error was detected
QNetworkReply::UnknownContentError 299 an unknown error related to the remote content was detected
QNetworkReply::ProtocolFailure 399 a breakdown in protocol was detected (parsing error, invalid or unexpected responses, etc.)
QNetworkReply::UnknownServerError 499 an unknown error related to the server response was detected

After studying this list of errors, we can conclude that this list combines a much larger list of errors than, for example, the list of error codes that the http server can return. Let's talk a little about possible errors and because of what they can arise.

QNetworkReply::ConnectionRefusedError and QNetworkReply::RemoteHostClosedError

If we talk about the interpretation of these errors, then the most striking example for me is connecting via SSH to another host. The meaning of the errors is that in the first case the server does not allow us, and in the second case the connection could be closed after a certain period of time.

Also, the ConnectionRefusedError error can occur when there is simply no service on a particular PC port that could process the request.

QNetworkReply::HostNotFoundError

Perhaps a fairly understandable error, which means that you just typed the wrong ip address or domain from which you are trying to get data. Also, this error can occur if the domain has ceased to be available on the network. This error is similar to error number 105 - ERR_NAME_NOT_RESOLVED (HTTP).

QNetworkReply::TimeoutError

The waiting interval is exceeded. The closest comparison is the use of the ICMP protocol, checking the availability of the node on the network when we make it ping. That is, there is a node in the network, but it does not respond.

QNetworkReply::OperationCanceledError

And here is an error that already applies to the actions of the program itself on Qt. In this case, it will occur when the program logic stops receiving data through the QNetworkAccessManager . That is, this error should not occur if the data receiving operation was interrupted from the outside. Therefore, if you catch such a mistake, then look for a problem inside your own program.

QNetworkReply::SslHandshakeFailedError

To establish encrypted communication channels that use SSL encryption, it is required to establish a connection through acknowledgment operations, that is, through acknowledgment of the reception / transmission of information. In this case, the encryption parameters are negotiated, the session key is transmitted, as well as optional server authentication operations by the client and the client by the server. If any of the above goes wrong, then this error will be thrown out.

QNetworkReply::TemporaryNetworkFailureError and QNetworkReply::NetworkSessionFailedError

The occurrence of these errors can be caused by any network problem until the physical connection to the network falls. You can check connections through the QNetworkInterface class.

The QNetworkInterface class has a static QList<QNetworkInterface> QNetworkInterface::allInterfaces() method that returns a list of all interfaces on your PC. This will take into account absolutely all connections, up to the connections that were created for the virtual machine, for example, for the Virtual Box . Here, by the way, there is a very interesting moment when software is being developed that should work on the network, and at the same time the developer has a virtual machine on board, especially if it is running, then this should be taken into account, because the program can try to get data through the connection With a virtual machine, that is, it will assume that the network is available, although the developer will test the User Case with the connection disconnected. However, even a disabled virtual machine will cause some problems, since the connection will be active, although Link will not be raised.

Therefore, to understand what's wrong, when you receive QNetworkReply::TemporaryNetworkFailureError and QNetworkReply::NetworkSessionFailedError errors, you will have to test the PC interfaces for activity: QNetworkInterface::IsUp and QNetworkInterface::IsRunning .

QNetworkReply::BackgroundRequestNotAllowedError

But this error depends directly on the policies of the platform for which the application is developed. For example, if some abstract Android device prohibits the exchange of information on the network in an energy-saving mode, then in this mode we will receive this error when trying to exchange information.

QNetworkReply::TooManyRedirectsError and QNetworkReply::InsecureRedirectError

But these errors from the category of new in Qt 5.6. Now you can monitor the excess of the number of redirects from site pages, as well as redirects from pages with https encryption to pages without encryption. What can be useful for developing software for website analysis.

Without additional settings, these errors usually do not occur. The point is that when QNetworkRequest is set and configuration flags are not set, then when you try to request a page from the site from which the redirect is done, there will be no transition to the new url, and QNetworkReply will not have any useful content. Therefore, you will need to set the QNetworkRequest flag in the QNetworkRequest::FollowRedirectsAttribute , then QNetworkAccessManager will go through the redirects until it receives the summary page or exceeds the limit on the number of transitions. By default, the number of transitions is limited to 50th.

The attribute can be set as follows:

QNetworkRequest request;  
request.setAttribute(QNetworkRequest::FollowRedirectsAttribute, QVariant(true));

As for QNetworkReply::InsecureRedirectError , the point is to track the redirect to an unsafe protocol.

Errors of QNetworkReply::Proxy*

The following five errors are similar in nature to server connection errors without proxying.

QNetworkReply::ContentAccessDenied

The documentation says that this error is similar to the 401 error in HTTP, that is, authorization is required, but I believe that this error can also occur in cases of receiving codes 403 and 407. Error 407 is similar to error 401, but is used for a proxy server. And error 403 is generative for errors 401 and 407.

QNetworkReply::AuthenticationRequiredError

This error is specific to the HTTP protocol. The fact is that the http protocol supports authentication schemes. In this case it is necessary to send a request to the server with the setting of login and password. Note that this directly means that you can write an application on Qt that will be authenticated on sites and perform certain actions on the site already in authorized mode, that is, you can write and bot to work on the site.

The solution to this problem is to set the user's login and password in QAuthenticator, which will mix the credentials to the request. And this will be done in automatic mode at the signal QNetworkAccessManager::authenticationRequired , and the login and password will be cached, so the signal will not be emitted at each request.

connect(&m_manager,&QNetworkAccessManager::authenticationRequired,
        [this](QNetworkReply *rep, QAuthenticator* auth){
            auth->setUser("username");
            auth->setPassword("passwordd");
        });

QNetworkReply::ContentReSendError

It is difficult to make any exact analogy with the HTTP codes for this error, since it can be caused by various reasons.

QNetworkReply::ContentConflictError

This error corresponds to a 409 Conflict error in the HTTP protocol.

QNetworkReply::ContentGoneError

This error corresponds to a 410 Gone error in the HTTP protocol.

QNetworkReply::InternalServerError

This error corresponds to 500 Internal Server Error in the http protocol.

QNetworkReply::OperationNotImplementedError

This error corresponds to a 501 Not Implemented error in the http protocol. It occurs when you try to execute, for example, a POST request to a URL where the server processes only GET requests.

This behavior can be found, for example, in the Django project. If the query is not implemented, the server with Django will send a blank page to the POST request with this code.

QNetworkReply::ProtocolUnknownError

An error such as QNetworkReply::ProtocolUnknownError can occur because a url was passed to the request without specifying the protocol type, that is, instead of

http://www.example.com

Was transferred

//www.example.com

This problem can arise if you parse the pages and extract the url of the images. For example, on this site the addresses of all images in the articles are as follows

/media/uploads/2017/02/03/testquickwidget.jpg

That is, the protocol and domain of the site are not specified. Therefore, if you extract all image URLs from a page, you will not be able to download images without additional processing, namely without the domain and protocol substitution at the beginning of the line, having received this error.

QNetworkReply::ServiceUnavailableError

Corresponds to the error 503 Service Unavailable in the http protocol

QNetworkReply::ProtocolInvalidOperationError

In this case, the protocol is defined, but the exact correspondence of the error from the http protocol is not traced, with respect to other protocols, it can also be anything.

QNetworkReply::UnknownNetworkError

The most common variant of what this error may correspond to is the 502 Bad Gateway error  in the http protocol

QNetworkReply::UnknownProxyError

There may also be a 502 error, but already in the version with a proxy server

Errors QNetworkReply::UnknownContentError,QNetworkReply::ProtocolFailure, QNetworkReply::UnknownServerError

With these errors, I find it difficult to find a working correspondence, I will be glad to help if anyone has encountered.

Example with error output in qDebug

You can check for an error when the request is terminated from the QNetworkAccessManager in the slot that is connected to process the result of the request.

manager = new QNetworkAccessManager(this);
connect(manager, &QNetworkAccessManager::finished, this, &Downloader::onResult);

In this case, there is a wrapper class over the QNetworkAccessManager class named Downloader . This class has an onResult slot, which in turn is responsible for processing the result of the QNetworkAccessManager response.

void Downloader::onResult(QNetworkReply *reply)
{
    // If an error occurred while receiving the data
    if(reply->error()){
        // We inform you about this and show information about errors
        qDebug() << "ERROR";
        // Here we get one of the enum NetworkError, that is, the error code
        qDebug() << reply->error();
    } else {
        // ToDo something
    }
}
10% refund of hotel reservation amount on Booking
10% refund of hotel reservation amount on Booking
We offer a link with a 10% return on the amount of the order when booking a hotel through Booking
KL

Unable to init SSL Context: Выдает приложение, что это может быть?

OpenSSL библиотеки возможно требуются. В этой статье есть ссылки, где скачать библиотеки OpenSSL.

Comments

Only authorized users can post comments.
Please, Log in or Sign up
d
April 26, 2019, 2:45 a.m.
djanaibekova_0301@mail.ru

C++ - Тест 003. Условия и циклы

  • Result:42points,
  • Rating points-8
Z
April 25, 2019, 8:02 p.m.
ZadvornyAlexey

C++ - Test 001. The first program and data types

  • Result:60points,
  • Rating points-1
m
April 24, 2019, 2:30 p.m.
maksImkа

C++ - Тест 003. Условия и циклы

  • Result:50points,
  • Rating points-4
Last comments
April 21, 2019, 4:22 p.m.
Евгений Легоцкой

Через метод setIcon table.horizontalHeaderItem(0).setIcon("qrc://path/to/icon.png")
April 21, 2019, 3:48 p.m.
Евгений Легоцкой

Добрый день! Спасибо за комментарий. Там действительно лучше будет сделать с инициализацией по умолчанию.
U
April 18, 2019, 3:37 p.m.
Unreal_man

А как иконку в хедер задать?
u
April 18, 2019, 2:15 a.m.
uaa

доброго времени,большое спасибо за пример для начинающего)при адаптации к своему проекту столкнулся с таким ньансом:в vepolyline.h в 47 строке нужна инициализация по умолчанию: int m_pointF...
E
April 11, 2019, 12:49 p.m.
Evgeny

Спасибо за ответ) У меня компоновщик на нее ругался просто. Оказалось, просто забыл Q_OBJECT в начале класса указать.
Now discuss on the forum
April 25, 2019, 10:51 a.m.
Ruslan Polupan

Изменил функциютеперь работает. bool ModelTerminals::setData(const QModelIndex &index, const QVariant &value, int role){ Q_UNUSED(role) if(!index.isValid()) {return false;...
April 24, 2019, 6:20 a.m.
Ruslan Polupan

я так понимаю надо инфорация об устройствах.Я бы пробовал так rust@suse:~> lsblk -PNAME="sda" MAJ:MIN="8:0" RM="0" SIZE="111,8G" RO="0" TYPE="disk" MOUNTPOINT=""NAME="sda1" MAJ:MIN="8...
April 21, 2019, 4:16 p.m.
Евгений Легоцкой

Приветствую Нужно сохранять где-то выбранное значение, а потом восстанавливать его. Или использовать QSettings или добавить метод open(), в который передавать начальные значения для того...
R
April 19, 2019, 9:55 a.m.
RED_Spider

мені важко це зараз навіть перевірити, тому що знайшов коміт, це ще було в 2016 році, і цей код не буде працювати коректно зараз, єдине скажу що це були QThread
Join us in social networks

For registered users on the site there is a minimum amount of advertising