From d96f856fea35e8a8f6e426318a87f044223de8d8 Mon Sep 17 00:00:00 2001
From: Kevin Smith <git@kismith.co.uk>
Date: Tue, 4 Dec 2012 15:56:42 +0000
Subject: Make sure we say the session's ended after calling close() with BOSH.

Change-Id: I35b290cb75657e2d9778cc81d83c8a52693f1103
Resolves: #1184

diff --git a/Swiften/Network/BOSHConnection.cpp b/Swiften/Network/BOSHConnection.cpp
index 539109a..377373d 100644
--- a/Swiften/Network/BOSHConnection.cpp
+++ b/Swiften/Network/BOSHConnection.cpp
@@ -60,11 +60,14 @@ void BOSHConnection::cancelConnector() {
 }
 
 void BOSHConnection::disconnect() {
-	cancelConnector();
-	if(connection_) {
+	if (connection_) {
 		connection_->disconnect();
 		sid_ = "";
 	}
+	else {
+		/* handleDisconnected takes care of the connector_ as well */
+		handleDisconnected(boost::optional<Connection::Error>());
+	}
 }
 
 void BOSHConnection::restartStream() {
diff --git a/Swiften/Network/BOSHConnectionPool.cpp b/Swiften/Network/BOSHConnectionPool.cpp
index 83310fb..e535deb 100644
--- a/Swiften/Network/BOSHConnectionPool.cpp
+++ b/Swiften/Network/BOSHConnectionPool.cpp
@@ -45,7 +45,14 @@ BOSHConnectionPool::BOSHConnectionPool(const URL& boshURL, DomainNameResolver* r
 }
 
 BOSHConnectionPool::~BOSHConnectionPool() {
-	close();
+	/* Don't do a normal close here. Instead kill things forcibly, as close() or writeFooter() will already have been called */
+	std::vector<BOSHConnection::ref> connectionCopies = connections;
+	foreach (BOSHConnection::ref connection, connectionCopies) {
+		if (connection) {
+			destroyConnection(connection);
+			connection->disconnect();
+		}
+	}
 	foreach (ConnectionFactory* factory, myConnectionFactories) {
 		delete factory;
 	}
@@ -82,12 +89,16 @@ void BOSHConnectionPool::writeFooter() {
 }
 
 void BOSHConnectionPool::close() {
-	/* TODO: Send a terminate here. */
-	std::vector<BOSHConnection::ref> connectionCopies = connections;
-	foreach (BOSHConnection::ref connection, connectionCopies) {
-		if (connection) {
-			connection->disconnect();
-			destroyConnection(connection);
+	if (!sid.empty()) {
+		writeFooter();
+	}
+	else {
+		pendingTerminate = true;
+		std::vector<BOSHConnection::ref> connectionCopies = connections;
+		foreach (BOSHConnection::ref connection, connectionCopies) {
+			if (connection) {
+				connection->disconnect();
+			}
 		}
 	}
 }
@@ -158,7 +169,8 @@ void BOSHConnectionPool::tryToSendQueuedData() {
 			rid++;
 			suitableConnection->setRID(rid);
 			suitableConnection->terminateStream();
-			onSessionTerminated(boost::shared_ptr<BOSHError>());
+			sid = "";
+			close();
 		}
 	}
 	if (!pendingTerminate) {
@@ -200,7 +212,10 @@ void BOSHConnectionPool::handleHTTPError(const std::string& /*errorCode*/) {
 
 void BOSHConnectionPool::handleConnectionDisconnected(bool error, BOSHConnection::ref connection) {
 	destroyConnection(connection);
-	if (false && error) {
+	if (pendingTerminate && sid.empty() && connections.empty()) {
+		handleSessionTerminated(BOSHError::ref());
+	}
+	else if (false && error) {
 		handleSessionTerminated(boost::make_shared<BOSHError>(BOSHError::UndefinedCondition));
 	}
 	else {
-- 
cgit v0.10.2-6-g49f6