From 3f3c855a6dd9f926fe186e75da8e41f9c2b94753 Mon Sep 17 00:00:00 2001
From: Jeff Mitchell <tomahawk@jefferai.org>
Date: Fri, 9 Mar 2012 17:41:38 -0500
Subject: [PATCH] Fix XMPP proxy. Make no proxy hosts static so changing it
 works across all threads; make a duplication method so jreen doesn't
 scopepointer us to death on shutdown; pass in proxyfactory to jreen.

---
 src/accounts/xmpp/sip/xmppsip.cpp       |  3 +-
 src/libtomahawk/utils/tomahawkutils.cpp | 46 +++++++++++++++++--------
 src/libtomahawk/utils/tomahawkutils.h   |  2 +-
 src/proxydialog.ui                      |  3 +-
 src/settingsdialog.cpp                  | 21 +++++------
 src/settingsdialog.h                    |  4 +--
 src/tomahawkapp.cpp                     |  1 -
 7 files changed, 47 insertions(+), 33 deletions(-)

diff --git a/src/accounts/xmpp/sip/xmppsip.cpp b/src/accounts/xmpp/sip/xmppsip.cpp
index d89111ccb..9a1f4f58e 100644
--- a/src/accounts/xmpp/sip/xmppsip.cpp
+++ b/src/accounts/xmpp/sip/xmppsip.cpp
@@ -60,11 +60,11 @@ using namespace Accounts;
 
 XmppSipPlugin::XmppSipPlugin( Account *account )
     : SipPlugin( account )
+    , m_state( Account::Disconnected )
 #ifndef ENABLE_HEADLESS
     , m_menu( 0 )
     , m_xmlConsole( 0 )
 #endif
-    , m_state( Account::Disconnected )
 {
     qDebug() << Q_FUNC_INFO;
 
@@ -79,6 +79,7 @@ XmppSipPlugin::XmppSipPlugin( Account *account )
 
     // general client setup
     m_client = new Jreen::Client( jid, m_currentPassword );
+    m_client->setProxyFactory( TomahawkUtils::proxyFactory( true ) );
     setupClientHelper();
 
     m_client->registerPayload( new TomahawkXmppMessageFactory );
diff --git a/src/libtomahawk/utils/tomahawkutils.cpp b/src/libtomahawk/utils/tomahawkutils.cpp
index 640b075a5..237b64c5c 100644
--- a/src/libtomahawk/utils/tomahawkutils.cpp
+++ b/src/libtomahawk/utils/tomahawkutils.cpp
@@ -302,10 +302,11 @@ extensionToMimetype( const QString& extension )
     return s_ext2mime.value( extension, "unknown" );
 }
 
+static QMutex s_noProxyHostsMutex;
+static QStringList s_noProxyHosts;
 
 NetworkProxyFactory::NetworkProxyFactory( const NetworkProxyFactory& other )
 {
-    m_noProxyHosts = QStringList( other.m_noProxyHosts );
     m_proxy = QNetworkProxy( other.m_proxy );
 }
 
@@ -313,13 +314,17 @@ NetworkProxyFactory::NetworkProxyFactory( const NetworkProxyFactory& other )
 QList< QNetworkProxy >
 NetworkProxyFactory::queryProxy( const QNetworkProxyQuery& query )
 {
+    tDebug() << Q_FUNC_INFO << "query hostname is " << query.peerHostName();
     QList< QNetworkProxy > proxies;
     QString hostname = query.peerHostName();
-    if ( m_proxy.hostName().isEmpty() || hostname.isEmpty() || m_noProxyHosts.contains( hostname ) || TomahawkSettings::instance()->proxyType() == QNetworkProxy::NoProxy )
+    s_noProxyHostsMutex.lock();
+    if ( s_noProxyHosts.contains( hostname ) )
+        proxies << QNetworkProxy::NoProxy << systemProxyForQuery( query );
+    else if ( m_proxy.hostName().isEmpty() || hostname.isEmpty() || TomahawkSettings::instance()->proxyType() == QNetworkProxy::NoProxy )
         proxies << systemProxyForQuery( query );
     else
         proxies << m_proxy << systemProxyForQuery( query );
-
+    s_noProxyHostsMutex.unlock();
     return proxies;
 }
 
@@ -336,7 +341,9 @@ NetworkProxyFactory::setNoProxyHosts( const QStringList& hosts )
         //TODO: wildcard support
     }
     tDebug() << Q_FUNC_INFO << "New no-proxy hosts:" << newList;
-    m_noProxyHosts = newList;
+    s_noProxyHostsMutex.lock();
+    s_noProxyHosts = newList;
+    s_noProxyHostsMutex.unlock();
 }
 
 
