Allow a network configuration to be included in a proxy query

When Qt is compiled with bearer management support, the network
configuration can be included as a parameter in QNetworkProxyQuery.

This allows QNetworkProxyFactory::systemProxyForQuery to get the right
proxy setting for a specific network. For example a mobile phone could
have network configurations for home WLAN, work WLAN and 3G data
access points, each with different proxy configurations.

Task-number: QTBUG-18618
Reviewed-by: Peter Hartmann
This commit is contained in:
Shane Kearns 2011-04-15 14:09:43 +01:00 committed by Markus Goetz
parent 279883fdf1
commit f0f55cd59f
3 changed files with 123 additions and 4 deletions

View File

@ -228,6 +228,10 @@
#include "qmutex.h" #include "qmutex.h"
#include "qurl.h" #include "qurl.h"
#ifndef QT_NO_BEARERMANAGEMENT
#include <QtNetwork/QNetworkConfiguration>
#endif
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QSocks5SocketEngineHandler; class QSocks5SocketEngineHandler;
@ -716,6 +720,9 @@ public:
QUrl remote; QUrl remote;
int localPort; int localPort;
QNetworkProxyQuery::QueryType type; QNetworkProxyQuery::QueryType type;
#ifndef QT_NO_BEARERMANAGEMENT
QNetworkConfiguration config;
#endif
}; };
template<> void QSharedDataPointer<QNetworkProxyQueryPrivate>::detach() template<> void QSharedDataPointer<QNetworkProxyQueryPrivate>::detach()
@ -777,6 +784,11 @@ template<> void QSharedDataPointer<QNetworkProxyQueryPrivate>::detach()
like choosing an caching HTTP proxy for HTTP-based connections, like choosing an caching HTTP proxy for HTTP-based connections,
but a more powerful SOCKSv5 proxy for all others. but a more powerful SOCKSv5 proxy for all others.
The network configuration specifies which configuration to use,
when bearer management is used. For example on a mobile phone
the proxy settings are likely to be different for the cellular
network vs WLAN.
Some of the criteria may not make sense in all of the types of Some of the criteria may not make sense in all of the types of
query. The following table lists the criteria that are most query. The following table lists the criteria that are most
commonly used, according to the type of query. commonly used, according to the type of query.
@ -902,6 +914,68 @@ QNetworkProxyQuery::QNetworkProxyQuery(quint16 bindPort, const QString &protocol
d->type = queryType; d->type = queryType;
} }
#ifndef QT_NO_BEARERMANAGEMENT
/*!
Constructs a QNetworkProxyQuery with the URL \a requestUrl and
sets the query type to \a queryType. The specified \a networkConfiguration
is used to resolve the proxy settings.
\sa protocolTag(), peerHostName(), peerPort(), networkConfiguration()
*/
QNetworkProxyQuery::QNetworkProxyQuery(const QNetworkConfiguration &networkConfiguration,
const QUrl &requestUrl, QueryType queryType)
{
d->config = networkConfiguration;
d->remote = requestUrl;
d->type = queryType;
}
/*!
Constructs a QNetworkProxyQuery of type \a queryType and sets the
protocol tag to be \a protocolTag. This constructor is suitable
for QNetworkProxyQuery::TcpSocket queries, because it sets the
peer hostname to \a hostname and the peer's port number to \a
port. The specified \a networkConfiguration
is used to resolve the proxy settings.
\sa networkConfiguration()
*/
QNetworkProxyQuery::QNetworkProxyQuery(const QNetworkConfiguration &networkConfiguration,
const QString &hostname, int port,
const QString &protocolTag,
QueryType queryType)
{
d->config = networkConfiguration;
d->remote.setScheme(protocolTag);
d->remote.setHost(hostname);
d->remote.setPort(port);
d->type = queryType;
}
/*!
Constructs a QNetworkProxyQuery of type \a queryType and sets the
protocol tag to be \a protocolTag. This constructor is suitable
for QNetworkProxyQuery::TcpSocket queries because it sets the
local port number to \a bindPort. The specified \a networkConfiguration
is used to resolve the proxy settings.
Note that \a bindPort is of type quint16 to indicate the exact
port number that is requested. The value of -1 (unknown) is not
allowed in this context.
\sa localPort(), networkConfiguration()
*/
QNetworkProxyQuery::QNetworkProxyQuery(const QNetworkConfiguration &networkConfiguration,
quint16 bindPort, const QString &protocolTag,
QueryType queryType)
{
d->config = networkConfiguration;
d->remote.setScheme(protocolTag);
d->localPort = bindPort;
d->type = queryType;
}
#endif
/*! /*!
Constructs a QNetworkProxyQuery object that is a copy of \a other. Constructs a QNetworkProxyQuery object that is a copy of \a other.
*/ */
@ -1116,6 +1190,30 @@ void QNetworkProxyQuery::setUrl(const QUrl &url)
d->remote = url; d->remote = url;
} }
#ifndef QT_NO_BEARERMANAGEMENT
QNetworkConfiguration QNetworkProxyQuery::networkConfiguration() const
{
return d ? d->config : QNetworkConfiguration();
}
/*!
Sets the network configuration component of this QNetworkProxyQuery
object to be \a networkConfiguration. The network configuration can
be used to return different proxy settings based on the network in
use, for example WLAN vs cellular networks on a mobile phone.
In the case of "user choice" or "service network" configurations,
you should first start the QNetworkSession and obtain the active
configuration from its properties.
\sa networkConfiguration
*/
void QNetworkProxyQuery::setNetworkConfiguration(const QNetworkConfiguration &networkConfiguration)
{
d->config = networkConfiguration;
}
#endif
/*! /*!
\class QNetworkProxyFactory \class QNetworkProxyFactory
\brief The QNetworkProxyFactory class provides fine-grained proxy selection. \brief The QNetworkProxyFactory class provides fine-grained proxy selection.

View File

@ -54,6 +54,7 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Network) QT_MODULE(Network)
class QUrl; class QUrl;
class QNetworkConfiguration;
class QNetworkProxyQueryPrivate; class QNetworkProxyQueryPrivate;
class Q_NETWORK_EXPORT QNetworkProxyQuery class Q_NETWORK_EXPORT QNetworkProxyQuery
@ -73,6 +74,16 @@ public:
QNetworkProxyQuery(quint16 bindPort, const QString &protocolTag = QString(), QNetworkProxyQuery(quint16 bindPort, const QString &protocolTag = QString(),
QueryType queryType = TcpServer); QueryType queryType = TcpServer);
QNetworkProxyQuery(const QNetworkProxyQuery &other); QNetworkProxyQuery(const QNetworkProxyQuery &other);
#ifndef QT_NO_BEARERMANAGEMENT
QNetworkProxyQuery(const QNetworkConfiguration &networkConfiguration,
const QUrl &requestUrl, QueryType queryType = UrlRequest);
QNetworkProxyQuery(const QNetworkConfiguration &networkConfiguration,
const QString &hostname, int port, const QString &protocolTag = QString(),
QueryType queryType = TcpSocket);
QNetworkProxyQuery(const QNetworkConfiguration &networkConfiguration,
quint16 bindPort, const QString &protocolTag = QString(),
QueryType queryType = TcpServer);
#endif
~QNetworkProxyQuery(); ~QNetworkProxyQuery();
QNetworkProxyQuery &operator=(const QNetworkProxyQuery &other); QNetworkProxyQuery &operator=(const QNetworkProxyQuery &other);
bool operator==(const QNetworkProxyQuery &other) const; bool operator==(const QNetworkProxyQuery &other) const;
@ -97,6 +108,11 @@ public:
QUrl url() const; QUrl url() const;
void setUrl(const QUrl &url); void setUrl(const QUrl &url);
#ifndef QT_NO_BEARERMANAGEMENT
QNetworkConfiguration networkConfiguration() const;
void setNetworkConfiguration(const QNetworkConfiguration &networkConfiguration);
#endif
private: private:
QSharedDataPointer<QNetworkProxyQueryPrivate> d; QSharedDataPointer<QNetworkProxyQueryPrivate> d;
}; };

View File

@ -58,6 +58,7 @@
#include <commsdattypeinfov1_1.h> // CCDIAPRecord, CCDProxiesRecord #include <commsdattypeinfov1_1.h> // CCDIAPRecord, CCDProxiesRecord
#include <commsdattypesv1_1.h> // KCDTIdIAPRecord, KCDTIdProxiesRecord #include <commsdattypesv1_1.h> // KCDTIdIAPRecord, KCDTIdProxiesRecord
#include <QtNetwork/QNetworkConfigurationManager> #include <QtNetwork/QNetworkConfigurationManager>
#include <QtNetwork/QNetworkConfiguration>
#include <QFlags> #include <QFlags>
using namespace CommsDat; using namespace CommsDat;
@ -88,7 +89,7 @@ class SymbianProxyQuery
{ {
public: public:
static QNetworkConfiguration findCurrentConfiguration(QNetworkConfigurationManager& configurationManager); static QNetworkConfiguration findCurrentConfiguration(QNetworkConfigurationManager& configurationManager);
static SymbianIapId getIapId(QNetworkConfigurationManager& configurationManager); static SymbianIapId getIapId(QNetworkConfigurationManager &configurationManager, const QNetworkProxyQuery &query);
static CCDIAPRecord *getIapRecordLC(TUint32 aIAPId, CMDBSession &aDb); static CCDIAPRecord *getIapRecordLC(TUint32 aIAPId, CMDBSession &aDb);
static CMDBRecordSet<CCDProxiesRecord> *prepareQueryLC(TUint32 serviceId, TDesC& serviceType); static CMDBRecordSet<CCDProxiesRecord> *prepareQueryLC(TUint32 serviceId, TDesC& serviceType);
static QList<QNetworkProxy> proxyQueryL(TUint32 aIAPId, const QNetworkProxyQuery &query); static QList<QNetworkProxy> proxyQueryL(TUint32 aIAPId, const QNetworkProxyQuery &query);
@ -137,11 +138,15 @@ QNetworkConfiguration SymbianProxyQuery::findCurrentConfiguration(QNetworkConfig
return currentConfig; return currentConfig;
} }
SymbianIapId SymbianProxyQuery::getIapId(QNetworkConfigurationManager& configurationManager) SymbianIapId SymbianProxyQuery::getIapId(QNetworkConfigurationManager& configurationManager, const QNetworkProxyQuery &query)
{ {
SymbianIapId iapId; SymbianIapId iapId;
QNetworkConfiguration currentConfig = findCurrentConfiguration(configurationManager); QNetworkConfiguration currentConfig = query.networkConfiguration();
if (!currentConfig.isValid()) {
//If config is not specified, then try to find out an active or default one
currentConfig = findCurrentConfiguration(configurationManager);
}
if (currentConfig.isValid()) { if (currentConfig.isValid()) {
// Note: the following code assumes that the identifier is in format // Note: the following code assumes that the identifier is in format
// I_xxxx where xxxx is the identifier of IAP. This is meant as a // I_xxxx where xxxx is the identifier of IAP. This is meant as a
@ -249,7 +254,7 @@ QList<QNetworkProxy> QNetworkProxyFactory::systemProxyForQuery(const QNetworkPro
SymbianIapId iapId; SymbianIapId iapId;
TInt error; TInt error;
QNetworkConfigurationManager manager; QNetworkConfigurationManager manager;
iapId = SymbianProxyQuery::getIapId(manager); iapId = SymbianProxyQuery::getIapId(manager, query);
if (iapId.isValid()) { if (iapId.isValid()) {
TRAP(error, proxies = SymbianProxyQuery::proxyQueryL(iapId.iapId(), query)) TRAP(error, proxies = SymbianProxyQuery::proxyQueryL(iapId.iapId(), query))
if (error != KErrNone) { if (error != KErrNone) {