/**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the examples of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the either Technology Preview License Agreement or the ** Beta Release License Agreement. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain ** additional rights. These rights are described in the Nokia Qt LGPL ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this ** package. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3.0 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU General Public License version 3.0 requirements will be ** met: http://www.gnu.org/copyleft/gpl.html. ** ** If you are unsure which license is appropriate for your use, please ** contact the sales department at http://www.qtsoftware.com/contact. ** $QT_END_LICENSE$ ** ****************************************************************************/ #include #include #include "httpwindow.h" #include "ui_authenticationdialog.h" HttpWindow::HttpWindow(QWidget *parent) : QDialog(parent) { #ifndef QT_NO_OPENSSL urlLineEdit = new QLineEdit("https://"); #else urlLineEdit = new QLineEdit("http://"); #endif urlLabel = new QLabel(tr("&URL:")); urlLabel->setBuddy(urlLineEdit); statusLabel = new QLabel(tr("Please enter the URL of a file you want to " "download.")); 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); http = new QHttp(this); connect(urlLineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(enableDownloadButton())); connect(http, SIGNAL(requestFinished(int, bool)), this, SLOT(httpRequestFinished(int, bool))); connect(http, SIGNAL(dataReadProgress(int, int)), this, SLOT(updateDataReadProgress(int, int))); connect(http, SIGNAL(responseHeaderReceived(const QHttpResponseHeader &)), this, SLOT(readResponseHeader(const QHttpResponseHeader &))); connect(http, SIGNAL(authenticationRequired(const QString &, quint16, QAuthenticator *)), this, SLOT(slotAuthenticationRequired(const QString &, quint16, QAuthenticator *))); #ifndef QT_NO_OPENSSL connect(http, SIGNAL(sslErrors(const QList &)), this, SLOT(sslErrors(const QList &))); #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::downloadFile() { QUrl 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; } QHttp::ConnectionMode mode = url.scheme().toLower() == "https" ? QHttp::ConnectionModeHttps : QHttp::ConnectionModeHttp; http->setHost(url.host(), mode, url.port() == -1 ? 0 : url.port()); if (!url.userName().isEmpty()) http->setUser(url.userName(), url.password()); httpRequestAborted = false; QByteArray path = QUrl::toPercentEncoding(url.path(), "!$&'()*+,;=:@/"); if (path.isEmpty()) path = "/"; httpGetId = http->get(path, file); progressDialog->setWindowTitle(tr("HTTP")); progressDialog->setLabelText(tr("Downloading %1.").arg(fileName)); downloadButton->setEnabled(false); } void HttpWindow::cancelDownload() { statusLabel->setText(tr("Download canceled.")); httpRequestAborted = true; http->abort(); downloadButton->setEnabled(true); } void HttpWindow::httpRequestFinished(int requestId, bool error) { if (requestId != httpGetId) return; if (httpRequestAborted) { if (file) { file->close(); file->remove(); delete file; file = 0; } progressDialog->hide(); return; } if (requestId != httpGetId) return; progressDialog->hide(); file->close(); if (error) { file->remove(); QMessageBox::information(this, tr("HTTP"), tr("Download failed: %1.") .arg(http->errorString())); } else { QString fileName = QFileInfo(QUrl(urlLineEdit->text()).path()).fileName(); statusLabel->setText(tr("Downloaded %1 to current directory.").arg(fileName)); } downloadButton->setEnabled(true); delete file; file = 0; } void HttpWindow::readResponseHeader(const QHttpResponseHeader &responseHeader) { switch (responseHeader.statusCode()) { case 200: // Ok case 301: // Moved Permanently case 302: // Found case 303: // See Other case 307: // Temporary Redirect // these are not error conditions break; default: QMessageBox::information(this, tr("HTTP"), tr("Download failed: %1.") .arg(responseHeader.reasonPhrase())); httpRequestAborted = true; progressDialog->hide(); http->abort(); } } void HttpWindow::updateDataReadProgress(int bytesRead, int totalBytes) { if (httpRequestAborted) return; progressDialog->setMaximum(totalBytes); progressDialog->setValue(bytesRead); } void HttpWindow::enableDownloadButton() { downloadButton->setEnabled(!urlLineEdit->text().isEmpty()); } void HttpWindow::slotAuthenticationRequired(const QString &hostName, quint16, QAuthenticator *authenticator) { QDialog dlg; Ui::Dialog ui; ui.setupUi(&dlg); dlg.adjustSize(); ui.siteDescription->setText(tr("%1 at %2").arg(authenticator->realm()).arg(hostName)); if (dlg.exec() == QDialog::Accepted) { authenticator->setUser(ui.userEdit->text()); authenticator->setPassword(ui.passwordEdit->text()); } } #ifndef QT_NO_OPENSSL void HttpWindow::sslErrors(const QList &errors) { QString errorString; foreach (const QSslError &error, errors) { if (!errorString.isEmpty()) errorString += ", "; errorString += error.errorString(); } if (QMessageBox::warning(this, tr("HTTP Example"), tr("One or more SSL errors has occurred: %1").arg(errorString), QMessageBox::Ignore | QMessageBox::Abort) == QMessageBox::Ignore) { http->ignoreSslErrors(); } } #endif