From 0bb2f5b6e811842c52500eef6685cc64367bd611 Mon Sep 17 00:00:00 2001
From: Nick Hudson <nick.hudson@isode.com>
Date: Fri, 7 Feb 2014 16:33:32 +0000
Subject: Move hardcoded XMPP SRV information from Connector into CoreClient

The Connector class had "_xmpp-client._tcp." hard-coded in it, which meant
that it was not suitable for non-XMPP clients.

This change means that the Connector can now be used by clients who
are interested in arbitrary SRV records; the CoreClient class is updated
accordingly.

Test-information:
Built and ran Swift - seems to work as expected
Ran unit-tests ("scons test=unit") - reports OK

Change-Id: I0fea9aa90f5d1d5e3a4b90f3362b663fe9d8e207

diff --git a/Swiften/Client/CoreClient.cpp b/Swiften/Client/CoreClient.cpp
index 4438135..f6a3bb8 100644
--- a/Swiften/Client/CoreClient.cpp
+++ b/Swiften/Client/CoreClient.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011 Remko Tronçon
+ * Copyright (c) 2010-2014 Remko Tronçon
  * Licensed under the GNU General Public License v3.
  * See Documentation/Licenses/GPLv3.txt for more information.
  */
@@ -7,6 +7,7 @@
 #include <Swiften/Client/CoreClient.h>
 
 #include <boost/bind.hpp>
+#include <boost/optional.hpp>
 #include <boost/smart_ptr/make_shared.hpp>
 
 #include <Swiften/Base/IDGenerator.h>
