From d4f97143cdcdea196875124bd195a3f54666db3e Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Wed, 4 Aug 2010 13:56:52 +0000 Subject: [PATCH] (trunk qt) #3481 "crash when accessing a remote session that's password protected" -- fixed --- qt/session.cc | 74 +++++++++++++++++++++++++-------------------------- qt/session.h | 11 ++------ 2 files changed, 39 insertions(+), 46 deletions(-) diff --git a/qt/session.cc b/qt/session.cc index 49d9d9357..cf2ccd4e7 100644 --- a/qt/session.cc +++ b/qt/session.cc @@ -234,7 +234,8 @@ Session :: Session( const char * configDir, Prefs& prefs ): myBlocklistSize( -1 ), myPrefs( prefs ), mySession( 0 ), - myConfigDir( configDir ) + myConfigDir( configDir ), + myNAM( 0 ) { myStats.ratio = TR_RATIO_NA; myStats.uploadedBytes = 0; @@ -244,8 +245,6 @@ Session :: Session( const char * configDir, Prefs& prefs ): myStats.secondsActive = 0; myCumulativeStats = myStats; - connect( &myNAM, SIGNAL(finished(QNetworkReply*)), this, SLOT(onFinished(QNetworkReply*)) ); - connect( &myNAM, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), this, SIGNAL(httpAuthenticationRequired()) ); connect( &myPrefs, SIGNAL(changed(int)), this, SLOT(updatePref(int)) ); } @@ -254,6 +253,23 @@ Session :: ~Session( ) stop( ); } +QNetworkAccessManager * +Session :: networkAccessManager( ) +{ + if( myNAM == 0 ) + { + myNAM = new QNetworkAccessManager; + + connect( myNAM, SIGNAL(finished(QNetworkReply*)), + this, SLOT(onFinished(QNetworkReply*)) ); + + connect( myNAM, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), + this, SIGNAL(httpAuthenticationRequired()) ); + } + + return myNAM; +} + /*** **** ***/ @@ -261,8 +277,12 @@ Session :: ~Session( ) void Session :: stop( ) { - foreach( Reply myReply, myReplies ) - myReply.networkReply->abort(); + if( myNAM != 0 ) + { + myNAM->deleteLater( ); + myNAM = 0; + } + myUrl.clear( ); if( mySession ) @@ -284,20 +304,15 @@ Session :: start( ) { if( myPrefs.get(Prefs::SESSION_IS_REMOTE) ) { - const int port( myPrefs.get(Prefs::SESSION_REMOTE_PORT) ); - const bool auth( myPrefs.get(Prefs::SESSION_REMOTE_AUTH) ); - const QString host( myPrefs.get(Prefs::SESSION_REMOTE_HOST) ); - const QString user( myPrefs.get(Prefs::SESSION_REMOTE_USERNAME) ); - const QString pass( myPrefs.get(Prefs::SESSION_REMOTE_PASSWORD) ); - QUrl url; url.setScheme( "http" ); - url.setHost( host ); - url.setPort( port ); + url.setHost( myPrefs.get(Prefs::SESSION_REMOTE_HOST) ); + url.setPort( myPrefs.get(Prefs::SESSION_REMOTE_PORT) ); url.setPath( "/transmission/rpc" ); - if( auth ) { - url.setUserName( user ); - url.setPassword( pass ); + if( myPrefs.get(Prefs::SESSION_REMOTE_AUTH) ) + { + url.setUserName( myPrefs.get(Prefs::SESSION_REMOTE_USERNAME) ); + url.setPassword( myPrefs.get(Prefs::SESSION_REMOTE_PASSWORD) ); } myUrl = url; } @@ -602,6 +617,8 @@ Session :: localSessionCallback( tr_session * session, const char * json, size_t ((Session*)self)->parseResponse( json, len ); } +#define REQUEST_DATA_PROPERTY_KEY "requestData" + void Session :: exec( const char * json ) { @@ -618,17 +635,12 @@ Session :: exec( const char * json ) if( !mySessionId.isEmpty( ) ) request.setRawHeader( TR_RPC_SESSION_ID_HEADER, mySessionId.toAscii() ); - QBuffer * reqbuf = new QBuffer; - reqbuf->setData( QByteArray( json ) ); - - QNetworkReply * reply = myNAM.post( request, reqbuf ); + const QByteArray requestData( json ); + QNetworkReply * reply = networkAccessManager()->post( request, requestData ); + reply->setProperty( REQUEST_DATA_PROPERTY_KEY, requestData ); connect( reply, SIGNAL(downloadProgress(qint64,qint64)), this, SIGNAL(dataReadProgress())); connect( reply, SIGNAL(uploadProgress(qint64,qint64)), this, SIGNAL(dataSendProgress())); - Reply myReply; - myReply.networkReply = reply; - myReply.buffer = reqbuf; - myReplies << myReply; #ifdef DEBUG_HTTP std::cerr << "sending " << "POST " << qPrintable( myUrl.path() ) << std::endl; foreach( QByteArray b, request.rawHeaderList() ) @@ -644,17 +656,6 @@ Session :: exec( const char * json ) void Session :: onFinished( QNetworkReply * reply ) { - QBuffer * buffer; - for( QList::iterator i = myReplies.begin(); i != myReplies.end(); ++i ) - { - if( reply == i->networkReply ) - { - buffer = i->buffer; - myReplies.erase( i ); - break; - } - } - #ifdef DEBUG_HTTP std::cerr << "http response header: " << std::endl; foreach( QByteArray b, reply->rawHeaderList() ) @@ -671,7 +672,7 @@ Session :: onFinished( QNetworkReply * reply ) // we got a 409 telling us our session id has expired. // update it and resubmit the request. mySessionId = QString( reply->rawHeader( TR_RPC_SESSION_ID_HEADER ) ); - exec( buffer->buffer().constData() ); + exec( reply->property( REQUEST_DATA_PROPERTY_KEY ).toByteArray( ).constData( ) ); } else if( reply->error() != QNetworkReply::NoError ) { @@ -686,7 +687,6 @@ Session :: onFinished( QNetworkReply * reply ) parseResponse( json, jsonLength ); } - delete buffer; reply->deleteLater(); } diff --git a/qt/session.h b/qt/session.h index 1d25222c2..1c4446f0b 100644 --- a/qt/session.h +++ b/qt/session.h @@ -34,13 +34,6 @@ extern "C" class Prefs; -struct Reply -{ - QNetworkReply * networkReply; - QBuffer * buffer; -}; -typedef QList ReplyList; - class Session: public QObject { Q_OBJECT @@ -96,6 +89,7 @@ class Session: public QObject void sendTorrentRequest( const char * request, const QSet& torrentIds ); static void updateStats( struct tr_benc * d, struct tr_session_stats * stats ); void refreshTorrents( const QSet& torrentIds ); + QNetworkAccessManager * networkAccessManager( ); public: void torrentSet( const QSet& ids, const QString& key, bool val ); @@ -149,8 +143,7 @@ class Session: public QObject QString myConfigDir; QString mySessionId; QUrl myUrl; - QNetworkAccessManager myNAM; - ReplyList myReplies; + QNetworkAccessManager * myNAM; struct tr_session_stats myStats; struct tr_session_stats myCumulativeStats; QString mySessionVersion; -- 2.40.0