summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/libs/installer/downloadfiletask.cpp23
-rw-r--r--src/libs/installer/downloadfiletask.h16
-rw-r--r--src/libs/installer/downloadfiletask_p.h1
-rw-r--r--src/libs/installer/installer.pro8
-rw-r--r--src/libs/installer/metadatajob.cpp20
-rw-r--r--src/libs/installer/packagemanagerproxyfactory.cpp54
-rw-r--r--src/libs/installer/packagemanagerproxyfactory.h11
-rw-r--r--src/libs/installer/proxycredentialsdialog.cpp79
-rw-r--r--src/libs/installer/proxycredentialsdialog.h66
-rw-r--r--src/libs/installer/proxycredentialsdialog.ui106
10 files changed, 376 insertions, 8 deletions
diff --git a/src/libs/installer/downloadfiletask.cpp b/src/libs/installer/downloadfiletask.cpp
index bbb3cc4e3..0bd38615e 100644
--- a/src/libs/installer/downloadfiletask.cpp
+++ b/src/libs/installer/downloadfiletask.cpp
@@ -36,6 +36,7 @@
#include "downloadfiletask_p.h"
#include "observer.h"
+#include <QCoreApplication>
#include <QEventLoop>
#include <QFile>
#include <QFileInfo>
@@ -46,6 +47,13 @@
namespace QInstaller {
+ProxyAuthenticationRequiredException::ProxyAuthenticationRequiredException(const QNetworkProxy &proxy)
+ : FileTaskException(QCoreApplication::translate("ProxyAuthenticationRequiredException",
+ "Proxy requires authentication.")),
+ m_proxy(proxy)
+{
+}
+
Downloader::Downloader()
: m_finished(0)
{
@@ -80,6 +88,8 @@ void Downloader::download(QFutureInterface<FileTaskResult> &fi, const QList<File
m_nam.setProxyFactory(networkProxyFactory);
connect(&m_nam, SIGNAL(authenticationRequired(QNetworkReply*, QAuthenticator*)), this,
SLOT(onAuthenticationRequired(QNetworkReply*, QAuthenticator*)));
+ connect(&m_nam, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), this,
+ SLOT(onProxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)));
QTimer::singleShot(0, this, SLOT(doDownload()));
}
@@ -224,6 +234,12 @@ void Downloader::onFinished(QNetworkReply *reply)
void Downloader::onError(QNetworkReply::NetworkError error)
{
QNetworkReply *const reply = qobject_cast<QNetworkReply *>(sender());
+
+ if (error == QNetworkReply::ProxyAuthenticationRequiredError) {
+ // already handled by onProxyAuthenticationRequired
+ return;
+ }
+
if (reply) {
const Data &data = m_downloads[reply];
//: %2 is a sentence describing the error
@@ -275,6 +291,13 @@ void Downloader::onAuthenticationRequired(QNetworkReply *reply, QAuthenticator *
}
}
+void Downloader::onProxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *)
+{
+ // Report to GUI thread.
+ // (MetadataJob will ask for username/password, and restart the download ...)
+ m_futureInterface->reportException(ProxyAuthenticationRequiredException(proxy));
+}
+
// -- private
diff --git a/src/libs/installer/downloadfiletask.h b/src/libs/installer/downloadfiletask.h
index 3ad972763..6b3ddf24e 100644
--- a/src/libs/installer/downloadfiletask.h
+++ b/src/libs/installer/downloadfiletask.h
@@ -50,6 +50,22 @@ enum
};
}
+class ProxyAuthenticationRequiredException : public FileTaskException
+{
+public:
+ ProxyAuthenticationRequiredException(const QNetworkProxy &proxy);
+ ~ProxyAuthenticationRequiredException() throw() {}
+
+ QNetworkProxy proxy() const { return m_proxy; }
+
+ void raise() const { throw *this; }
+ ProxyAuthenticationRequiredException *clone() const {
+ return new ProxyAuthenticationRequiredException(*this); }
+
+private:
+ QNetworkProxy m_proxy;
+};
+
class INSTALLER_EXPORT DownloadFileTask : public AbstractFileTask
{
Q_OBJECT
diff --git a/src/libs/installer/downloadfiletask_p.h b/src/libs/installer/downloadfiletask_p.h
index d4a2c8ea5..16c38cba5 100644
--- a/src/libs/installer/downloadfiletask_p.h
+++ b/src/libs/installer/downloadfiletask_p.h
@@ -85,6 +85,7 @@ private slots:
void onSslErrors(const QList<QSslError> &sslErrors);
void onDownloadProgress(qint64 bytesReceived, qint64 bytesTotal);
void onAuthenticationRequired(QNetworkReply *reply, QAuthenticator *authenticator);
+ void onProxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator);
private:
diff --git a/src/libs/installer/installer.pro b/src/libs/installer/installer.pro
index 448b4acc4..445a2a05b 100644
--- a/src/libs/installer/installer.pro
+++ b/src/libs/installer/installer.pro
@@ -122,7 +122,8 @@ HEADERS += packagemanagercore.h \
binarycontent.h \
binarylayout.h \
installercalculator.h \
- uninstallercalculator.h
+ uninstallercalculator.h \
+ proxycredentialsdialog.h
SOURCES += packagemanagercore.cpp \
packagemanagercore_p.cpp \
@@ -193,7 +194,10 @@ SOURCES += packagemanagercore.cpp \
binarycontent.cpp \
binarylayout.cpp \
installercalculator.cpp \
- uninstallercalculator.cpp
+ uninstallercalculator.cpp \
+ proxycredentialsdialog.cpp
+
+FORMS += proxycredentialsdialog.ui
RESOURCES += resources/patch_file_lists.qrc \
resources/installer.qrc
diff --git a/src/libs/installer/metadatajob.cpp b/src/libs/installer/metadatajob.cpp
index 5e5a27416..6cb5652c2 100644
--- a/src/libs/installer/metadatajob.cpp
+++ b/src/libs/installer/metadatajob.cpp
@@ -37,6 +37,7 @@
#include "packagemanagercore.h"
#include "packagemanagerproxyfactory.h"
#include "productkeycheck.h"
+#include "proxycredentialsdialog.h"
#include "settings.h"
#include <QTemporaryDir>
@@ -116,6 +117,25 @@ void MetadataJob::xmlTaskFinished()
try {
m_xmlTask.waitForFinished();
status = parseUpdatesXml(m_xmlTask.future().results());
+ } catch (const ProxyAuthenticationRequiredException &e) {
+ //! will be shown as title in the UI dialog
+
+ const QNetworkProxy proxy = e.proxy();
+ ProxyCredentialsDialog proxyCredentials(proxy);
+ qDebug() << e.message();
+
+ if (proxyCredentials.exec() == QDialog::Accepted) {
+ qDebug() << "Retrying with new credentials ...";
+ PackageManagerProxyFactory *factory = m_core->proxyFactory();
+
+ factory->setProxyCredentials(proxy, proxyCredentials.userName(),
+ proxyCredentials.password());
+ m_core->setProxyFactory(factory);
+ status = XmlDownloadRetry;
+ } else {
+ reset();
+ emitFinishedWithError(QInstaller::DownloadError, tr("Missing proxy credentials."));
+ }
} catch (const FileTaskException &e) {
reset();
emitFinishedWithError(QInstaller::DownloadError, e.message());
diff --git a/src/libs/installer/packagemanagerproxyfactory.cpp b/src/libs/installer/packagemanagerproxyfactory.cpp
index 9456a7015..317b3257f 100644
--- a/src/libs/installer/packagemanagerproxyfactory.cpp
+++ b/src/libs/installer/packagemanagerproxyfactory.cpp
@@ -37,6 +37,8 @@
#include "packagemanagercore.h"
#include "settings.h"
+#include <QNetworkProxy>
+
namespace QInstaller {
PackageManagerProxyFactory::PackageManagerProxyFactory(const PackageManagerCore *const core)
@@ -46,9 +48,20 @@ PackageManagerProxyFactory::PackageManagerProxyFactory(const PackageManagerCore
PackageManagerProxyFactory *PackageManagerProxyFactory::clone() const
{
- return new PackageManagerProxyFactory(m_core);
+ PackageManagerProxyFactory *factory = new PackageManagerProxyFactory(m_core);
+ factory->m_proxyCredentials = m_proxyCredentials;
+ return factory;
}
+struct FindProxyCredential {
+ FindProxyCredential(const QString &host, int port) : host(host), port(port) {}
+
+ bool operator()(const ProxyCredential &c) { return c.host == host && c.port == port; }
+private:
+ QString host;
+ int port;
+};
+
QList<QNetworkProxy> PackageManagerProxyFactory::queryProxy(const QNetworkProxyQuery &query)
{
const Settings &settings = m_core->settings();
@@ -69,15 +82,44 @@ QList<QNetworkProxy> PackageManagerProxyFactory::queryProxy(const QNetworkProxyQ
return list << QNetworkProxy(QNetworkProxy::NoProxy);
if (query.queryType() == QNetworkProxyQuery::UrlRequest) {
- if (query.url().scheme() == QLatin1String("ftp"))
- return list << settings.ftpProxy();
+ QNetworkProxy proxy;
+ if (query.url().scheme() == QLatin1String("ftp")) {
+ proxy = settings.ftpProxy();
+ } else if (query.url().scheme() == QLatin1String("http")
+ || query.url().scheme() == QLatin1String("https")) {
+ proxy = settings.httpProxy();
+ }
+
- if ((query.url().scheme() == QLatin1String("http"))
- || (query.url().scheme() == QLatin1String("https"))) {
- return list << settings.httpProxy();
+ auto p = std::find_if(m_proxyCredentials.constBegin(), m_proxyCredentials.constEnd(),
+ FindProxyCredential(proxy.hostName(), proxy.port()));
+ if (p != m_proxyCredentials.constEnd()) {
+ proxy.setUser(p->user);
+ proxy.setPassword(p->password);
}
+ return list << proxy;
}
return list << QNetworkProxy(QNetworkProxy::DefaultProxy);
}
+void PackageManagerProxyFactory::setProxyCredentials(const QNetworkProxy &proxy,
+ const QString &user,
+ const QString &password)
+{
+ auto p = std::find_if(m_proxyCredentials.begin(), m_proxyCredentials.end(),
+ FindProxyCredential(proxy.hostName(), proxy.port()));
+
+ if (p == m_proxyCredentials.constEnd()) {
+ ProxyCredential proxyCredential;
+ proxyCredential.host = proxy.hostName();
+ proxyCredential.port = proxy.port();
+ proxyCredential.user = user;
+ proxyCredential.password = password;
+ m_proxyCredentials.append(proxyCredential);
+ } else {
+ p->user = user;
+ p->password = password;
+ }
+}
+
} // QInstaller
diff --git a/src/libs/installer/packagemanagerproxyfactory.h b/src/libs/installer/packagemanagerproxyfactory.h
index b64183a7e..3d3439bd9 100644
--- a/src/libs/installer/packagemanagerproxyfactory.h
+++ b/src/libs/installer/packagemanagerproxyfactory.h
@@ -41,6 +41,13 @@ namespace QInstaller {
class PackageManagerCore;
+struct ProxyCredential {
+ QString host;
+ QString user;
+ QString password;
+ int port;
+};
+
class PackageManagerProxyFactory : public KDUpdater::FileDownloaderProxyFactory
{
public:
@@ -49,7 +56,11 @@ public:
PackageManagerProxyFactory *clone() const;
QList<QNetworkProxy> queryProxy(const QNetworkProxyQuery &query = QNetworkProxyQuery());
+ void setProxyCredentials(const QNetworkProxy &proxy, const QString &user, const QString &password);
+
private:
+
+ QList<ProxyCredential> m_proxyCredentials;
const PackageManagerCore *const m_core;
};
diff --git a/src/libs/installer/proxycredentialsdialog.cpp b/src/libs/installer/proxycredentialsdialog.cpp
new file mode 100644
index 000000000..689849e48
--- /dev/null
+++ b/src/libs/installer/proxycredentialsdialog.cpp
@@ -0,0 +1,79 @@
+/**************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Installer Framework.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+**
+** $QT_END_LICENSE$
+**
+**************************************************************************/
+#include "proxycredentialsdialog.h"
+#include "ui_proxycredentialsdialog.h"
+
+#include <QNetworkProxy>
+
+namespace QInstaller {
+
+ProxyCredentialsDialog::ProxyCredentialsDialog(const QNetworkProxy &proxy, QWidget *parent) :
+ QDialog(parent),
+ ui(new Ui::ProxyCredentialsDialog)
+{
+ ui->setupUi(this);
+
+ setUserName(proxy.user());
+ setPassword(proxy.password());
+
+ const QString proxyString = QString::fromLatin1("%1:%2").arg(proxy.hostName()).arg(proxy.port());
+ ui->infotext->setText(ui->infotext->text().arg(proxyString));
+}
+
+ProxyCredentialsDialog::~ProxyCredentialsDialog()
+{
+ delete ui;
+}
+
+QString ProxyCredentialsDialog::userName() const
+{
+ return ui->usernameLineEdit->text();
+}
+
+void ProxyCredentialsDialog::setUserName(const QString &username)
+{
+ ui->usernameLineEdit->setText(username);
+}
+
+QString ProxyCredentialsDialog::password() const
+{
+ return ui->passwordLineEdit->text();
+}
+
+void ProxyCredentialsDialog::setPassword(const QString &passwd)
+{
+ ui->passwordLineEdit->setText(passwd);
+}
+
+} // namespace QInstaller
diff --git a/src/libs/installer/proxycredentialsdialog.h b/src/libs/installer/proxycredentialsdialog.h
new file mode 100644
index 000000000..5d5d4583e
--- /dev/null
+++ b/src/libs/installer/proxycredentialsdialog.h
@@ -0,0 +1,66 @@
+/**************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Installer Framework.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+**
+** $QT_END_LICENSE$
+**
+**************************************************************************/
+#ifndef PROXYCREDENTIALSDIALOG_H
+#define PROXYCREDENTIALSDIALOG_H
+
+#include <QDialog>
+
+class QNetworkProxy;
+
+namespace QInstaller {
+
+namespace Ui {
+class ProxyCredentialsDialog;
+}
+
+class ProxyCredentialsDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit ProxyCredentialsDialog(const QNetworkProxy &proxy, QWidget *parent = 0);
+ ~ProxyCredentialsDialog();
+
+ QString userName() const;
+ void setUserName(const QString &username);
+ QString password() const;
+ void setPassword(const QString &passwd);
+
+private:
+ Ui::ProxyCredentialsDialog *ui;
+};
+
+} // QInstaller
+
+#endif // PROXYCREDENTIALSDIALOG_H
diff --git a/src/libs/installer/proxycredentialsdialog.ui b/src/libs/installer/proxycredentialsdialog.ui
new file mode 100644
index 000000000..e6edf03e8
--- /dev/null
+++ b/src/libs/installer/proxycredentialsdialog.ui
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>QInstaller::ProxyCredentialsDialog</class>
+ <widget class="QDialog" name="QInstaller::ProxyCredentialsDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>262</width>
+ <height>114</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Dialog</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QLabel" name="infotext">
+ <property name="text">
+ <string>The proxy %1 requires a username and password.</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QFormLayout" name="formLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="usernameLabel">
+ <property name="text">
+ <string>Username:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLineEdit" name="usernameLineEdit">
+ <property name="placeholderText">
+ <string>Username</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="passwordLabel">
+ <property name="text">
+ <string>Password:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="passwordLineEdit">
+ <property name="echoMode">
+ <enum>QLineEdit::Password</enum>
+ </property>
+ <property name="placeholderText">
+ <string>Password</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>QInstaller::ProxyCredentialsDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>QInstaller::ProxyCredentialsDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>