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:
parent
fc15c5ba4b
commit
d4f97143cd
2 changed files with 39 additions and 46 deletions
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
11
qt/session.h
11
qt/session.h
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue