Revision control
++ // Copyright (C) 2020 The Qt Company Ltd.
++ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
++
++ /*!
++ \example http
++ \examplecategory {Networking}
++ \examplecategory {Web Technologies}
++ \meta tags {http,network,https,proxy}
++ \title HTTP Client
++ \ingroup examples-network
++ \brief Demonstrates a simple HTTP client.
++
++ This example demonstrates how a simple HTTP client can fetch files
++ from remote hosts.
++
++ \image http-example.webp {The user enters the URL, file name, and download location in the main window. The QNetworkAccessManager class uses this information to download the file}
++
++ The main work of this example is done in the HttpWindow class.
++ Thus we will focus on that.
++
++ \snippet http/httpwindow.cpp qnam-tcpkeepalive
++
++ Since Qt 6.11, it is possible to explicitly specify the TCP keepalive
++ parameters for a QNetworkRequest. In the snippet above, we are overriding
++ the defaults used by QNetworkAccessManager to follow a more aggressive
++ strategy. This can be useful, for example, in early detection of network
++ hangs caused by network changes on Linux. In this particular example, the
++ connection will be closed after thirty seconds of inactivity.
++
++ \snippet http/httpwindow.cpp qnam-download
++
++ Using QNetworkAccessManager, we begin the download of a resource as
++ pointed to by the \c url. If you are unfamiliar with it or the function used,
++ QNetworkAccessManager::get(), or simply want to look into it in more detail,
++ take a look at its documentation and the documentation for
++ QNetworkReply and QNetworkRequest.
++
++ \snippet http/httpwindow.cpp connecting-reply-to-slots
++
++ Above, we connect some of the reply's signals to slots in the class.
++ These slots will take care of both incoming data and finalizing the
++ download/handling errors.
++
++ \snippet http/httpwindow.cpp networkreply-readyread-1
++
++ As for handling the incoming data, since we don't know the maximum
++ download size of any potential input and we don't want to exhaust
++ the memory of any computer which might run the example program, we
++ handle incoming data in QNetworkReply::readyRead() instead of in
++ QNetworkReply::finished().
++
++ \snippet http/httpwindow.cpp networkreply-readyread-2
++
++ Then we write the data to file as it arrives. It is less convenient,
++ but the application will consume less memory at its peak!
++
++ \snippet http/httpwindow.cpp sslerrors-1
++
++ With the QNetworkReply::sslErrors() signal we can also handle errors that may
++ occur during the TLS handshake when connecting to secure websites (i.e. HTTPS).
++
++ \snippet http/httpwindow.cpp sslerrors-2
++
++ In this example, we show a dialog to the user so that they can choose whether
++ or not to ignore the errors.
++
++ \snippet http/httpwindow.cpp networkreply-error-handling-1
++ \snippet http/httpwindow.cpp networkreply-error-handling-2
++
++ If an error occurs then QNetworkReply will emit the
++ QNetworkReply::errorOccurred() signal, followed by the
++ QNetworkReply::finished() signal. In this example, we only connect to the
++ latter. We handle any potential error(s) in the respective slot by deleting
++ the file we were writing to, and display the error with our status label.
++
++ \snippet http/httpwindow.cpp qnam-auth-required-1
++
++ If you connect to a website that uses
++ \l{https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication}{HTTP authentication},
++ assuming you didn't supply the credentials that should be used ahead of time,
++ you can handle missing credentials when the website requests it. With QNetworkAccessManager,
++ we do this in a slot connected to the signal
++ QNetworkAccessManager::authenticationRequired(). We make this connection once,
++ in the constructor.
++
++ \snippet http/httpwindow.cpp qnam-auth-required-2
++
++ In this example, we show a dialog where the user can either insert a
++ username and password, or cancel. Canceling causes the request to fail.
++
++ */