@@ -358,7 +365,6 @@ NetworkProxyFactory::operator=( const NetworkProxyFactory& rhs )
     if ( this != &rhs )
     {
         m_proxy = QNetworkProxy( rhs.m_proxy );
-        m_noProxyHosts = QStringList( rhs.m_noProxyHosts );
     }
 
     return *this;
@@ -368,7 +374,7 @@ NetworkProxyFactory::operator=( const NetworkProxyFactory& rhs )
 bool NetworkProxyFactory::operator==( const NetworkProxyFactory& other ) const
 {
     tDebug() << Q_FUNC_INFO;
-    if ( m_noProxyHosts != other.m_noProxyHosts || m_proxy != other.m_proxy )
+    if ( m_proxy != other.m_proxy )
         return false;
 
     return true;
@@ -379,25 +385,29 @@ static QMap< QThread*, NetworkProxyFactory* > s_threadProxyFactoryHash;
 static QMutex s_namAccessMutex;
 
 NetworkProxyFactory*
-proxyFactory( bool noMutexLocker )
+proxyFactory( bool makeClone, bool noMutexLocker )
 {
     // Don't lock if being called from nam()
     tDebug() << Q_FUNC_INFO;
     QMutex otherMutex;
     QMutexLocker locker( noMutexLocker ? &otherMutex : &s_namAccessMutex );
 
-    if ( s_threadProxyFactoryHash.contains( QThread::currentThread() ) )
-        return s_threadProxyFactoryHash[ QThread::currentThread() ];
+    if ( !makeClone )
+    {
+        if ( s_threadProxyFactoryHash.contains( QThread::currentThread() ) )
+            return s_threadProxyFactoryHash[ QThread::currentThread() ];
 
-    if ( !s_threadProxyFactoryHash.contains( TOMAHAWK_APPLICATION::instance()->thread() ) )
-        return 0;
+        if ( !s_threadProxyFactoryHash.contains( TOMAHAWK_APPLICATION::instance()->thread() ) )
+            return 0;
+    }
 
     // create a new proxy factory for this thread
     TomahawkUtils::NetworkProxyFactory *mainProxyFactory = s_threadProxyFactoryHash[ TOMAHAWK_APPLICATION::instance()->thread() ];
     TomahawkUtils::NetworkProxyFactory *newProxyFactory = new TomahawkUtils::NetworkProxyFactory();
     *newProxyFactory = *mainProxyFactory;
 
-    s_threadProxyFactoryHash[ QThread::currentThread() ] = newProxyFactory;
+    if ( !makeClone )
+        s_threadProxyFactoryHash[ QThread::currentThread() ] = newProxyFactory;
 
     return newProxyFactory;
 }
@@ -456,7 +466,7 @@ nam()
 
     newNam->setConfiguration( QNetworkConfiguration( mainNam->configuration() ) );
     newNam->setNetworkAccessible( mainNam->networkAccessible() );
-    newNam->setProxyFactory( proxyFactory( true ) );
+    newNam->setProxyFactory( proxyFactory( false, true ) );
 
     s_threadNamHash[ QThread::currentThread() ] = newNam;
 
@@ -486,9 +496,15 @@ setNam( QNetworkAccessManager* nam, bool noMutexLocker )
             QNetworkProxy proxy( s->proxyType(), s->proxyHost(), s->proxyPort(), s->proxyUsername(), s->proxyPassword() );
             proxyFactory->setProxy( proxy );
             //FIXME: Jreen is broke without this
-            QNetworkProxy::setApplicationProxy( proxy );
-            if ( !s->proxyNoProxyHosts().isEmpty() )
+            //QNetworkProxy::setApplicationProxy( proxy );
+            s_noProxyHostsMutex.lock();
+            if ( !s->proxyNoProxyHosts().isEmpty() && s_noProxyHosts.isEmpty() )
+            {
+                s_noProxyHostsMutex.unlock();
                 proxyFactory->setNoProxyHosts( s->proxyNoProxyHosts().split( ',', QString::SkipEmptyParts ) );
+            }
+            else
+                s_noProxyHostsMutex.unlock();
         }
 
         nam->setProxyFactory( proxyFactory );
diff --git a/src/libtomahawk/utils/tomahawkutils.h b/src/libtomahawk/utils/tomahawkutils.h
index 8b3252a98..c5eb57ad4 100644
--- a/src/libtomahawk/utils/tomahawkutils.h
+++ b/src/libtomahawk/utils/tomahawkutils.h
@@ -93,7 +93,7 @@ namespace TomahawkUtils
     DLLEXPORT QString extensionToMimetype( const QString& extension );
     DLLEXPORT bool newerVersion( const QString& oldVersion, const QString& newVersion );
 
-    DLLEXPORT NetworkProxyFactory* proxyFactory( bool noMutexLocker = false );
+    DLLEXPORT NetworkProxyFactory* proxyFactory( bool makeClone = false, bool noMutexLocker = false );
     DLLEXPORT void setProxyFactory( TomahawkUtils::NetworkProxyFactory* factory, bool noMutexLocker = false );
     DLLEXPORT QNetworkAccessManager* nam();
     DLLEXPORT void setNam( QNetworkAccessManager* nam, bool noMutexLocker = false );
