summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRemko Tronçon <git@el-tramo.be>2011-12-22 15:46:23 (GMT)
committerRemko Tronçon <git@el-tramo.be>2011-12-22 16:53:18 (GMT)
commit732253a9b3e88b99b36dd3298157cf502f743294 (patch)
tree3471f2d999dfe3cb2ae8f5aec5bdd7b3d1465078
parent6c1e7d8a8339a849896566464bd9f1db33e3b3da (diff)
downloadswift-contrib-732253a9b3e88b99b36dd3298157cf502f743294.zip
swift-contrib-732253a9b3e88b99b36dd3298157cf502f743294.tar.bz2
BOSH Refactoring.
-rw-r--r--Swiften/Client/CoreClient.cpp15
-rw-r--r--Swiften/Network/BOSHConnectionFactory.cpp26
-rw-r--r--Swiften/Network/BOSHConnectionFactory.h43
-rw-r--r--Swiften/Network/BOSHConnectionPool.cpp13
-rw-r--r--Swiften/Network/BOSHConnectionPool.h9
-rw-r--r--Swiften/Network/SConscript1
-rw-r--r--Swiften/Network/UnitTest/BOSHConnectionPoolTest.cpp10
-rw-r--r--Swiften/Session/BOSHSessionStream.cpp10
-rw-r--r--Swiften/Session/BOSHSessionStream.h24
9 files changed, 48 insertions, 103 deletions
diff --git a/Swiften/Client/CoreClient.cpp b/Swiften/Client/CoreClient.cpp
index cef2b24..49fb9fa 100644
--- a/Swiften/Client/CoreClient.cpp
+++ b/Swiften/Client/CoreClient.cpp
@@ -1,121 +1,132 @@
/*
* Copyright (c) 2010-2011 Remko Tronçon
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
*/
#include <Swiften/Client/CoreClient.h>
#include <boost/bind.hpp>
#include <boost/smart_ptr/make_shared.hpp>
#include <Swiften/Base/IDGenerator.h>
#include <Swiften/Base/Log.h>
#include <Swiften/Base/foreach.h>
#include <Swiften/Base/Algorithm.h>
#include <Swiften/Client/ClientSession.h>
#include <Swiften/TLS/CertificateVerificationError.h>
#include <Swiften/Network/ChainedConnector.h>
#include <Swiften/Network/NetworkFactories.h>
#include <Swiften/Network/ProxyProvider.h>
#include <Swiften/TLS/PKCS12Certificate.h>
#include <Swiften/Session/BasicSessionStream.h>
#include <Swiften/Session/BOSHSessionStream.h>
#include <Swiften/Queries/IQRouter.h>
#include <Swiften/Client/ClientSessionStanzaChannel.h>
#include <Swiften/Network/SOCKS5ProxiedConnectionFactory.h>
#include <Swiften/Network/HTTPConnectProxiedConnectionFactory.h>
-#include <Swiften/Network/BOSHConnectionFactory.h>
namespace Swift {
CoreClient::CoreClient(const JID& jid, const SafeByteArray& password, NetworkFactories* networkFactories) : jid_(jid), password_(password), networkFactories(networkFactories), disconnectRequested_(false), certificateTrustChecker(NULL) {
stanzaChannel_ = new ClientSessionStanzaChannel();
stanzaChannel_->onMessageReceived.connect(boost::bind(&CoreClient::handleMessageReceived, this, _1));
stanzaChannel_->onPresenceReceived.connect(boost::bind(&CoreClient::handlePresenceReceived, this, _1));
stanzaChannel_->onStanzaAcked.connect(boost::bind(&CoreClient::handleStanzaAcked, this, _1));
stanzaChannel_->onAvailableChanged.connect(boost::bind(&CoreClient::handleStanzaChannelAvailableChanged, this, _1));
iqRouter_ = new IQRouter(stanzaChannel_);
iqRouter_->setJID(jid);
}
CoreClient::~CoreClient() {
forceReset();
delete iqRouter_;
stanzaChannel_->onAvailableChanged.disconnect(boost::bind(&CoreClient::handleStanzaChannelAvailableChanged, this, _1));
stanzaChannel_->onMessageReceived.disconnect(boost::bind(&CoreClient::handleMessageReceived, this, _1));
stanzaChannel_->onPresenceReceived.disconnect(boost::bind(&CoreClient::handlePresenceReceived, this, _1));
stanzaChannel_->onStanzaAcked.disconnect(boost::bind(&CoreClient::handleStanzaAcked, this, _1));
delete stanzaChannel_;
}
void CoreClient::connect(const ClientOptions& o) {
SWIFT_LOG(debug) << "Connecting" << std::endl;
options = o;
connect(jid_.getDomain());
}
void CoreClient::connect(const std::string& host) {
forceReset();
SWIFT_LOG(debug) << "Connecting to host " << host << std::endl;
disconnectRequested_ = false;
assert(!connector_);
assert(proxyConnectionFactories.empty());
if(networkFactories->getProxyProvider()->getSOCKS5Proxy().isValid()) {
proxyConnectionFactories.push_back(new SOCKS5ProxiedConnectionFactory(networkFactories->getConnectionFactory(), networkFactories->getProxyProvider()->getSOCKS5Proxy()));
}
if(networkFactories->getProxyProvider()->getHTTPConnectProxy().isValid()) {
proxyConnectionFactories.push_back(new HTTPConnectProxiedConnectionFactory(networkFactories->getConnectionFactory(), networkFactories->getProxyProvider()->getHTTPConnectProxy()));
}
std::vector<ConnectionFactory*> connectionFactories(proxyConnectionFactories);
if (options.boshURL.empty()) {
connectionFactories.push_back(networkFactories->getConnectionFactory());
connector_ = boost::make_shared<ChainedConnector>(host, networkFactories->getDomainNameResolver(), connectionFactories, networkFactories->getTimerFactory());
connector_->onConnectFinished.connect(boost::bind(&CoreClient::handleConnectorFinished, this, _1));
connector_->setTimeoutMilliseconds(60*1000);
connector_->start();
}
else {
/* Autodiscovery of which proxy works is largely ok with a TCP session, because this is a one-off. With BOSH
* it would be quite painful given that potentially every stanza could be sent on a new connection.
*/
//sessionStream_ = boost::make_shared<BOSHSessionStream>(boost::make_shared<BOSHConnectionFactory>(options.boshURL, networkFactories->getConnectionFactory(), networkFactories->getXMLParserFactory(), networkFactories->getTLSContextFactory()), getPayloadParserFactories(), getPayloadSerializers(), networkFactories->getTLSContextFactory(), networkFactories->getTimerFactory(), networkFactories->getXMLParserFactory(), networkFactories->getEventLoop(), host, options.boshHTTPConnectProxyURL, options.boshHTTPConnectProxyAuthID, options.boshHTTPConnectProxyAuthPassword);
- sessionStream_ = boost::shared_ptr<BOSHSessionStream>(new BOSHSessionStream(boost::make_shared<BOSHConnectionFactory>(options.boshURL, networkFactories->getConnectionFactory(), networkFactories->getXMLParserFactory(), networkFactories->getTLSContextFactory()), getPayloadParserFactories(), getPayloadSerializers(), networkFactories->getTLSContextFactory(), networkFactories->getTimerFactory(), networkFactories->getXMLParserFactory(), networkFactories->getEventLoop(), host, options.boshHTTPConnectProxyURL, options.boshHTTPConnectProxyAuthID, options.boshHTTPConnectProxyAuthPassword));
+ sessionStream_ = boost::shared_ptr<BOSHSessionStream>(new BOSHSessionStream(
+ options.boshURL,
+ getPayloadParserFactories(),
+ getPayloadSerializers(),
+ networkFactories->getConnectionFactory(),
+ networkFactories->getTLSContextFactory(),
+ networkFactories->getTimerFactory(),
+ networkFactories->getXMLParserFactory(),
+ networkFactories->getEventLoop(),
+ host,
+ options.boshHTTPConnectProxyURL,
+ options.boshHTTPConnectProxyAuthID,
+ options.boshHTTPConnectProxyAuthPassword));
sessionStream_->onDataRead.connect(boost::bind(&CoreClient::handleDataRead, this, _1));
sessionStream_->onDataWritten.connect(boost::bind(&CoreClient::handleDataWritten, this, _1));
bindSessionToStream();
}
}
void CoreClient::bindSessionToStream() {
session_ = ClientSession::create(jid_, sessionStream_);
session_->setCertificateTrustChecker(certificateTrustChecker);
session_->setUseStreamCompression(options.useStreamCompression);
session_->setAllowPLAINOverNonTLS(options.allowPLAINWithoutTLS);
switch(options.useTLS) {
case ClientOptions::UseTLSWhenAvailable:
session_->setUseTLS(ClientSession::UseTLSWhenAvailable);
break;
case ClientOptions::NeverUseTLS:
session_->setUseTLS(ClientSession::NeverUseTLS);
break;
case ClientOptions::RequireTLS:
session_->setUseTLS(ClientSession::RequireTLS);
break;
}
session_->setUseAcks(options.useAcks);
stanzaChannel_->setSession(session_);
session_->onFinished.connect(boost::bind(&CoreClient::handleSessionFinished, this, _1));
session_->onNeedCredentials.connect(boost::bind(&CoreClient::handleNeedCredentials, this));
session_->start();
}
/**
* Only called for TCP sessions. BOSH is handled inside the BOSHSessionStream.
*/
void CoreClient::handleConnectorFinished(boost::shared_ptr<Connection> connection) {
resetConnector();
diff --git a/Swiften/Network/BOSHConnectionFactory.cpp b/Swiften/Network/BOSHConnectionFactory.cpp
deleted file mode 100644
index 7b83034..0000000
--- a/Swiften/Network/BOSHConnectionFactory.cpp
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2011 Thilo Cestonaro
- * Licensed under the simplified BSD license.
- * See Documentation/Licenses/BSD-simplified.txt for more information.
- */
-
-/*
- * Copyright (c) 2011 Kevin Smith
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
- */
-
-#include <Swiften/Network/BOSHConnectionFactory.h>
-#include <Swiften/Network/BOSHConnection.h>
-
-namespace Swift {
-
-BOSHConnectionFactory::BOSHConnectionFactory(const URL& boshURL, ConnectionFactory* connectionFactory, XMLParserFactory* xmlParserFactory, TLSContextFactory* tlsFactory) : boshURL(boshURL), connectionFactory(connectionFactory), xmlParserFactory(xmlParserFactory), tlsFactory(tlsFactory) {
-
-}
-
-boost::shared_ptr<Connection> BOSHConnectionFactory::createConnection(ConnectionFactory* overrideFactory) {
- return BOSHConnection::create(boshURL, overrideFactory != NULL ? overrideFactory : connectionFactory, xmlParserFactory, tlsFactory);
-}
-
-}
diff --git a/Swiften/Network/BOSHConnectionFactory.h b/Swiften/Network/BOSHConnectionFactory.h
deleted file mode 100644
index 3750057..0000000
--- a/Swiften/Network/BOSHConnectionFactory.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (c) 2011 Thilo Cestonaro
- * Licensed under the simplified BSD license.
- * See Documentation/Licenses/BSD-simplified.txt for more information.
- */
-
-/*
- * Copyright (c) 2011 Kevin Smith
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
- */
-
-#pragma once
-
-#include <string>
-
-#include <Swiften/Network/ConnectionFactory.h>
-#include <Swiften/Network/HostAddressPort.h>
-#include <Swiften/TLS/TLSContextFactory.h>
-#include <Swiften/Base/URL.h>
-
-namespace Swift {
-
-class XMLParserFactory;
-
-class BOSHConnectionFactory {
- public:
- BOSHConnectionFactory(const URL& boshURL, ConnectionFactory* connectionFactory, XMLParserFactory* xmlParserFactory, TLSContextFactory* tlsFactory);
-
- /**
- * @param overrideFactory If non-NULL, creates a connection over the given factory instead.
- */
- boost::shared_ptr<Connection> createConnection(ConnectionFactory* overrideFactory);
- ConnectionFactory* getRawConnectionFactory() {return connectionFactory;}
- TLSContextFactory* getTLSContextFactory() {return tlsFactory;}
- private:
- URL boshURL;
- ConnectionFactory* connectionFactory;
- XMLParserFactory* xmlParserFactory;
- TLSContextFactory* tlsFactory;
-};
-
-}
diff --git a/Swiften/Network/BOSHConnectionPool.cpp b/Swiften/Network/BOSHConnectionPool.cpp
index 6c3ba7e..4886ede 100644
--- a/Swiften/Network/BOSHConnectionPool.cpp
+++ b/Swiften/Network/BOSHConnectionPool.cpp
@@ -1,69 +1,72 @@
/*
* Copyright (c) 2011 Kevin Smith
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
*/
#include <Swiften/Network/BOSHConnectionPool.h>
#include <climits>
#include <boost/bind.hpp>
#include <boost/lexical_cast.hpp>
#include <Swiften/Base/foreach.h>
#include <Swiften/Base/SafeString.h>
#include <Swiften/Network/TLSConnectionFactory.h>
#include <Swiften/Network/HTTPConnectProxiedConnectionFactory.h>
namespace Swift {
-BOSHConnectionPool::BOSHConnectionPool(boost::shared_ptr<BOSHConnectionFactory> connectionFactory, const std::string& to, long initialRID, const URL& boshHTTPConnectProxyURL, const SafeString& boshHTTPConnectProxyAuthID, const SafeString& boshHTTPConnectProxyAuthPassword)
- : connectionFactory(connectionFactory),
+BOSHConnectionPool::BOSHConnectionPool(const URL& boshURL, ConnectionFactory* connectionFactory, XMLParserFactory* parserFactory, TLSContextFactory* tlsFactory, const std::string& to, long initialRID, const URL& boshHTTPConnectProxyURL, const SafeString& boshHTTPConnectProxyAuthID, const SafeString& boshHTTPConnectProxyAuthPassword) :
+ boshURL(boshURL),
+ connectionFactory(connectionFactory),
+ xmlParserFactory(parserFactory),
+ tlsFactory(tlsFactory),
rid(initialRID),
pendingTerminate(false),
to(to),
requestLimit(2),
restartCount(0),
pendingRestart(false) {
tlsConnectionFactory = NULL;
if (boshHTTPConnectProxyURL.empty()) {
connectProxyFactory = NULL;
}
else {
- ConnectionFactory* rawFactory = connectionFactory->getRawConnectionFactory();
+ ConnectionFactory* rawFactory = connectionFactory;
if (boshHTTPConnectProxyURL.getScheme() == "https") {
- tlsConnectionFactory = new TLSConnectionFactory(connectionFactory->getTLSContextFactory(), rawFactory);
+ tlsConnectionFactory = new TLSConnectionFactory(tlsFactory, rawFactory);
rawFactory = tlsConnectionFactory;
}
connectProxyFactory = new HTTPConnectProxiedConnectionFactory(rawFactory, HostAddressPort(HostAddress(boshHTTPConnectProxyURL.getHost()), boshHTTPConnectProxyURL.getPort()), boshHTTPConnectProxyAuthID, boshHTTPConnectProxyAuthPassword);
}
createConnection();
}
BOSHConnectionPool::~BOSHConnectionPool() {
close();
delete connectProxyFactory;
delete tlsConnectionFactory;
}
void BOSHConnectionPool::write(const SafeByteArray& data) {
dataQueue.push_back(data);
tryToSendQueuedData();
}
void BOSHConnectionPool::handleDataRead(const SafeByteArray& data) {
onXMPPDataRead(data);
tryToSendQueuedData(); /* Will rebalance the connections */
}
void BOSHConnectionPool::restartStream() {
BOSHConnection::ref connection = getSuitableConnection();
if (connection) {
pendingRestart = false;
rid++;
connection->setRID(rid);
connection->restartStream();
restartCount++;
}
else {
pendingRestart = true;
}
@@ -174,71 +177,71 @@ void BOSHConnectionPool::tryToSendQueuedData() {
suitableConnection->write(createSafeByteArray(""));
}
else {
/* My thought process I went through when writing this, to aid anyone else confused why this can happen...
*
* What to do here? I think this isn't possible.
If you didn't have two connections, suitable would have made one.
If you have two connections and neither is suitable, pending would be true.
If you have a non-pending connection, it's suitable.
If I decide to do something here, remove assert above.
Ah! Yes, because there's a period between creating the connection and it being connected. */
}
}
}
}
}
void BOSHConnectionPool::handleHTTPError(const std::string& /*errorCode*/) {
handleSessionTerminated(boost::make_shared<BOSHError>(BOSHError::UndefinedCondition));
}
void BOSHConnectionPool::handleConnectionDisconnected(const boost::optional<Connection::Error>& error, BOSHConnection::ref connection) {
destroyConnection(connection);
if (false && error) {
handleSessionTerminated(boost::make_shared<BOSHError>(BOSHError::UndefinedCondition));
}
else {
/* We might have just freed up a connection slot to send with */
tryToSendQueuedData();
}
}
boost::shared_ptr<BOSHConnection> BOSHConnectionPool::createConnection() {
- BOSHConnection::ref connection = boost::dynamic_pointer_cast<BOSHConnection>(connectionFactory->createConnection(connectProxyFactory));
+ BOSHConnection::ref connection = BOSHConnection::create(boshURL, connectProxyFactory ? connectProxyFactory : connectionFactory, xmlParserFactory, tlsFactory);
connection->onXMPPDataRead.connect(boost::bind(&BOSHConnectionPool::handleDataRead, this, _1));
connection->onSessionStarted.connect(boost::bind(&BOSHConnectionPool::handleSessionStarted, this, _1, _2));
connection->onBOSHDataRead.connect(boost::bind(&BOSHConnectionPool::handleBOSHDataRead, this, _1));
connection->onBOSHDataWritten.connect(boost::bind(&BOSHConnectionPool::handleBOSHDataWritten, this, _1));
connection->onDisconnected.connect(boost::bind(&BOSHConnectionPool::handleConnectionDisconnected, this, _1, connection));
connection->onConnectFinished.connect(boost::bind(&BOSHConnectionPool::handleConnectFinished, this, _1, connection));
connection->onSessionTerminated.connect(boost::bind(&BOSHConnectionPool::handleSessionTerminated, this, _1));
connection->onHTTPError.connect(boost::bind(&BOSHConnectionPool::handleHTTPError, this, _1));
connection->connect(HostAddressPort(HostAddress("0.0.0.0"), 0));
connections.push_back(connection);
return connection;
}
void BOSHConnectionPool::destroyConnection(boost::shared_ptr<BOSHConnection> connection) {
connections.erase(std::remove(connections.begin(), connections.end(), connection), connections.end());
connection->onXMPPDataRead.disconnect(boost::bind(&BOSHConnectionPool::handleDataRead, this, _1));
connection->onSessionStarted.disconnect(boost::bind(&BOSHConnectionPool::handleSessionStarted, this, _1, _2));
connection->onBOSHDataRead.disconnect(boost::bind(&BOSHConnectionPool::handleBOSHDataRead, this, _1));
connection->onBOSHDataWritten.disconnect(boost::bind(&BOSHConnectionPool::handleBOSHDataWritten, this, _1));
connection->onDisconnected.disconnect(boost::bind(&BOSHConnectionPool::handleConnectionDisconnected, this, _1, connection));
connection->onConnectFinished.disconnect(boost::bind(&BOSHConnectionPool::handleConnectFinished, this, _1, connection));
connection->onSessionTerminated.disconnect(boost::bind(&BOSHConnectionPool::handleSessionTerminated, this, _1));
connection->onHTTPError.disconnect(boost::bind(&BOSHConnectionPool::handleHTTPError, this, _1));
}
void BOSHConnectionPool::handleSessionTerminated(BOSHError::ref error) {
onSessionTerminated(error);
}
void BOSHConnectionPool::handleBOSHDataRead(const SafeByteArray& data) {
onBOSHDataRead(data);
}
void BOSHConnectionPool::handleBOSHDataWritten(const SafeByteArray& data) {
onBOSHDataWritten(data);
diff --git a/Swiften/Network/BOSHConnectionPool.h b/Swiften/Network/BOSHConnectionPool.h
index 85e598d..2264c90 100644
--- a/Swiften/Network/BOSHConnectionPool.h
+++ b/Swiften/Network/BOSHConnectionPool.h
@@ -1,64 +1,67 @@
/*
* Copyright (c) 2011 Kevin Smith
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
*/
#pragma once
#include <vector>
#include <Swiften/Base/SafeString.h>
-#include <Swiften/Network/BOSHConnectionFactory.h>
#include <Swiften/Network/BOSHConnection.h>
namespace Swift {
class HTTPConnectProxiedConnectionFactory;
class TLSConnectionFactory;
+
class BOSHConnectionPool : public boost::bsignals::trackable {
public:
- BOSHConnectionPool(boost::shared_ptr<BOSHConnectionFactory> factory, const std::string& to, long initialRID, const URL& boshHTTPConnectProxyURL, const SafeString& boshHTTPConnectProxyAuthID, const SafeString& boshHTTPConnectProxyAuthPassword);
+ BOSHConnectionPool(const URL& boshURL, ConnectionFactory* connectionFactory, XMLParserFactory* parserFactory, TLSContextFactory* tlsFactory, const std::string& to, long initialRID, const URL& boshHTTPConnectProxyURL, const SafeString& boshHTTPConnectProxyAuthID, const SafeString& boshHTTPConnectProxyAuthPassword);
~BOSHConnectionPool();
void write(const SafeByteArray& data);
void writeFooter();
void close();
void restartStream();
boost::signal<void (BOSHError::ref)> onSessionTerminated;
boost::signal<void ()> onSessionStarted;
boost::signal<void (const SafeByteArray&)> onXMPPDataRead;
boost::signal<void (const SafeByteArray&)> onBOSHDataRead;
boost::signal<void (const SafeByteArray&)> onBOSHDataWritten;
private:
void handleDataRead(const SafeByteArray& data);
void handleSessionStarted(const std::string& sid, size_t requests);
void handleBOSHDataRead(const SafeByteArray& data);
void handleBOSHDataWritten(const SafeByteArray& data);
void handleSessionTerminated(BOSHError::ref condition);
void handleConnectFinished(bool, BOSHConnection::ref connection);
void handleConnectionDisconnected(const boost::optional<Connection::Error>& error, BOSHConnection::ref connection);
void handleHTTPError(const std::string& errorCode);
private:
BOSHConnection::ref createConnection();
void destroyConnection(BOSHConnection::ref connection);
void tryToSendQueuedData();
BOSHConnection::ref getSuitableConnection();
private:
- boost::shared_ptr<BOSHConnectionFactory> connectionFactory;
+ URL boshURL;
+ ConnectionFactory* connectionFactory;
+ XMLParserFactory* xmlParserFactory;
+ TLSContextFactory* tlsFactory;
std::vector<BOSHConnection::ref> connections;
std::string sid;
unsigned long rid;
std::vector<SafeByteArray> dataQueue;
bool pendingTerminate;
std::string to;
size_t requestLimit;
int restartCount;
bool pendingRestart;
HTTPConnectProxiedConnectionFactory* connectProxyFactory;
TLSConnectionFactory* tlsConnectionFactory;
};
}
diff --git a/Swiften/Network/SConscript b/Swiften/Network/SConscript
index 4a5370f..6975fe6 100644
--- a/Swiften/Network/SConscript
+++ b/Swiften/Network/SConscript
@@ -1,55 +1,54 @@
Import("swiften_env")
myenv = swiften_env.Clone()
myenv.MergeFlags(myenv["LIBIDN_FLAGS"])
if myenv.get("HAVE_CARES", False) :
myenv.MergeFlags(myenv.get("CARES_FLAGS", {}))
sourceList = [
"HTTPConnectProxiedConnection.cpp",
"HTTPConnectProxiedConnectionFactory.cpp",
"SOCKS5ProxiedConnection.cpp",
"SOCKS5ProxiedConnectionFactory.cpp",
"BoostConnection.cpp",
"BoostConnectionFactory.cpp",
"BoostConnectionServer.cpp",
"BoostConnectionServerFactory.cpp",
"BoostIOServiceThread.cpp",
"BOSHConnection.cpp",
"BOSHConnectionPool.cpp",
- "BOSHConnectionFactory.cpp",
"ConnectionFactory.cpp",
"ConnectionServer.cpp",
"ConnectionServerFactory.cpp",
"DummyConnection.cpp",
"FakeConnection.cpp",
"ChainedConnector.cpp",
"Connector.cpp",
"Connection.cpp",
"TimerFactory.cpp",
"DummyTimerFactory.cpp",
"BoostTimerFactory.cpp",
"DomainNameResolver.cpp",
"DomainNameAddressQuery.cpp",
"DomainNameServiceQuery.cpp",
"PlatformDomainNameResolver.cpp",
"PlatformDomainNameServiceQuery.cpp",
"PlatformDomainNameAddressQuery.cpp",
"StaticDomainNameResolver.cpp",
"HostAddress.cpp",
"HostAddressPort.cpp",
"NetworkFactories.cpp",
"BoostNetworkFactories.cpp",
"NetworkEnvironment.cpp",
"Timer.cpp",
"TLSConnection.cpp",
"TLSConnectionFactory.cpp",
"BoostTimer.cpp",
"ProxyProvider.cpp",
"NullProxyProvider.cpp",
"NATTraverser.cpp",
"NullNATTraverser.cpp",
"NATTraversalGetPublicIPRequest.cpp",
"NATTraversalForwardPortRequest.cpp",
"NATTraversalRemovePortForwardingRequest.cpp",
"NATTraversalInterface.cpp",
diff --git a/Swiften/Network/UnitTest/BOSHConnectionPoolTest.cpp b/Swiften/Network/UnitTest/BOSHConnectionPoolTest.cpp
index 978bf3b..1bfee10 100644
--- a/Swiften/Network/UnitTest/BOSHConnectionPoolTest.cpp
+++ b/Swiften/Network/UnitTest/BOSHConnectionPoolTest.cpp
@@ -1,96 +1,95 @@
/*
* Copyright (c) 2011 Kevin Smith
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
*/
#include <QA/Checker/IO.h>
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/extensions/TestFactoryRegistry.h>
#include <boost/optional.hpp>
#include <boost/bind.hpp>
#include <boost/smart_ptr/make_shared.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/lexical_cast.hpp>
#include <Swiften/Base/Algorithm.h>
#include <Swiften/Network/Connection.h>
#include <Swiften/Network/ConnectionFactory.h>
#include <Swiften/Network/BOSHConnection.h>
-#include <Swiften/Network/BOSHConnectionFactory.h>
#include <Swiften/Network/BOSHConnectionPool.h>
#include <Swiften/Network/HostAddressPort.h>
#include <Swiften/EventLoop/DummyEventLoop.h>
#include <Swiften/Parser/PlatformXMLParserFactory.h>
using namespace Swift;
typedef boost::shared_ptr<BOSHConnectionPool> PoolRef;
class BOSHConnectionPoolTest : public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(BOSHConnectionPoolTest);
CPPUNIT_TEST(testConnectionCount_OneWrite);
CPPUNIT_TEST(testConnectionCount_TwoWrites);
CPPUNIT_TEST(testConnectionCount_ThreeWrites);
CPPUNIT_TEST(testConnectionCount_ThreeWrites_ManualConnect);
CPPUNIT_TEST(testConnectionCount_ThreeWritesTwoReads);
CPPUNIT_TEST(testSession);
CPPUNIT_TEST(testWrite_Empty);
CPPUNIT_TEST_SUITE_END();
public:
void setUp() {
to = "wonderland.lit";
path = "http-bind";
port = "5280";
sid = "MyShinySID";
initial = "<body wait='60' "
"inactivity='30' "
"polling='5' "
"requests='2' "
"hold='1' "
"maxpause='120' "
"sid='" + sid + "' "
"ver='1.6' "
"from='wonderland.lit' "
"xmlns='http://jabber.org/protocol/httpbind'/>";
eventLoop = new DummyEventLoop();
connectionFactory = new MockConnectionFactory(eventLoop);
- factory = boost::make_shared<BOSHConnectionFactory>(URL("http", to, 5280, path), connectionFactory, &parserFactory, static_cast<TLSContextFactory*>(NULL));
+ boshURL = URL("http", to, 5280, path);
sessionTerminated = 0;
sessionStarted = 0;
initialRID = 2349876;
xmppDataRead.clear();
boshDataRead.clear();
boshDataWritten.clear();
}
void tearDown() {
eventLoop->processEvents();
delete connectionFactory;
delete eventLoop;
}
void testConnectionCount_OneWrite() {
PoolRef testling = createTestling();
CPPUNIT_ASSERT_EQUAL(st(1), connectionFactory->connections.size());
eventLoop->processEvents();
CPPUNIT_ASSERT_EQUAL(0, sessionStarted);
readResponse(initial, connectionFactory->connections[0]);
CPPUNIT_ASSERT_EQUAL(1, sessionStarted);
CPPUNIT_ASSERT_EQUAL(st(1), connectionFactory->connections.size());
testling->write(createSafeByteArray("<blah/>"));
eventLoop->processEvents();
CPPUNIT_ASSERT_EQUAL(st(1), connectionFactory->connections.size());
CPPUNIT_ASSERT_EQUAL(1, sessionStarted);
}
void testConnectionCount_TwoWrites() {
PoolRef testling = createTestling();
CPPUNIT_ASSERT_EQUAL(st(1), connectionFactory->connections.size());
eventLoop->processEvents();
readResponse(initial, connectionFactory->connections[0]);
testling->write(createSafeByteArray("<blah/>"));
CPPUNIT_ASSERT_EQUAL(st(1), connectionFactory->connections.size());
@@ -184,136 +183,135 @@ class BOSHConnectionPoolTest : public CppUnit::TestFixture {
rid++;
readResponse("<body xmlns='http://jabber.org/protocol/httpbind'><message><splatploing/></message></body>", c0); /* Doesn't include necessary attributes - as the support is improved this'll start to fail */
eventLoop->processEvents();
CPPUNIT_ASSERT(!c0->pending);
CPPUNIT_ASSERT(c1->pending);
CPPUNIT_ASSERT_EQUAL(st(4), boshDataWritten.size()); /* don't send empty in [0], still have [1] waiting */
CPPUNIT_ASSERT_EQUAL(st(2), connectionFactory->connections.size());
rid++;
readResponse("<body xmlns='http://jabber.org/protocol/httpbind'><message><splatploing><blittlebarg/></splatploing></message></body>", c1);
eventLoop->processEvents();
CPPUNIT_ASSERT(!c1->pending);
CPPUNIT_ASSERT(c0->pending);
CPPUNIT_ASSERT_EQUAL(st(5), boshDataWritten.size()); /* empty to make room */
CPPUNIT_ASSERT_EQUAL(st(2), connectionFactory->connections.size());
rid++;
testling->write(createSafeByteArray("<bleh/>"));
CPPUNIT_ASSERT(c0->pending);
CPPUNIT_ASSERT(c1->pending);
CPPUNIT_ASSERT_EQUAL(st(6), boshDataWritten.size()); /* data */
rid++;
testling->write(createSafeByteArray("<bluh/>"));
CPPUNIT_ASSERT(c0->pending);
CPPUNIT_ASSERT(c1->pending);
CPPUNIT_ASSERT_EQUAL(st(6), boshDataWritten.size()); /* Don't send data, no room */
eventLoop->processEvents();
CPPUNIT_ASSERT_EQUAL(st(2), connectionFactory->connections.size());
}
void testSession() {
to = "prosody.doomsong.co.uk";
path = "http-bind/";
- factory = boost::make_shared<BOSHConnectionFactory>(URL("http", to, 5280, path), connectionFactory, &parserFactory, static_cast<TLSContextFactory*>(NULL));
-
+ boshURL = URL("http", to, 5280, path);
PoolRef testling = createTestling();
CPPUNIT_ASSERT_EQUAL(st(1), connectionFactory->connections.size());
eventLoop->processEvents();
CPPUNIT_ASSERT_EQUAL(st(1), boshDataWritten.size()); /* header*/
CPPUNIT_ASSERT_EQUAL(st(1), connectionFactory->connections.size());
std::string response = "<body authid='743da605-4c2e-4de1-afac-ac040dd4a940' xmpp:version='1.0' xmlns:stream='http://etherx.jabber.org/streams' xmlns:xmpp='urn:xmpp:xbosh' inactivity='60' wait='60' polling='5' secure='true' hold='1' from='prosody.doomsong.co.uk' ver='1.6' sid='743da605-4c2e-4de1-afac-ac040dd4a940' requests='2' xmlns='http://jabber.org/protocol/httpbind'><stream:features><auth xmlns='http://jabber.org/features/iq-auth'/><mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'><mechanism>SCRAM-SHA-1</mechanism><mechanism>DIGEST-MD5</mechanism></mechanisms></stream:features></body>";
readResponse(response, connectionFactory->connections[0]);
eventLoop->processEvents();
CPPUNIT_ASSERT_EQUAL(st(1), boshDataWritten.size());
CPPUNIT_ASSERT_EQUAL(st(1), connectionFactory->connections.size());
std::string send = "<auth xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\" mechanism=\"SCRAM-SHA-1\">biwsbj1hZG1pbixyPWZhOWE5ZDhiLWZmMDctNGE4Yy04N2E3LTg4YWRiNDQxZGUwYg==</auth>";
testling->write(createSafeByteArray(send));
eventLoop->processEvents();
CPPUNIT_ASSERT_EQUAL(st(2), boshDataWritten.size());
CPPUNIT_ASSERT_EQUAL(st(1), connectionFactory->connections.size());
response = "<body xmlns='http://jabber.org/protocol/httpbind' sid='743da605-4c2e-4de1-afac-ac040dd4a940' xmlns:stream = 'http://etherx.jabber.org/streams'><challenge xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>cj1mYTlhOWQ4Yi1mZjA3LTRhOGMtODdhNy04OGFkYjQ0MWRlMGJhZmZlMWNhMy1mMDJkLTQ5NzEtYjkyNS0yM2NlNWQ2MDQyMjYscz1OVGd5WkdWaFptTXRaVE15WXkwMFpXUmhMV0ZqTURRdFpqYzRNbUppWmpGa1pqWXgsaT00MDk2</challenge></body>";
readResponse(response, connectionFactory->connections[0]);
eventLoop->processEvents();
CPPUNIT_ASSERT_EQUAL(st(2), boshDataWritten.size());
CPPUNIT_ASSERT_EQUAL(st(1), connectionFactory->connections.size());
send = "<response xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">Yz1iaXdzLHI9ZmE5YTlkOGItZmYwNy00YThjLTg3YTctODhhZGI0NDFkZTBiYWZmZTFjYTMtZjAyZC00OTcxLWI5MjUtMjNjZTVkNjA0MjI2LHA9aU11NWt3dDN2VWplU2RqL01Jb3VIRldkZjBnPQ==</response>";
testling->write(createSafeByteArray(send));
eventLoop->processEvents();
CPPUNIT_ASSERT_EQUAL(st(3), boshDataWritten.size());
CPPUNIT_ASSERT_EQUAL(st(1), connectionFactory->connections.size());
response = "<body xmlns='http://jabber.org/protocol/httpbind' sid='743da605-4c2e-4de1-afac-ac040dd4a940' xmlns:stream = 'http://etherx.jabber.org/streams'><success xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>dj1YNmNBY3BBOWxHNjNOOXF2bVQ5S0FacERrVm89</success></body>";
readResponse(response, connectionFactory->connections[0]);
eventLoop->processEvents();
CPPUNIT_ASSERT_EQUAL(st(3), boshDataWritten.size());
CPPUNIT_ASSERT_EQUAL(st(1), connectionFactory->connections.size());
}
void testWrite_Empty() {
boost::shared_ptr<MockConnection> c0;
PoolRef testling = createTestling();
c0 = connectionFactory->connections[0];
CPPUNIT_ASSERT_EQUAL(st(1), connectionFactory->connections.size());
eventLoop->processEvents();
readResponse(initial, c0);
CPPUNIT_ASSERT_EQUAL(st(1), boshDataWritten.size()); /* Shouldn't have sent anything extra */
testling->restartStream();
CPPUNIT_ASSERT_EQUAL(st(2), boshDataWritten.size());
readResponse("<body></body>", c0);
CPPUNIT_ASSERT_EQUAL(st(3), boshDataWritten.size());
std::string fullBody = "<body rid='" + boost::lexical_cast<std::string>(initialRID + 2) + "' sid='" + sid + "' xmlns='http://jabber.org/protocol/httpbind'></body>";
std::string response = boshDataWritten[2];
size_t bodyPosition = response.find("\r\n\r\n");
CPPUNIT_ASSERT_EQUAL(fullBody, response.substr(bodyPosition+4));
}
private:
PoolRef createTestling() {
- PoolRef pool = boost::make_shared<BOSHConnectionPool>(factory, to, initialRID, URL(), "", "");
+ PoolRef pool = boost::make_shared<BOSHConnectionPool>(boshURL, connectionFactory, &parserFactory, static_cast<TLSContextFactory*>(NULL), to, initialRID, URL(), "", "");
pool->onXMPPDataRead.connect(boost::bind(&BOSHConnectionPoolTest::handleXMPPDataRead, this, _1));
pool->onBOSHDataRead.connect(boost::bind(&BOSHConnectionPoolTest::handleBOSHDataRead, this, _1));
pool->onBOSHDataWritten.connect(boost::bind(&BOSHConnectionPoolTest::handleBOSHDataWritten, this, _1));
pool->onSessionStarted.connect(boost::bind(&BOSHConnectionPoolTest::handleSessionStarted, this));
pool->onSessionTerminated.connect(boost::bind(&BOSHConnectionPoolTest::handleSessionTerminated, this));
return pool;
}
std::string lastBody() {
std::string response = boshDataWritten[boshDataWritten.size() - 1];
size_t bodyPosition = response.find("\r\n\r\n");
return response.substr(bodyPosition+4);
}
size_t st(int val) {
return static_cast<size_t>(val);
}
void handleXMPPDataRead(const SafeByteArray& d) {
xmppDataRead.push_back(safeByteArrayToString(d));
}
void handleBOSHDataRead(const SafeByteArray& d) {
boshDataRead.push_back(safeByteArrayToString(d));
}
void handleBOSHDataWritten(const SafeByteArray& d) {
boshDataWritten.push_back(safeByteArrayToString(d));
}
void handleSessionStarted() {
sessionStarted++;
}
@@ -369,55 +367,55 @@ class BOSHConnectionPoolTest : public CppUnit::TestFixture {
EventLoop* eventLoop;
std::vector< boost::shared_ptr<MockConnection> > connections;
std::vector<HostAddressPort> failingPorts;
bool autoFinishConnect;
};
void readResponse(const std::string& response, boost::shared_ptr<MockConnection> connection) {
connection->pending = false;
boost::shared_ptr<SafeByteArray> data1 = boost::make_shared<SafeByteArray>(createSafeByteArray(
"HTTP/1.1 200 OK\r\n"
"Content-Type: text/xml; charset=utf-8\r\n"
"Access-Control-Allow-Origin: *\r\n"
"Access-Control-Allow-Headers: Content-Type\r\n"
"Content-Length: "));
connection->onDataRead(data1);
boost::shared_ptr<SafeByteArray> data2 = boost::make_shared<SafeByteArray>(createSafeByteArray(boost::lexical_cast<std::string>(response.size())));
connection->onDataRead(data2);
boost::shared_ptr<SafeByteArray> data3 = boost::make_shared<SafeByteArray>(createSafeByteArray("\r\n\r\n"));
connection->onDataRead(data3);
boost::shared_ptr<SafeByteArray> data4 = boost::make_shared<SafeByteArray>(createSafeByteArray(response));
connection->onDataRead(data4);
}
std::string fullRequestFor(const std::string& data) {
std::string body = data;
std::string result = "POST /" + path + " HTTP/1.1\r\n"
+ "Host: " + to + ":" + port + "\r\n"
+ "Content-Type: text/xml; charset=utf-8\r\n"
+ "Content-Length: " + boost::lexical_cast<std::string>(body.size()) + "\r\n\r\n"
+ body;
return result;
}
private:
+ URL boshURL;
DummyEventLoop* eventLoop;
MockConnectionFactory* connectionFactory;
std::vector<std::string> xmppDataRead;
std::vector<std::string> boshDataRead;
std::vector<std::string> boshDataWritten;
PlatformXMLParserFactory parserFactory;
std::string to;
std::string path;
std::string port;
std::string sid;
std::string initial;
long initialRID;
- boost::shared_ptr<BOSHConnectionFactory> factory;
int sessionStarted;
int sessionTerminated;
};
CPPUNIT_TEST_SUITE_REGISTRATION(BOSHConnectionPoolTest);
diff --git a/Swiften/Session/BOSHSessionStream.cpp b/Swiften/Session/BOSHSessionStream.cpp
index 73bbfd6..f53b8e1 100644
--- a/Swiften/Session/BOSHSessionStream.cpp
+++ b/Swiften/Session/BOSHSessionStream.cpp
@@ -1,91 +1,91 @@
/*
* Copyright (c) 2011 Kevin Smith
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
*/
#include <Swiften/Session/BOSHSessionStream.h>
#include <boost/bind.hpp>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/uniform_int.hpp>
#include <boost/random/variate_generator.hpp>
#include <Swiften/Base/foreach.h>
#include <Swiften/Elements/StreamType.h>
#include <Swiften/StreamStack/XMPPLayer.h>
#include <Swiften/StreamStack/StreamStack.h>
#include <Swiften/StreamStack/ConnectionLayer.h>
#include <Swiften/StreamStack/WhitespacePingLayer.h>
#include <Swiften/StreamStack/CompressionLayer.h>
#include <Swiften/StreamStack/TLSLayer.h>
#include <Swiften/TLS/TLSContextFactory.h>
#include <Swiften/TLS/TLSContext.h>
#include <Swiften/EventLoop/EventLoop.h>
namespace Swift {
BOSHSessionStream::BOSHSessionStream(
- boost::shared_ptr<BOSHConnectionFactory> connectionFactory, /*FIXME: probably rip out*/
+ const URL& boshURL,
PayloadParserFactoryCollection* payloadParserFactories,
PayloadSerializerCollection* payloadSerializers,
+ ConnectionFactory* connectionFactory,
TLSContextFactory* tlsContextFactory,
TimerFactory* timerFactory,
XMLParserFactory* xmlParserFactory,
EventLoop* eventLoop,
const std::string& to,
const URL& boshHTTPConnectProxyURL,
const SafeString& boshHTTPConnectProxyAuthID,
const SafeString& boshHTTPConnectProxyAuthPassword) :
available(false),
payloadParserFactories(payloadParserFactories),
payloadSerializers(payloadSerializers),
tlsContextFactory(tlsContextFactory),
timerFactory(timerFactory),
xmlParserFactory(xmlParserFactory),
eventLoop(eventLoop),
firstHeader(true) {
boost::mt19937 random;
- boost::uniform_int<long> dist(0, LONG_MAX);
+ boost::uniform_int<long long> dist(0, (1LL<<53) - 1);
random.seed(time(NULL));
- boost::variate_generator<boost::mt19937&, boost::uniform_int<long> > randomRID(random, dist);
- long initialRID = randomRID();
+ long long initialRID = boost::variate_generator<boost::mt19937&, boost::uniform_int<long long> >(random, dist)();
- connectionPool = new BOSHConnectionPool(connectionFactory, to, initialRID, boshHTTPConnectProxyURL, boshHTTPConnectProxyAuthID, boshHTTPConnectProxyAuthPassword);
+ connectionPool = new BOSHConnectionPool(boshURL, connectionFactory, xmlParserFactory, tlsContextFactory, to, initialRID, boshHTTPConnectProxyURL, boshHTTPConnectProxyAuthID, boshHTTPConnectProxyAuthPassword);
connectionPool->onSessionTerminated.connect(boost::bind(&BOSHSessionStream::handlePoolSessionTerminated, this, _1));
connectionPool->onSessionStarted.connect(boost::bind(&BOSHSessionStream::handlePoolSessionStarted, this));
connectionPool->onXMPPDataRead.connect(boost::bind(&BOSHSessionStream::handlePoolXMPPDataRead, this, _1));
connectionPool->onBOSHDataRead.connect(boost::bind(&BOSHSessionStream::handlePoolBOSHDataRead, this, _1));
connectionPool->onBOSHDataWritten.connect(boost::bind(&BOSHSessionStream::handlePoolBOSHDataWritten, this, _1));
xmppLayer = new XMPPLayer(payloadParserFactories, payloadSerializers, xmlParserFactory, ClientStreamType);
xmppLayer->onStreamStart.connect(boost::bind(&BOSHSessionStream::handleStreamStartReceived, this, _1));
xmppLayer->onElement.connect(boost::bind(&BOSHSessionStream::handleElementReceived, this, _1));
xmppLayer->onError.connect(boost::bind(&BOSHSessionStream::handleXMPPError, this));
xmppLayer->onWriteData.connect(boost::bind(&BOSHSessionStream::handleXMPPLayerDataWritten, this, _1));
available = true;
}
BOSHSessionStream::~BOSHSessionStream() {
close();
connectionPool->onSessionTerminated.disconnect(boost::bind(&BOSHSessionStream::handlePoolSessionTerminated, this, _1));
connectionPool->onSessionStarted.disconnect(boost::bind(&BOSHSessionStream::handlePoolSessionStarted, this));
connectionPool->onXMPPDataRead.disconnect(boost::bind(&BOSHSessionStream::handlePoolXMPPDataRead, this, _1));
connectionPool->onBOSHDataRead.disconnect(boost::bind(&BOSHSessionStream::handlePoolBOSHDataRead, this, _1));
connectionPool->onBOSHDataWritten.disconnect(boost::bind(&BOSHSessionStream::handlePoolBOSHDataWritten, this, _1));
delete connectionPool;
connectionPool = NULL;
xmppLayer->onStreamStart.disconnect(boost::bind(&BOSHSessionStream::handleStreamStartReceived, this, _1));
xmppLayer->onElement.disconnect(boost::bind(&BOSHSessionStream::handleElementReceived, this, _1));
xmppLayer->onError.disconnect(boost::bind(&BOSHSessionStream::handleXMPPError, this));
xmppLayer->onWriteData.disconnect(boost::bind(&BOSHSessionStream::handleXMPPLayerDataWritten, this, _1));
delete xmppLayer;
xmppLayer = NULL;
}
void BOSHSessionStream::handlePoolXMPPDataRead(const SafeByteArray& data) {
xmppLayer->handleDataRead(data);
}
diff --git a/Swiften/Session/BOSHSessionStream.h b/Swiften/Session/BOSHSessionStream.h
index 75c1f2a..c3f6220 100644
--- a/Swiften/Session/BOSHSessionStream.h
+++ b/Swiften/Session/BOSHSessionStream.h
@@ -1,79 +1,79 @@
/*
* Copyright (c) 2011 Kevin Smith
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
*/
#pragma once
#include <boost/shared_ptr.hpp>
#include <Swiften/Base/SafeString.h>
#include <Swiften/Base/SafeByteArray.h>
#include <Swiften/Network/BOSHConnectionPool.h>
-#include <Swiften/Network/BOSHConnectionFactory.h>
#include <Swiften/Session/SessionStream.h>
#include <Swiften/Elements/StreamType.h>
#include <Swiften/EventLoop/EventOwner.h>
namespace Swift {
class TimerFactory;
class PayloadParserFactoryCollection;
class PayloadSerializerCollection;
class StreamStack;
class XMPPLayer;
class ConnectionLayer;
class CompressionLayer;
class XMLParserFactory;
class TLSContextFactory;
class EventLoop;
class BOSHSessionStream : public SessionStream, public EventOwner, public boost::enable_shared_from_this<BOSHSessionStream> {
public:
BOSHSessionStream(
- boost::shared_ptr<BOSHConnectionFactory> connectionFactory,
- PayloadParserFactoryCollection* payloadParserFactories,
- PayloadSerializerCollection* payloadSerializers,
- TLSContextFactory* tlsContextFactory,
- TimerFactory* whitespacePingLayerFactory,
- XMLParserFactory* xmlParserFactory,
- EventLoop* eventLoop,
- const std::string& to,
- const URL& boshHTTPConnectProxyURL,
- const SafeString& boshHTTPConnectProxyAuthID,
- const SafeString& boshHTTPConnectProxyAuthPassword
+ const URL& boshURL,
+ PayloadParserFactoryCollection* payloadParserFactories,
+ PayloadSerializerCollection* payloadSerializers,
+ ConnectionFactory* connectionFactory,
+ TLSContextFactory* tlsContextFactory,
+ TimerFactory* whitespacePingLayerFactory,
+ XMLParserFactory* xmlParserFactory,
+ EventLoop* eventLoop,
+ const std::string& to,
+ const URL& boshHTTPConnectProxyURL,
+ const SafeString& boshHTTPConnectProxyAuthID,
+ const SafeString& boshHTTPConnectProxyAuthPassword
);
~BOSHSessionStream();
virtual void close();
virtual bool isOpen();
virtual void writeHeader(const ProtocolHeader& header);
virtual void writeElement(boost::shared_ptr<Element>);
virtual void writeFooter();
virtual void writeData(const std::string& data);
virtual bool supportsZLibCompression();
virtual void addZLibCompression();
virtual bool supportsTLSEncryption();
virtual void addTLSEncryption();
virtual bool isTLSEncrypted();
virtual Certificate::ref getPeerCertificate() const;
virtual boost::shared_ptr<CertificateVerificationError> getPeerCertificateVerificationError() const;
virtual ByteArray getTLSFinishMessage() const;
virtual void setWhitespacePingEnabled(bool);
virtual void resetXMPPParser();
private:
void handleXMPPError();
void handleStreamStartReceived(const ProtocolHeader&);
void handleElementReceived(boost::shared_ptr<Element>);
void handlePoolXMPPDataRead(const SafeByteArray& data);
void handleXMPPLayerDataWritten(const SafeByteArray& data);
void handlePoolSessionStarted();
void handlePoolBOSHDataRead(const SafeByteArray& data);
void handlePoolBOSHDataWritten(const SafeByteArray& data);
void handlePoolSessionTerminated(BOSHError::ref condition);