@@ -108,9 +109,13 @@ void CoreClient::connect(const ClientOptions& o) {
 	// Create connector
 	std::string host = o.manualHostname.empty() ?  jid_.getDomain() : o.manualHostname;
 	int port = o.manualPort;
+	boost::optional<std::string> serviceLookupPrefix;
+	if (o.manualHostname.empty()) {
+		serviceLookupPrefix = "_xmpp-client._tcp.";
+	}
 	assert(!connector_);
 	if (options.boshURL.isEmpty()) {
-		connector_ = boost::make_shared<ChainedConnector>(host, port, o.manualHostname.empty(), networkFactories->getDomainNameResolver(), connectionFactories, networkFactories->getTimerFactory());
+		connector_ = boost::make_shared<ChainedConnector>(host, port, serviceLookupPrefix, networkFactories->getDomainNameResolver(), connectionFactories, networkFactories->getTimerFactory());
 		connector_->onConnectFinished.connect(boost::bind(&CoreClient::handleConnectorFinished, this, _1, _2));
 		connector_->setTimeoutMilliseconds(2*60*1000);
 		connector_->start();
diff --git a/Swiften/Network/BOSHConnectionPool.cpp b/Swiften/Network/BOSHConnectionPool.cpp
index 4517ffb..fdfe420 100644
--- a/Swiften/Network/BOSHConnectionPool.cpp
+++ b/Swiften/Network/BOSHConnectionPool.cpp
@@ -225,7 +225,7 @@ void BOSHConnectionPool::handleConnectionDisconnected(bool/* error*/, BOSHConnec
 }
 
 boost::shared_ptr<BOSHConnection> BOSHConnectionPool::createConnection() {
-	Connector::ref connector = Connector::create(boshURL.getHost(), URL::getPortOrDefaultPort(boshURL), false, resolver, connectionFactory, timerFactory);
+	Connector::ref connector = Connector::create(boshURL.getHost(), URL::getPortOrDefaultPort(boshURL), boost::optional<std::string>(), resolver, connectionFactory, timerFactory);
 	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));
diff --git a/Swiften/Network/ChainedConnector.cpp b/Swiften/Network/ChainedConnector.cpp
index 8c7c04b..14d66ae 100644
--- a/Swiften/Network/ChainedConnector.cpp
+++ b/Swiften/Network/ChainedConnector.cpp
@@ -19,13 +19,13 @@ using namespace Swift;
 ChainedConnector::ChainedConnector(
 		const std::string& hostname, 
 		int port,
-		bool doServiceLookups,
+		const boost::optional<std::string>& serviceLookupPrefix,
 		DomainNameResolver* resolver, 
 		const std::vector<ConnectionFactory*>& connectionFactories, 
 		TimerFactory* timerFactory) : 
 			hostname(hostname), 
 			port(port),
-			doServiceLookups(doServiceLookups),
+			serviceLookupPrefix(serviceLookupPrefix),
 			resolver(resolver), 
 			connectionFactories(connectionFactories), 
 			timerFactory(timerFactory), 
@@ -62,7 +62,7 @@ void ChainedConnector::tryNextConnectionFactory() {
 		ConnectionFactory* connectionFactory = connectionFactoryQueue.front();
 		SWIFT_LOG(debug) << "Trying next connection factory: " << typeid(*connectionFactory).name() << std::endl;
 		connectionFactoryQueue.pop_front();
-		currentConnector = Connector::create(hostname, port, doServiceLookups, resolver, connectionFactory, timerFactory);
+		currentConnector = Connector::create(hostname, port, serviceLookupPrefix, resolver, connectionFactory, timerFactory);
 		currentConnector->setTimeoutMilliseconds(timeoutMilliseconds);
 		currentConnector->onConnectFinished.connect(boost::bind(&ChainedConnector::handleConnectorFinished, this, _1, _2));
 		currentConnector->start();
diff --git a/Swiften/Network/ChainedConnector.h b/Swiften/Network/ChainedConnector.h
index 03462bc..0a1cca9 100644
--- a/Swiften/Network/ChainedConnector.h
+++ b/Swiften/Network/ChainedConnector.h
@@ -10,6 +10,7 @@
 #include <vector>
 #include <deque>
 #include <boost/shared_ptr.hpp>
+#include <boost/optional.hpp>
 
 #include <Swiften/Base/API.h>
 #include <Swiften/Base/boost_bsignals.h>
@@ -24,7 +25,7 @@ namespace Swift {
 
 	class SWIFTEN_API ChainedConnector {
 		public:
-			ChainedConnector(const std::string& hostname, int port, bool doServiceLookups, DomainNameResolver*, const std::vector<ConnectionFactory*>&, TimerFactory*);
+			ChainedConnector(const std::string& hostname, int port, const boost::optional<std::string>& serviceLookupPrefix, DomainNameResolver*, const std::vector<ConnectionFactory*>&, TimerFactory*);
 
 			void setTimeoutMilliseconds(int milliseconds);
 			void start();
@@ -40,7 +41,7 @@ namespace Swift {
 		private:
 			std::string hostname;
 			int port;
-			bool doServiceLookups;
+			boost::optional<std::string> serviceLookupPrefix;
 			DomainNameResolver* resolver;
 			std::vector<ConnectionFactory*> connectionFactories;
 			TimerFactory* timerFactory;
diff --git a/Swiften/Network/Connector.cpp b/Swiften/Network/Connector.cpp
index a0155cf..a58efbc 100644
--- a/Swiften/Network/Connector.cpp
+++ b/Swiften/Network/Connector.cpp
@@ -17,7 +17,7 @@
 
 namespace Swift {
 
-Connector::Connector(const std::string& hostname, int port, bool doServiceLookups, DomainNameResolver* resolver, ConnectionFactory* connectionFactory, TimerFactory* timerFactory) : hostname(hostname), port(port), doServiceLookups(doServiceLookups), resolver(resolver), connectionFactory(connectionFactory), timerFactory(timerFactory), timeoutMilliseconds(0), queriedAllServices(true), foundSomeDNS(false) {
+Connector::Connector(const std::string& hostname, int port, const boost::optional<std::string>& serviceLookupPrefix, DomainNameResolver* resolver, ConnectionFactory* connectionFactory, TimerFactory* timerFactory) : hostname(hostname), port(port), serviceLookupPrefix(serviceLookupPrefix), resolver(resolver), connectionFactory(connectionFactory), timerFactory(timerFactory), timeoutMilliseconds(0), queriedAllServices(true), foundSomeDNS(false) {
 }
 
 void Connector::setTimeoutMilliseconds(int milliseconds) {
@@ -31,8 +31,8 @@ void Connector::start() {
 	assert(!serviceQuery);
 	assert(!timer);
 	queriedAllServices = false;
-	if (doServiceLookups) {
-		serviceQuery = resolver->createServiceQuery("_xmpp-client._tcp." + hostname);
+	if (serviceLookupPrefix) {
+		serviceQuery = resolver->createServiceQuery((*serviceLookupPrefix) + hostname);
 		serviceQuery->onResult.connect(boost::bind(&Connector::handleServiceQueryResult, shared_from_this(), _1));
 		if (timeoutMilliseconds > 0) {
 			timer = timerFactory->createTimer(timeoutMilliseconds);
diff --git a/Swiften/Network/Connector.h b/Swiften/Network/Connector.h
index 49ac271..16f8539 100644
--- a/Swiften/Network/Connector.h
+++ b/Swiften/Network/Connector.h
@@ -9,7 +9,7 @@
 #include <deque>
 #include <Swiften/Base/boost_bsignals.h>
 #include <boost/shared_ptr.hpp>
-
+#include <boost/optional.hpp>
 #include <Swiften/Base/API.h>
 #include <Swiften/Network/DomainNameServiceQuery.h>
 #include <Swiften/Network/Connection.h>
@@ -28,8 +28,8 @@ namespace Swift {
 		public:
 			typedef boost::shared_ptr<Connector> ref;
 
-			static Connector::ref create(const std::string& hostname, int port, bool doServiceLookups, DomainNameResolver* resolver, ConnectionFactory* connectionFactory, TimerFactory* timerFactory) {
-				return ref(new Connector(hostname, port, doServiceLookups, resolver, connectionFactory, timerFactory));
+			static Connector::ref create(const std::string& hostname, int port, const boost::optional<std::string>& serviceLookupPrefix, DomainNameResolver* resolver, ConnectionFactory* connectionFactory, TimerFactory* timerFactory) {
+				return ref(new Connector(hostname, port, serviceLookupPrefix, resolver, connectionFactory, timerFactory));
 			}
 
 			void setTimeoutMilliseconds(int milliseconds);
@@ -39,7 +39,7 @@ namespace Swift {
 			boost::signal<void (boost::shared_ptr<Connection>, boost::shared_ptr<Error>)> onConnectFinished;
 
 		private:
-			Connector(const std::string& hostname, int port, bool doServiceLookups, DomainNameResolver*, ConnectionFactory*, TimerFactory*);
+			Connector(const std::string& hostname, int port, const boost::optional<std::string>& serviceLookupPrefix, DomainNameResolver*, ConnectionFactory*, TimerFactory*);
 
 			void handleServiceQueryResult(const std::vector<DomainNameServiceQuery::Result>& result);
 			void handleAddressQueryResult(const std::vector<HostAddress>& address, boost::optional<DomainNameResolveError> error);
@@ -57,7 +57,7 @@ namespace Swift {
 		private:
 			std::string hostname;
 			int port;
-			bool doServiceLookups;
+			boost::optional<std::string> serviceLookupPrefix;
 			DomainNameResolver* resolver;
 			ConnectionFactory* connectionFactory;
 			TimerFactory* timerFactory;
diff --git a/Swiften/Network/ProxiedConnection.cpp b/Swiften/Network/ProxiedConnection.cpp
index 8bf12d3..0061820 100644
--- a/Swiften/Network/ProxiedConnection.cpp
+++ b/Swiften/Network/ProxiedConnection.cpp
@@ -53,7 +53,7 @@ void ProxiedConnection::cancelConnector() {
 void ProxiedConnection::connect(const HostAddressPort& server) {
 	server_ = server;
 
-	connector_ = Connector::create(proxyHost_, proxyPort_, false, resolver_, connectionFactory_, timerFactory_);
+	connector_ = Connector::create(proxyHost_, proxyPort_, boost::optional<std::string>(), resolver_, connectionFactory_, timerFactory_);
 	connector_->onConnectFinished.connect(boost::bind(&ProxiedConnection::handleConnectFinished, shared_from_this(), _1));
 	connector_->start();
 }
diff --git a/Swiften/Network/UnitTest/BOSHConnectionTest.cpp b/Swiften/Network/UnitTest/BOSHConnectionTest.cpp
index 9c4bc27..0d06420 100644
--- a/Swiften/Network/UnitTest/BOSHConnectionTest.cpp
+++ b/Swiften/Network/UnitTest/BOSHConnectionTest.cpp
@@ -192,7 +192,7 @@ class BOSHConnectionTest : public CppUnit::TestFixture {
 
 		BOSHConnection::ref createTestling() {
 			resolver->addAddress("wonderland.lit", HostAddress("127.0.0.1"));
-			Connector::ref connector = Connector::create("wonderland.lit", 5280, false, resolver, connectionFactory, timerFactory);
+			Connector::ref connector = Connector::create("wonderland.lit", 5280, boost::optional<std::string>(), resolver, connectionFactory, timerFactory);
 			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));
diff --git a/Swiften/Network/UnitTest/ChainedConnectorTest.cpp b/Swiften/Network/UnitTest/ChainedConnectorTest.cpp
index 9abed57..9176fe7 100644
--- a/Swiften/Network/UnitTest/ChainedConnectorTest.cpp
+++ b/Swiften/Network/UnitTest/ChainedConnectorTest.cpp
@@ -126,7 +126,7 @@ class ChainedConnectorTest : public CppUnit::TestFixture {
 			std::vector<ConnectionFactory*> factories;
 			factories.push_back(connectionFactory1);
 			factories.push_back(connectionFactory2);
-			boost::shared_ptr<ChainedConnector> connector = boost::make_shared<ChainedConnector>("foo.com", -1, true, resolver, factories, timerFactory);
+			boost::shared_ptr<ChainedConnector> connector = boost::make_shared<ChainedConnector>("foo.com", -1, boost::optional<std::string>("_xmpp-client._tcp."), resolver, factories, timerFactory);
 			connector->onConnectFinished.connect(boost::bind(&ChainedConnectorTest::handleConnectorFinished, this, _1, _2));
 			return connector;
 		}
diff --git a/Swiften/Network/UnitTest/ConnectorTest.cpp b/Swiften/Network/UnitTest/ConnectorTest.cpp
index fe18340..3b1d4e4 100644
--- a/Swiften/Network/UnitTest/ConnectorTest.cpp
+++ b/Swiften/Network/UnitTest/ConnectorTest.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 Remko Tronçon
+ * Copyright (c) 2010-2014 Remko Tronçon
  * Licensed under the GNU General Public License v3.
  * See Documentation/Licenses/GPLv3.txt for more information.
  */
@@ -75,7 +75,7 @@ class ConnectorTest : public CppUnit::TestFixture {
 		}
 
 		void testConnect_NoServiceLookups() {
-			Connector::ref testling(createConnector(4321, false));
+			Connector::ref testling(createConnector(4321, boost::optional<std::string>()));
 			resolver->addXMPPClientService("foo.com", host1);
 			resolver->addXMPPClientService("foo.com", host2);
 			resolver->addAddress("foo.com", host3.getAddress());
@@ -91,7 +91,7 @@ class ConnectorTest : public CppUnit::TestFixture {
 		}
 
 		void testConnect_NoServiceLookups_DefaultPort() {
-			Connector::ref testling(createConnector(-1, false));
+			Connector::ref testling(createConnector(-1, boost::optional<std::string>()));
 			resolver->addXMPPClientService("foo.com", host1);
 			resolver->addXMPPClientService("foo.com", host2);
 			resolver->addAddress("foo.com", host3.getAddress());
@@ -312,8 +312,8 @@ class ConnectorTest : public CppUnit::TestFixture {
 
 
 	private:
-		Connector::ref createConnector(int port = -1, bool doServiceLookups = true) {
-			Connector::ref connector = Connector::create("foo.com", port, doServiceLookups, resolver, connectionFactory, timerFactory);
+		Connector::ref createConnector(int port = -1, boost::optional<std::string> serviceLookupPrefix = boost::optional<std::string>("_xmpp-client._tcp.")) {
+			Connector::ref connector = Connector::create("foo.com", port, serviceLookupPrefix, resolver, connectionFactory, timerFactory);
 			connector->onConnectFinished.connect(boost::bind(&ConnectorTest::handleConnectorFinished, this, _1, _2));
 			return connector;
 		}
-- 
cgit v0.10.2-6-g49f6