summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swiften')
-rw-r--r--Swiften/Client/ClientOptions.h2
-rw-r--r--Swiften/Client/CoreClient.cpp15
-rw-r--r--Swiften/Network/BOSHConnection.cpp46
-rw-r--r--Swiften/Network/BOSHConnection.h18
-rw-r--r--Swiften/Network/BOSHConnectionPool.cpp34
-rw-r--r--Swiften/Network/BOSHConnectionPool.h11
-rw-r--r--Swiften/Network/CachingNameOnlyDomainNameResolver.cpp32
-rw-r--r--Swiften/Network/CachingNameOnlyDomainNameResolver.h32
-rw-r--r--Swiften/Network/Connector.cpp4
-rw-r--r--Swiften/Network/Connector.h7
-rw-r--r--Swiften/Network/HTTPConnectProxiedConnection.cpp35
-rw-r--r--Swiften/Network/HTTPConnectProxiedConnection.h19
-rw-r--r--Swiften/Network/HTTPConnectProxiedConnectionFactory.cpp12
-rw-r--r--Swiften/Network/HTTPConnectProxiedConnectionFactory.h19
-rw-r--r--Swiften/Network/SConscript1
-rw-r--r--Swiften/Network/StaticDomainNameResolver.cpp29
-rw-r--r--Swiften/Network/StaticDomainNameResolver.h5
-rw-r--r--Swiften/Network/UnitTest/BOSHConnectionPoolTest.cpp38
-rw-r--r--Swiften/Network/UnitTest/BOSHConnectionTest.cpp14
-rw-r--r--Swiften/Network/UnitTest/HTTPConnectProxiedConnectionTest.cpp55
-rw-r--r--Swiften/Session/BOSHSessionStream.cpp7
-rw-r--r--Swiften/Session/BOSHSessionStream.h1
22 files changed, 313 insertions, 123 deletions
diff --git a/Swiften/Client/ClientOptions.h b/Swiften/Client/ClientOptions.h
index 06bf947..fbec272 100644
--- a/Swiften/Client/ClientOptions.h
+++ b/Swiften/Client/ClientOptions.h
@@ -67,7 +67,6 @@ namespace Swift {
/**
* If non-empty, use BOSH instead of direct TCP, with the given URL.
- * The host currently needs to be specified by IP, rather than hostname.
* Default: empty (no BOSH)
*/
URL boshURL;
@@ -75,7 +74,6 @@ namespace Swift {
/**
* If non-empty, BOSH connections will try to connect over this HTTP CONNECT
* proxy instead of directly.
- * Must be specified by IP, rather than hostname.
* Default: empty (no proxy)
*/
URL boshHTTPConnectProxyURL;
diff --git a/Swiften/Client/CoreClient.cpp b/Swiften/Client/CoreClient.cpp
index 49fb9fa..de12fb7 100644
--- a/Swiften/Client/CoreClient.cpp
+++ b/Swiften/Client/CoreClient.cpp
@@ -67,7 +67,7 @@ void CoreClient::connect(const std::string& host) {
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()));
+ proxyConnectionFactories.push_back(new HTTPConnectProxiedConnectionFactory(networkFactories->getDomainNameResolver(), networkFactories->getConnectionFactory(), networkFactories->getTimerFactory(), networkFactories->getEventLoop(), networkFactories->getProxyProvider()->getHTTPConnectProxy().getAddress().toString(), networkFactories->getProxyProvider()->getHTTPConnectProxy().getPort()));
}
std::vector<ConnectionFactory*> connectionFactories(proxyConnectionFactories);
if (options.boshURL.empty()) {
@@ -87,13 +87,14 @@ void CoreClient::connect(const std::string& host) {
getPayloadParserFactories(),
getPayloadSerializers(),
networkFactories->getConnectionFactory(),
- networkFactories->getTLSContextFactory(),
- networkFactories->getTimerFactory(),
+ networkFactories->getTLSContextFactory(),
+ networkFactories->getTimerFactory(),
networkFactories->getXMLParserFactory(),
- networkFactories->getEventLoop(),
- host,
- options.boshHTTPConnectProxyURL,
- options.boshHTTPConnectProxyAuthID,
+ networkFactories->getEventLoop(),
+ networkFactories->getDomainNameResolver(),
+ 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));
diff --git a/Swiften/Network/BOSHConnection.cpp b/Swiften/Network/BOSHConnection.cpp
index ea84400..73f8ed6 100644
--- a/Swiften/Network/BOSHConnection.cpp
+++ b/Swiften/Network/BOSHConnection.cpp
@@ -17,32 +17,29 @@
#include <boost/lexical_cast.hpp>
#include <string>
-#include <Swiften/Network/ConnectionFactory.h>
#include <Swiften/Base/Log.h>
#include <Swiften/Base/String.h>
#include <Swiften/Base/Concat.h>
#include <Swiften/Base/ByteArray.h>
#include <Swiften/Network/HostAddressPort.h>
-#include <Swiften/Network/TLSConnection.h>
#include <Swiften/Parser/BOSHBodyExtractor.h>
namespace Swift {
-BOSHConnection::BOSHConnection(const URL& boshURL, ConnectionFactory* connectionFactory, XMLParserFactory* parserFactory, TLSContextFactory* tlsFactory)
- : boshURL_(boshURL),
- connectionFactory_(connectionFactory),
+BOSHConnection::BOSHConnection(const URL& boshURL, Connector::ref connector, XMLParserFactory* parserFactory)
+ : boshURL_(boshURL),
+ connector_(connector),
parserFactory_(parserFactory),
sid_(),
waitingForStartResponse_(false),
pending_(false),
- tlsFactory_(tlsFactory),
connectionReady_(false)
{
}
BOSHConnection::~BOSHConnection() {
+ cancelConnector();
if (connection_) {
- connection_->onConnectFinished.disconnect(boost::bind(&BOSHConnection::handleConnectionConnectFinished, shared_from_this(), _1));
connection_->onDataRead.disconnect(boost::bind(&BOSHConnection::handleDataRead, shared_from_this(), _1));
connection_->onDisconnected.disconnect(boost::bind(&BOSHConnection::handleDisconnected, shared_from_this(), _1));
}
@@ -50,15 +47,20 @@ BOSHConnection::~BOSHConnection() {
}
void BOSHConnection::connect() {
- Connection::ref rawConnection = connectionFactory_->createConnection();
- connection_ = (boshURL_.getScheme() == "https") ? boost::make_shared<TLSConnection>(rawConnection, tlsFactory_) : rawConnection;
- connection_->onConnectFinished.connect(boost::bind(&BOSHConnection::handleConnectionConnectFinished, shared_from_this(), _1));
- connection_->onDataRead.connect(boost::bind(&BOSHConnection::handleDataRead, shared_from_this(), _1));
- connection_->onDisconnected.connect(boost::bind(&BOSHConnection::handleDisconnected, shared_from_this(), _1));
- connection_->connect(HostAddressPort(HostAddress(boshURL_.getHost()), boshURL_.getPort()));
+ connector_->onConnectFinished.connect(boost::bind(&BOSHConnection::handleConnectFinished, shared_from_this(), _1));
+ connector_->start();
+}
+
+void BOSHConnection::cancelConnector() {
+ if (connector_) {
+ connector_->onConnectFinished.disconnect(boost::bind(&BOSHConnection::handleConnectFinished, shared_from_this(), _1));
+ connector_->stop();
+ connector_.reset();
+ }
}
void BOSHConnection::disconnect() {
+ cancelConnector();
if(connection_) {
connection_->disconnect();
sid_ = "";
@@ -78,7 +80,7 @@ void BOSHConnection::write(const SafeByteArray& data) {
write(data, false, false);
}
-std::pair<SafeByteArray, size_t> BOSHConnection::createHTTPRequest(const SafeByteArray& data, bool streamRestart, bool terminate, long rid, const std::string& sid, const URL& boshURL) {
+std::pair<SafeByteArray, size_t> BOSHConnection::createHTTPRequest(const SafeByteArray& data, bool streamRestart, bool terminate, unsigned long long rid, const std::string& sid, const URL& boshURL) {
size_t size;
std::stringstream content;
SafeByteArray contentTail = createSafeByteArray("</body>");
@@ -124,13 +126,18 @@ void BOSHConnection::write(const SafeByteArray& data, bool streamRestart, bool t
SWIFT_LOG(debug) << "write data: " << safeByteArrayToString(safeHeader) << std::endl;
}
-void BOSHConnection::handleConnectionConnectFinished(bool error) {
- connection_->onConnectFinished.disconnect(boost::bind(&BOSHConnection::handleConnectionConnectFinished, shared_from_this(), _1));
- connectionReady_ = !error;
- onConnectFinished(error);
+void BOSHConnection::handleConnectFinished(Connection::ref connection) {
+ cancelConnector();
+ connectionReady_ = connection;
+ if (connectionReady_) {
+ connection_ = connection;
+ connection_->onDataRead.connect(boost::bind(&BOSHConnection::handleDataRead, shared_from_this(), _1));
+ connection_->onDisconnected.connect(boost::bind(&BOSHConnection::handleDisconnected, shared_from_this(), _1));
+ }
+ onConnectFinished(!connectionReady_);
}
-void BOSHConnection::startStream(const std::string& to, unsigned long rid) {
+void BOSHConnection::startStream(const std::string& to, unsigned long long rid) {
assert(connectionReady_);
// Session Creation Request
std::stringstream content;
@@ -265,6 +272,7 @@ void BOSHConnection::setSID(const std::string& sid) {
}
void BOSHConnection::handleDisconnected(const boost::optional<Connection::Error>& error) {
+ cancelConnector();
onDisconnected(error);
sid_ = "";
connectionReady_ = false;
diff --git a/Swiften/Network/BOSHConnection.h b/Swiften/Network/BOSHConnection.h
index 4d53253..d9fa016 100644
--- a/Swiften/Network/BOSHConnection.h
+++ b/Swiften/Network/BOSHConnection.h
@@ -16,6 +16,7 @@
#include <boost/enable_shared_from_this.hpp>
#include <Swiften/Network/Connection.h>
+#include <Swiften/Network/Connector.h>
#include <Swiften/Network/HostAddressPort.h>
#include <Swiften/Base/String.h>
#include <Swiften/Base/URL.h>
@@ -32,7 +33,6 @@ namespace boost {
class BOSHConnectionTest;
namespace Swift {
- class ConnectionFactory;
class XMLParserFactory;
class TLSContextFactory;
@@ -54,8 +54,8 @@ namespace Swift {
class BOSHConnection : public boost::enable_shared_from_this<BOSHConnection> {
public:
typedef boost::shared_ptr<BOSHConnection> ref;
- static ref create(const URL& boshURL, ConnectionFactory* connectionFactory, XMLParserFactory* parserFactory, TLSContextFactory* tlsFactory) {
- return ref(new BOSHConnection(boshURL, connectionFactory, parserFactory, tlsFactory));
+ static ref create(const URL& boshURL, Connector::ref connector, XMLParserFactory* parserFactory) {
+ return ref(new BOSHConnection(boshURL, connector, parserFactory));
}
virtual ~BOSHConnection();
virtual void connect();
@@ -65,7 +65,7 @@ namespace Swift {
const std::string& getSID();
void setRID(unsigned long long rid);
void setSID(const std::string& sid);
- void startStream(const std::string& to, unsigned long rid);
+ void startStream(const std::string& to, unsigned long long rid);
void terminateStream();
bool isReadyToSend();
void restartStream();
@@ -83,17 +83,18 @@ namespace Swift {
private:
friend class ::BOSHConnectionTest;
- BOSHConnection(const URL& boshURL, ConnectionFactory* connectionFactory, XMLParserFactory* parserFactory, TLSContextFactory* tlsFactory);
+ BOSHConnection(const URL& boshURL, Connector::ref connector, XMLParserFactory* parserFactory);
- static std::pair<SafeByteArray, size_t> createHTTPRequest(const SafeByteArray& data, bool streamRestart, bool terminate, long rid, const std::string& sid, const URL& boshURL);
- void handleConnectionConnectFinished(bool error);
+ static std::pair<SafeByteArray, size_t> createHTTPRequest(const SafeByteArray& data, bool streamRestart, bool terminate, unsigned long long rid, const std::string& sid, const URL& boshURL);
+ void handleConnectFinished(Connection::ref);
void handleDataRead(boost::shared_ptr<SafeByteArray> data);
void handleDisconnected(const boost::optional<Connection::Error>& error);
void write(const SafeByteArray& data, bool streamRestart, bool terminate); /* FIXME: refactor */
BOSHError::Type parseTerminationCondition(const std::string& text);
+ void cancelConnector();
URL boshURL_;
- ConnectionFactory* connectionFactory_;
+ Connector::ref connector_;
XMLParserFactory* parserFactory_;
boost::shared_ptr<Connection> connection_;
std::string sid_;
@@ -101,7 +102,6 @@ namespace Swift {
unsigned long long rid_;
SafeByteArray buffer_;
bool pending_;
- TLSContextFactory* tlsFactory_;
bool connectionReady_;
};
}
diff --git a/Swiften/Network/BOSHConnectionPool.cpp b/Swiften/Network/BOSHConnectionPool.cpp
index a30bf7b..7d43f42 100644
--- a/Swiften/Network/BOSHConnectionPool.cpp
+++ b/Swiften/Network/BOSHConnectionPool.cpp
@@ -14,38 +14,43 @@
#include <Swiften/Base/SafeString.h>
#include <Swiften/Network/TLSConnectionFactory.h>
#include <Swiften/Network/HTTPConnectProxiedConnectionFactory.h>
+#include <Swiften/Network/CachingNameOnlyDomainNameResolver.h>
namespace Swift {
-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) :
+BOSHConnectionPool::BOSHConnectionPool(const URL& boshURL, DomainNameResolver* realResolver, ConnectionFactory* connectionFactoryParameter, XMLParserFactory* parserFactory, TLSContextFactory* tlsFactory, TimerFactory* timerFactory, EventLoop* eventLoop, const std::string& to, unsigned long long initialRID, const URL& boshHTTPConnectProxyURL, const SafeString& boshHTTPConnectProxyAuthID, const SafeString& boshHTTPConnectProxyAuthPassword) :
boshURL(boshURL),
- connectionFactory(connectionFactory),
+ connectionFactory(connectionFactoryParameter),
xmlParserFactory(parserFactory),
tlsFactory(tlsFactory),
+ timerFactory(timerFactory),
rid(initialRID),
pendingTerminate(false),
to(to),
requestLimit(2),
restartCount(0),
pendingRestart(false) {
- tlsConnectionFactory = NULL;
- if (boshHTTPConnectProxyURL.empty()) {
- connectProxyFactory = NULL;
- }
- else {
- ConnectionFactory* rawFactory = connectionFactory;
+
+ if (!boshHTTPConnectProxyURL.empty()) {
if (boshHTTPConnectProxyURL.getScheme() == "https") {
- tlsConnectionFactory = new TLSConnectionFactory(tlsFactory, rawFactory);
- rawFactory = tlsConnectionFactory;
+ connectionFactory = new TLSConnectionFactory(tlsFactory, connectionFactory);
+ myConnectionFactories.push_back(connectionFactory);
}
- connectProxyFactory = new HTTPConnectProxiedConnectionFactory(rawFactory, HostAddressPort(HostAddress(boshHTTPConnectProxyURL.getHost()), boshHTTPConnectProxyURL.getPort()), boshHTTPConnectProxyAuthID, boshHTTPConnectProxyAuthPassword);
+ connectionFactory = new HTTPConnectProxiedConnectionFactory(realResolver, connectionFactory, timerFactory, eventLoop, boshHTTPConnectProxyURL.getHost(), boshHTTPConnectProxyURL.getPort(), boshHTTPConnectProxyAuthID, boshHTTPConnectProxyAuthPassword);
}
+ if (boshURL.getScheme() == "https") {
+ connectionFactory = new TLSConnectionFactory(tlsFactory, connectionFactory);
+ myConnectionFactories.push_back(connectionFactory);
+ }
+ resolver = new CachingNameOnlyDomainNameResolver(realResolver, eventLoop);
createConnection();
}
BOSHConnectionPool::~BOSHConnectionPool() {
close();
- delete connectProxyFactory;
- delete tlsConnectionFactory;
+ foreach (ConnectionFactory* factory, myConnectionFactories) {
+ delete factory;
+ }
+ delete resolver;
}
void BOSHConnectionPool::write(const SafeByteArray& data) {
@@ -209,7 +214,8 @@ void BOSHConnectionPool::handleConnectionDisconnected(bool error, BOSHConnection
}
boost::shared_ptr<BOSHConnection> BOSHConnectionPool::createConnection() {
- BOSHConnection::ref connection = BOSHConnection::create(boshURL, connectProxyFactory ? connectProxyFactory : connectionFactory, xmlParserFactory, tlsFactory);
+ Connector::ref connector = Connector::create(boshURL.getHost(), resolver, connectionFactory, timerFactory, boshURL.getPort());
+ BOSHConnection::ref connection = BOSHConnection::create(boshURL, connector, xmlParserFactory);
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));
diff --git a/Swiften/Network/BOSHConnectionPool.h b/Swiften/Network/BOSHConnectionPool.h
index cc354b8..8bc0a7c 100644
--- a/Swiften/Network/BOSHConnectionPool.h
+++ b/Swiften/Network/BOSHConnectionPool.h
@@ -15,10 +15,12 @@
namespace Swift {
class HTTPConnectProxiedConnectionFactory;
class TLSConnectionFactory;
+ class CachingNameOnlyDomainNameResolver;
+ class EventLoop;
class BOSHConnectionPool : public boost::bsignals::trackable {
public:
- 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(const URL& boshURL, DomainNameResolver* resolver, ConnectionFactory* connectionFactory, XMLParserFactory* parserFactory, TLSContextFactory* tlsFactory, TimerFactory* timerFactory, EventLoop* eventLoop, const std::string& to, unsigned long long initialRID, const URL& boshHTTPConnectProxyURL, const SafeString& boshHTTPConnectProxyAuthID, const SafeString& boshHTTPConnectProxyAuthPassword);
~BOSHConnectionPool();
void write(const SafeByteArray& data);
void writeFooter();
@@ -52,16 +54,17 @@ namespace Swift {
ConnectionFactory* connectionFactory;
XMLParserFactory* xmlParserFactory;
TLSContextFactory* tlsFactory;
+ TimerFactory* timerFactory;
std::vector<BOSHConnection::ref> connections;
std::string sid;
- unsigned long rid;
+ unsigned long long rid;
std::vector<SafeByteArray> dataQueue;
bool pendingTerminate;
std::string to;
size_t requestLimit;
int restartCount;
bool pendingRestart;
- HTTPConnectProxiedConnectionFactory* connectProxyFactory;
- TLSConnectionFactory* tlsConnectionFactory;
+ std::vector<ConnectionFactory*> myConnectionFactories;
+ CachingNameOnlyDomainNameResolver* resolver;
};
}
diff --git a/Swiften/Network/CachingNameOnlyDomainNameResolver.cpp b/Swiften/Network/CachingNameOnlyDomainNameResolver.cpp
new file mode 100644
index 0000000..a83bebd
--- /dev/null
+++ b/Swiften/Network/CachingNameOnlyDomainNameResolver.cpp
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2012 Kevin Smith
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#include <Swiften/Network/CachingNameOnlyDomainNameResolver.h>
+
+#include <boost/smart_ptr/make_shared.hpp>
+
+namespace Swift {
+CachingNameOnlyDomainNameResolver::CachingNameOnlyDomainNameResolver(DomainNameResolver* realResolver, EventLoop* eventLoop) : realResolver(realResolver) {
+ staticResolver = boost::make_shared<StaticDomainNameResolver>(eventLoop);
+}
+
+CachingNameOnlyDomainNameResolver::~CachingNameOnlyDomainNameResolver() {
+
+}
+
+DomainNameServiceQuery::ref CachingNameOnlyDomainNameResolver::createServiceQuery(const std::string& name) {
+ return staticResolver->createServiceQuery(name);
+}
+
+DomainNameAddressQuery::ref CachingNameOnlyDomainNameResolver::createAddressQuery(const std::string& name) {
+ return realResolver->createAddressQuery(name);
+}
+
+void CachingNameOnlyDomainNameResolver::handleAddressQueryResult(const std::string hostname, const std::vector<HostAddress>& address, boost::optional<DomainNameResolveError> error) {
+ //FIXME: Cache
+}
+
+}
diff --git a/Swiften/Network/CachingNameOnlyDomainNameResolver.h b/Swiften/Network/CachingNameOnlyDomainNameResolver.h
new file mode 100644
index 0000000..d9e78e6
--- /dev/null
+++ b/Swiften/Network/CachingNameOnlyDomainNameResolver.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2012 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/Network/DomainNameResolver.h>
+#include <Swiften/Network/StaticDomainNameResolver.h>
+
+
+namespace Swift {
+ class EventLoop;
+ class CachingNameOnlyDomainNameResolver : public DomainNameResolver {
+ public:
+ CachingNameOnlyDomainNameResolver(DomainNameResolver* realResolver, EventLoop* eventLoop);
+ ~CachingNameOnlyDomainNameResolver();
+
+ virtual DomainNameServiceQuery::ref createServiceQuery(const std::string& name);
+ virtual DomainNameAddressQuery::ref createAddressQuery(const std::string& name);
+
+ private:
+ void handleAddressQueryResult(const std::string hostname, const std::vector<HostAddress>& address, boost::optional<DomainNameResolveError> error);
+
+ private:
+ DomainNameResolver* realResolver;
+ boost::shared_ptr<StaticDomainNameResolver> staticResolver;
+ };
+}
diff --git a/Swiften/Network/Connector.cpp b/Swiften/Network/Connector.cpp
index 8f35aba..378875b 100644
--- a/Swiften/Network/Connector.cpp
+++ b/Swiften/Network/Connector.cpp
@@ -17,7 +17,7 @@
namespace Swift {
-Connector::Connector(const std::string& hostname, DomainNameResolver* resolver, ConnectionFactory* connectionFactory, TimerFactory* timerFactory) : hostname(hostname), resolver(resolver), connectionFactory(connectionFactory), timerFactory(timerFactory), timeoutMilliseconds(0), queriedAllServices(true) {
+Connector::Connector(const std::string& hostname, DomainNameResolver* resolver, ConnectionFactory* connectionFactory, TimerFactory* timerFactory, int defaultPort) : hostname(hostname), resolver(resolver), connectionFactory(connectionFactory), timerFactory(timerFactory), defaultPort(defaultPort), timeoutMilliseconds(0), queriedAllServices(true) {
}
void Connector::setTimeoutMilliseconds(int milliseconds) {
@@ -105,7 +105,7 @@ void Connector::tryNextAddress() {
HostAddress address = addressQueryResults.front();
addressQueryResults.pop_front();
- int port = 5222;
+ int port = defaultPort;
if (!serviceQueryResults.empty()) {
port = serviceQueryResults.front().port;
}
diff --git a/Swiften/Network/Connector.h b/Swiften/Network/Connector.h
index 8336299..8f2c359 100644
--- a/Swiften/Network/Connector.h
+++ b/Swiften/Network/Connector.h
@@ -27,8 +27,8 @@ namespace Swift {
public:
typedef boost::shared_ptr<Connector> ref;
- static Connector::ref create(const std::string& hostname, DomainNameResolver* resolver, ConnectionFactory* connectionFactory, TimerFactory* timerFactory) {
- return ref(new Connector(hostname, resolver, connectionFactory, timerFactory));
+ static Connector::ref create(const std::string& hostname, DomainNameResolver* resolver, ConnectionFactory* connectionFactory, TimerFactory* timerFactory, int defaultPort = 5222) {
+ return ref(new Connector(hostname, resolver, connectionFactory, timerFactory, defaultPort));
}
void setTimeoutMilliseconds(int milliseconds);
@@ -38,7 +38,7 @@ namespace Swift {
boost::signal<void (boost::shared_ptr<Connection>)> onConnectFinished;
private:
- Connector(const std::string& hostname, DomainNameResolver*, ConnectionFactory*, TimerFactory*);
+ Connector(const std::string& hostname, DomainNameResolver*, ConnectionFactory*, TimerFactory*, int defaultPort);
void handleServiceQueryResult(const std::vector<DomainNameServiceQuery::Result>& result);
void handleAddressQueryResult(const std::vector<HostAddress>& address, boost::optional<DomainNameResolveError> error);
@@ -58,6 +58,7 @@ namespace Swift {
DomainNameResolver* resolver;
ConnectionFactory* connectionFactory;
TimerFactory* timerFactory;
+ int defaultPort;
int timeoutMilliseconds;
boost::shared_ptr<Timer> timer;
boost::shared_ptr<DomainNameServiceQuery> serviceQuery;
diff --git a/Swiften/Network/HTTPConnectProxiedConnection.cpp b/Swiften/Network/HTTPConnectProxiedConnection.cpp
index 9ef63f0..512381f 100644
--- a/Swiften/Network/HTTPConnectProxiedConnection.cpp
+++ b/Swiften/Network/HTTPConnectProxiedConnection.cpp
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (c) 2011 Kevin Smith
+ * Copyright (c) 2011-2012 Kevin Smith
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
*/
@@ -24,17 +24,20 @@
#include <Swiften/Base/ByteArray.h>
#include <Swiften/Network/HostAddressPort.h>
#include <Swiften/Network/ConnectionFactory.h>
+#include <Swiften/Network/CachingNameOnlyDomainNameResolver.h>
#include <Swiften/StringCodecs/Base64.h>
using namespace Swift;
-HTTPConnectProxiedConnection::HTTPConnectProxiedConnection(ConnectionFactory* connectionFactory, HostAddressPort proxy, const SafeString& authID, const SafeString& authPassword) : connectionFactory_(connectionFactory), proxy_(proxy), server_(HostAddressPort(HostAddress("0.0.0.0"), 0)), authID_(authID), authPassword_(authPassword) {
+HTTPConnectProxiedConnection::HTTPConnectProxiedConnection(DomainNameResolver* resolver, ConnectionFactory* connectionFactory, TimerFactory* timerFactory, EventLoop* eventLoop, const std::string& proxyHost, int proxyPort, const SafeString& authID, const SafeString& authPassword) : connectionFactory_(connectionFactory), timerFactory_(timerFactory), proxyHost_(proxyHost), proxyPort_(proxyPort), server_(HostAddressPort(HostAddress("0.0.0.0"), 0)), authID_(authID), authPassword_(authPassword) {
+ resolver_ = new CachingNameOnlyDomainNameResolver(resolver, eventLoop);
connected_ = false;
}
HTTPConnectProxiedConnection::~HTTPConnectProxiedConnection() {
+ cancelConnector();
+ delete resolver_;
if (connection_) {
- connection_->onConnectFinished.disconnect(boost::bind(&HTTPConnectProxiedConnection::handleConnectionConnectFinished, shared_from_this(), _1));
connection_->onDataRead.disconnect(boost::bind(&HTTPConnectProxiedConnection::handleDataRead, shared_from_this(), _1));
connection_->onDisconnected.disconnect(boost::bind(&HTTPConnectProxiedConnection::handleDisconnected, shared_from_this(), _1));
}
@@ -44,13 +47,19 @@ HTTPConnectProxiedConnection::~HTTPConnectProxiedConnection() {
}
}
+void HTTPConnectProxiedConnection::cancelConnector() {
+ if (connector_) {
+ connector_->onConnectFinished.disconnect(boost::bind(&HTTPConnectProxiedConnection::handleConnectFinished, shared_from_this(), _1));
+ connector_->stop();
+ connector_.reset();
+ }
+}
+
void HTTPConnectProxiedConnection::connect(const HostAddressPort& server) {
server_ = server;
- connection_ = connectionFactory_->createConnection();
- connection_->onConnectFinished.connect(boost::bind(&HTTPConnectProxiedConnection::handleConnectionConnectFinished, shared_from_this(), _1));
- connection_->onDataRead.connect(boost::bind(&HTTPConnectProxiedConnection::handleDataRead, shared_from_this(), _1));
- connection_->onDisconnected.connect(boost::bind(&HTTPConnectProxiedConnection::handleDisconnected, shared_from_this(), _1));
- connection_->connect(proxy_);
+ connector_ = Connector::create(proxyHost_, resolver_, connectionFactory_, timerFactory_, proxyPort_);
+ connector_->onConnectFinished.connect(boost::bind(&HTTPConnectProxiedConnection::handleConnectFinished, shared_from_this(), _1));
+ connector_->start();
}
void HTTPConnectProxiedConnection::listen() {
@@ -71,9 +80,13 @@ void HTTPConnectProxiedConnection::write(const SafeByteArray& data) {
connection_->write(data);
}
-void HTTPConnectProxiedConnection::handleConnectionConnectFinished(bool error) {
- connection_->onConnectFinished.disconnect(boost::bind(&HTTPConnectProxiedConnection::handleConnectionConnectFinished, shared_from_this(), _1));
- if (!error) {
+void HTTPConnectProxiedConnection::handleConnectFinished(Connection::ref connection) {
+ cancelConnector();
+ if (connection) {
+ connection_ = connection;
+ connection_->onDataRead.connect(boost::bind(&HTTPConnectProxiedConnection::handleDataRead, shared_from_this(), _1));
+ connection_->onDisconnected.connect(boost::bind(&HTTPConnectProxiedConnection::handleDisconnected, shared_from_this(), _1));
+
std::stringstream connect;
connect << "CONNECT " << server_.getAddress().toString() << ":" << server_.getPort() << " HTTP/1.1\r\n";
SafeByteArray data = createSafeByteArray(connect.str());
diff --git a/Swiften/Network/HTTPConnectProxiedConnection.h b/Swiften/Network/HTTPConnectProxiedConnection.h
index 02d3edd..8318ecc 100644
--- a/Swiften/Network/HTTPConnectProxiedConnection.h
+++ b/Swiften/Network/HTTPConnectProxiedConnection.h
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (c) 2011 Kevin Smith
+ * Copyright (c) 2011-2012 Kevin Smith
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
*/
@@ -16,6 +16,7 @@
#include <boost/enable_shared_from_this.hpp>
#include <Swiften/Network/Connection.h>
+#include <Swiften/Network/Connector.h>
#include <Swiften/Network/HostAddressPort.h>
#include <Swiften/Base/SafeString.h>
@@ -28,6 +29,7 @@ namespace boost {
namespace Swift {
class ConnectionFactory;
+ class EventLoop;
class HTTPConnectProxiedConnection : public Connection, public boost::enable_shared_from_this<HTTPConnectProxiedConnection> {
public:
@@ -35,8 +37,8 @@ namespace Swift {
~HTTPConnectProxiedConnection();
- static ref create(ConnectionFactory* connectionFactory, HostAddressPort proxy, const SafeString& authID, const SafeString& authPassword) {
- return ref(new HTTPConnectProxiedConnection(connectionFactory, proxy, authID, authPassword));
+ static ref create(DomainNameResolver* resolver, ConnectionFactory* connectionFactory, TimerFactory* timerFactory, EventLoop* eventLoop, const std::string& proxyHost, int proxyPort, const SafeString& authID, const SafeString& authPassword) {
+ return ref(new HTTPConnectProxiedConnection(resolver, connectionFactory, timerFactory, eventLoop, proxyHost, proxyPort, authID, authPassword));
}
virtual void listen();
@@ -46,19 +48,24 @@ namespace Swift {
virtual HostAddressPort getLocalAddress() const;
private:
- HTTPConnectProxiedConnection(ConnectionFactory* connectionFactory, HostAddressPort proxy, const SafeString& authID, const SafeString& authPassword);
+ HTTPConnectProxiedConnection(DomainNameResolver* resolver, ConnectionFactory* connectionFactory, TimerFactory* timerFactory, EventLoop* eventLoop, const std::string& proxyHost, int proxyPort, const SafeString& authID, const SafeString& authPassword);
- void handleConnectionConnectFinished(bool error);
+ void handleConnectFinished(Connection::ref connection);
void handleDataRead(boost::shared_ptr<SafeByteArray> data);
void handleDisconnected(const boost::optional<Error>& error);
+ void cancelConnector();
private:
bool connected_;
+ DomainNameResolver* resolver_;
ConnectionFactory* connectionFactory_;
- HostAddressPort proxy_;
+ TimerFactory* timerFactory_;
+ std::string proxyHost_;
+ int proxyPort_;
HostAddressPort server_;
SafeByteArray authID_;
SafeByteArray authPassword_;
+ Connector::ref connector_;
boost::shared_ptr<Connection> connection_;
};
}
diff --git a/Swiften/Network/HTTPConnectProxiedConnectionFactory.cpp b/Swiften/Network/HTTPConnectProxiedConnectionFactory.cpp
index 6ad0228..14d702c 100644
--- a/Swiften/Network/HTTPConnectProxiedConnectionFactory.cpp
+++ b/Swiften/Network/HTTPConnectProxiedConnectionFactory.cpp
@@ -1,4 +1,10 @@
/*
+ * Copyright (c) 2012 Kevin Smith
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+/*
* Copyright (c) 2010-2011 Thilo Cestonaro
* Licensed under the simplified BSD license.
* See Documentation/Licenses/BSD-simplified.txt for more information.
@@ -10,15 +16,15 @@
namespace Swift {
-HTTPConnectProxiedConnectionFactory::HTTPConnectProxiedConnectionFactory(ConnectionFactory* connectionFactory, const HostAddressPort& proxy) : connectionFactory_(connectionFactory), proxy_(proxy), authID_(""), authPassword_("") {
+HTTPConnectProxiedConnectionFactory::HTTPConnectProxiedConnectionFactory(DomainNameResolver* resolver, ConnectionFactory* connectionFactory, TimerFactory* timerFactory, EventLoop* eventLoop, const std::string& proxyHost, int proxyPort) : resolver_(resolver), connectionFactory_(connectionFactory), timerFactory_(timerFactory), eventLoop_(eventLoop), proxyHost_(proxyHost), proxyPort_(proxyPort), authID_(""), authPassword_("") {
}
-HTTPConnectProxiedConnectionFactory::HTTPConnectProxiedConnectionFactory(ConnectionFactory* connectionFactory, const HostAddressPort& proxy, const SafeString& authID, const SafeString& authPassword) : connectionFactory_(connectionFactory), proxy_(proxy), authID_(authID), authPassword_(authPassword) {
+HTTPConnectProxiedConnectionFactory::HTTPConnectProxiedConnectionFactory(DomainNameResolver* resolver, ConnectionFactory* connectionFactory, TimerFactory* timerFactory, EventLoop* eventLoop, const std::string& proxyHost, int proxyPort, const SafeString& authID, const SafeString& authPassword) : resolver_(resolver), connectionFactory_(connectionFactory), timerFactory_(timerFactory), eventLoop_(eventLoop), proxyHost_(proxyHost), proxyPort_(proxyPort), authID_(authID), authPassword_(authPassword) {
}
boost::shared_ptr<Connection> HTTPConnectProxiedConnectionFactory::createConnection() {
- return HTTPConnectProxiedConnection::create(connectionFactory_, proxy_, authID_, authPassword_);
+ return HTTPConnectProxiedConnection::create(resolver_, connectionFactory_, timerFactory_, eventLoop_, proxyHost_, proxyPort_, authID_, authPassword_);
}
}
diff --git a/Swiften/Network/HTTPConnectProxiedConnectionFactory.h b/Swiften/Network/HTTPConnectProxiedConnectionFactory.h
index ef3af66..7d003e8 100644
--- a/Swiften/Network/HTTPConnectProxiedConnectionFactory.h
+++ b/Swiften/Network/HTTPConnectProxiedConnectionFactory.h
@@ -1,4 +1,10 @@
/*
+ * Copyright (c) 2012 Kevin Smith
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+/*
* Copyright (c) 2010-2011 Thilo Cestonaro
* Licensed under the simplified BSD license.
* See Documentation/Licenses/BSD-simplified.txt for more information.
@@ -11,16 +17,23 @@
#include <Swiften/Base/SafeString.h>
namespace Swift {
+ class DomainNameResolver;
+ class TimerFactory;
+ class EventLoop;
class HTTPConnectProxiedConnectionFactory : public ConnectionFactory {
public:
- HTTPConnectProxiedConnectionFactory(ConnectionFactory* connectionFactory, const HostAddressPort& proxy);
- HTTPConnectProxiedConnectionFactory(ConnectionFactory* connectionFactory, const HostAddressPort& proxy, const SafeString& authID, const SafeString& authPassword);
+ HTTPConnectProxiedConnectionFactory(DomainNameResolver* resolver, ConnectionFactory* connectionFactory, TimerFactory* timerFactory, EventLoop* eventLoop, const std::string& proxyHost, int proxyPort);
+ HTTPConnectProxiedConnectionFactory(DomainNameResolver* resolver, ConnectionFactory* connectionFactory, TimerFactory* timerFactory, EventLoop* eventLoop, const std::string& proxyHost, int proxyPort, const SafeString& authID, const SafeString& authPassword);
virtual boost::shared_ptr<Connection> createConnection();
private:
+ DomainNameResolver* resolver_;
ConnectionFactory* connectionFactory_;
- HostAddressPort proxy_;
+ TimerFactory* timerFactory_;
+ EventLoop* eventLoop_;
+ std::string proxyHost_;
+ int proxyPort_;
SafeString authID_;
SafeString authPassword_;
};
diff --git a/Swiften/Network/SConscript b/Swiften/Network/SConscript
index 6975fe6..0d0abbd 100644
--- a/Swiften/Network/SConscript
+++ b/Swiften/Network/SConscript
@@ -17,6 +17,7 @@ sourceList = [
"BoostIOServiceThread.cpp",
"BOSHConnection.cpp",
"BOSHConnectionPool.cpp",
+ "CachingNameOnlyDomainNameResolver.cpp",
"ConnectionFactory.cpp",
"ConnectionServer.cpp",
"ConnectionServerFactory.cpp",
diff --git a/Swiften/Network/StaticDomainNameResolver.cpp b/Swiften/Network/StaticDomainNameResolver.cpp
index 76ab411..ee18ee5 100644
--- a/Swiften/Network/StaticDomainNameResolver.cpp
+++ b/Swiften/Network/StaticDomainNameResolver.cpp
@@ -10,13 +10,14 @@
#include <boost/lexical_cast.hpp>
#include <Swiften/Network/DomainNameResolveError.h>
+#include <Swiften/EventLoop/EventOwner.h>
#include <string>
using namespace Swift;
namespace {
struct ServiceQuery : public DomainNameServiceQuery, public boost::enable_shared_from_this<ServiceQuery> {
- ServiceQuery(const std::string& service, Swift::StaticDomainNameResolver* resolver, EventLoop* eventLoop) : eventLoop(eventLoop), service(service), resolver(resolver) {}
+ ServiceQuery(const std::string& service, Swift::StaticDomainNameResolver* resolver, EventLoop* eventLoop, boost::shared_ptr<EventOwner> owner) : eventLoop(eventLoop), service(service), resolver(resolver), owner(owner) {}
virtual void run() {
if (!resolver->getIsResponsive()) {
@@ -28,7 +29,7 @@ namespace {
results.push_back(i->second);
}
}
- eventLoop->postEvent(boost::bind(&ServiceQuery::emitOnResult, shared_from_this(), results));
+ eventLoop->postEvent(boost::bind(&ServiceQuery::emitOnResult, shared_from_this(), results), owner);
}
void emitOnResult(std::vector<DomainNameServiceQuery::Result> results) {
@@ -38,10 +39,11 @@ namespace {
EventLoop* eventLoop;
std::string service;
StaticDomainNameResolver* resolver;
+ boost::shared_ptr<EventOwner> owner;
};
struct AddressQuery : public DomainNameAddressQuery, public boost::enable_shared_from_this<AddressQuery> {
- AddressQuery(const std::string& host, StaticDomainNameResolver* resolver, EventLoop* eventLoop) : eventLoop(eventLoop), host(host), resolver(resolver) {}
+ AddressQuery(const std::string& host, StaticDomainNameResolver* resolver, EventLoop* eventLoop, boost::shared_ptr<EventOwner> owner) : eventLoop(eventLoop), host(host), resolver(resolver), owner(owner) {}
virtual void run() {
if (!resolver->getIsResponsive()) {
@@ -53,7 +55,7 @@ namespace {
boost::bind(&AddressQuery::emitOnResult, shared_from_this(), i->second, boost::optional<DomainNameResolveError>()));
}
else {
- eventLoop->postEvent(boost::bind(&AddressQuery::emitOnResult, shared_from_this(), std::vector<HostAddress>(), boost::optional<DomainNameResolveError>(DomainNameResolveError())));
+ eventLoop->postEvent(boost::bind(&AddressQuery::emitOnResult, shared_from_this(), std::vector<HostAddress>(), boost::optional<DomainNameResolveError>(DomainNameResolveError())), owner);
}
}
@@ -64,12 +66,25 @@ namespace {
EventLoop* eventLoop;
std::string host;
StaticDomainNameResolver* resolver;
+ boost::shared_ptr<EventOwner> owner;
};
}
+class StaticDomainNameResolverEventOwner : public EventOwner {
+ public:
+ ~StaticDomainNameResolverEventOwner() {
+
+ }
+};
+
+
namespace Swift {
-StaticDomainNameResolver::StaticDomainNameResolver(EventLoop* eventLoop) : eventLoop(eventLoop), isResponsive(true) {
+StaticDomainNameResolver::StaticDomainNameResolver(EventLoop* eventLoop) : eventLoop(eventLoop), isResponsive(true), owner(new StaticDomainNameResolverEventOwner()) {
+}
+
+StaticDomainNameResolver::~StaticDomainNameResolver() {
+ eventLoop->removeEventsFromOwner(owner);
}
void StaticDomainNameResolver::addAddress(const std::string& domain, const HostAddress& address) {
@@ -94,11 +109,11 @@ void StaticDomainNameResolver::addXMPPClientService(const std::string& domain, c
}
boost::shared_ptr<DomainNameServiceQuery> StaticDomainNameResolver::createServiceQuery(const std::string& name) {
- return boost::shared_ptr<DomainNameServiceQuery>(new ServiceQuery(name, this, eventLoop));
+ return boost::shared_ptr<DomainNameServiceQuery>(new ServiceQuery(name, this, eventLoop, owner));
}
boost::shared_ptr<DomainNameAddressQuery> StaticDomainNameResolver::createAddressQuery(const std::string& name) {
- return boost::shared_ptr<DomainNameAddressQuery>(new AddressQuery(name, this, eventLoop));
+ return boost::shared_ptr<DomainNameAddressQuery>(new AddressQuery(name, this, eventLoop, owner));
}
}
diff --git a/Swiften/Network/StaticDomainNameResolver.h b/Swiften/Network/StaticDomainNameResolver.h
index a72db7c..29d1629 100644
--- a/Swiften/Network/StaticDomainNameResolver.h
+++ b/Swiften/Network/StaticDomainNameResolver.h
@@ -17,8 +17,6 @@
#include <Swiften/EventLoop/EventLoop.h>
namespace Swift {
-
-
class StaticDomainNameResolver : public DomainNameResolver {
public:
typedef std::map<std::string, std::vector<HostAddress> > AddressesMap;
@@ -26,6 +24,7 @@ namespace Swift {
public:
StaticDomainNameResolver(EventLoop* eventLoop);
+ ~StaticDomainNameResolver();
void addAddress(const std::string& domain, const HostAddress& address);
void addService(const std::string& service, const DomainNameServiceQuery::Result& result);
@@ -50,11 +49,11 @@ namespace Swift {
virtual boost::shared_ptr<DomainNameServiceQuery> createServiceQuery(const std::string& name);
virtual boost::shared_ptr<DomainNameAddressQuery> createAddressQuery(const std::string& name);
-
private:
EventLoop* eventLoop;
bool isResponsive;
AddressesMap addresses;
ServicesCollection services;
+ boost::shared_ptr<EventOwner> owner;
};
}
diff --git a/Swiften/Network/UnitTest/BOSHConnectionPoolTest.cpp b/Swiften/Network/UnitTest/BOSHConnectionPoolTest.cpp
index 1bfee10..82762c5 100644
--- a/Swiften/Network/UnitTest/BOSHConnectionPoolTest.cpp
+++ b/Swiften/Network/UnitTest/BOSHConnectionPoolTest.cpp
@@ -21,13 +21,18 @@
#include <Swiften/Network/BOSHConnection.h>
#include <Swiften/Network/BOSHConnectionPool.h>
#include <Swiften/Network/HostAddressPort.h>
+#include <Swiften/Network/StaticDomainNameResolver.h>
+#include <Swiften/Network/DummyTimerFactory.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);
@@ -64,11 +69,16 @@ class BOSHConnectionPoolTest : public CppUnit::TestFixture {
xmppDataRead.clear();
boshDataRead.clear();
boshDataWritten.clear();
+ resolver = new StaticDomainNameResolver(eventLoop);
+ resolver->addAddress(to, HostAddress("127.0.0.1"));
+ timerFactory = new DummyTimerFactory();
}
void tearDown() {
eventLoop->processEvents();
delete connectionFactory;
+ delete resolver;
+ delete timerFactory;
delete eventLoop;
}
@@ -91,10 +101,13 @@ class BOSHConnectionPoolTest : public CppUnit::TestFixture {
CPPUNIT_ASSERT_EQUAL(st(1), connectionFactory->connections.size());
eventLoop->processEvents();
readResponse(initial, connectionFactory->connections[0]);
+ eventLoop->processEvents();
testling->write(createSafeByteArray("<blah/>"));
+ eventLoop->processEvents();
CPPUNIT_ASSERT_EQUAL(st(1), connectionFactory->connections.size());
testling->write(createSafeByteArray("<bleh/>"));
eventLoop->processEvents();
+ eventLoop->processEvents();
CPPUNIT_ASSERT_EQUAL(st(2), connectionFactory->connections.size());
}
@@ -125,15 +138,20 @@ class BOSHConnectionPoolTest : public CppUnit::TestFixture {
CPPUNIT_ASSERT_EQUAL(st(1), boshDataWritten.size()); /* Connection finished, stream header sent */
readResponse(initial, connectionFactory->connections[0]);
+ eventLoop->processEvents();
CPPUNIT_ASSERT_EQUAL(st(1), connectionFactory->connections.size());
CPPUNIT_ASSERT_EQUAL(st(1), boshDataWritten.size()); /* Don't respond to initial data with a holding call */
testling->restartStream();
+ eventLoop->processEvents();
readResponse("<body/>", connectionFactory->connections[0]);
+ eventLoop->processEvents();
testling->restartStream();
+ eventLoop->processEvents();
testling->write(createSafeByteArray("<blah/>"));
+ eventLoop->processEvents();
CPPUNIT_ASSERT_EQUAL(st(2), connectionFactory->connections.size());
CPPUNIT_ASSERT_EQUAL(st(3), boshDataWritten.size()); /* New connection isn't up yet. */
@@ -142,6 +160,7 @@ class BOSHConnectionPoolTest : public CppUnit::TestFixture {
CPPUNIT_ASSERT_EQUAL(st(4), boshDataWritten.size()); /* New connection ready. */
testling->write(createSafeByteArray("<bleh/>"));
+ eventLoop->processEvents();
testling->write(createSafeByteArray("<bluh/>"));
CPPUNIT_ASSERT_EQUAL(st(4), boshDataWritten.size()); /* New data can't be sent, no free connections. */
eventLoop->processEvents();
@@ -167,6 +186,7 @@ class BOSHConnectionPoolTest : public CppUnit::TestFixture {
rid++;
testling->restartStream();
+ eventLoop->processEvents();
readResponse("<body/>", connectionFactory->connections[0]);
rid++;
@@ -199,6 +219,7 @@ class BOSHConnectionPoolTest : public CppUnit::TestFixture {
rid++;
testling->write(createSafeByteArray("<bleh/>"));
+ eventLoop->processEvents();
CPPUNIT_ASSERT(c0->pending);
CPPUNIT_ASSERT(c1->pending);
CPPUNIT_ASSERT_EQUAL(st(6), boshDataWritten.size()); /* data */
@@ -214,6 +235,7 @@ class BOSHConnectionPoolTest : public CppUnit::TestFixture {
void testSession() {
to = "prosody.doomsong.co.uk";
+ resolver->addAddress("prosody.doomsong.co.uk", HostAddress("127.0.0.1"));
path = "http-bind/";
boshURL = URL("http", to, 5280, path);
@@ -258,15 +280,18 @@ class BOSHConnectionPoolTest : public CppUnit::TestFixture {
boost::shared_ptr<MockConnection> c0;
PoolRef testling = createTestling();
- c0 = connectionFactory->connections[0];
CPPUNIT_ASSERT_EQUAL(st(1), connectionFactory->connections.size());
- eventLoop->processEvents();
+ c0 = connectionFactory->connections[0];
readResponse(initial, c0);
+ eventLoop->processEvents();
CPPUNIT_ASSERT_EQUAL(st(1), boshDataWritten.size()); /* Shouldn't have sent anything extra */
+ eventLoop->processEvents();
testling->restartStream();
+ eventLoop->processEvents();
CPPUNIT_ASSERT_EQUAL(st(2), boshDataWritten.size());
readResponse("<body></body>", c0);
+ eventLoop->processEvents();
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];
@@ -279,12 +304,17 @@ class BOSHConnectionPoolTest : public CppUnit::TestFixture {
private:
PoolRef createTestling() {
- PoolRef pool = boost::make_shared<BOSHConnectionPool>(boshURL, connectionFactory, &parserFactory, static_cast<TLSContextFactory*>(NULL), to, initialRID, URL(), "", "");
+ BOSHConnectionPool* a = new BOSHConnectionPool(boshURL, resolver, connectionFactory, &parserFactory, static_cast<TLSContextFactory*>(NULL), timerFactory, eventLoop, to, initialRID, URL(), SafeString(""), SafeString(""));
+ PoolRef pool(a);
+ //FIXME: Remko - why does the above work, but the below fail?
+ //PoolRef pool = boost::make_shared<BOSHConnectionPool>(boshURL, resolver, connectionFactory, &parserFactory, static_cast<TLSContextFactory*>(NULL), timerFactory, eventLoop, to, initialRID, URL(), SafeString(""), SafeString(""));
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));
+ eventLoop->processEvents();
+ eventLoop->processEvents();
return pool;
}
@@ -406,6 +436,8 @@ class BOSHConnectionPoolTest : public CppUnit::TestFixture {
std::vector<std::string> boshDataRead;
std::vector<std::string> boshDataWritten;
PlatformXMLParserFactory parserFactory;
+ StaticDomainNameResolver* resolver;
+ TimerFactory* timerFactory;
std::string to;
std::string path;
std::string port;
diff --git a/Swiften/Network/UnitTest/BOSHConnectionTest.cpp b/Swiften/Network/UnitTest/BOSHConnectionTest.cpp
index 8062bea..e0dc0bf 100644
--- a/Swiften/Network/UnitTest/BOSHConnectionTest.cpp
+++ b/Swiften/Network/UnitTest/BOSHConnectionTest.cpp
@@ -20,6 +20,8 @@
#include <Swiften/Network/ConnectionFactory.h>
#include <Swiften/Network/BOSHConnection.h>
#include <Swiften/Network/HostAddressPort.h>
+#include <Swiften/Network/StaticDomainNameResolver.h>
+#include <Swiften/Network/DummyTimerFactory.h>
#include <Swiften/EventLoop/DummyEventLoop.h>
#include <Swiften/Parser/PlatformXMLParserFactory.h>
@@ -43,6 +45,8 @@ class BOSHConnectionTest : public CppUnit::TestFixture {
void setUp() {
eventLoop = new DummyEventLoop();
connectionFactory = new MockConnectionFactory(eventLoop);
+ resolver = new StaticDomainNameResolver(eventLoop);
+ timerFactory = new DummyTimerFactory();
connectFinished = false;
disconnected = false;
disconnectedError = false;
@@ -52,7 +56,9 @@ class BOSHConnectionTest : public CppUnit::TestFixture {
void tearDown() {
eventLoop->processEvents();
delete connectionFactory;
- delete eventLoop;
+ delete resolver;
+ delete timerFactory;
+ delete eventLoop;
}
void testHeader() {
@@ -185,7 +191,9 @@ class BOSHConnectionTest : public CppUnit::TestFixture {
private:
BOSHConnection::ref createTestling() {
- BOSHConnection::ref c = BOSHConnection::create(URL("http", "wonderland.lit", 5280, "http-bind"), connectionFactory, &parserFactory, static_cast<TLSContextFactory*>(NULL));
+ resolver->addAddress("wonderland.lit", HostAddress("127.0.0.1"));
+ Connector::ref connector = Connector::create("wonderland.lit", resolver, connectionFactory, timerFactory, 5280);
+ BOSHConnection::ref c = BOSHConnection::create(URL("http", "wonderland.lit", 5280, "http-bind"), connector, &parserFactory);
c->onConnectFinished.connect(boost::bind(&BOSHConnectionTest::handleConnectFinished, this, _1));
c->onDisconnected.connect(boost::bind(&BOSHConnectionTest::handleDisconnected, this, _1));
c->onXMPPDataRead.connect(boost::bind(&BOSHConnectionTest::handleDataRead, this, _1));
@@ -284,6 +292,8 @@ class BOSHConnectionTest : public CppUnit::TestFixture {
bool disconnectedError;
ByteArray dataRead;
PlatformXMLParserFactory parserFactory;
+ StaticDomainNameResolver* resolver;
+ TimerFactory* timerFactory;
std::string sid;
};
diff --git a/Swiften/Network/UnitTest/HTTPConnectProxiedConnectionTest.cpp b/Swiften/Network/UnitTest/HTTPConnectProxiedConnectionTest.cpp
index c0252d4..347a145 100644
--- a/Swiften/Network/UnitTest/HTTPConnectProxiedConnectionTest.cpp
+++ b/Swiften/Network/UnitTest/HTTPConnectProxiedConnectionTest.cpp
@@ -18,6 +18,8 @@
#include <Swiften/Network/ConnectionFactory.h>
#include <Swiften/Network/HTTPConnectProxiedConnection.h>
#include <Swiften/Network/HostAddressPort.h>
+#include <Swiften/Network/StaticDomainNameResolver.h>
+#include <Swiften/Network/DummyTimerFactory.h>
#include <Swiften/EventLoop/DummyEventLoop.h>
using namespace Swift;
@@ -37,44 +39,55 @@ class HTTPConnectProxiedConnectionTest : public CppUnit::TestFixture {
public:
void setUp() {
- proxyHost = HostAddressPort(HostAddress("1.1.1.1"), 1234);
+ proxyHost = "doo.bah";
+ proxyPort = 1234;
+ proxyHostAddress = HostAddressPort(HostAddress("1.1.1.1"), proxyPort);
host = HostAddressPort(HostAddress("2.2.2.2"), 2345);
eventLoop = new DummyEventLoop();
+ resolver = new StaticDomainNameResolver(eventLoop);
+ resolver->addAddress(proxyHost, proxyHostAddress.getAddress());
+ timerFactory = new DummyTimerFactory();
connectionFactory = new MockConnectionFactory(eventLoop);
connectFinished = false;
disconnected = false;
}
void tearDown() {
+ delete timerFactory;
delete connectionFactory;
+ delete resolver;
delete eventLoop;
}
+ void connect(HTTPConnectProxiedConnection::ref connection, const HostAddressPort& to) {
+ connection->connect(to);
+ eventLoop->processEvents();
+ eventLoop->processEvents();
+ eventLoop->processEvents();
+ }
+
void testConnect_CreatesConnectionToProxy() {
HTTPConnectProxiedConnection::ref testling(createTestling());
- testling->connect(host);
- eventLoop->processEvents();
+ connect(testling, host);
CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(connectionFactory->connections.size()));
CPPUNIT_ASSERT(connectionFactory->connections[0]->hostAddressPort);
- CPPUNIT_ASSERT(proxyHost == *connectionFactory->connections[0]->hostAddressPort);
+ CPPUNIT_ASSERT(proxyHostAddress == *connectionFactory->connections[0]->hostAddressPort);
CPPUNIT_ASSERT(!connectFinished);
}
void testConnect_SendsConnectRequest() {
HTTPConnectProxiedConnection::ref testling(createTestling());
- testling->connect(HostAddressPort(HostAddress("2.2.2.2"), 2345));
- eventLoop->processEvents();
+ connect(testling, HostAddressPort(HostAddress("2.2.2.2"), 2345));
CPPUNIT_ASSERT_EQUAL(createByteArray("CONNECT 2.2.2.2:2345 HTTP/1.1\r\n\r\n"), connectionFactory->connections[0]->dataWritten);
}
void testConnect_ReceiveConnectResponse() {
HTTPConnectProxiedConnection::ref testling(createTestling());
- testling->connect(HostAddressPort(HostAddress("2.2.2.2"), 2345));
- eventLoop->processEvents();
+ connect(testling, HostAddressPort(HostAddress("2.2.2.2"), 2345));
connectionFactory->connections[0]->onDataRead(createSafeByteArrayRef("HTTP/1.0 200 Connection established\r\n\r\n"));
eventLoop->processEvents();
@@ -86,8 +99,7 @@ class HTTPConnectProxiedConnectionTest : public CppUnit::TestFixture {
void testConnect_ReceiveMalformedConnectResponse() {
HTTPConnectProxiedConnection::ref testling(createTestling());
- testling->connect(HostAddressPort(HostAddress("2.2.2.2"), 2345));
- eventLoop->processEvents();
+ connect(testling, HostAddressPort(HostAddress("2.2.2.2"), 2345));
connectionFactory->connections[0]->onDataRead(createSafeByteArrayRef("FLOOP"));
eventLoop->processEvents();
@@ -99,8 +111,7 @@ class HTTPConnectProxiedConnectionTest : public CppUnit::TestFixture {
void testConnect_ReceiveErrorConnectResponse() {
HTTPConnectProxiedConnection::ref testling(createTestling());
- testling->connect(HostAddressPort(HostAddress("2.2.2.2"), 2345));
- eventLoop->processEvents();
+ connect(testling, HostAddressPort(HostAddress("2.2.2.2"), 2345));
connectionFactory->connections[0]->onDataRead(createSafeByteArrayRef("HTTP/1.0 401 Unauthorized\r\n\r\n"));
eventLoop->processEvents();
@@ -112,8 +123,7 @@ class HTTPConnectProxiedConnectionTest : public CppUnit::TestFixture {
void testConnect_ReceiveDataAfterConnect() {
HTTPConnectProxiedConnection::ref testling(createTestling());
- testling->connect(HostAddressPort(HostAddress("2.2.2.2"), 2345));
- eventLoop->processEvents();
+ connect(testling, HostAddressPort(HostAddress("2.2.2.2"), 2345));
connectionFactory->connections[0]->onDataRead(createSafeByteArrayRef("HTTP/1.0 200 Connection established\r\n\r\n"));
eventLoop->processEvents();
@@ -124,8 +134,7 @@ class HTTPConnectProxiedConnectionTest : public CppUnit::TestFixture {
void testWrite_AfterConnect() {
HTTPConnectProxiedConnection::ref testling(createTestling());
- testling->connect(HostAddressPort(HostAddress("2.2.2.2"), 2345));
- eventLoop->processEvents();
+ connect(testling, HostAddressPort(HostAddress("2.2.2.2"), 2345));
connectionFactory->connections[0]->onDataRead(createSafeByteArrayRef("HTTP/1.0 200 Connection established\r\n\r\n"));
eventLoop->processEvents();
connectionFactory->connections[0]->dataWritten.clear();
@@ -137,8 +146,7 @@ class HTTPConnectProxiedConnectionTest : public CppUnit::TestFixture {
void testDisconnect_AfterConnectRequest() {
HTTPConnectProxiedConnection::ref testling(createTestling());
- testling->connect(HostAddressPort(HostAddress("2.2.2.2"), 2345));
- eventLoop->processEvents();
+ connect(testling, HostAddressPort(HostAddress("2.2.2.2"), 2345));
testling->disconnect();
@@ -149,8 +157,7 @@ class HTTPConnectProxiedConnectionTest : public CppUnit::TestFixture {
void testDisconnect_AfterConnect() {
HTTPConnectProxiedConnection::ref testling(createTestling());
- testling->connect(HostAddressPort(HostAddress("2.2.2.2"), 2345));
- eventLoop->processEvents();
+ connect(testling, HostAddressPort(HostAddress("2.2.2.2"), 2345));
connectionFactory->connections[0]->onDataRead(createSafeByteArrayRef("HTTP/1.0 200 Connection established\r\n\r\n"));
eventLoop->processEvents();
@@ -163,7 +170,7 @@ class HTTPConnectProxiedConnectionTest : public CppUnit::TestFixture {
private:
HTTPConnectProxiedConnection::ref createTestling() {
- boost::shared_ptr<HTTPConnectProxiedConnection> c = HTTPConnectProxiedConnection::create(connectionFactory, proxyHost, "", "");
+ boost::shared_ptr<HTTPConnectProxiedConnection> c = HTTPConnectProxiedConnection::create(resolver, connectionFactory, timerFactory, eventLoop, proxyHost, proxyPort, "", "");
c->onConnectFinished.connect(boost::bind(&HTTPConnectProxiedConnectionTest::handleConnectFinished, this, _1));
c->onDisconnected.connect(boost::bind(&HTTPConnectProxiedConnectionTest::handleDisconnected, this, _1));
c->onDataRead.connect(boost::bind(&HTTPConnectProxiedConnectionTest::handleDataRead, this, _1));
@@ -231,10 +238,14 @@ class HTTPConnectProxiedConnectionTest : public CppUnit::TestFixture {
};
private:
- HostAddressPort proxyHost;
+ std::string proxyHost;
+ HostAddressPort proxyHostAddress;
+ int proxyPort;
HostAddressPort host;
DummyEventLoop* eventLoop;
+ StaticDomainNameResolver* resolver;
MockConnectionFactory* connectionFactory;
+ TimerFactory* timerFactory;
std::vector< boost::shared_ptr<MockConnection> > connections;
bool connectFinished;
bool connectFinishedWithError;
diff --git a/Swiften/Session/BOSHSessionStream.cpp b/Swiften/Session/BOSHSessionStream.cpp
index f53b8e1..d706d43 100644
--- a/Swiften/Session/BOSHSessionStream.cpp
+++ b/Swiften/Session/BOSHSessionStream.cpp
@@ -35,6 +35,7 @@ BOSHSessionStream::BOSHSessionStream(
TimerFactory* timerFactory,
XMLParserFactory* xmlParserFactory,
EventLoop* eventLoop,
+ DomainNameResolver* resolver,
const std::string& to,
const URL& boshHTTPConnectProxyURL,
const SafeString& boshHTTPConnectProxyAuthID,
@@ -49,11 +50,11 @@ BOSHSessionStream::BOSHSessionStream(
firstHeader(true) {
boost::mt19937 random;
- boost::uniform_int<long long> dist(0, (1LL<<53) - 1);
+ boost::uniform_int<unsigned long long> dist(0, (1LL<<53) - 1);
random.seed(time(NULL));
- long long initialRID = boost::variate_generator<boost::mt19937&, boost::uniform_int<long long> >(random, dist)();
+ unsigned long long initialRID = boost::variate_generator<boost::mt19937&, boost::uniform_int<unsigned long long> >(random, dist)();
- connectionPool = new BOSHConnectionPool(boshURL, connectionFactory, xmlParserFactory, tlsContextFactory, to, initialRID, boshHTTPConnectProxyURL, boshHTTPConnectProxyAuthID, boshHTTPConnectProxyAuthPassword);
+ connectionPool = new BOSHConnectionPool(boshURL, resolver, connectionFactory, xmlParserFactory, tlsContextFactory, timerFactory, eventLoop, 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));
diff --git a/Swiften/Session/BOSHSessionStream.h b/Swiften/Session/BOSHSessionStream.h
index c3f6220..497d391 100644
--- a/Swiften/Session/BOSHSessionStream.h
+++ b/Swiften/Session/BOSHSessionStream.h
@@ -38,6 +38,7 @@ namespace Swift {
TimerFactory* whitespacePingLayerFactory,
XMLParserFactory* xmlParserFactory,
EventLoop* eventLoop,
+ DomainNameResolver* resolver,
const std::string& to,
const URL& boshHTTPConnectProxyURL,
const SafeString& boshHTTPConnectProxyAuthID,