diff options
| author | Remko Tronçon <git@el-tramo.be> | 2011-04-16 22:11:30 (GMT) | 
|---|---|---|
| committer | Remko Tronçon <git@el-tramo.be> | 2011-04-18 19:11:46 (GMT) | 
| commit | 60925bd2f77df3be75ad46118a940a096499f18b (patch) | |
| tree | ee9d86cb343a029d839a8a82c2a20d59f5f12524 | |
| parent | 676f09bd4af048f71916039f1c4fd59e9305cccd (diff) | |
| download | swift-60925bd2f77df3be75ad46118a940a096499f18b.zip swift-60925bd2f77df3be75ad46118a940a096499f18b.tar.bz2 | |
Added HTTPConnectProxiedConnection test.
| -rw-r--r-- | Swiften/Network/Connection.cpp | 15 | ||||
| -rw-r--r-- | Swiften/Network/Connection.h | 4 | ||||
| -rw-r--r-- | Swiften/Network/HTTPConnectProxiedConnection.cpp | 30 | ||||
| -rw-r--r-- | Swiften/Network/HTTPConnectProxiedConnection.h | 5 | ||||
| -rw-r--r-- | Swiften/Network/SConscript | 1 | ||||
| -rw-r--r-- | Swiften/Network/UnitTest/HTTPConnectProxiedConnectionTest.cpp | 244 | ||||
| -rw-r--r-- | Swiften/SConscript | 1 | 
7 files changed, 275 insertions, 25 deletions
| diff --git a/Swiften/Network/Connection.cpp b/Swiften/Network/Connection.cpp new file mode 100644 index 0000000..9bb29e1 --- /dev/null +++ b/Swiften/Network/Connection.cpp @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/Network/Connection.h> + +using namespace Swift; + +Connection::Connection() { +} + +Connection::~Connection() { +} diff --git a/Swiften/Network/Connection.h b/Swiften/Network/Connection.h index fdbbef6..74d25aa 100644 --- a/Swiften/Network/Connection.h +++ b/Swiften/Network/Connection.h @@ -23,8 +23,8 @@ namespace Swift {  				WriteError  			}; -			Connection() {} -			virtual ~Connection() {} +			Connection(); +			virtual ~Connection();  			virtual void listen() = 0;  			virtual void connect(const HostAddressPort& address) = 0; diff --git a/Swiften/Network/HTTPConnectProxiedConnection.cpp b/Swiften/Network/HTTPConnectProxiedConnection.cpp index 2e90b52..51130e5 100644 --- a/Swiften/Network/HTTPConnectProxiedConnection.cpp +++ b/Swiften/Network/HTTPConnectProxiedConnection.cpp @@ -64,7 +64,6 @@ void HTTPConnectProxiedConnection::write(const ByteArray& data) {  void HTTPConnectProxiedConnection::handleConnectionConnectFinished(bool error) {  	connection_->onConnectFinished.disconnect(boost::bind(&HTTPConnectProxiedConnection::handleConnectionConnectFinished, shared_from_this(), _1));  	if (!error) { -		proxyState_ = ProxyConnecting;  		std::stringstream connect;  		connect << "CONNECT " << server_.getAddress().toString() << ":" << server_.getPort() << " HTTP/1.1\r\n\r\n";  		connection_->write(ByteArray(connect.str())); @@ -76,29 +75,24 @@ void HTTPConnectProxiedConnection::handleConnectionConnectFinished(bool error) {  void HTTPConnectProxiedConnection::handleDataRead(const ByteArray& data) {  	if (!connected_) { -		if (proxyState_ == ProxyConnecting) { -			SWIFT_LOG(debug) << data.toString() << std::endl; -			std::vector<std::string> tmp = String::split(data.toString(), ' '); -			if(tmp.size() > 1) { -				int status = boost::lexical_cast<int> (tmp[1].c_str());  -				SWIFT_LOG(debug) << "Proxy Status: " << status << std::endl; -				if (status / 100 == 2) { // all 2XX states are OK -					connected_ = true; -					onConnectFinished(false); -					return; -				} +		SWIFT_LOG(debug) << data.toString() << std::endl; +		std::vector<std::string> tmp = String::split(data.toString(), ' '); +		if(tmp.size() > 1) { +			int status = boost::lexical_cast<int> (tmp[1].c_str());  +			SWIFT_LOG(debug) << "Proxy Status: " << status << std::endl; +			if (status / 100 == 2) { // all 2XX states are OK +				connected_ = true; +				onConnectFinished(false); +				return;  			} - -			std::cerr << "HTTP Proxy returned an error: " << data.toString() << std::endl; -			return; +			SWIFT_LOG(debug) << "HTTP Proxy returned an error: " << data.toString() << std::endl;  		} +		disconnect(); +		onConnectFinished(true);  	}  	else {  		onDataRead(data); -		return;  	} -	disconnect(); -	onConnectFinished(true);  }  HostAddressPort HTTPConnectProxiedConnection::getLocalAddress() const { diff --git a/Swiften/Network/HTTPConnectProxiedConnection.h b/Swiften/Network/HTTPConnectProxiedConnection.h index 232f4eb..930f5e1 100644 --- a/Swiften/Network/HTTPConnectProxiedConnection.h +++ b/Swiften/Network/HTTPConnectProxiedConnection.h @@ -38,11 +38,6 @@ namespace Swift {  			virtual HostAddressPort getLocalAddress() const;  		private: -			enum { -				ProxyAuthenticating = 0, -				ProxyConnecting, -			} proxyState_; -  			HTTPConnectProxiedConnection(ConnectionFactory* connectionFactory, HostAddressPort proxy);  			void handleConnectionConnectFinished(bool error); diff --git a/Swiften/Network/SConscript b/Swiften/Network/SConscript index 61eb69a..ecfc66a 100644 --- a/Swiften/Network/SConscript +++ b/Swiften/Network/SConscript @@ -20,6 +20,7 @@ sourceList = [  			"FakeConnection.cpp",   			"ChainedConnector.cpp",   			"Connector.cpp", + 			"Connection.cpp",  			"TimerFactory.cpp",  			"DummyTimerFactory.cpp",  			"BoostTimerFactory.cpp", diff --git a/Swiften/Network/UnitTest/HTTPConnectProxiedConnectionTest.cpp b/Swiften/Network/UnitTest/HTTPConnectProxiedConnectionTest.cpp new file mode 100644 index 0000000..6c4c89c --- /dev/null +++ b/Swiften/Network/UnitTest/HTTPConnectProxiedConnectionTest.cpp @@ -0,0 +1,244 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#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 <Swiften/Network/Connection.h> +#include <Swiften/Network/ConnectionFactory.h> +#include <Swiften/Network/HTTPConnectProxiedConnection.h> +#include <Swiften/Network/HostAddressPort.h> +#include <Swiften/EventLoop/DummyEventLoop.h> + +using namespace Swift; + +class HTTPConnectProxiedConnectionTest : public CppUnit::TestFixture { +		CPPUNIT_TEST_SUITE(HTTPConnectProxiedConnectionTest); +		CPPUNIT_TEST(testConnect_CreatesConnectionToProxy); +		CPPUNIT_TEST(testConnect_SendsConnectRequest); +		CPPUNIT_TEST(testConnect_ReceiveConnectResponse); +		CPPUNIT_TEST(testConnect_ReceiveMalformedConnectResponse); +		CPPUNIT_TEST(testConnect_ReceiveErrorConnectResponse); +		CPPUNIT_TEST(testConnect_ReceiveDataAfterConnect); +		CPPUNIT_TEST(testWrite_AfterConnect); +		CPPUNIT_TEST(testDisconnect_AfterConnectRequest); +		CPPUNIT_TEST(testDisconnect_AfterConnect); +		CPPUNIT_TEST_SUITE_END(); + +	public: +		void setUp() { +			proxyHost = HostAddressPort(HostAddress("1.1.1.1"), 1234); +			host = HostAddressPort(HostAddress("2.2.2.2"), 2345); +			eventLoop = new DummyEventLoop(); +			connectionFactory = new MockConnectionFactory(eventLoop); +			connectFinished = false; +			disconnected = false; +		} + +		void tearDown() { +			delete connectionFactory; +			delete eventLoop; +		} + +		void testConnect_CreatesConnectionToProxy() { +			HTTPConnectProxiedConnection::ref testling(createTestling()); + +			testling->connect(host); +			eventLoop->processEvents(); + +			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(!connectFinished); +		} + +		void testConnect_SendsConnectRequest() { +			HTTPConnectProxiedConnection::ref testling(createTestling()); + +			testling->connect(HostAddressPort(HostAddress("2.2.2.2"), 2345)); +			eventLoop->processEvents(); + +			CPPUNIT_ASSERT_EQUAL(ByteArray("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(); + +			connectionFactory->connections[0]->onDataRead(ByteArray("HTTP/1.0 200 Connection established\r\n\r\n")); +			eventLoop->processEvents(); + +			CPPUNIT_ASSERT(connectFinished); +			CPPUNIT_ASSERT(!connectFinishedWithError); +			CPPUNIT_ASSERT(dataRead.isEmpty()); +		} + +		void testConnect_ReceiveMalformedConnectResponse() { +			HTTPConnectProxiedConnection::ref testling(createTestling()); +			testling->connect(HostAddressPort(HostAddress("2.2.2.2"), 2345)); +			eventLoop->processEvents(); + +			connectionFactory->connections[0]->onDataRead(ByteArray("FLOOP")); +			eventLoop->processEvents(); + +			CPPUNIT_ASSERT(connectFinished); +			CPPUNIT_ASSERT(connectFinishedWithError); +			CPPUNIT_ASSERT(connectionFactory->connections[0]->disconnected); +		} + +		void testConnect_ReceiveErrorConnectResponse() { +			HTTPConnectProxiedConnection::ref testling(createTestling()); +			testling->connect(HostAddressPort(HostAddress("2.2.2.2"), 2345)); +			eventLoop->processEvents(); + +			connectionFactory->connections[0]->onDataRead(ByteArray("HTTP/1.0 401 Unauthorized\r\n\r\n")); +			eventLoop->processEvents(); + +			CPPUNIT_ASSERT(connectFinished); +			CPPUNIT_ASSERT(connectFinishedWithError); +			CPPUNIT_ASSERT(connectionFactory->connections[0]->disconnected); +		} + +		void testConnect_ReceiveDataAfterConnect() { +			HTTPConnectProxiedConnection::ref testling(createTestling()); +			testling->connect(HostAddressPort(HostAddress("2.2.2.2"), 2345)); +			eventLoop->processEvents(); +			connectionFactory->connections[0]->onDataRead(ByteArray("HTTP/1.0 200 Connection established\r\n\r\n")); +			eventLoop->processEvents(); + +			connectionFactory->connections[0]->onDataRead(ByteArray("abcdef")); + +			CPPUNIT_ASSERT_EQUAL(ByteArray("abcdef"), dataRead); +		} + +		void testWrite_AfterConnect() { +			HTTPConnectProxiedConnection::ref testling(createTestling()); +			testling->connect(HostAddressPort(HostAddress("2.2.2.2"), 2345)); +			eventLoop->processEvents(); +			connectionFactory->connections[0]->onDataRead(ByteArray("HTTP/1.0 200 Connection established\r\n\r\n")); +			eventLoop->processEvents(); +			connectionFactory->connections[0]->dataWritten.clear(); + +			testling->write(ByteArray("abcdef")); + +			CPPUNIT_ASSERT_EQUAL(ByteArray("abcdef"), connectionFactory->connections[0]->dataWritten); +		} + +		void testDisconnect_AfterConnectRequest() { +			HTTPConnectProxiedConnection::ref testling(createTestling()); +			testling->connect(HostAddressPort(HostAddress("2.2.2.2"), 2345)); +			eventLoop->processEvents(); + +			testling->disconnect(); + +			CPPUNIT_ASSERT(connectionFactory->connections[0]->disconnected); +			CPPUNIT_ASSERT(disconnected); +			CPPUNIT_ASSERT(!disconnectedError); +		} + +		void testDisconnect_AfterConnect() { +			HTTPConnectProxiedConnection::ref testling(createTestling()); +			testling->connect(HostAddressPort(HostAddress("2.2.2.2"), 2345)); +			eventLoop->processEvents(); +			connectionFactory->connections[0]->onDataRead(ByteArray("HTTP/1.0 200 Connection established\r\n\r\n")); +			eventLoop->processEvents(); + +			testling->disconnect(); + +			CPPUNIT_ASSERT(connectionFactory->connections[0]->disconnected); +			CPPUNIT_ASSERT(disconnected); +			CPPUNIT_ASSERT(!disconnectedError); +		} + +	private: +		HTTPConnectProxiedConnection::ref createTestling() { +			boost::shared_ptr<HTTPConnectProxiedConnection> c = HTTPConnectProxiedConnection::create(connectionFactory, proxyHost); +			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)); +			return c; +		} + +		void handleConnectFinished(bool error) { +			connectFinished = true; +			connectFinishedWithError = error; +		} + +		void handleDisconnected(const boost::optional<Connection::Error>& e) { +			disconnected = true; +			disconnectedError = e; +		} + +		void handleDataRead(const ByteArray& d) { +			dataRead += d; +		} + +		struct MockConnection : public Connection { +			public: +				MockConnection(const std::vector<HostAddressPort>& failingPorts, EventLoop* eventLoop) : eventLoop(eventLoop), failingPorts(failingPorts), disconnected(false) { +				} + +				void listen() { assert(false); } + +				void connect(const HostAddressPort& address) { +					hostAddressPort = address; +					bool fail = std::find(failingPorts.begin(), failingPorts.end(), address) != failingPorts.end(); +					eventLoop->postEvent(boost::bind(boost::ref(onConnectFinished), fail)); +				} + +				HostAddressPort getLocalAddress() const { return HostAddressPort(); } + +				void disconnect() {  +					disconnected = true; +					onDisconnected(boost::optional<Connection::Error>()); +				} +				 +				void write(const ByteArray& d) {  +					dataWritten += d; +				} + +				EventLoop* eventLoop; +				boost::optional<HostAddressPort> hostAddressPort; +				std::vector<HostAddressPort> failingPorts; +				ByteArray dataWritten; +				bool disconnected; +		}; + +		struct MockConnectionFactory : public ConnectionFactory { +			MockConnectionFactory(EventLoop* eventLoop) : eventLoop(eventLoop) { +			} + +			boost::shared_ptr<Connection> createConnection() { +				boost::shared_ptr<MockConnection> connection = boost::make_shared<MockConnection>(failingPorts, eventLoop); +				connections.push_back(connection); +				return connection; +			} + +			EventLoop* eventLoop; +			std::vector< boost::shared_ptr<MockConnection> > connections; +			std::vector<HostAddressPort> failingPorts; +		}; + +	private: +		HostAddressPort proxyHost; +		HostAddressPort host; +		DummyEventLoop* eventLoop; +		MockConnectionFactory* connectionFactory; +		std::vector< boost::shared_ptr<MockConnection> > connections; +		bool connectFinished; +		bool connectFinishedWithError; +		bool disconnected; +		boost::optional<Connection::Error> disconnectedError; +		ByteArray dataRead; +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(HTTPConnectProxiedConnectionTest); diff --git a/Swiften/SConscript b/Swiften/SConscript index 0a229e8..f207c62 100644 --- a/Swiften/SConscript +++ b/Swiften/SConscript @@ -232,6 +232,7 @@ if env["SCONS_STAGE"] == "build" :  			File("Network/UnitTest/HostAddressTest.cpp"),  			File("Network/UnitTest/ConnectorTest.cpp"),  			File("Network/UnitTest/ChainedConnectorTest.cpp"), +			File("Network/UnitTest/HTTPConnectProxiedConnectionTest.cpp"),  			File("Parser/PayloadParsers/UnitTest/BodyParserTest.cpp"),  			File("Parser/PayloadParsers/UnitTest/DiscoInfoParserTest.cpp"),  			File("Parser/PayloadParsers/UnitTest/ErrorParserTest.cpp"), | 
 Swift
 Swift