QtNetwork: bypass proxy for local connections

According to Qt doc, "Network proxy is not used if the address used in
connectToHost(), bind() or listen() is equivalent to
QHostAddress::LocalHost or QHostAddress::LocalHostIPv6. This is not the
case in current implementation.

Change-Id: I6b8a40c1e8bd8aad9504d8f939b87eda6e93337c
Reviewed-by: Richard J. Moore <rich@kde.org>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Shane Kearns <shane.kearns@accenture.com>
This commit is contained in:
Julien Brianceau 2012-09-03 13:56:09 +02:00 committed by Qt by Nokia
parent 89a962c3a0
commit 5b1bc864a9
3 changed files with 73 additions and 9 deletions

View File

@ -318,6 +318,18 @@ QList<QNetworkProxy> QGlobalNetworkProxy::proxyForQuery(const QNetworkProxyQuery
QMutexLocker locker(&mutex);
QList<QNetworkProxy> result;
// don't look for proxies for a local connection
QHostAddress parsed;
QString hostname = query.url().host();
if (hostname == QLatin1String("localhost")
|| hostname.startsWith(QLatin1String("localhost."))
|| (parsed.setAddress(hostname)
&& (parsed.isLoopback()))) {
result << QNetworkProxy(QNetworkProxy::NoProxy);
return result;
}
if (!applicationLevelProxyFactory) {
if (applicationLevelProxy
&& applicationLevelProxy->type() != QNetworkProxy::DefaultProxy)

View File

@ -906,15 +906,6 @@ bool QAbstractSocketPrivate::flush()
*/
void QAbstractSocketPrivate::resolveProxy(const QString &hostname, quint16 port)
{
QHostAddress parsed;
if (hostname == QLatin1String("localhost")
|| hostname.startsWith(QLatin1String("localhost."))
|| (parsed.setAddress(hostname)
&& (parsed.isLoopback()))) {
proxyInUse = QNetworkProxy::NoProxy;
return;
}
QList<QNetworkProxy> proxies;
if (proxy.type() != QNetworkProxy::DefaultProxy) {

View File

@ -80,6 +80,7 @@ private slots:
void systemProxyForQueryCalledFromThread();
void systemProxyForQuery_data();
void systemProxyForQuery() const;
void systemProxyForQuery_local();
#ifndef QT_NO_BEARERMANAGEMENT
void fromConfigurations();
void inNetworkAccessManager_data();
@ -196,6 +197,66 @@ void tst_QNetworkProxyFactory::systemProxyForQuery() const
}
}
void tst_QNetworkProxyFactory::systemProxyForQuery_local()
{
QList<QNetworkProxy> list;
const QString proxyHost("myproxy.test.com");
// set an arbitrary proxy
QNetworkProxy::setApplicationProxy(QNetworkProxy(QNetworkProxy::HttpProxy, proxyHost, 80));
// localhost
list = QNetworkProxyFactory::proxyForQuery(QNetworkProxyQuery(QUrl("http://localhost/")));
QVERIFY(list.isEmpty() || (list[0].type() == QNetworkProxy::NoProxy));
list = QNetworkProxyFactory::proxyForQuery(QNetworkProxyQuery(QString("localhost"), 80));
QVERIFY(list.isEmpty() || (list[0].type() == QNetworkProxy::NoProxy));
// 127.0.0.1
list = QNetworkProxyFactory::proxyForQuery(QNetworkProxyQuery(QUrl("http://127.0.0.1/")));
QVERIFY(list.isEmpty() || (list[0].type() == QNetworkProxy::NoProxy));
list = QNetworkProxyFactory::proxyForQuery(QNetworkProxyQuery(QString("127.0.0.1"), 80));
QVERIFY(list.isEmpty() || (list[0].type() == QNetworkProxy::NoProxy));
// [::1]
list = QNetworkProxyFactory::proxyForQuery(QNetworkProxyQuery(QUrl("http://[::1]/")));
QVERIFY(list.isEmpty() || (list[0].type() == QNetworkProxy::NoProxy));
list = QNetworkProxyFactory::proxyForQuery(QNetworkProxyQuery(QString("[::1]"), 80));
QVERIFY(list.isEmpty() || (list[0].type() == QNetworkProxy::NoProxy));
// an arbitrary host
list = QNetworkProxyFactory::proxyForQuery(QNetworkProxyQuery(QUrl("http://another.host.com/")));
QVERIFY((!list.isEmpty()) && (list[0].hostName() == proxyHost));
list = QNetworkProxyFactory::proxyForQuery(QNetworkProxyQuery(QString("another.host.com"), 80));
QVERIFY((!list.isEmpty()) && (list[0].hostName() == proxyHost));
// disable proxy
QNetworkProxy::setApplicationProxy(QNetworkProxy(QNetworkProxy::NoProxy));
// localhost
list = QNetworkProxyFactory::proxyForQuery(QNetworkProxyQuery(QUrl("http://localhost/")));
QVERIFY(list.isEmpty() || (list[0].type() == QNetworkProxy::NoProxy));
list = QNetworkProxyFactory::proxyForQuery(QNetworkProxyQuery(QString("localhost"), 80));
QVERIFY(list.isEmpty() || (list[0].type() == QNetworkProxy::NoProxy));
// 127.0.0.1
list = QNetworkProxyFactory::proxyForQuery(QNetworkProxyQuery(QUrl("http://127.0.0.1/")));
QVERIFY(list.isEmpty() || (list[0].type() == QNetworkProxy::NoProxy));
list = QNetworkProxyFactory::proxyForQuery(QNetworkProxyQuery(QString("127.0.0.1"), 80));
QVERIFY(list.isEmpty() || (list[0].type() == QNetworkProxy::NoProxy));
// [::1]
list = QNetworkProxyFactory::proxyForQuery(QNetworkProxyQuery(QUrl("http://[::1]/")));
QVERIFY(list.isEmpty() || (list[0].type() == QNetworkProxy::NoProxy));
list = QNetworkProxyFactory::proxyForQuery(QNetworkProxyQuery(QString("[::1]"), 80));
QVERIFY(list.isEmpty() || (list[0].type() == QNetworkProxy::NoProxy));
// an arbitrary host
list = QNetworkProxyFactory::proxyForQuery(QNetworkProxyQuery(QUrl("http://another.host.com/")));
QVERIFY(list.isEmpty() || (list[0].type() == QNetworkProxy::NoProxy));
list = QNetworkProxyFactory::proxyForQuery(QNetworkProxyQuery(QString("another.host.com"), 80));
QVERIFY(list.isEmpty() || (list[0].type() == QNetworkProxy::NoProxy));
}
#ifndef QT_NO_BEARERMANAGEMENT
//Purpose of this test is just to check systemProxyForQuery doesn't hang or crash