/**************************************************************************** ** ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the plugins of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** GNU Lesser General Public License Usage ** This file may be used under the terms of the GNU Lesser General Public ** License version 2.1 as published by the Free Software Foundation and ** appearing in the file LICENSE.LGPL included in the packaging of this ** file. Please review the following information to ensure the GNU Lesser ** General Public License version 2.1 requirements will be met: ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU General ** Public License version 3.0 as published by the Free Software Foundation ** and appearing in the file LICENSE.GPL included in the packaging of this ** file. Please review the following information to ensure the GNU General ** Public License version 3.0 requirements will be met: ** http://www.gnu.org/copyleft/gpl.html. ** ** Other Usage ** Alternatively, this file may be used in accordance with the terms and ** conditions contained in a signed written agreement between you and Nokia. ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include #include #include #include #include #include #include #include #include "proxyconf.h" #define CONF_PROXY "/system/proxy" #define HTTP_PROXY "/system/http_proxy" namespace Maemo { static QString convertKey(const char *key) { return QString::fromUtf8(key); } static QVariant convertValue(GConfValue *src) { if (!src) { return QVariant(); } else { switch (src->type) { case GCONF_VALUE_INVALID: return QVariant(QVariant::Invalid); case GCONF_VALUE_BOOL: return QVariant((bool)gconf_value_get_bool(src)); case GCONF_VALUE_INT: return QVariant(gconf_value_get_int(src)); case GCONF_VALUE_FLOAT: return QVariant(gconf_value_get_float(src)); case GCONF_VALUE_STRING: return QVariant(QString::fromUtf8(gconf_value_get_string(src))); case GCONF_VALUE_LIST: switch (gconf_value_get_list_type(src)) { case GCONF_VALUE_STRING: { QStringList result; for (GSList *elts = gconf_value_get_list(src); elts; elts = elts->next) result.append(QString::fromUtf8(gconf_value_get_string((GConfValue *)elts->data))); return QVariant(result); } default: { QList result; for (GSList *elts = gconf_value_get_list(src); elts; elts = elts->next) result.append(convertValue((GConfValue *)elts->data)); return QVariant(result); } } case GCONF_VALUE_SCHEMA: default: return QVariant(); } } } /* Fast version of GConfItem, allows reading subtree at a time */ class GConfItemFast { public: GConfItemFast(const QString &k) : key(k) {} QHash getEntries() const; private: QString key; }; #define withClient(c) for (GConfClient *c = gconf_client_get_default(); c; c=0) QHash GConfItemFast::getEntries() const { QHash children; withClient(client) { QByteArray k = key.toUtf8(); GSList *entries = gconf_client_all_entries(client, k.data(), NULL); for (GSList *e = entries; e; e = e->next) { char *key_name = strrchr(((GConfEntry *)e->data)->key, '/'); if (!key_name) key_name = ((GConfEntry *)e->data)->key; else key_name++; QString key(convertKey(key_name)); QVariant value = convertValue(((GConfEntry *)e->data)->value); gconf_entry_unref((GConfEntry *)e->data); //qDebug()<<"key="< queryProxy(const QNetworkProxyQuery &query = QNetworkProxyQuery()); }; QList NetworkProxyFactory::queryProxy(const QNetworkProxyQuery &query) { if (proxy_data_read == false) { proxy_data_read = true; proxy_conf.readProxyData(); } QList result = proxy_conf.flush(query); if (result.isEmpty()) result << QNetworkProxy::NoProxy; return result; } class ProxyConfPrivate { private: // proxy values from gconf QString mode; bool use_http_host; QString autoconfig_url; QString http_proxy; quint16 http_port; QList ignore_hosts; QString secure_host; quint16 secure_port; QString ftp_host; quint16 ftp_port; QString socks_host; quint16 socks_port; QString rtsp_host; quint16 rtsp_port; bool isHostExcluded(const QString &host); public: QString prefix; QString http_prefix; void readProxyData(); QList flush(const QNetworkProxyQuery &query); }; static QHash getValues(const QString& prefix) { GConfItemFast item(prefix); return item.getEntries(); } static QHash getHttpValues(const QString& prefix) { GConfItemFast item(prefix); return item.getEntries(); } #define GET(var, type) \ do { \ QVariant v = values.value(#var); \ if (v.isValid()) \ var = v.to##type (); \ } while(0) #define GET_HTTP(var, name, type) \ do { \ QVariant v = httpValues.value(#name); \ if (v.isValid()) \ var = v.to##type (); \ } while(0) void ProxyConfPrivate::readProxyData() { QHash values = getValues(prefix); QHash httpValues = getHttpValues(http_prefix); //qDebug()<<"values="< ProxyConfPrivate::flush(const QNetworkProxyQuery &query) { QList result; #if 0 qDebug()<<"http_proxy" << http_proxy; qDebug()<<"http_port" << http_port; qDebug()<<"ignore_hosts" << ignore_hosts; qDebug()<<"use_http_host" << use_http_host; qDebug()<<"mode" << mode; qDebug()<<"autoconfig_url" << autoconfig_url; qDebug()<<"secure_host" << secure_host; qDebug()<<"secure_port" << secure_port; qDebug()<<"ftp_host" << ftp_host; qDebug()<<"ftp_port" << ftp_port; qDebug()<<"socks_host" << socks_host; qDebug()<<"socks_port" << socks_port; qDebug()<<"rtsp_host" << rtsp_host; qDebug()<<"rtsp_port" << rtsp_port; #endif if (isHostExcluded(query.peerHostName())) return result; // no proxy for this host if (mode == QLatin1String("AUTO")) { // TODO: pac currently not supported, fix me return result; } if (mode == QLatin1String("MANUAL")) { bool isHttps = false; QString protocol = query.protocolTag().toLower(); // try the protocol-specific proxy QNetworkProxy protocolSpecificProxy; if (protocol == QLatin1String("ftp")) { if (!ftp_host.isEmpty()) { protocolSpecificProxy.setType(QNetworkProxy::FtpCachingProxy); protocolSpecificProxy.setHostName(ftp_host); protocolSpecificProxy.setPort(ftp_port); } } else if (protocol == QLatin1String("http")) { if (!http_proxy.isEmpty()) { protocolSpecificProxy.setType(QNetworkProxy::HttpProxy); protocolSpecificProxy.setHostName(http_proxy); protocolSpecificProxy.setPort(http_port); } } else if (protocol == QLatin1String("https")) { isHttps = true; if (!secure_host.isEmpty()) { protocolSpecificProxy.setType(QNetworkProxy::HttpProxy); protocolSpecificProxy.setHostName(secure_host); protocolSpecificProxy.setPort(secure_port); } } if (protocolSpecificProxy.type() != QNetworkProxy::DefaultProxy) result << protocolSpecificProxy; if (!socks_host.isEmpty()) { QNetworkProxy proxy; proxy.setType(QNetworkProxy::Socks5Proxy); proxy.setHostName(socks_host); proxy.setPort(socks_port); result << proxy; } // Add the HTTPS proxy if present (and if we haven't added yet) if (!isHttps) { QNetworkProxy https; if (!secure_host.isEmpty()) { https.setType(QNetworkProxy::HttpProxy); https.setHostName(secure_host); https.setPort(secure_port); } if (https.type() != QNetworkProxy::DefaultProxy && https != protocolSpecificProxy) result << https; } } return result; } ProxyConf::ProxyConf() : d_ptr(new ProxyConfPrivate) { g_type_init(); d_ptr->prefix = CONF_PROXY; d_ptr->http_prefix = HTTP_PROXY; } ProxyConf::~ProxyConf() { delete d_ptr; } void ProxyConf::readProxyData() { d_ptr->readProxyData(); } QList ProxyConf::flush(const QNetworkProxyQuery &query) { return d_ptr->flush(query); } static int refcount = 0; static QReadWriteLock lock; void ProxyConf::update() { QWriteLocker locker(&lock); NetworkProxyFactory *factory = new NetworkProxyFactory(); QNetworkProxyFactory::setApplicationProxyFactory((QNetworkProxyFactory*)factory); refcount++; } void ProxyConf::clear(void) { QWriteLocker locker(&lock); refcount--; if (refcount == 0) QNetworkProxyFactory::setApplicationProxyFactory(NULL); if (refcount<0) refcount = 0; } } // namespace Maemo