Allow a network configuration to be included in a proxy query
authorShane Kearns <shane.kearns@accenture.com>
Fri, 15 Apr 2011 13:09:43 +0000 (14:09 +0100)
committerMarkus Goetz <Markus.Goetz@nokia.com>
Mon, 9 May 2011 11:14:37 +0000 (13:14 +0200)
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
src/network/kernel/qnetworkproxy.cpp
src/network/kernel/qnetworkproxy.h
src/network/kernel/qnetworkproxy_symbian.cpp

index 68ff955..14db913 100644 (file)
 #include "qmutex.h"
 #include "qurl.h"
 
+#ifndef QT_NO_BEARERMANAGEMENT
+#include <QtNetwork/QNetworkConfiguration>
+#endif
+
 QT_BEGIN_NAMESPACE
 
 class QSocks5SocketEngineHandler;
@@ -716,6 +720,9 @@ public:
     QUrl remote;
     int localPort;
     QNetworkProxyQuery::QueryType type;
+#ifndef QT_NO_BEARERMANAGEMENT
+    QNetworkConfiguration config;
+#endif
 };
 
 template<> void QSharedDataPointer<QNetworkProxyQueryPrivate>::detach()
@@ -777,6 +784,11 @@ template<> void QSharedDataPointer<QNetworkProxyQueryPrivate>::detach()
     like choosing an caching HTTP proxy for HTTP-based connections,
     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
     query. The following table lists the criteria that are most
     commonly used, according to the type of query.
@@ -902,6 +914,68 @@ QNetworkProxyQuery::QNetworkProxyQuery(quint16 bindPort, const QString &protocol
     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.
 */
@@ -1116,6 +1190,30 @@ void QNetworkProxyQuery::setUrl(const QUrl &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
     \brief The QNetworkProxyFactory class provides fine-grained proxy selection.
index 26562d5..e16b29e 100644 (file)
@@ -54,6 +54,7 @@ QT_BEGIN_NAMESPACE
 QT_MODULE(Network)
 
 class QUrl;
+class QNetworkConfiguration;
 
 class QNetworkProxyQueryPrivate;
 class Q_NETWORK_EXPORT QNetworkProxyQuery
@@ -73,6 +74,16 @@ public:
     QNetworkProxyQuery(quint16 bindPort, const QString &protocolTag = QString(),
                        QueryType queryType = TcpServer);
     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 &operator=(const QNetworkProxyQuery &other);
     bool operator==(const QNetworkProxyQuery &other) const;
@@ -97,6 +108,11 @@ public:
     QUrl url() const;
     void setUrl(const QUrl &url);
 
+#ifndef QT_NO_BEARERMANAGEMENT
+    QNetworkConfiguration networkConfiguration() const;
+    void setNetworkConfiguration(const QNetworkConfiguration &networkConfiguration);
+#endif
+
 private:
     QSharedDataPointer<QNetworkProxyQueryPrivate> d;
 };
index 79dfb27..4ba14c0 100644 (file)
@@ -58,6 +58,7 @@
 #include <commsdattypeinfov1_1.h> // CCDIAPRecord, CCDProxiesRecord
 #include <commsdattypesv1_1.h> // KCDTIdIAPRecord, KCDTIdProxiesRecord
 #include <QtNetwork/QNetworkConfigurationManager>
+#include <QtNetwork/QNetworkConfiguration>
 #include <QFlags>
 
 using namespace CommsDat;
@@ -88,7 +89,7 @@ class SymbianProxyQuery
 {
 public:
     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 CMDBRecordSet<CCDProxiesRecord> *prepareQueryLC(TUint32 serviceId, TDesC& serviceType);
     static QList<QNetworkProxy> proxyQueryL(TUint32 aIAPId, const QNetworkProxyQuery &query);
@@ -137,11 +138,15 @@ QNetworkConfiguration SymbianProxyQuery::findCurrentConfiguration(QNetworkConfig
     return currentConfig;
 }
 
-SymbianIapId SymbianProxyQuery::getIapId(QNetworkConfigurationManager& configurationManager)
+SymbianIapId SymbianProxyQuery::getIapId(QNetworkConfigurationManager& configurationManager, const QNetworkProxyQuery &query)
 {
     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()) {
         // 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
@@ -249,7 +254,7 @@ QList<QNetworkProxy> QNetworkProxyFactory::systemProxyForQuery(const QNetworkPro
     SymbianIapId iapId;
     TInt error;
     QNetworkConfigurationManager manager;
-    iapId = SymbianProxyQuery::getIapId(manager);
+    iapId = SymbianProxyQuery::getIapId(manager, query);
     if (iapId.isValid()) {
         TRAP(error, proxies = SymbianProxyQuery::proxyQueryL(iapId.iapId(), query))
         if (error != KErrNone) {