mirror of
https://github.com/transmission/transmission
synced 2025-02-21 13:46:52 +00:00
(qt) #3147: qtr delayed to connect to remote session automatically
This commit is contained in:
parent
e6af3ea090
commit
32a4f1df10
3 changed files with 72 additions and 56 deletions
|
@ -709,7 +709,7 @@ TrMainWindow :: refreshTitle( )
|
|||
QString title( "Transmission" );
|
||||
const QUrl url( mySession.getRemoteUrl( ) );
|
||||
if( !url.isEmpty() )
|
||||
title += tr( " - %1" ).arg( url.toString(QUrl::RemoveUserInfo) );
|
||||
title += tr( " - %1:%2" ).arg( url.host() ).arg( url.port() );
|
||||
setWindowTitle( title );
|
||||
}
|
||||
|
||||
|
|
108
qt/session.cc
108
qt/session.cc
|
@ -19,6 +19,8 @@
|
|||
#include <QCoreApplication>
|
||||
#include <QDesktopServices>
|
||||
#include <QMessageBox>
|
||||
#include <QNetworkReply>
|
||||
#include <QNetworkRequest>
|
||||
#include <QSet>
|
||||
#include <QStyle>
|
||||
#include <QTextStream>
|
||||
|
@ -220,14 +222,9 @@ Session :: Session( const char * configDir, Prefs& prefs ):
|
|||
myStats.secondsActive = 0;
|
||||
myCumulativeStats = myStats;
|
||||
|
||||
connect( &myHttp, SIGNAL(requestStarted(int)), this, SLOT(onRequestStarted(int)));
|
||||
connect( &myHttp, SIGNAL(requestFinished(int,bool)), this, SLOT(onRequestFinished(int,bool)));
|
||||
connect( &myHttp, SIGNAL(dataReadProgress(int,int)), this, SIGNAL(dataReadProgress()));
|
||||
connect( &myHttp, SIGNAL(dataSendProgress(int,int)), this, SIGNAL(dataSendProgress()));
|
||||
connect( &myHttp, SIGNAL(authenticationRequired(QString, quint16, QAuthenticator*)), this, SIGNAL(httpAuthenticationRequired()) );
|
||||
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)) );
|
||||
|
||||
myBuffer.open( QIODevice::ReadWrite );
|
||||
}
|
||||
|
||||
Session :: ~Session( )
|
||||
|
@ -242,7 +239,8 @@ Session :: ~Session( )
|
|||
void
|
||||
Session :: stop( )
|
||||
{
|
||||
myHttp.abort( );
|
||||
foreach( Reply myReply, myReplies )
|
||||
myReply.networkReply->abort();
|
||||
myUrl.clear( );
|
||||
|
||||
if( mySession )
|
||||
|
@ -274,14 +272,12 @@ Session :: start( )
|
|||
url.setScheme( "http" );
|
||||
url.setHost( host );
|
||||
url.setPort( port );
|
||||
url.setPath( "/transmission/rpc" );
|
||||
if( auth ) {
|
||||
url.setUserName( user );
|
||||
url.setPassword( pass );
|
||||
}
|
||||
myUrl = url;
|
||||
|
||||
myHttp.setHost( host, port );
|
||||
myHttp.setUser( user, pass );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -570,77 +566,91 @@ Session :: localSessionCallback( tr_session * session, const char * json, size_t
|
|||
}
|
||||
|
||||
void
|
||||
Session :: exec( const char * request )
|
||||
Session :: exec( const char * json )
|
||||
{
|
||||
if( mySession )
|
||||
{
|
||||
tr_rpc_request_exec_json( mySession, request, strlen( request ), localSessionCallback, this );
|
||||
tr_rpc_request_exec_json( mySession, json, strlen( json ), localSessionCallback, this );
|
||||
}
|
||||
else if( !myUrl.isEmpty( ) )
|
||||
{
|
||||
static const QString path( "/transmission/rpc" );
|
||||
QHttpRequestHeader header( "POST", path );
|
||||
header.setValue( "User-Agent", QCoreApplication::instance()->applicationName() + "/" + LONG_VERSION_STRING );
|
||||
header.setValue( "Content-Type", "application/json; charset=UTF-8" );
|
||||
QNetworkRequest request;
|
||||
request.setUrl( myUrl );
|
||||
request.setRawHeader( "User-Agent", QString( QCoreApplication::instance()->applicationName() + "/" + LONG_VERSION_STRING ).toAscii() );
|
||||
request.setRawHeader( "Content-Type", "application/json; charset=UTF-8" );
|
||||
if( !mySessionId.isEmpty( ) )
|
||||
header.setValue( TR_RPC_SESSION_ID_HEADER, mySessionId );
|
||||
request.setRawHeader( TR_RPC_SESSION_ID_HEADER, mySessionId.toAscii() );
|
||||
|
||||
QBuffer * reqbuf = new QBuffer;
|
||||
reqbuf->setData( QByteArray( request ) );
|
||||
myHttp.request( header, reqbuf, &myBuffer );
|
||||
reqbuf->setData( QByteArray( json ) );
|
||||
|
||||
QNetworkReply * reply = myNAM.post( request, reqbuf );
|
||||
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 " << qPrintable(header.toString()) << "\nBody:\n" << request << std::endl;
|
||||
std::cerr << "sending " << "POST " << qPrintable( myUrl.path() ) << std::endl;
|
||||
foreach( QByteArray b, request.rawHeaderList() )
|
||||
std::cerr << b.constData()
|
||||
<< ": "
|
||||
<< request.rawHeader( b ).constData()
|
||||
<< std::endl;
|
||||
std::cerr << "Body:\n" << json << std::endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Session :: onRequestStarted( int id )
|
||||
Session :: onFinished( QNetworkReply * reply )
|
||||
{
|
||||
Q_UNUSED( id );
|
||||
|
||||
assert( myBuffer.atEnd( ) );
|
||||
}
|
||||
|
||||
void
|
||||
Session :: onRequestFinished( int id, bool error )
|
||||
{
|
||||
Q_UNUSED( id );
|
||||
QIODevice * sourceDevice = myHttp.currentSourceDevice( );
|
||||
|
||||
QHttpResponseHeader response = myHttp.lastResponse();
|
||||
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
|
||||
std::cerr << "http request " << id << " ended.. response header: "
|
||||
<< qPrintable( myHttp.lastResponse().toString() )
|
||||
<< std::endl
|
||||
<< "json: " << myBuffer.buffer( ).constData( )
|
||||
<< std::endl;
|
||||
std::cerr << "http response header: " << std::endl;
|
||||
foreach( QByteArray b, reply->rawHeaderList() )
|
||||
std::cerr << b.constData()
|
||||
<< ": "
|
||||
<< reply->rawHeader( b ).constData()
|
||||
<< std::endl;
|
||||
std::cerr << "json:\n" << reply->peek( reply->bytesAvailable() ).constData() << std::endl;
|
||||
#endif
|
||||
|
||||
if( ( response.statusCode() == 409 ) && ( myBuffer.buffer().indexOf("invalid session-id") != -1 ) )
|
||||
if( ( reply->attribute( QNetworkRequest::HttpStatusCodeAttribute ).toInt() == 409 )
|
||||
&& ( reply->hasRawHeader( TR_RPC_SESSION_ID_HEADER ) ) )
|
||||
{
|
||||
// we got a 409 telling us our session id has expired.
|
||||
// update it and resubmit the request.
|
||||
mySessionId = response.value( TR_RPC_SESSION_ID_HEADER );
|
||||
exec( qobject_cast<QBuffer*>(sourceDevice)->buffer().constData() );
|
||||
mySessionId = QString( reply->rawHeader( TR_RPC_SESSION_ID_HEADER ) );
|
||||
exec( buffer->buffer().constData() );
|
||||
}
|
||||
else if( error )
|
||||
else if( reply->error() != QNetworkReply::NoError )
|
||||
{
|
||||
std::cerr << "http error: " << qPrintable(myHttp.errorString()) << std::endl;
|
||||
std::cerr << "http error: " << qPrintable( reply->errorString() ) << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
const QByteArray& response( myBuffer.buffer( ) );
|
||||
const QByteArray response( reply->readAll() );
|
||||
const char * json( response.constData( ) );
|
||||
int jsonLength( response.size( ) );
|
||||
if( jsonLength>0 && json[jsonLength-1] == '\n' ) --jsonLength;
|
||||
parseResponse( json, jsonLength );
|
||||
}
|
||||
|
||||
delete sourceDevice;
|
||||
myBuffer.buffer( ).clear( );
|
||||
myBuffer.reset( );
|
||||
assert( myBuffer.bytesAvailable( ) < 1 );
|
||||
delete buffer;
|
||||
reply->deleteLater();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
18
qt/session.h
18
qt/session.h
|
@ -17,8 +17,8 @@
|
|||
#include <QSet>
|
||||
#include <QBuffer>
|
||||
#include <QFileInfoList>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QString>
|
||||
#include <QHttp>
|
||||
#include <QUrl>
|
||||
|
||||
#include <libtransmission/transmission.h>
|
||||
|
@ -32,6 +32,13 @@ extern "C"
|
|||
|
||||
class Prefs;
|
||||
|
||||
struct Reply
|
||||
{
|
||||
QNetworkReply * networkReply;
|
||||
QBuffer * buffer;
|
||||
};
|
||||
typedef QList<Reply> ReplyList;
|
||||
|
||||
class Session: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
@ -75,7 +82,7 @@ class Session: public QObject
|
|||
static void localSessionCallback( tr_session *, const char *, size_t, void * );
|
||||
|
||||
public:
|
||||
void exec( const char * request );
|
||||
void exec( const char * json );
|
||||
void exec( const struct tr_benc * request );
|
||||
|
||||
public:
|
||||
|
@ -116,8 +123,7 @@ class Session: public QObject
|
|||
void refreshExtraStats( const QSet<int>& ids );
|
||||
|
||||
private slots:
|
||||
void onRequestStarted( int id );
|
||||
void onRequestFinished( int id, bool error );
|
||||
void onFinished( QNetworkReply * reply );
|
||||
|
||||
signals:
|
||||
void executed( int64_t tag, const QString& result, struct tr_benc * arguments );
|
||||
|
@ -140,8 +146,8 @@ class Session: public QObject
|
|||
QString myConfigDir;
|
||||
QString mySessionId;
|
||||
QUrl myUrl;
|
||||
QBuffer myBuffer;
|
||||
QHttp myHttp;
|
||||
QNetworkAccessManager myNAM;
|
||||
ReplyList myReplies;
|
||||
struct tr_session_stats myStats;
|
||||
struct tr_session_stats myCumulativeStats;
|
||||
QString mySessionVersion;
|
||||
|
|
Loading…
Reference in a new issue