- Qt 5.5
- Qt Network
- HTTP Example
- httpwindow.cpp Example File
- Qt 5.5.1 Reference Documentation

# httpwindow.cpp Example File

http/httpwindow.cpp

    /****************************************************************************
    **
    ** Copyright (C) 2015 The Qt Company Ltd.
    ** Contact: http://www.qt.io/licensing/
    **
    ** This file is part of the examples of the Qt Toolkit.
    **
    ** $QT_BEGIN_LICENSE:BSD$
    ** You may use this file under the terms of the BSD license as follows:
    **
    ** "Redistribution and use in source and binary forms, with or without
    ** modification, are permitted provided that the following conditions are
    ** met:
    **   * Redistributions of source code must retain the above copyright
    **     notice, this list of conditions and the following disclaimer.
    **   * Redistributions in binary form must reproduce the above copyright
    **     notice, this list of conditions and the following disclaimer in
    **     the documentation and/or other materials provided with the
    **     distribution.
    **   * Neither the name of The Qt Company Ltd nor the names of its
    **     contributors may be used to endorse or promote products derived
    **     from this software without specific prior written permission.
    **
    **
    ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
    **
    ** $QT_END_LICENSE$
    **
    ****************************************************************************/

    #include <QtWidgets>
    #include <QtNetwork>

    #include "httpwindow.h"
    #include "ui_authenticationdialog.h"

    HttpWindow::HttpWindow(QWidget *parent)
        : QDialog(parent)
    {
    #ifndef QT_NO_SSL
        urlLineEdit = new QLineEdit("https://qt-project.org/");
    #else
        urlLineEdit = new QLineEdit("http://qt-project.org/");
    #endif

        urlLabel = new QLabel(tr("&URL:"));
        urlLabel->setBuddy(urlLineEdit);
        statusLabel = new QLabel(tr("Please enter the URL of a file you want to "
                                    "download."));
        statusLabel->setWordWrap(true);

        downloadButton = new QPushButton(tr("Download"));
        downloadButton->setDefault(true);
        quitButton = new QPushButton(tr("Quit"));
        quitButton->setAutoDefault(false);

        buttonBox = new QDialogButtonBox;
        buttonBox->addButton(downloadButton, QDialogButtonBox::ActionRole);
        buttonBox->addButton(quitButton, QDialogButtonBox::RejectRole);

        progressDialog = new QProgressDialog(this);

        connect(urlLineEdit, SIGNAL(textChanged(QString)),
                this, SLOT(enableDownloadButton()));

        connect(&qnam, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)),
                this, SLOT(slotAuthenticationRequired(QNetworkReply*,QAuthenticator*)));
    #ifndef QT_NO_SSL
        connect(&qnam, SIGNAL(sslErrors(QNetworkReply*,QList<QSslError>)),
                this, SLOT(sslErrors(QNetworkReply*,QList<QSslError>)));
    #endif
        connect(progressDialog, SIGNAL(canceled()), this, SLOT(cancelDownload()));
        connect(downloadButton, SIGNAL(clicked()), this, SLOT(downloadFile()));
        connect(quitButton, SIGNAL(clicked()), this, SLOT(close()));

        QHBoxLayout *topLayout = new QHBoxLayout;
        topLayout->addWidget(urlLabel);
        topLayout->addWidget(urlLineEdit);

        QVBoxLayout *mainLayout = new QVBoxLayout;
        mainLayout->addLayout(topLayout);
        mainLayout->addWidget(statusLabel);
        mainLayout->addWidget(buttonBox);
        setLayout(mainLayout);

        setWindowTitle(tr("HTTP"));
        urlLineEdit->setFocus();
    }

    void HttpWindow::startRequest(QUrl url)
    {
        reply = qnam.get(QNetworkRequest(url));
        connect(reply, SIGNAL(finished()),
                this, SLOT(httpFinished()));
        connect(reply, SIGNAL(readyRead()),
                this, SLOT(httpReadyRead()));
        connect(reply, SIGNAL(downloadProgress(qint64,qint64)),
                this, SLOT(updateDataReadProgress(qint64,qint64)));
    }

    void HttpWindow::downloadFile()
    {
        url = urlLineEdit->text();

        QFileInfo fileInfo(url.path());
        QString fileName = fileInfo.fileName();
        if (fileName.isEmpty())
            fileName = "index.html";

        if (QFile::exists(fileName)) {
            if (QMessageBox::question(this, tr("HTTP"),
                                      tr("There already exists a file called %1 in "
                                         "the current directory. Overwrite?").arg(fileName),
                                      QMessageBox::Yes|QMessageBox::No, QMessageBox::No)
                == QMessageBox::No)
                return;
            QFile::remove(fileName);
        }

        file = new QFile(fileName);
        if (!file->open(QIODevice::WriteOnly)) {
            QMessageBox::information(this, tr("HTTP"),
                                     tr("Unable to save the file %1: %2.")
                                     .arg(fileName).arg(file->errorString()));
            delete file;
            file = 0;
            return;
        }

        progressDialog->setWindowTitle(tr("HTTP"));
        progressDialog->setLabelText(tr("Downloading %1.").arg(fileName));
        downloadButton->setEnabled(false);

        // schedule the request
        httpRequestAborted = false;
        startRequest(url);
    }

    void HttpWindow::cancelDownload()
    {
        statusLabel->setText(tr("Download canceled."));
        httpRequestAborted = true;
        reply->abort();
        downloadButton->setEnabled(true);
    }

    void HttpWindow::httpFinished()
    {
        if (httpRequestAborted) {
            if (file) {
                file->close();
                file->remove();
                delete file;
                file = 0;
            }
            reply->deleteLater();
            progressDialog->hide();
            return;
        }

        progressDialog->hide();
        file->flush();
        file->close();

        QVariant redirectionTarget = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
        if (reply->error()) {
            file->remove();
            QMessageBox::information(this, tr("HTTP"),
                                     tr("Download failed: %1.")
                                     .arg(reply->errorString()));
            downloadButton->setEnabled(true);
        } else if (!redirectionTarget.isNull()) {
            QUrl newUrl = url.resolved(redirectionTarget.toUrl());
            if (QMessageBox::question(this, tr("HTTP"),
                                      tr("Redirect to %1 ?").arg(newUrl.toString()),
                                      QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
                url = newUrl;
                reply->deleteLater();
                file->open(QIODevice::WriteOnly);
                file->resize(0);
                startRequest(url);
                return;
            }
        } else {
            QString fileName = QFileInfo(QUrl(urlLineEdit->text()).path()).fileName();
            statusLabel->setText(tr("Downloaded %1 to %2.").arg(fileName).arg(QDir::currentPath()));
            downloadButton->setEnabled(true);
        }

        reply->deleteLater();
        reply = 0;
        delete file;
        file = 0;
    }

    void HttpWindow::httpReadyRead()
    {
        // this slot gets called every time the QNetworkReply has new data.
        // We read all of its new data and write it into the file.
        // That way we use less RAM than when reading it at the finished()
        // signal of the QNetworkReply
        if (file)
            file->write(reply->readAll());
    }

    void HttpWindow::updateDataReadProgress(qint64 bytesRead, qint64 totalBytes)
    {
        if (httpRequestAborted)
            return;

        progressDialog->setMaximum(totalBytes);
        progressDialog->setValue(bytesRead);
    }

    void HttpWindow::enableDownloadButton()
    {
        downloadButton->setEnabled(!urlLineEdit->text().isEmpty());
    }

    void HttpWindow::slotAuthenticationRequired(QNetworkReply*,QAuthenticator *authenticator)
    {
        QDialog dlg;
        Ui::Dialog ui;
        ui.setupUi(&dlg);
        dlg.adjustSize();
        ui.siteDescription->setText(tr("%1 at %2").arg(authenticator->realm()).arg(url.host()));

        // Did the URL have information? Fill the UI
        // This is only relevant if the URL-supplied credentials were wrong
        ui.userEdit->setText(url.userName());
        ui.passwordEdit->setText(url.password());

        if (dlg.exec() == QDialog::Accepted) {
            authenticator->setUser(ui.userEdit->text());
            authenticator->setPassword(ui.passwordEdit->text());
        }
    }

    #ifndef QT_NO_SSL
    void HttpWindow::sslErrors(QNetworkReply*,const QList<QSslError> &errors)
    {
        QString errorString;
        foreach (const QSslError &error, errors) {
            if (!errorString.isEmpty())
                errorString += ", ";
            errorString += error.errorString();
        }

        if (QMessageBox::warning(this, tr("HTTP"),
                                 tr("One or more SSL errors has occurred: %1").arg(errorString),
                                 QMessageBox::Ignore | QMessageBox::Abort) == QMessageBox::Ignore) {
            reply->ignoreSslErrors();
        }
    }
    #endif