diff --git a/src/proxydialog.ui b/src/proxydialog.ui
index 4b30ca1ca..321fcb09c 100644
--- a/src/proxydialog.ui
+++ b/src/proxydialog.ui
@@ -139,7 +139,8 @@
      <item row="5" column="0">
       <widget class="QLabel" name="label">
        <property name="text">
-        <string>No Proxy Hosts:</string>
+        <string>No Proxy Hosts:
+(Overrides system proxy)</string>
        </property>
       </widget>
      </item>
diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp
index 62e03e36f..db18dc98e 100644
--- a/src/settingsdialog.cpp
+++ b/src/settingsdialog.cpp
@@ -20,13 +20,13 @@
 #include "settingsdialog.h"
 #include "config.h"
 
-#include <QDesktopServices>
-#include <QFileDialog>
-#include <QMessageBox>
-#include <QNetworkConfiguration>
-#include <QNetworkProxy>
-#include <QVBoxLayout>
-#include <QSizeGrip>
+#include <QtGui/QDesktopServices>
+#include <QtGui/QFileDialog>
+#include <QtGui/QMessageBox>
+#include <QtNetwork/QNetworkConfiguration>
+#include <QtNetwork/QNetworkProxy>
+#include <QtGui/QVBoxLayout>
+#include <QtGui/QSizeGrip>
 
 #include "AtticaManager.h"
 #include "tomahawkapp.h"
@@ -457,7 +457,6 @@ ProxyDialog::ProxyDialog( QWidget *parent )
         ui->userLineEdit->setEnabled( false );
         ui->passwordLineEdit->setEnabled( false );
         ui->checkBoxUseProxyForDns->setEnabled( false );
-        ui->noHostLineEdit->setEnabled( false );
     }
 
     connect( ui->typeBox, SIGNAL( currentIndexChanged( int ) ), SLOT( proxyTypeChangedSlot( int ) ) );
@@ -474,7 +473,6 @@ ProxyDialog::proxyTypeChangedSlot( int index )
         ui->userLineEdit->setEnabled( false );
         ui->passwordLineEdit->setEnabled( false );
         ui->checkBoxUseProxyForDns->setEnabled( false );
-        ui->noHostLineEdit->setEnabled( false );
     }
     else
     {
@@ -483,7 +481,6 @@ ProxyDialog::proxyTypeChangedSlot( int index )
         ui->userLineEdit->setEnabled( true );
         ui->passwordLineEdit->setEnabled( true );
         ui->checkBoxUseProxyForDns->setEnabled( true );
-        ui->noHostLineEdit->setEnabled( true );
     }
 }
 
@@ -521,8 +518,8 @@ ProxyDialog::saveSettings()
         proxyFactory->setProxy( QNetworkProxy( type, s->proxyHost(), s->proxyPort(), s->proxyUsername(), s->proxyPassword() ) );
         if ( !ui->noHostLineEdit->text().isEmpty() )
         {
-            tDebug() << Q_FUNC_INFO << "hosts line edit is " << ui->noHostLineEdit->text();
-            tDebug() << Q_FUNC_INFO << "split hosts line edit is " << ui->noHostLineEdit->text().split( ' ', QString::SkipEmptyParts );
+            tDebug() << Q_FUNC_INFO << "noproxy line edit is " << ui->noHostLineEdit->text();
+            tDebug() << Q_FUNC_INFO << "split noproxy line edit is " << ui->noHostLineEdit->text().split( ' ', QString::SkipEmptyParts );
             proxyFactory->setNoProxyHosts( ui->noHostLineEdit->text().split( ' ', QString::SkipEmptyParts ) );
         }
     }
diff --git a/src/settingsdialog.h b/src/settingsdialog.h
index cb02666bd..8199a786b 100644
--- a/src/settingsdialog.h
+++ b/src/settingsdialog.h
@@ -20,8 +20,8 @@
 #ifndef SETTINGSDIALOG_H
 #define SETTINGSDIALOG_H
 
-#include <QDialog>
-#include <QModelIndex>
+#include <QtGui/QDialog>
+#include <QtCore/QModelIndex>
 
 #include "config.h"
 
diff --git a/src/tomahawkapp.cpp b/src/tomahawkapp.cpp
index 669a3383d..1b3f9fe78 100644
--- a/src/tomahawkapp.cpp
+++ b/src/tomahawkapp.cpp
@@ -28,7 +28,6 @@
 #include <QtNetwork/QNetworkReply>
 #include <QtCore/QFile>
 #include <QtCore/QFileInfo>
-#include <QtNetwork/QNetworkProxy>
 
 #include "artist.h"
 #include "album.h"