diff options
| author | Jeremy Lainé <jeremy.laine@m4x.org> | 2012-04-12 07:51:21 +0000 |
|---|---|---|
| committer | Jeremy Lainé <jeremy.laine@m4x.org> | 2012-04-12 07:51:21 +0000 |
| commit | c6623e6a7e86fab1c973900ede0de1eb2e488230 (patch) | |
| tree | d1f98598bf425df2173a0d5ef83e3024a7e4c59e /src/client | |
| parent | b93f06fbc497305180792f8b4a9029fa097d8a49 (diff) | |
| download | qxmpp-c6623e6a7e86fab1c973900ede0de1eb2e488230.tar.gz | |
remove last blocking code in QXmppTransferManager
Diffstat (limited to 'src/client')
| -rw-r--r-- | src/client/QXmppTransferManager.cpp | 469 | ||||
| -rw-r--r-- | src/client/QXmppTransferManager.h | 16 | ||||
| -rw-r--r-- | src/client/QXmppTransferManager_p.h | 77 | ||||
| -rw-r--r-- | src/client/client.pri | 1 |
4 files changed, 377 insertions, 186 deletions
diff --git a/src/client/QXmppTransferManager.cpp b/src/client/QXmppTransferManager.cpp index b9d71408..f7949024 100644 --- a/src/client/QXmppTransferManager.cpp +++ b/src/client/QXmppTransferManager.cpp @@ -39,6 +39,7 @@ #include "QXmppSocks.h" #include "QXmppStreamInitiationIq.h" #include "QXmppTransferManager.h" +#include "QXmppTransferManager_p.h" #include "QXmppUtils.h" // time to try to connect to a SOCKS host (7 seconds) @@ -110,6 +111,7 @@ public: QXmppTransferJobPrivate(); int blockSize; + QXmppClient *client; QXmppTransferJob::Direction direction; qint64 done; QXmppTransferJob::Error error; @@ -138,6 +140,7 @@ public: QXmppTransferJobPrivate::QXmppTransferJobPrivate() : blockSize(16384), + client(0), done(0), error(QXmppTransferJob::NoError), hash(QCryptographicHash::Md5), @@ -149,10 +152,11 @@ QXmppTransferJobPrivate::QXmppTransferJobPrivate() { } -QXmppTransferJob::QXmppTransferJob(const QString &jid, QXmppTransferJob::Direction direction, QObject *parent) +QXmppTransferJob::QXmppTransferJob(const QString &jid, QXmppTransferJob::Direction direction, QXmppClient *client, QObject *parent) : QXmppLoggable(parent), d(new QXmppTransferJobPrivate) { + d->client = client; d->direction = direction; d->jid = jid; } @@ -350,7 +354,160 @@ void QXmppTransferJob::_q_disconnected() } } -void QXmppTransferJob::_q_receiveData() +void QXmppTransferJob::_q_terminated() +{ + emit stateChanged(d->state); + if (d->error != NoError) + emit error(d->error); + emit finished(); +} + +void QXmppTransferJob::terminate(QXmppTransferJob::Error cause) +{ + if (d->state == FinishedState) + return; + + // change state + d->error = cause; + d->state = FinishedState; + + // close IO device + if (d->iodevice) + d->iodevice->close(); + + // close socket + if (d->socksSocket) + { + d->socksSocket->flush(); + d->socksSocket->close(); + } + + // emit signals later + QTimer::singleShot(0, this, SLOT(_q_terminated())); +} + +bool QXmppTransferJob::writeData(const QByteArray &data) +{ + const qint64 written = d->iodevice->write(data); + if (written < 0) + return false; + d->done += written; + if (!d->fileInfo.hash().isEmpty()) + d->hash.addData(data); + progress(d->done, d->fileInfo.size()); + return true; +} + +QXmppTransferIncomingJob::QXmppTransferIncomingJob(const QString& jid, QXmppClient* client, QObject* parent) + : QXmppTransferJob(jid, IncomingDirection, client, parent) + , m_candidateClient(0) +{ +} + +void QXmppTransferIncomingJob::connectToNextHost() +{ + bool check; + Q_UNUSED(check); + + if (m_streamCandidates.isEmpty()) { + // could not connect to any stream host + QXmppByteStreamIq response; + response.setId(m_streamOfferId); + response.setTo(m_streamOfferFrom); + QXmppStanza::Error error(QXmppStanza::Error::Cancel, QXmppStanza::Error::ItemNotFound); + error.setCode(404); + response.setType(QXmppIq::Error); + response.setError(error); + d->client->sendPacket(response); + + terminate(QXmppTransferJob::ProtocolError); + return; + } + + // try next host + m_candidateHost = m_streamCandidates.takeFirst(); + info(QString("Connecting to streamhost: %1 (%2:%3)").arg( + m_candidateHost.jid(), + m_candidateHost.host().toString(), + QString::number(m_candidateHost.port()))); + + const QString hostName = streamHash(d->sid, + d->jid, + d->client->configuration().jid()); + + // try to connect to stream host + m_candidateClient = new QXmppSocksClient(m_candidateHost.host(), m_candidateHost.port(), this); + + check = connect(m_candidateClient, SIGNAL(disconnected()), + this, SLOT(_q_candidateDisconnected())); + Q_ASSERT(check); + + check = connect(m_candidateClient, SIGNAL(ready()), + this, SLOT(_q_candidateReady())); + Q_ASSERT(check); + + m_candidateClient->connectToHost(hostName, 0); +} + +void QXmppTransferIncomingJob::connectToHosts(const QXmppByteStreamIq &iq) +{ + bool check; + Q_UNUSED(check); + + m_streamCandidates = iq.streamHosts(); + m_streamOfferId = iq.id(); + m_streamOfferFrom = iq.from(); + + connectToNextHost(); +} + +void QXmppTransferIncomingJob::_q_candidateReady() +{ + bool check; + Q_UNUSED(check); + + if (!m_candidateClient) + return; + + setState(QXmppTransferJob::TransferState); + d->socksSocket = m_candidateClient; + m_candidateClient = 0; + + check = connect(d->socksSocket, SIGNAL(readyRead()), + this, SLOT(_q_receiveData())); + Q_ASSERT(check); + + check = connect(d->socksSocket, SIGNAL(disconnected()), + this, SLOT(_q_disconnected())); + Q_ASSERT(check); + + QXmppByteStreamIq ackIq; + ackIq.setId(m_streamOfferId); + ackIq.setTo(m_streamOfferFrom); + ackIq.setType(QXmppIq::Result); + ackIq.setSid(d->sid); + ackIq.setStreamHostUsed(m_candidateHost.jid()); + d->client->sendPacket(ackIq); +} + +void QXmppTransferIncomingJob::_q_candidateDisconnected() +{ + if (!m_candidateClient) + return; + + warning(QString("Failed to connect to streamhost: %1 (%2:%3)").arg( + m_candidateHost.jid(), + m_candidateHost.host().toString(), + QString::number(m_candidateHost.port()))); + + m_candidateClient->deleteLater(); + m_candidateClient = 0; + + // try next host + connectToNextHost(); +} + +void QXmppTransferIncomingJob::_q_receiveData() { if (d->state != QXmppTransferJob::TransferState) return; @@ -366,7 +523,71 @@ void QXmppTransferJob::_q_receiveData() } } -void QXmppTransferJob::_q_sendData() +QXmppTransferOutgoingJob::QXmppTransferOutgoingJob(const QString& jid, QXmppClient* client, QObject* parent) + : QXmppTransferJob(jid, OutgoingDirection, client, parent) +{ +} + +void QXmppTransferOutgoingJob::connectToProxy() +{ + bool check; + Q_UNUSED(check); + + info(QString("Connecting to proxy: %1 (%2:%3)").arg( + d->socksProxy.jid(), + d->socksProxy.host().toString(), + QString::number(d->socksProxy.port()))); + + const QString hostName = streamHash(d->sid, + d->client->configuration().jid(), + d->jid); + + QXmppSocksClient *socksClient = new QXmppSocksClient(d->socksProxy.host(), d->socksProxy.port(), this); + + check = connect(socksClient, SIGNAL(disconnected()), + this, SLOT(_q_disconnected())); + Q_ASSERT(check); + + check = connect(socksClient, SIGNAL(ready()), + this, SLOT(_q_proxyReady())); + Q_ASSERT(check); + + d->socksSocket = socksClient; + socksClient->connectToHost(hostName, 0); +} + +void QXmppTransferOutgoingJob::startSending() +{ + bool check; + Q_ASSERT(check); + + setState(QXmppTransferJob::TransferState); + + check = connect(d->socksSocket, SIGNAL(bytesWritten(qint64)), + this, SLOT(_q_sendData())); + Q_ASSERT(check); + + check = connect(d->iodevice, SIGNAL(readyRead()), + this, SLOT(_q_sendData())); + Q_ASSERT(check); + + _q_sendData(); +} + +void QXmppTransferOutgoingJob::_q_proxyReady() +{ + // activate stream + QXmppByteStreamIq streamIq; + streamIq.setType(QXmppIq::Set); + streamIq.setFrom(d->client->configuration().jid()); + streamIq.setTo(d->socksProxy.jid()); + streamIq.setSid(d->sid); + streamIq.setActivate(d->jid); + d->requestId = streamIq.id(); + d->client->sendPacket(streamIq); +} + +void QXmppTransferOutgoingJob::_q_sendData() { if (d->state != QXmppTransferJob::TransferState) return; @@ -400,48 +621,53 @@ void QXmppTransferJob::_q_sendData() } } -void QXmppTransferJob::_q_terminated() +class QXmppTransferManagerPrivate { - emit stateChanged(d->state); - if (d->error != NoError) - emit error(d->error); - emit finished(); -} +public: + QXmppTransferManagerPrivate(QXmppTransferManager *qq); -void QXmppTransferJob::terminate(QXmppTransferJob::Error cause) -{ - if (d->state == FinishedState) - return; + QXmppTransferIncomingJob *getIncomingJobByRequestId(const QString &jid, const QString &id); + QXmppTransferIncomingJob *getIncomingJobBySid(const QString &jid, const QString &sid); + QXmppTransferOutgoingJob *getOutgoingJobByRequestId(const QString &jid, const QString &id); - // change state - d->error = cause; - d->state = FinishedState; +private: + QXmppTransferJob *getJobByRequestId(QXmppTransferJob::Direction direction, const QString &jid, const QString &id); + QXmppTransferManager *q; +}; - // close IO device - if (d->iodevice) - d->iodevice->close(); +QXmppTransferManagerPrivate::QXmppTransferManagerPrivate(QXmppTransferManager *qq) + : q(qq) +{ +} - // close socket - if (d->socksSocket) - { - d->socksSocket->flush(); - d->socksSocket->close(); - } +QXmppTransferJob* QXmppTransferManagerPrivate::getJobByRequestId(QXmppTransferJob::Direction direction, const QString &jid, const QString &id) +{ + foreach (QXmppTransferJob *job, q->m_jobs) + if (job->d->direction == direction && + job->d->jid == jid && + job->d->requestId == id) + return job; + return 0; +} - // emit signals later - QTimer::singleShot(0, this, SLOT(_q_terminated())); +QXmppTransferIncomingJob *QXmppTransferManagerPrivate::getIncomingJobByRequestId(const QString &jid, const QString &id) +{ + return static_cast<QXmppTransferIncomingJob*>(getJobByRequestId(QXmppTransferJob::IncomingDirection, jid, id)); } -bool QXmppTransferJob::writeData(const QByteArray &data) +QXmppTransferIncomingJob* QXmppTransferManagerPrivate::getIncomingJobBySid(const QString &jid, const QString &sid) { - const qint64 written = d->iodevice->write(data); - if (written < 0) - return false; - d->done += written; - if (!d->fileInfo.hash().isEmpty()) - d->hash.addData(data); - progress(d->done, d->fileInfo.size()); - return true; + foreach (QXmppTransferJob *job, q->m_jobs) + if (job->d->direction == QXmppTransferJob::IncomingDirection && + job->d->jid == jid && + job->d->sid == sid) + return static_cast<QXmppTransferIncomingJob*>(job); + return 0; +} + +QXmppTransferOutgoingJob *QXmppTransferManagerPrivate::getOutgoingJobByRequestId(const QString &jid, const QString &id) +{ + return static_cast<QXmppTransferOutgoingJob*>(getJobByRequestId(QXmppTransferJob::OutgoingDirection, jid, id)); } /// Constructs a QXmppTransferManager to handle incoming and outgoing @@ -456,6 +682,8 @@ QXmppTransferManager::QXmppTransferManager() bool check; Q_UNUSED(check); + d = new QXmppTransferManagerPrivate(this); + // start SOCKS server m_socksServer = new QXmppSocksServer(this); if (m_socksServer->listen()) { @@ -467,6 +695,11 @@ QXmppTransferManager::QXmppTransferManager() } } +QXmppTransferManager::~QXmppTransferManager() +{ + delete d; +} + void QXmppTransferManager::setClient(QXmppClient *client) { bool check; @@ -506,7 +739,7 @@ void QXmppTransferManager::byteStreamIqReceived(const QXmppByteStreamIq &iq) /// that we connected to a stream host. void QXmppTransferManager::byteStreamResponseReceived(const QXmppIq &iq) { - QXmppTransferJob *job = getJobByRequestId(QXmppTransferJob::IncomingDirection, iq.from(), iq.id()); + QXmppTransferJob *job = d->getIncomingJobByRequestId(iq.from(), iq.id()); if (!job || job->method() != QXmppTransferJob::SocksMethod || job->state() != QXmppTransferJob::StartState) @@ -523,7 +756,7 @@ void QXmppTransferManager::byteStreamResultReceived(const QXmppByteStreamIq &iq) bool check; Q_UNUSED(check); - QXmppTransferJob *job = getJobByRequestId(QXmppTransferJob::OutgoingDirection, iq.from(), iq.id()); + QXmppTransferOutgoingJob *job = d->getOutgoingJobByRequestId(iq.from(), iq.id()); if (!job || job->method() != QXmppTransferJob::SocksMethod || job->state() != QXmppTransferJob::StartState) @@ -532,44 +765,7 @@ void QXmppTransferManager::byteStreamResultReceived(const QXmppByteStreamIq &iq) // check the stream host if (iq.streamHostUsed() == job->d->socksProxy.jid()) { - const QXmppByteStreamIq::StreamHost streamHost = job->d->socksProxy; - info(QString("Connecting to proxy: %1 (%2:%3)").arg( - streamHost.jid(), - streamHost.host().toString(), - QString::number(streamHost.port()))); - - // connect to proxy - const QString hostName = streamHash(job->d->sid, - client()->configuration().jid(), - job->d->jid); - - QXmppSocksClient *socksClient = new QXmppSocksClient(streamHost.host(), streamHost.port(), job); - socksClient->connectToHost(hostName, 0); - // FIXME : this should probably be made asynchronous as it blocks XMPP packet handling - if (!socksClient->waitForReady(socksTimeout)) - { - warning(QString("Failed to connect to proxy: %1 (%2:%3)").arg( - streamHost.jid(), - streamHost.host().toString(), - QString::number(streamHost.port()))); - delete socksClient; - job->terminate(QXmppTransferJob::ProtocolError); - return; - } - job->d->socksSocket = socksClient; - check = connect(job->d->socksSocket, SIGNAL(disconnected()), - job, SLOT(_q_disconnected())); - Q_ASSERT(check); - - // activate stream - QXmppByteStreamIq streamIq; - streamIq.setType(QXmppIq::Set); - streamIq.setFrom(client()->configuration().jid()); - streamIq.setTo(streamHost.jid()); - streamIq.setSid(job->d->sid); - streamIq.setActivate(job->d->jid); - job->d->requestId = streamIq.id(); - client()->sendPacket(streamIq); + job->connectToProxy(); return; } @@ -580,20 +776,11 @@ void QXmppTransferManager::byteStreamResultReceived(const QXmppByteStreamIq &iq) job->terminate(QXmppTransferJob::ProtocolError); return; } - job->setState(QXmppTransferJob::TransferState); check = connect(job->d->socksSocket, SIGNAL(disconnected()), job, SLOT(_q_disconnected())); Q_ASSERT(check); - check = connect(job->d->socksSocket, SIGNAL(bytesWritten(qint64)), - job, SLOT(_q_sendData())); - Q_ASSERT(check); - - check = connect(job->d->iodevice, SIGNAL(readyRead()), - job, SLOT(_q_sendData())); - Q_ASSERT(check); - - job->_q_sendData(); + job->startSending(); } /// Handle a bytestream set, i.e. an invitation from the remote party to connect @@ -607,7 +794,7 @@ void QXmppTransferManager::byteStreamSetReceived(const QXmppByteStreamIq &iq) response.setId(iq.id()); response.setTo(iq.from()); - QXmppTransferJob *job = getJobBySid(QXmppTransferJob::IncomingDirection, iq.from(), iq.sid()); + QXmppTransferIncomingJob *job = d->getIncomingJobBySid(iq.from(), iq.sid()); if (!job || job->method() != QXmppTransferJob::SocksMethod || job->state() != QXmppTransferJob::StartState) @@ -621,59 +808,7 @@ void QXmppTransferManager::byteStreamSetReceived(const QXmppByteStreamIq &iq) return; } - // try connecting to the offered stream hosts - foreach (const QXmppByteStreamIq::StreamHost &streamHost, iq.streamHosts()) - { - info(QString("Connecting to streamhost: %1 (%2:%3)").arg( - streamHost.jid(), - streamHost.host().toString(), - QString::number(streamHost.port()))); - - const QString hostName = streamHash(job->d->sid, - job->d->jid, - client()->configuration().jid()); - - // try to connect to stream host - QXmppSocksClient *socksClient = new QXmppSocksClient(streamHost.host(), streamHost.port(), job); - socksClient->connectToHost(hostName, 0); - // FIXME : this should probably be made asynchronous as it blocks XMPP packet handling - if (socksClient->waitForReady(socksTimeout)) { - job->setState(QXmppTransferJob::TransferState); - job->d->socksSocket = socksClient; - - check = connect(job->d->socksSocket, SIGNAL(readyRead()), - job, SLOT(_q_receiveData())); - Q_ASSERT(check); - - check = connect(job->d->socksSocket, SIGNAL(disconnected()), - job, SLOT(_q_disconnected())); - Q_ASSERT(check); - - QXmppByteStreamIq ackIq; - ackIq.setId(iq.id()); - ackIq.setTo(iq.from()); - ackIq.setType(QXmppIq::Result); - ackIq.setSid(job->d->sid); - ackIq.setStreamHostUsed(streamHost.jid()); - client()->sendPacket(ackIq); - return; - } else { - warning(QString("Failed to connect to streamhost: %1 (%2:%3)").arg( - streamHost.jid(), - streamHost.host().toString(), - QString::number(streamHost.port()))); - delete socksClient; - } - } - - // could not connect to any stream host - QXmppStanza::Error error(QXmppStanza::Error::Cancel, QXmppStanza::Error::ItemNotFound); - error.setCode(404); - response.setType(QXmppIq::Error); - response.setError(error); - client()->sendPacket(response); - - job->terminate(QXmppTransferJob::ProtocolError); + job->connectToHosts(iq); } QStringList QXmppTransferManager::discoveryFeatures() const @@ -732,33 +867,13 @@ bool QXmppTransferManager::handleStanza(const QDomElement &element) return false; } -QXmppTransferJob* QXmppTransferManager::getJobByRequestId(QXmppTransferJob::Direction direction, const QString &jid, const QString &id) -{ - foreach (QXmppTransferJob *job, m_jobs) - if (job->d->direction == direction && - job->d->jid == jid && - job->d->requestId == id) - return job; - return 0; -} - -QXmppTransferJob* QXmppTransferManager::getJobBySid(QXmppTransferJob::Direction direction, const QString &jid, const QString &sid) -{ - foreach (QXmppTransferJob *job, m_jobs) - if (job->d->direction == direction && - job->d->jid == jid && - job->d->sid == sid) - return job; - return 0; -} - void QXmppTransferManager::ibbCloseIqReceived(const QXmppIbbCloseIq &iq) { QXmppIq response; response.setTo(iq.from()); response.setId(iq.id()); - QXmppTransferJob *job = getJobBySid(QXmppTransferJob::IncomingDirection, iq.from(), iq.sid()); + QXmppTransferJob *job = d->getIncomingJobBySid(iq.from(), iq.sid()); if (!job || job->method() != QXmppTransferJob::InBandMethod) { @@ -784,7 +899,7 @@ void QXmppTransferManager::ibbDataIqReceived(const QXmppIbbDataIq &iq) response.setTo(iq.from()); response.setId(iq.id()); - QXmppTransferJob *job = getJobBySid(QXmppTransferJob::IncomingDirection, iq.from(), iq.sid()); + QXmppTransferJob *job = d->getIncomingJobBySid(iq.from(), iq.sid()); if (!job || job->method() != QXmppTransferJob::InBandMethod || job->state() != QXmppTransferJob::TransferState) @@ -822,7 +937,7 @@ void QXmppTransferManager::ibbOpenIqReceived(const QXmppIbbOpenIq &iq) response.setTo(iq.from()); response.setId(iq.id()); - QXmppTransferJob *job = getJobBySid(QXmppTransferJob::IncomingDirection, iq.from(), iq.sid()); + QXmppTransferJob *job = d->getIncomingJobBySid(iq.from(), iq.sid()); if (!job || job->method() != QXmppTransferJob::InBandMethod) { @@ -854,7 +969,7 @@ void QXmppTransferManager::ibbOpenIqReceived(const QXmppIbbOpenIq &iq) void QXmppTransferManager::ibbResponseReceived(const QXmppIq &iq) { - QXmppTransferJob *job = getJobByRequestId(QXmppTransferJob::OutgoingDirection, iq.from(), iq.id()); + QXmppTransferJob *job = d->getOutgoingJobByRequestId(iq.from(), iq.id()); if (!job || job->method() != QXmppTransferJob::InBandMethod || job->state() == QXmppTransferJob::FinishedState) @@ -910,28 +1025,19 @@ void QXmppTransferManager::_q_iqReceived(const QXmppIq &iq) bool check; Q_UNUSED(check); - foreach (QXmppTransferJob *job, m_jobs) + foreach (QXmppTransferJob *ptr, m_jobs) { // handle IQ from proxy - if (job->d->socksProxy.jid() == iq.from() && job->d->requestId == iq.id()) + if (ptr->direction() == QXmppTransferJob::OutgoingDirection && ptr->d->socksProxy.jid() == iq.from() && ptr->d->requestId == iq.id()) { + QXmppTransferOutgoingJob *job = static_cast<QXmppTransferOutgoingJob*>(ptr); if (job->d->socksSocket) { // proxy connection activation result if (iq.type() == QXmppIq::Result) { // proxy stream activated, start sending data - job->setState(QXmppTransferJob::TransferState); - - check = connect(job->d->socksSocket, SIGNAL(bytesWritten(qint64)), - job, SLOT(_q_sendData())); - Q_ASSERT(check); - - check = connect(job->d->iodevice, SIGNAL(readyRead()), - job, SLOT(_q_sendData())); - Q_ASSERT(check); - - job->_q_sendData(); + job->startSending(); } else if (iq.type() == QXmppIq::Error) { // proxy stream not activated, terminate warning("Could not activate SOCKS5 proxy bytestream"); @@ -946,8 +1052,9 @@ void QXmppTransferManager::_q_iqReceived(const QXmppIq &iq) } // handle IQ from peer - else if (job->d->jid == iq.from() && job->d->requestId == iq.id()) + else if (ptr->d->jid == iq.from() && ptr->d->requestId == iq.id()) { + QXmppTransferJob *job = ptr; if (job->direction() == QXmppTransferJob::OutgoingDirection && job->method() == QXmppTransferJob::InBandMethod) { @@ -1139,7 +1246,7 @@ QXmppTransferJob *QXmppTransferManager::sendFile(const QString &jid, QIODevice * return 0; } - QXmppTransferJob *job = new QXmppTransferJob(jid, QXmppTransferJob::OutgoingDirection, this); + QXmppTransferOutgoingJob *job = new QXmppTransferOutgoingJob(jid, client(), this); if (sid.isEmpty()) job->d->sid = generateStanzaHash(); else @@ -1324,7 +1431,7 @@ void QXmppTransferManager::streamInitiationIqReceived(const QXmppStreamInitiatio // The remote party has accepted an outgoing transfer. void QXmppTransferManager::streamInitiationResultReceived(const QXmppStreamInitiationIq &iq) { - QXmppTransferJob *job = getJobByRequestId(QXmppTransferJob::OutgoingDirection, iq.from(), iq.id()); + QXmppTransferJob *job = d->getOutgoingJobByRequestId(iq.from(), iq.id()); if (!job || job->state() != QXmppTransferJob::OfferState) return; @@ -1426,7 +1533,7 @@ void QXmppTransferManager::streamInitiationSetReceived(const QXmppStreamInitiati } // check the stream type - QXmppTransferJob *job = new QXmppTransferJob(iq.from(), QXmppTransferJob::IncomingDirection, this); + QXmppTransferIncomingJob *job = new QXmppTransferIncomingJob(iq.from(), client(), this); int offeredMethods = QXmppTransferJob::NoMethod; job->d->offerId = iq.id(); job->d->sid = iq.siId(); diff --git a/src/client/QXmppTransferManager.h b/src/client/QXmppTransferManager.h index 900d2163..33b103e2 100644 --- a/src/client/QXmppTransferManager.h +++ b/src/client/QXmppTransferManager.h @@ -41,6 +41,8 @@ class QXmppSocksClient; class QXmppSocksServer; class QXmppStreamInitiationIq; class QXmppTransferJobPrivate; +class QXmppTransferManager; +class QXmppTransferManagerPrivate; class QXmppTransferFileInfo { @@ -176,12 +178,10 @@ public slots: private slots: void _q_disconnected(); - void _q_receiveData(); - void _q_sendData(); void _q_terminated(); private: - QXmppTransferJob(const QString &jid, QXmppTransferJob::Direction direction, QObject *parent); + QXmppTransferJob(const QString &jid, QXmppTransferJob::Direction direction, QXmppClient *client, QObject *parent); void checkData(); void setState(QXmppTransferJob::State state); void terminate(QXmppTransferJob::Error error); @@ -189,6 +189,9 @@ private: QXmppTransferJobPrivate *const d; friend class QXmppTransferManager; + friend class QXmppTransferManagerPrivate; + friend class QXmppTransferIncomingJob; + friend class QXmppTransferOutgoingJob; }; /// \brief The QXmppTransferManager class provides support for sending and @@ -217,6 +220,7 @@ class QXmppTransferManager : public QXmppClientExtension public: QXmppTransferManager(); + ~QXmppTransferManager(); QString proxy() const; void setProxy(const QString &proxyJid); @@ -265,8 +269,8 @@ private slots: void _q_socksServerConnected(QTcpSocket *socket, const QString &hostName, quint16 port); private: - QXmppTransferJob *getJobByRequestId(QXmppTransferJob::Direction direction, const QString &jid, const QString &id); - QXmppTransferJob *getJobBySid(QXmppTransferJob::Direction, const QString &jid, const QString &sid); + QXmppTransferManagerPrivate *d; + void byteStreamIqReceived(const QXmppByteStreamIq&); void byteStreamResponseReceived(const QXmppIq&); void byteStreamResultReceived(const QXmppByteStreamIq&); @@ -286,6 +290,8 @@ private: bool m_proxyOnly; QXmppSocksServer *m_socksServer; QXmppTransferJob::Methods m_supportedMethods; + + friend class QXmppTransferManagerPrivate; }; Q_DECLARE_OPERATORS_FOR_FLAGS(QXmppTransferJob::Methods) diff --git a/src/client/QXmppTransferManager_p.h b/src/client/QXmppTransferManager_p.h new file mode 100644 index 00000000..d3b2d62a --- /dev/null +++ b/src/client/QXmppTransferManager_p.h @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2008-2011 The QXmpp developers + * + * Author: + * Jeremy Lainé + * + * Source: + * http://code.google.com/p/qxmpp + * + * This file is a part of QXmpp library. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + */ + +#ifndef QXMPPTRANSFERMANAGER_P_H +#define QXMPPTRANSFERMANAGER_P_H + +#include "QXmppTransferManager.h" + +// +// W A R N I N G +// ------------- +// +// This file is not part of the QXmpp API. It exists for the convenience +// of the QXmppTransferManager class. This header file may change from +// version to version without notice, or even be removed. +// +// We mean it. +// + +class QXmppTransferIncomingJob : public QXmppTransferJob +{ + Q_OBJECT + +public: + QXmppTransferIncomingJob(const QString &jid, QXmppClient *client, QObject *parent); + void connectToHosts(const QXmppByteStreamIq &iq); + +private slots: + void _q_candidateDisconnected(); + void _q_candidateReady(); + void _q_receiveData(); + +private: + void connectToNextHost(); + + QXmppByteStreamIq::StreamHost m_candidateHost; + QXmppSocksClient *m_candidateClient; + QList<QXmppByteStreamIq::StreamHost> m_streamCandidates; + QString m_streamOfferId; + QString m_streamOfferFrom; +}; + +class QXmppTransferOutgoingJob : public QXmppTransferJob +{ + Q_OBJECT + +public: + QXmppTransferOutgoingJob(const QString &jid, QXmppClient *client, QObject *parent); + void connectToProxy(); + void startSending(); + +private slots: + void _q_proxyReady(); + void _q_sendData(); +}; + +#endif diff --git a/src/client/client.pri b/src/client/client.pri index c031cbaa..aa138442 100644 --- a/src/client/client.pri +++ b/src/client/client.pri @@ -17,6 +17,7 @@ INSTALL_HEADERS += \ client/QXmppRosterManager.h \ client/QXmppRpcManager.h \ client/QXmppTransferManager.h \ + client/QXmppTransferManager_p.h \ client/QXmppVCardManager.h \ client/QXmppVersionManager.h |
