src/3rdparty/libconninet/src/proxyconf.cpp
changeset 37 758a864f9613
equal deleted inserted replaced
36:ef0373b55136 37:758a864f9613
       
     1 /*
       
     2   libconninet - Internet Connectivity support library
       
     3 
       
     4   Copyright (C) 2010 Nokia Corporation. All rights reserved.
       
     5 
       
     6   Contact: Jukka Rissanen <jukka.rissanen@nokia.com>
       
     7 
       
     8   This library is free software; you can redistribute it and/or
       
     9   modify it under the terms of the GNU Lesser General Public License
       
    10   version 2.1 as published by the Free Software Foundation.
       
    11 
       
    12   This library is distributed in the hope that it will be useful, but
       
    13   WITHOUT ANY WARRANTY; without even the implied warranty of
       
    14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
       
    15   Lesser General Public License for more details.
       
    16 
       
    17   You should have received a copy of the GNU Lesser General Public
       
    18   License along with this library; if not, write to the Free Software
       
    19   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
       
    20   02110-1301 USA
       
    21 */
       
    22 
       
    23 #include <QDebug>
       
    24 #include <QWriteLocker>
       
    25 #include <QNetworkProxyFactory>
       
    26 #include <QNetworkProxy>
       
    27 #include <GConfItem>
       
    28 #include <gconf/gconf-client.h>
       
    29 #include "proxyconf.h"
       
    30 
       
    31 #define CONF_PROXY "/system/proxy"
       
    32 #define HTTP_PROXY "/system/http_proxy"
       
    33 
       
    34 
       
    35 namespace Maemo {
       
    36 
       
    37 class NetworkProxyFactory : QNetworkProxyFactory {
       
    38 public:
       
    39     NetworkProxyFactory() { }
       
    40     QList<QNetworkProxy> queryProxy(const QNetworkProxyQuery &query = QNetworkProxyQuery());
       
    41 };
       
    42 
       
    43 
       
    44 QList<QNetworkProxy> NetworkProxyFactory::queryProxy(const QNetworkProxyQuery &query)
       
    45 {
       
    46     ProxyConf proxy_conf;
       
    47 
       
    48     QList<QNetworkProxy> result = proxy_conf.flush(query);
       
    49     if (result.isEmpty())
       
    50         result << QNetworkProxy::NoProxy;
       
    51 
       
    52     return result;
       
    53 }
       
    54 
       
    55 
       
    56 class ProxyConfPrivate {
       
    57 private:
       
    58     // proxy values from gconf
       
    59     QString mode;
       
    60     bool use_http_host;
       
    61     QString autoconfig_url;
       
    62     QString http_proxy;
       
    63     quint16 http_port;
       
    64     QList<QVariant> ignore_hosts;
       
    65     QString secure_host;
       
    66     quint16 secure_port;
       
    67     QString ftp_host;
       
    68     quint16 ftp_port;
       
    69     QString socks_host;
       
    70     quint16 socks_port;
       
    71     QString rtsp_host;
       
    72     quint16 rtsp_port;
       
    73 
       
    74     QVariant getValue(QString& name);
       
    75     QVariant getHttpValue(QString& name);
       
    76     QVariant getValue(const char *name);
       
    77     QVariant getHttpValue(const char *name);
       
    78     bool isHostExcluded(const QString &host);
       
    79 
       
    80 public:
       
    81     QString prefix;
       
    82     QString http_prefix;
       
    83 
       
    84     void readProxyData();
       
    85     QList<QNetworkProxy> flush(const QNetworkProxyQuery &query);
       
    86 };
       
    87 
       
    88 
       
    89 QVariant ProxyConfPrivate::getValue(QString& name)
       
    90 {
       
    91     GConfItem item(prefix + name);
       
    92     return item.value();
       
    93 }
       
    94 
       
    95 QVariant ProxyConfPrivate::getHttpValue(QString& name)
       
    96 {
       
    97     GConfItem item(http_prefix + name);
       
    98     return item.value();
       
    99 }
       
   100 
       
   101 
       
   102 QVariant ProxyConfPrivate::getValue(const char *name)
       
   103 {
       
   104     QString n = QString(name);
       
   105     return getValue(n);
       
   106 }
       
   107 
       
   108 QVariant ProxyConfPrivate::getHttpValue(const char *name)
       
   109 {
       
   110     QString n = QString(name);
       
   111     return getHttpValue(n);
       
   112 }
       
   113 
       
   114 
       
   115 #define GET(var, type)				\
       
   116   do {						\
       
   117     var = getValue(#var).to##type ();		\
       
   118     /*qDebug()<<"var="<<var;*/			\
       
   119   } while(0)
       
   120 
       
   121 #define GET2(var, name, type)			\
       
   122   do {						\
       
   123     var = getHttpValue(#name).to##type ();	\
       
   124     /*qDebug()<<"var="<<var;*/			\
       
   125   } while(0)
       
   126 
       
   127 
       
   128 void ProxyConfPrivate::readProxyData()
       
   129 {
       
   130     /* Read the proxy settings from /system/proxy* */
       
   131     GET2(http_proxy, host, String);
       
   132     GET2(http_port, port, Int);
       
   133     GET2(ignore_hosts, ignore_hosts, List);
       
   134 
       
   135     GET(mode, String);
       
   136     GET(autoconfig_url, String);
       
   137     GET(secure_host, String);
       
   138     GET(secure_port, Int);
       
   139     GET(ftp_host, String);
       
   140     GET(ftp_port, Int);
       
   141     GET(socks_host, String);
       
   142     GET(socks_port, Int);
       
   143     GET(rtsp_host, String);
       
   144     GET(rtsp_port, Int);
       
   145 
       
   146     if (http_proxy.isEmpty())
       
   147         use_http_host = false;
       
   148     else
       
   149         use_http_host = true;
       
   150 }
       
   151 
       
   152 
       
   153 bool ProxyConfPrivate::isHostExcluded(const QString &host)
       
   154 {
       
   155     if (host.isEmpty())
       
   156         return true;
       
   157 
       
   158     if (ignore_hosts.isEmpty())
       
   159         return false;
       
   160 
       
   161     QHostAddress ipAddress;
       
   162     bool isIpAddress = ipAddress.setAddress(host);
       
   163 
       
   164     foreach (QVariant h, ignore_hosts) {
       
   165         QString entry = h.toString();
       
   166         if (isIpAddress && ipAddress.isInSubnet(QHostAddress::parseSubnet(entry))) {
       
   167             return true;  // excluded
       
   168         } else {
       
   169             // do wildcard matching
       
   170             QRegExp rx(entry, Qt::CaseInsensitive, QRegExp::Wildcard);
       
   171             if (rx.exactMatch(host))
       
   172                 return true;
       
   173         }
       
   174     }
       
   175 
       
   176     // host was not excluded
       
   177     return false;
       
   178 }
       
   179 
       
   180 
       
   181 QList<QNetworkProxy> ProxyConfPrivate::flush(const QNetworkProxyQuery &query)
       
   182 {
       
   183     QList<QNetworkProxy> result;
       
   184 
       
   185 #if 0
       
   186     qDebug()<<"http_proxy" << http_proxy;
       
   187     qDebug()<<"http_port" << http_port;
       
   188     qDebug()<<"ignore_hosts" << ignore_hosts;
       
   189     qDebug()<<"use_http_host" << use_http_host;
       
   190     qDebug()<<"mode" << mode;
       
   191     qDebug()<<"autoconfig_url" << autoconfig_url;
       
   192     qDebug()<<"secure_host" << secure_host;
       
   193     qDebug()<<"secure_port" << secure_port;
       
   194     qDebug()<<"ftp_host" << ftp_host;
       
   195     qDebug()<<"ftp_port" << ftp_port;
       
   196     qDebug()<<"socks_host" << socks_host;
       
   197     qDebug()<<"socks_port" << socks_port;
       
   198     qDebug()<<"rtsp_host" << rtsp_host;
       
   199     qDebug()<<"rtsp_port" << rtsp_port;
       
   200 #endif
       
   201 
       
   202     if (isHostExcluded(query.peerHostName()))
       
   203         return result;          // no proxy for this host
       
   204 
       
   205     if (mode == "auto") {
       
   206         // TODO: pac currently not supported, fix me
       
   207         return result;
       
   208     }
       
   209 
       
   210     if (mode == "manual") {
       
   211         bool isHttps = false;
       
   212 	QString protocol = query.protocolTag().toLower();
       
   213 
       
   214 	// try the protocol-specific proxy
       
   215 	QNetworkProxy protocolSpecificProxy;
       
   216 
       
   217 	if (protocol == QLatin1String("ftp")) {
       
   218 	    if (!ftp_host.isEmpty()) {
       
   219 	        protocolSpecificProxy.setType(QNetworkProxy::FtpCachingProxy);
       
   220 		protocolSpecificProxy.setHostName(ftp_host);
       
   221 		protocolSpecificProxy.setPort(ftp_port);
       
   222 	    }
       
   223 	} else if (protocol == QLatin1String("http")) {
       
   224 	    if (!http_proxy.isEmpty()) {
       
   225 	        protocolSpecificProxy.setType(QNetworkProxy::HttpProxy);
       
   226 		protocolSpecificProxy.setHostName(http_proxy);
       
   227 		protocolSpecificProxy.setPort(http_port);
       
   228 	    }
       
   229 	} else if (protocol == QLatin1String("https")) {
       
   230 	    isHttps = true;
       
   231 	    if (!secure_host.isEmpty()) {
       
   232 	        protocolSpecificProxy.setType(QNetworkProxy::HttpProxy);
       
   233 		protocolSpecificProxy.setHostName(secure_host);
       
   234 		protocolSpecificProxy.setPort(secure_port);
       
   235 	    }
       
   236 	}
       
   237 
       
   238 	if (protocolSpecificProxy.type() != QNetworkProxy::DefaultProxy)
       
   239 	    result << protocolSpecificProxy;
       
   240 
       
   241 
       
   242         if (!socks_host.isEmpty()) {
       
   243 	    QNetworkProxy proxy;
       
   244 	    proxy.setType(QNetworkProxy::Socks5Proxy);
       
   245 	    proxy.setHostName(socks_host);
       
   246 	    proxy.setPort(socks_port);
       
   247 	    result << proxy;
       
   248 	}
       
   249 
       
   250 
       
   251 	// Add the HTTPS proxy if present (and if we haven't added yet)
       
   252 	if (!isHttps) {
       
   253 	    QNetworkProxy https;
       
   254 	    if (!secure_host.isEmpty()) {
       
   255 	        https.setType(QNetworkProxy::HttpProxy);
       
   256 		https.setHostName(secure_host);
       
   257 		https.setPort(secure_port);
       
   258 	    }
       
   259 
       
   260 	    if (https.type() != QNetworkProxy::DefaultProxy &&
       
   261 		https != protocolSpecificProxy)
       
   262 	        result << https;
       
   263 	}
       
   264     }
       
   265 
       
   266     return result;
       
   267 }
       
   268 
       
   269 
       
   270 ProxyConf::ProxyConf()
       
   271     : d_ptr(new ProxyConfPrivate)
       
   272 {
       
   273     g_type_init();
       
   274     d_ptr->prefix = CONF_PROXY "/";
       
   275     d_ptr->http_prefix = HTTP_PROXY "/";
       
   276 }
       
   277 
       
   278 ProxyConf::~ProxyConf()
       
   279 {
       
   280     delete d_ptr;
       
   281 }
       
   282 
       
   283 
       
   284 QList<QNetworkProxy> ProxyConf::flush(const QNetworkProxyQuery &query)
       
   285 {
       
   286     d_ptr->readProxyData();
       
   287     return d_ptr->flush(query);
       
   288 }
       
   289 
       
   290 
       
   291 static int refcount = 0;
       
   292 static QReadWriteLock lock;
       
   293 
       
   294 void ProxyConf::update()
       
   295 {
       
   296     QWriteLocker locker(&lock);
       
   297     NetworkProxyFactory *factory = new NetworkProxyFactory();
       
   298     QNetworkProxyFactory::setApplicationProxyFactory((QNetworkProxyFactory*)factory);
       
   299     refcount++;
       
   300 }
       
   301 
       
   302 
       
   303 void ProxyConf::clear(void)
       
   304 {
       
   305     QWriteLocker locker(&lock);
       
   306     refcount--;
       
   307     if (refcount == 0)
       
   308         QNetworkProxyFactory::setApplicationProxyFactory(NULL);
       
   309 
       
   310     if (refcount<0)
       
   311         refcount = 0;
       
   312 }
       
   313 
       
   314 
       
   315 } // namespace Maemo