Enable per network configuration proxy settings in QNetworkAccessManager

Delayed the resolving of the proxy until the backend is being started.
This is because the proxy settings are not known until after
QNetworkAccessManager has brought the network online using
QNetworkSession.
On Nokia's symbian3 phones, the default network configuration is a
service network containing a list of access points in priority order.
For a typical user, this will include one or more WLAN networks and a
cellular network - each of which can have different proxy settings.

Task-number: QTBUG-18618
Reviewed-by: Peter Hartmann
This commit is contained in:
Shane Kearns 2011-04-18 15:23:33 +01:00 committed by Markus Goetz
parent f0f55cd59f
commit 1ad3814a56
2 changed files with 54 additions and 28 deletions

View File

@ -41,6 +41,7 @@
#include "qnetworkaccessbackend_p.h"
#include "qnetworkaccessmanager_p.h"
#include "qnetworkconfigmanager.h"
#include "qnetworkrequest.h"
#include "qnetworkreply.h"
#include "qnetworkreply_p.h"
@ -343,8 +344,6 @@ void QNetworkAccessBackend::sslErrors(const QList<QSslError> &errors)
#endif
}
#ifndef QT_NO_BEARERMANAGEMENT
/*!
Starts the backend. Returns true if the backend is started. Returns false if the backend
could not be started due to an unopened or roaming session. The caller should recall this
@ -352,31 +351,62 @@ void QNetworkAccessBackend::sslErrors(const QList<QSslError> &errors)
*/
bool QNetworkAccessBackend::start()
{
if (!manager->networkSession) {
open();
return true;
}
#ifndef QT_NO_BEARERMANAGEMENT
// For bearer, check if session start is required
if (manager->networkSession) {
// session required
if (manager->networkSession->isOpen() &&
manager->networkSession->state() == QNetworkSession::Connected) {
// Session is already open and ready to use.
// copy network session down to the backend
setProperty("_q_networksession", QVariant::fromValue(manager->networkSession));
} else {
// Session not ready, but can skip for loopback connections
// This is not ideal.
const QString host = reply->url.host();
if (host == QLatin1String("localhost") ||
QHostAddress(host) == QHostAddress::LocalHost ||
QHostAddress(host) == QHostAddress::LocalHostIPv6) {
// Don't need an open session for localhost access.
open();
return true;
}
// This is not ideal.
const QString host = reply->url.host();
if (manager->networkSession->isOpen() &&
manager->networkSession->state() == QNetworkSession::Connected) {
//copy network session down to the backend
setProperty("_q_networksession", QVariant::fromValue(manager->networkSession));
open();
return true;
if (host == QLatin1String("localhost") ||
QHostAddress(host) == QHostAddress::LocalHost ||
QHostAddress(host) == QHostAddress::LocalHostIPv6) {
// Don't need an open session for localhost access.
} else {
// need to wait for session to be opened
return false;
}
}
}
return false;
}
#endif
#ifndef QT_NO_NETWORKPROXY
#ifndef QT_NO_BEARERMANAGEMENT
// Get the proxy settings from the network session (in the case of service networks,
// the proxy settings change depending which AP was activated)
QNetworkSession *session = manager->networkSession.data();
QNetworkConfiguration config;
if (session) {
QNetworkConfigurationManager configManager;
// The active configuration tells us what IAP is in use
QVariant v = session->sessionProperty(QLatin1String("ActiveConfiguration"));
if (v.isValid())
config = configManager.configurationFromIdentifier(qvariant_cast<QString>(v));
// Fallback to using the configuration if no active configuration
if (!config.isValid())
config = session->configuration();
// or unspecified configuration if that is no good either
if (!config.isValid())
config = QNetworkConfiguration();
}
reply->proxyList = manager->queryProxy(QNetworkProxyQuery(config, url()));
#else // QT_NO_BEARERMANAGEMENT
// Without bearer management, the proxy depends only on the url
reply->proxyList = manager->queryProxy(QNetworkProxyQuery(url()));
#endif
#endif
// now start the request
open();
return true;
}
QT_END_NAMESPACE

View File

@ -1004,10 +1004,6 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera
// third step: find a backend
priv->backend = d->findBackend(op, request);
#ifndef QT_NO_NETWORKPROXY
QList<QNetworkProxy> proxyList = d->queryProxy(QNetworkProxyQuery(request.url()));
priv->proxyList = proxyList;
#endif
if (priv->backend) {
priv->backend->setParent(reply);
priv->backend->reply = priv;