httpwindow.cpp Example File

Find this file on Gitorious.

  1. /****************************************************************************
  2. **
  3. ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
  4. ** All rights reserved.
  5. ** Contact: Nokia Corporation (qt-info@nokia.com)
  6. **
  7. ** This file is part of the examples of the Qt Toolkit.
  8. **
  9. ** $QT_BEGIN_LICENSE:BSD$
  10. ** You may use this file under the terms of the BSD license as follows:
  11. **
  12. ** "Redistribution and use in source and binary forms, with or without
  13. ** modification, are permitted provided that the following conditions are
  14. ** met:
  15. **   * Redistributions of source code must retain the above copyright
  16. **     notice, this list of conditions and the following disclaimer.
  17. **   * Redistributions in binary form must reproduce the above copyright
  18. **     notice, this list of conditions and the following disclaimer in
  19. **     the documentation and/or other materials provided with the
  20. **     distribution.
  21. **   * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
  22. **     the names of its contributors may be used to endorse or promote
  23. **     products derived from this software without specific prior written
  24. **     permission.
  25. **
  26. ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  27. ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  28. ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  29. ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  30. ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  31. ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  32. ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  33. ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  34. ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  35. ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  36. ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
  37. ** $QT_END_LICENSE$
  38. **
  39. ****************************************************************************/
  40.  
  41. #include <QtGui>
  42. #include <QtNetwork>
  43.  
  44. #include "httpwindow.h"
  45. #include "ui_authenticationdialog.h"
  46.  
  47. HttpWindow::HttpWindow(QWidget *parent)
  48.     : QDialog(parent)
  49.  {
  50. #ifndef QT_NO_OPENSSL
  51.     urlLineEdit = new QLineEdit("https://qt.nokia.com/");
  52. #else
  53.     urlLineEdit = new QLineEdit("http://qt.nokia.com/");
  54. #endif
  55.  
  56.     urlLabel = new QLabel(tr("&URL:"));
  57.     urlLabel->setBuddy(urlLineEdit);
  58.     statusLabel = new QLabel(tr("Please enter the URL of a file you want to "
  59.                                 "download."));
  60.  
  61.     downloadButton = new QPushButton(tr("Download"));
  62.     downloadButton->setDefault(true);
  63.     quitButton = new QPushButton(tr("Quit"));
  64.     quitButton->setAutoDefault(false);
  65.  
  66.     buttonBox = new QDialogButtonBox;
  67.     buttonBox->addButton(downloadButton, QDialogButtonBox::ActionRole);
  68.     buttonBox->addButton(quitButton, QDialogButtonBox::RejectRole);
  69.  
  70.     progressDialog = new QProgressDialog(this);
  71.  
  72.     connect(urlLineEdit, SIGNAL(textChanged(QString)),
  73.             this, SLOT(enableDownloadButton()));
  74.  
  75.     connect(&qnam, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)),
  76.             this, SLOT(slotAuthenticationRequired(QNetworkReply*,QAuthenticator*)));
  77. #ifndef QT_NO_OPENSSL
  78.     connect(&qnam, SIGNAL(sslErrors(QNetworkReply*,QList<QSslError>)),
  79.             this, SLOT(sslErrors(QNetworkReply*,QList<QSslError>)));
  80. #endif
  81.     connect(progressDialog, SIGNAL(canceled()), this, SLOT(cancelDownload()));
  82.     connect(downloadButton, SIGNAL(clicked()), this, SLOT(downloadFile()));
  83.     connect(quitButton, SIGNAL(clicked()), this, SLOT(close()));
  84.  
  85.     QHBoxLayout *topLayout = new QHBoxLayout;
  86.     topLayout->addWidget(urlLabel);
  87.     topLayout->addWidget(urlLineEdit);
  88.  
  89.     QVBoxLayout *mainLayout = new QVBoxLayout;
  90.     mainLayout->addLayout(topLayout);
  91.     mainLayout->addWidget(statusLabel);
  92.     mainLayout->addWidget(buttonBox);
  93.     setLayout(mainLayout);
  94.  
  95.     setWindowTitle(tr("HTTP"));
  96.     urlLineEdit->setFocus();
  97. }
  98.  
  99. void HttpWindow::startRequest(QUrl url)
  100.  {
  101.     reply = qnam.get(QNetworkRequest(url));
  102.     connect(reply, SIGNAL(finished()),
  103.             this, SLOT(httpFinished()));
  104.     connect(reply, SIGNAL(readyRead()),
  105.             this, SLOT(httpReadyRead()));
  106.     connect(reply, SIGNAL(downloadProgress(qint64,qint64)),
  107.             this, SLOT(updateDataReadProgress(qint64,qint64)));
  108. }
  109.  
  110. void HttpWindow::downloadFile()
  111.  {
  112.     url = urlLineEdit->text();
  113.  
  114.     QFileInfo fileInfo(url.path());
  115.     QString fileName = fileInfo.fileName();
  116.     if (fileName.isEmpty())
  117.         fileName = "index.html";
  118.  
  119.     if (QFile::exists(fileName))  {
  120.         if (QMessageBox::question(this, tr("HTTP"),
  121.                                   tr("There already exists a file called %1 in "
  122.                                      "the current directory. Overwrite?").arg(fileName),
  123.                                   QMessageBox::Yes|QMessageBox::No, QMessageBox::No)
  124.             == QMessageBox::No)
  125.             return;
  126.         QFile::remove(fileName);
  127.     }
  128.  
  129.     file = new QFile(fileName);
  130.     if (!file->open(QIODevice::WriteOnly))  {
  131.         QMessageBox::information(this, tr("HTTP"),
  132.                                  tr("Unable to save the file %1: %2.")
  133.                                  .arg(fileName).arg(file->errorString()));
  134.         delete file;
  135.         file = 0;
  136.         return;
  137.     }
  138.  
  139.     progressDialog->setWindowTitle(tr("HTTP"));
  140.     progressDialog->setLabelText(tr("Downloading %1.").arg(fileName));
  141.     downloadButton->setEnabled(false);
  142.  
  143.     // schedule the request
  144.     httpRequestAborted = false;
  145.     startRequest(url);
  146. }
  147.  
  148. void HttpWindow::cancelDownload()
  149.  {
  150.     statusLabel->setText(tr("Download canceled."));
  151.     httpRequestAborted = true;
  152.     reply->abort();
  153.     downloadButton->setEnabled(true);
  154. }
  155.  
  156. void HttpWindow::httpFinished()
  157.  {
  158.     if (httpRequestAborted)  {
  159.         if (file)  {
  160.             file->close();
  161.             file->remove();
  162.             delete file;
  163.             file = 0;
  164.         }
  165.         reply->deleteLater();
  166.         progressDialog->hide();
  167.         return;
  168.     }
  169.  
  170.     progressDialog->hide();
  171.     file->flush();
  172.     file->close();
  173.  
  174.     QVariant redirectionTarget = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
  175.     if (reply->error())  {
  176.         file->remove();
  177.         QMessageBox::information(this, tr("HTTP"),
  178.                                  tr("Download failed: %1.")
  179.                                  .arg(reply->errorString()));
  180.         downloadButton->setEnabled(true);
  181.     } else if (!redirectionTarget.isNull())  {
  182.         QUrl newUrl = url.resolved(redirectionTarget.toUrl());
  183.         if (QMessageBox::question(this, tr("HTTP"),
  184.                                   tr("Redirect to %1 ?").arg(newUrl.toString()),
  185.                                   QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes)  {
  186.             url = newUrl;
  187.             reply->deleteLater();
  188.             file->open(QIODevice::WriteOnly);
  189.             file->resize(0);
  190.             startRequest(url);
  191.             return;
  192.         }
  193.     } else  {
  194.         QString fileName = QFileInfo(QUrl(urlLineEdit->text()).path()).fileName();
  195.         statusLabel->setText(tr("Downloaded %1 to current directory.").arg(fileName));
  196.         downloadButton->setEnabled(true);
  197.     }
  198.  
  199.     reply->deleteLater();
  200.     reply = 0;
  201.     delete file;
  202.     file = 0;
  203. }
  204.  
  205. void HttpWindow::httpReadyRead()
  206.  {
  207.     // this slot gets called every time the QNetworkReply has new data.
  208.     // We read all of its new data and write it into the file.
  209.     // That way we use less RAM than when reading it at the finished()
  210.     // signal of the QNetworkReply
  211.     if (file)
  212.         file->write(reply->readAll());
  213. }
  214.  
  215. void HttpWindow::updateDataReadProgress(qint64 bytesRead, qint64 totalBytes)
  216.  {
  217.     if (httpRequestAborted)
  218.         return;
  219.  
  220.     progressDialog->setMaximum(totalBytes);
  221.     progressDialog->setValue(bytesRead);
  222. }
  223.  
  224. void HttpWindow::enableDownloadButton()
  225.  {
  226.     downloadButton->setEnabled(!urlLineEdit->text().isEmpty());
  227. }
  228.  
  229. void HttpWindow::slotAuthenticationRequired(QNetworkReply*,QAuthenticator *authenticator)
  230.  {
  231.     QDialog dlg;
  232.     Ui::Dialog ui;
  233.     ui.setupUi(&dlg);
  234.     dlg.adjustSize();
  235.     ui.siteDescription->setText(tr("%1 at %2").arg(authenticator->realm()).arg(url.host()));
  236.  
  237.     // Did the URL have information? Fill the UI
  238.     // This is only relevant if the URL-supplied credentials were wrong
  239.     ui.userEdit->setText(url.userName());
  240.     ui.passwordEdit->setText(url.password());
  241.  
  242.     if (dlg.exec() == QDialog::Accepted)  {
  243.         authenticator->setUser(ui.userEdit->text());
  244.         authenticator->setPassword(ui.passwordEdit->text());
  245.     }
  246. }
  247.  
  248. #ifndef QT_NO_OPENSSL
  249. void HttpWindow::sslErrors(QNetworkReply*,const QList<QSslError> &errors)
  250.  {
  251.     QString errorString;
  252.     foreach (const QSslError &error, errors)  {
  253.         if (!errorString.isEmpty())
  254.             errorString += ", ";
  255.         errorString += error.errorString();
  256.     }
  257.  
  258.     if (QMessageBox::warning(this, tr("HTTP"),
  259.                              tr("One or more SSL errors has occurred: %1").arg(errorString),
  260.                              QMessageBox::Ignore | QMessageBox::Abort) == QMessageBox::Ignore)  {
  261.         reply->ignoreSslErrors();
  262.     }
  263. }
  264. #endif
Notes provided by the Qt Community

No notes