QNetworkProxyFactory: check the "no_proxy" environment variable
authorAdrien Bustany <adrien.bustany@nokia.com>
Mon, 23 Apr 2012 07:49:11 +0000 (10:49 +0300)
committerQt by Nokia <qt-info@nokia.com>
Tue, 1 May 2012 12:56:38 +0000 (14:56 +0200)
The QNetworkProxyFactory class considered the http_proxy environment
variable, but not the no_proxy one. This commit adds no_proxy handling,
loosely modeled after the way curl does it.

Change-Id: Ibb9e5ffcb30fed5c95dc9fc3bc4177e20d025a50
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Shane Kearns <shane.kearns@accenture.com>
src/network/kernel/qnetworkproxy_generic.cpp

index c0c6b9f..66053b0 100644 (file)
 #ifndef QT_NO_NETWORKPROXY
 
 /*
- * Construct a proxy from the environment variable http_proxy.
+ * Construct a proxy from the environment variables http_proxy and no_proxy.
  * Or no system proxy. Just return a list with NoProxy.
  */
 
 QT_BEGIN_NAMESPACE
 
-QList<QNetworkProxy> QNetworkProxyFactory::systemProxyForQuery(const QNetworkProxyQuery &)
+static bool ignoreProxyFor(const QNetworkProxyQuery &query)
+{
+    const QList<QByteArray> noProxyTokens = qgetenv("no_proxy").split(',');
+
+    foreach (const QByteArray rawToken, noProxyTokens) {
+        QByteArray token = rawToken.trimmed();
+        QString peerHostName = query.peerHostName();
+
+        // Since we use suffix matching, "*" is our 'default' behaviour
+        if (token.startsWith("*"))
+            token = token.mid(1);
+
+        // Harmonize trailing dot notation
+        if (token.endsWith('.') && !peerHostName.endsWith('.'))
+            token = token.left(token.length()-1);
+
+        // We prepend a dot to both values, so that when we do a suffix match,
+        // we don't match "donotmatch.com" with "match.com"
+        if (!token.startsWith('.'))
+            token.prepend('.');
+
+        if (!peerHostName.startsWith('.'))
+            peerHostName.prepend('.');
+
+        if (peerHostName.endsWith(QString::fromLatin1(token)))
+            return true;
+    }
+
+    return false;
+}
+
+QList<QNetworkProxy> QNetworkProxyFactory::systemProxyForQuery(const QNetworkProxyQuery &query)
 {
     QList<QNetworkProxy> proxyList;
 
+    if (ignoreProxyFor(query))
+        return proxyList << QNetworkProxy::NoProxy;
+
     QByteArray proxy_env = qgetenv("http_proxy");
     if (!proxy_env.isEmpty()) {
         QUrl url = QUrl(QString::fromLocal8Bit(proxy_env));