1
0
Fork 0
mirror of https://github.com/transmission/transmission synced 2025-03-03 10:15:45 +00:00

(trunk qt) #3481 "crash when accessing a remote session that's password protected" -- fixed

This commit is contained in:
Charles Kerr 2010-08-04 13:56:52 +00:00
parent fc15c5ba4b
commit d4f97143cd
2 changed files with 39 additions and 46 deletions

View file

@ -234,7 +234,8 @@ Session :: Session( const char * configDir, Prefs& prefs ):
myBlocklistSize( -1 ), myBlocklistSize( -1 ),
myPrefs( prefs ), myPrefs( prefs ),
mySession( 0 ), mySession( 0 ),
myConfigDir( configDir ) myConfigDir( configDir ),
myNAM( 0 )
{ {
myStats.ratio = TR_RATIO_NA; myStats.ratio = TR_RATIO_NA;
myStats.uploadedBytes = 0; myStats.uploadedBytes = 0;
@ -244,8 +245,6 @@ Session :: Session( const char * configDir, Prefs& prefs ):
myStats.secondsActive = 0; myStats.secondsActive = 0;
myCumulativeStats = myStats; 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)) ); connect( &myPrefs, SIGNAL(changed(int)), this, SLOT(updatePref(int)) );
} }
@ -254,6 +253,23 @@ Session :: ~Session( )
stop( ); 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 void
Session :: stop( ) Session :: stop( )
{ {
foreach( Reply myReply, myReplies ) if( myNAM != 0 )
myReply.networkReply->abort(); {
myNAM->deleteLater( );
myNAM = 0;
}
myUrl.clear( ); myUrl.clear( );
if( mySession ) if( mySession )
@ -284,20 +304,15 @@ Session :: start( )
{ {
if( myPrefs.get<bool>(Prefs::SESSION_IS_REMOTE) ) if( myPrefs.get<bool>(Prefs::SESSION_IS_REMOTE) )
{ {
const int port( myPrefs.get<int>(Prefs::SESSION_REMOTE_PORT) );
const bool auth( myPrefs.get<bool>(Prefs::SESSION_REMOTE_AUTH) );
const QString host( myPrefs.get<QString>(Prefs::SESSION_REMOTE_HOST) );
const QString user( myPrefs.get<QString>(Prefs::SESSION_REMOTE_USERNAME) );
const QString pass( myPrefs.get<QString>(Prefs::SESSION_REMOTE_PASSWORD) );
QUrl url; QUrl url;
url.setScheme( "http" ); url.setScheme( "http" );
url.setHost( host ); url.setHost( myPrefs.get<QString>(Prefs::SESSION_REMOTE_HOST) );
url.setPort( port ); url.setPort( myPrefs.get<int>(Prefs::SESSION_REMOTE_PORT) );
url.setPath( "/transmission/rpc" ); url.setPath( "/transmission/rpc" );
if( auth ) { if( myPrefs.get<bool>(Prefs::SESSION_REMOTE_AUTH) )
url.setUserName( user ); {
url.setPassword( pass ); url.setUserName( myPrefs.get<QString>(Prefs::SESSION_REMOTE_USERNAME) );
url.setPassword( myPrefs.get<QString>(Prefs::SESSION_REMOTE_PASSWORD) );
} }
myUrl = url; myUrl = url;
} }
@ -602,6 +617,8 @@ Session :: localSessionCallback( tr_session * session, const char * json, size_t
((Session*)self)->parseResponse( json, len ); ((Session*)self)->parseResponse( json, len );
} }
#define REQUEST_DATA_PROPERTY_KEY "requestData"
void void
Session :: exec( const char * json ) Session :: exec( const char * json )
{ {
@ -618,17 +635,12 @@ Session :: exec( const char * json )
if( !mySessionId.isEmpty( ) ) if( !mySessionId.isEmpty( ) )
request.setRawHeader( TR_RPC_SESSION_ID_HEADER, mySessionId.toAscii() ); request.setRawHeader( TR_RPC_SESSION_ID_HEADER, mySessionId.toAscii() );
QBuffer * reqbuf = new QBuffer; const QByteArray requestData( json );
reqbuf->setData( QByteArray( json ) ); QNetworkReply * reply = networkAccessManager()->post( request, requestData );
reply->setProperty( REQUEST_DATA_PROPERTY_KEY, requestData );
QNetworkReply * reply = myNAM.post( request, reqbuf );
connect( reply, SIGNAL(downloadProgress(qint64,qint64)), this, SIGNAL(dataReadProgress())); connect( reply, SIGNAL(downloadProgress(qint64,qint64)), this, SIGNAL(dataReadProgress()));
connect( reply, SIGNAL(uploadProgress(qint64,qint64)), this, SIGNAL(dataSendProgress())); connect( reply, SIGNAL(uploadProgress(qint64,qint64)), this, SIGNAL(dataSendProgress()));
Reply myReply;
myReply.networkReply = reply;
myReply.buffer = reqbuf;
myReplies << myReply;
#ifdef DEBUG_HTTP #ifdef DEBUG_HTTP
std::cerr << "sending " << "POST " << qPrintable( myUrl.path() ) << std::endl; std::cerr << "sending " << "POST " << qPrintable( myUrl.path() ) << std::endl;
foreach( QByteArray b, request.rawHeaderList() ) foreach( QByteArray b, request.rawHeaderList() )
@ -644,17 +656,6 @@ Session :: exec( const char * json )
void void
Session :: onFinished( QNetworkReply * reply ) Session :: onFinished( QNetworkReply * reply )
{ {
QBuffer * buffer;
for( QList<Reply>::iterator i = myReplies.begin(); i != myReplies.end(); ++i )
{
if( reply == i->networkReply )
{
buffer = i->buffer;
myReplies.erase( i );
break;
}
}
#ifdef DEBUG_HTTP #ifdef DEBUG_HTTP
std::cerr << "http response header: " << std::endl; std::cerr << "http response header: " << std::endl;
foreach( QByteArray b, reply->rawHeaderList() ) foreach( QByteArray b, reply->rawHeaderList() )
@ -671,7 +672,7 @@ Session :: onFinished( QNetworkReply * reply )
// we got a 409 telling us our session id has expired. // we got a 409 telling us our session id has expired.
// update it and resubmit the request. // update it and resubmit the request.
mySessionId = QString( reply->rawHeader( TR_RPC_SESSION_ID_HEADER ) ); 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 ) else if( reply->error() != QNetworkReply::NoError )
{ {
@ -686,7 +687,6 @@ Session :: onFinished( QNetworkReply * reply )
parseResponse( json, jsonLength ); parseResponse( json, jsonLength );
} }
delete buffer;
reply->deleteLater(); reply->deleteLater();
} }

View file

@ -34,13 +34,6 @@ extern "C"
class Prefs; class Prefs;
struct Reply
{
QNetworkReply * networkReply;
QBuffer * buffer;
};
typedef QList<Reply> ReplyList;
class Session: public QObject class Session: public QObject
{ {
Q_OBJECT Q_OBJECT
@ -96,6 +89,7 @@ class Session: public QObject
void sendTorrentRequest( const char * request, const QSet<int>& torrentIds ); void sendTorrentRequest( const char * request, const QSet<int>& torrentIds );
static void updateStats( struct tr_benc * d, struct tr_session_stats * stats ); static void updateStats( struct tr_benc * d, struct tr_session_stats * stats );
void refreshTorrents( const QSet<int>& torrentIds ); void refreshTorrents( const QSet<int>& torrentIds );
QNetworkAccessManager * networkAccessManager( );
public: public:
void torrentSet( const QSet<int>& ids, const QString& key, bool val ); void torrentSet( const QSet<int>& ids, const QString& key, bool val );
@ -149,8 +143,7 @@ class Session: public QObject
QString myConfigDir; QString myConfigDir;
QString mySessionId; QString mySessionId;
QUrl myUrl; QUrl myUrl;
QNetworkAccessManager myNAM; QNetworkAccessManager * myNAM;
ReplyList myReplies;
struct tr_session_stats myStats; struct tr_session_stats myStats;
struct tr_session_stats myCumulativeStats; struct tr_session_stats myCumulativeStats;
QString mySessionVersion; QString mySessionVersion;