diff options
| -rw-r--r-- | Limber/main.cpp | 35 | ||||
| -rw-r--r-- | Swiften/Client/UnitTest/SessionTest.cpp | 5 | ||||
| -rw-r--r-- | Swiften/Parser/UnitTest/XMPPParserTest.cpp | 23 | ||||
| -rw-r--r-- | Swiften/Parser/XMPPParser.cpp | 2 | ||||
| -rw-r--r-- | Swiften/Parser/XMPPParserClient.h | 2 | ||||
| -rw-r--r-- | Swiften/Serializer/XMPPSerializer.cpp | 15 | ||||
| -rw-r--r-- | Swiften/Serializer/XMPPSerializer.h | 2 | ||||
| -rw-r--r-- | Swiften/Server/ServerFromClientSession.cpp | 7 | ||||
| -rw-r--r-- | Swiften/Server/ServerFromClientSession.h | 6 | ||||
| -rw-r--r-- | Swiften/StreamStack/UnitTest/XMPPLayerTest.cpp | 10 | ||||
| -rw-r--r-- | Swiften/StreamStack/XMPPLayer.cpp | 12 | ||||
| -rw-r--r-- | Swiften/StreamStack/XMPPLayer.h | 7 | 
12 files changed, 98 insertions, 28 deletions
| diff --git a/Limber/main.cpp b/Limber/main.cpp index 6dad151..969a390 100644 --- a/Limber/main.cpp +++ b/Limber/main.cpp @@ -9,6 +9,7 @@  #include <boost/thread.hpp>  #include "Swiften/Base/ByteArray.h" +#include "Swiften/Base/IDGenerator.h"  #include "Swiften/EventLoop/MainEventLoop.h"  #include "Swiften/EventLoop/SimpleEventLoop.h"  #include "Swiften/Network/ConnectionServer.h" @@ -19,6 +20,8 @@  using namespace Swift; +static const size_t BUFFER_SIZE = 4096; +  // A reference-counted non-modifiable buffer class.  class SharedBuffer {  	public: @@ -58,17 +61,39 @@ class IncomingBoostConnection : public IncomingConnection, public boost::enable_  						boost::asio::placeholders::error));  		} +		void start() { +			read(); +		} +  	private: -		IncomingBoostConnection(boost::asio::io_service& ioService) : socket_(ioService) { +		IncomingBoostConnection(boost::asio::io_service& ioService) : socket_(ioService), readBuffer_(BUFFER_SIZE) { +		} + +		void read() { +			socket_.async_read_some( +					boost::asio::buffer(readBuffer_), +					boost::bind(&IncomingBoostConnection::handleDataRead, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); +		} + +		void handleDataRead(const boost::system::error_code& error, size_t bytesTransferred) { +			if (!error) { +				MainEventLoop::postEvent(boost::bind(boost::ref(onDataRead), ByteArray(&readBuffer_[0], bytesTransferred)), this); +				read(); +			} +			else if (error != boost::asio::error::operation_aborted) { +				//MainEventLoop::postEvent(boost::bind(boost::ref(onError), ReadError), this); +			}  		}  		void handleDataWritten(const boost::system::error_code& error) { -			if (error) { -				std::cerr << "ERROR: Unable to write data to socket" << std::endl; +			if (error && error != boost::asio::error::operation_aborted) { +				//std::cerr << "ERROR: Unable to write data to socket" << std::endl; +				//MainEventLoop::postEvent(boost::bind(boost::ref(onError), ReadError), this);  			}  		}  		boost::asio::ip::tcp::socket socket_; +		std::vector<char> readBuffer_;  };  class BoostConnectionServer : public ConnectionServer { @@ -87,6 +112,7 @@ class BoostConnectionServer : public ConnectionServer {  		void handleAccept(IncomingBoostConnection::pointer newConnection, const boost::system::error_code& error) {  			if (!error) {  				MainEventLoop::postEvent(boost::bind(boost::ref(onNewConnection), newConnection), this); +				newConnection->start();  				acceptNextConnection();  			}  		} @@ -107,7 +133,7 @@ class Server {  	private:  		void handleNewConnection(boost::shared_ptr<IncomingConnection> c) { -			ServerFromClientSession* session = new ServerFromClientSession(c, &payloadParserFactories_, &payloadSerializers_); +			ServerFromClientSession* session = new ServerFromClientSession(idGenerator_.generateID(), c, &payloadParserFactories_, &payloadSerializers_);  			serverFromClientSessions_.push_back(session);  			session->onSessionFinished.connect(boost::bind(&Server::handleSessionFinished, this, session));  		} @@ -118,6 +144,7 @@ class Server {  		}  	private: +		IDGenerator idGenerator_;  		BoostIOServiceThread boostIOServiceThread_;  		BoostConnectionServer* serverFromClientConnectionServer_;  		std::vector<ServerFromClientSession*> serverFromClientSessions_; diff --git a/Swiften/Client/UnitTest/SessionTest.cpp b/Swiften/Client/UnitTest/SessionTest.cpp index f4c40da..c2b99db 100644 --- a/Swiften/Client/UnitTest/SessionTest.cpp +++ b/Swiften/Client/UnitTest/SessionTest.cpp @@ -509,7 +509,8 @@ class SessionTest : public CppUnit::TestFixture {  				parser_ = new XMPPParser(this, &payloadParserFactories_);  			} -			void handleStreamStart() { +			void handleStreamStart(const String&, const String& to, const String&) { +				CPPUNIT_ASSERT_EQUAL(getDomain(), to);  				handleEvent(Event::StreamStartEvent);  			} @@ -543,7 +544,7 @@ class SessionTest : public CppUnit::TestFixture {  			String serializeEvent(const Event& event) {  				switch (event.type) {  					case Event::StreamStartEvent:  -						return serializer_.serializeHeader(getDomain()); +						return serializer_.serializeHeader("", getDomain(), "");  					case Event::ElementEvent:  						return serializer_.serializeElement(event.element);  					case Event::StreamEndEvent: diff --git a/Swiften/Parser/UnitTest/XMPPParserTest.cpp b/Swiften/Parser/UnitTest/XMPPParserTest.cpp index 787828c..a8b805e 100644 --- a/Swiften/Parser/UnitTest/XMPPParserTest.cpp +++ b/Swiften/Parser/UnitTest/XMPPParserTest.cpp @@ -19,6 +19,7 @@ class XMPPParserTest : public CppUnit::TestFixture  {  		CPPUNIT_TEST_SUITE(XMPPParserTest);  		CPPUNIT_TEST(testParse_SimpleSession); +		CPPUNIT_TEST(testParse_SimpleClientFromServerSession);  		CPPUNIT_TEST(testParse_Presence);  		CPPUNIT_TEST(testParse_IQ);  		CPPUNIT_TEST(testParse_Message); @@ -43,12 +44,26 @@ class XMPPParserTest : public CppUnit::TestFixture  			CPPUNIT_ASSERT_EQUAL(5, static_cast<int>(client_.events.size()));  			CPPUNIT_ASSERT_EQUAL(Client::StreamStart, client_.events[0].type); +			CPPUNIT_ASSERT_EQUAL(String("example.com"), client_.events[0].to);   			CPPUNIT_ASSERT_EQUAL(Client::ElementEvent, client_.events[1].type);  			CPPUNIT_ASSERT_EQUAL(Client::ElementEvent, client_.events[2].type);  			CPPUNIT_ASSERT_EQUAL(Client::ElementEvent, client_.events[3].type);  			CPPUNIT_ASSERT_EQUAL(Client::StreamEnd, client_.events[4].type);  		} +		void testParse_SimpleClientFromServerSession() { +			XMPPParser testling(&client_, &factories_); + +			CPPUNIT_ASSERT(testling.parse("<?xml version='1.0'?>")); +			CPPUNIT_ASSERT(testling.parse("<stream:stream from='example.com' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' id='aeab'>")); + +			CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(client_.events.size())); +			CPPUNIT_ASSERT_EQUAL(Client::StreamStart, client_.events[0].type); +			CPPUNIT_ASSERT_EQUAL(String("example.com"), client_.events[0].from);  +			CPPUNIT_ASSERT_EQUAL(String("aeab"), client_.events[0].id);  +		} + +  		void testParse_Presence() {  			XMPPParser testling(&client_, &factories_); @@ -137,17 +152,21 @@ class XMPPParserTest : public CppUnit::TestFixture  				struct Event {  					Event(Type type, boost::shared_ptr<Element> element)   						: type(type), element(element) {} +					Event(Type type, const String& from, const String& to, const String& id) : type(type), from(from), to(to), id(id) {}  					Event(Type type) : type(type) {}  					Type type; +					String from; +					String to; +					String id;  					boost::shared_ptr<Element> element;  				};  				Client() {} -				void handleStreamStart() { -					events.push_back(Event(StreamStart)); +				void handleStreamStart(const String& from, const String& to, const String& id) { +					events.push_back(Event(StreamStart, from, to, id));  				}  				void handleElement(boost::shared_ptr<Element> element) { diff --git a/Swiften/Parser/XMPPParser.cpp b/Swiften/Parser/XMPPParser.cpp index 59cfce7..0f04cca 100644 --- a/Swiften/Parser/XMPPParser.cpp +++ b/Swiften/Parser/XMPPParser.cpp @@ -54,7 +54,7 @@ bool XMPPParser::parse(const String& data) {  void XMPPParser::handleStartElement(const String& element, const String& ns, const AttributeMap& attributes) {  	if (!inStream()) {  		if (element == "stream" && ns == "http://etherx.jabber.org/streams") { -			client_->handleStreamStart(attributes.getAttribute("to")); +			client_->handleStreamStart(attributes.getAttribute("from"), attributes.getAttribute("to"), attributes.getAttribute("id"));  		}  		else {  			parseErrorOccurred_ = true; diff --git a/Swiften/Parser/XMPPParserClient.h b/Swiften/Parser/XMPPParserClient.h index d19c7d0..fb81df8 100644 --- a/Swiften/Parser/XMPPParserClient.h +++ b/Swiften/Parser/XMPPParserClient.h @@ -12,7 +12,7 @@ namespace Swift {  		public:  			virtual ~XMPPParserClient(); -			virtual void handleStreamStart(const String& header) = 0; +			virtual void handleStreamStart(const String& from, const String& to, const String& id) = 0;  			virtual void handleElement(boost::shared_ptr<Element>) = 0;  			virtual void handleStreamEnd() = 0;  	}; diff --git a/Swiften/Serializer/XMPPSerializer.cpp b/Swiften/Serializer/XMPPSerializer.cpp index c43f9db..6139586 100644 --- a/Swiften/Serializer/XMPPSerializer.cpp +++ b/Swiften/Serializer/XMPPSerializer.cpp @@ -34,8 +34,19 @@ XMPPSerializer::XMPPSerializer(PayloadSerializerCollection* payloadSerializers)  	serializers_.push_back(boost::shared_ptr<ElementSerializer>(new StreamFeaturesSerializer()));  } -String XMPPSerializer::serializeHeader(const String& domain) const { -	return "<?xml version='1.0'?><stream:stream to='" + domain + "' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0' >"; +String XMPPSerializer::serializeHeader(const String& from, const String& to, const String& id) const { +	String result = "<?xml version=\"1.0\"?><stream:stream xmlns=\"jabber:client\" xmlns:stream=\"http://etherx.jabber.org/streams\" version=\"1.0\""; +	if (!from.isEmpty()) { +		result += " from=\"" + from + "\""; +	} +	if (!to.isEmpty()) { +		result += " to=\"" + to + "\""; +	} +	if (!id.isEmpty()) { +		result += " id=\"" + id + "\""; +	} +	result += ">"; +	return result;  }  String XMPPSerializer::serializeElement(boost::shared_ptr<Element> element) const { diff --git a/Swiften/Serializer/XMPPSerializer.h b/Swiften/Serializer/XMPPSerializer.h index 1fc8b9d..f77e14b 100644 --- a/Swiften/Serializer/XMPPSerializer.h +++ b/Swiften/Serializer/XMPPSerializer.h @@ -16,7 +16,7 @@ namespace Swift {  		public:  			XMPPSerializer(PayloadSerializerCollection*); -			String serializeHeader(const String& domain) const; +			String serializeHeader(const String& from, const String& to, const String& id = "") const;  			String serializeElement(boost::shared_ptr<Element> stanza) const;  			String serializeFooter() const; diff --git a/Swiften/Server/ServerFromClientSession.cpp b/Swiften/Server/ServerFromClientSession.cpp index e85021e..be8b601 100644 --- a/Swiften/Server/ServerFromClientSession.cpp +++ b/Swiften/Server/ServerFromClientSession.cpp @@ -10,15 +10,17 @@  namespace Swift {  ServerFromClientSession::ServerFromClientSession( +		const String& id,  		boost::shared_ptr<IncomingConnection> connection,   		PayloadParserFactoryCollection* payloadParserFactories,   		PayloadSerializerCollection* payloadSerializers) :  +			id_(id),  			connection_(connection),   			payloadParserFactories_(payloadParserFactories),   			payloadSerializers_(payloadSerializers) {  	xmppLayer_ = new XMPPLayer(payloadParserFactories_, payloadSerializers_);  	xmppLayer_->onStreamStart.connect( -			boost::bind(&ServerFromClientSession::handleStreamStart, this, _1)); +			boost::bind(&ServerFromClientSession::handleStreamStart, this, _2));  	xmppLayer_->onElement.connect(  			boost::bind(&ServerFromClientSession::handleElement, this, _1));  	//xmppLayer_->onError.connect( @@ -41,7 +43,8 @@ void ServerFromClientSession::handleElement(boost::shared_ptr<Element>) {  }  void ServerFromClientSession::handleStreamStart(const String& domain) { -	xmppLayer_->writeHeader(domain); +	domain_ = domain; +	xmppLayer_->writeHeader(domain_, id_);  }  } diff --git a/Swiften/Server/ServerFromClientSession.h b/Swiften/Server/ServerFromClientSession.h index cedfcdb..3413a03 100644 --- a/Swiften/Server/ServerFromClientSession.h +++ b/Swiften/Server/ServerFromClientSession.h @@ -3,6 +3,8 @@  #include <boost/shared_ptr.hpp>  #include <boost/signal.hpp> +#include "Swiften/Base/String.h" +  namespace Swift {  	class Element;  	class PayloadParserFactoryCollection; @@ -12,11 +14,11 @@ namespace Swift {  	class IncomingConnectionLayer;  	class IncomingConnection;  	class ByteArray; -	class String;  	class ServerFromClientSession {  		public:  			ServerFromClientSession( +					const String& id,  					boost::shared_ptr<IncomingConnection> connection,   					PayloadParserFactoryCollection* payloadParserFactories,   					PayloadSerializerCollection* payloadSerializers); @@ -31,11 +33,13 @@ namespace Swift {  			void handleStreamStart(const String& domain);  		private: +			String id_;  			boost::shared_ptr<IncomingConnection> connection_;  			PayloadParserFactoryCollection* payloadParserFactories_;  			PayloadSerializerCollection* payloadSerializers_;  			IncomingConnectionLayer* connectionLayer_;  			StreamStack* streamStack_;  			XMPPLayer* xmppLayer_; +			String domain_;  	};  } diff --git a/Swiften/StreamStack/UnitTest/XMPPLayerTest.cpp b/Swiften/StreamStack/UnitTest/XMPPLayerTest.cpp index 2150f4d..f60c370 100644 --- a/Swiften/StreamStack/UnitTest/XMPPLayerTest.cpp +++ b/Swiften/StreamStack/UnitTest/XMPPLayerTest.cpp @@ -48,9 +48,9 @@ class XMPPLayerTest : public CppUnit::TestFixture  			testling_->onElement.connect(boost::bind(&XMPPLayerTest::handleElement, this, _1));  			testling_->onError.connect(boost::bind(&XMPPLayerTest::handleError, this)); -			testling_->parseData("<stream:stream to='example.com' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' >"); +			testling_->parseData("<stream:stream to=\"example.com\" xmlns=\"jabber:client\" xmlns:stream=\"http://etherx.jabber.org/streams\" >");  			testling_->resetParser(); -			testling_->parseData("<stream:stream to='example.com' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' >"); +			testling_->parseData("<stream:stream to=\"example.com\" xmlns=\"jabber:client\" xmlns:stream=\"http://etherx.jabber.org/streams\" >");  			testling_->parseData("<presence/>");  			CPPUNIT_ASSERT_EQUAL(1, elementsReceived_); @@ -59,8 +59,8 @@ class XMPPLayerTest : public CppUnit::TestFixture  		void testResetParser_FromSlot() {  			testling_->onElement.connect(boost::bind(&XMPPLayerTest::handleElementAndReset, this, _1)); -			testling_->parseData("<stream:stream to='example.com' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' ><presence/>"); -			testling_->parseData("<stream:stream to='example.com' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' ><presence/>"); +			testling_->parseData("<stream:stream to=\"example.com\" xmlns=\"jabber:client\" xmlns:stream=\"http://etherx.jabber.org/streams\" ><presence/>"); +			testling_->parseData("<stream:stream to=\"example.com\" xmlns=\"jabber:client\" xmlns:stream=\"http://etherx.jabber.org/streams\" ><presence/>");  			CPPUNIT_ASSERT_EQUAL(2, elementsReceived_);  			CPPUNIT_ASSERT_EQUAL(0, errorReceived_); @@ -70,7 +70,7 @@ class XMPPLayerTest : public CppUnit::TestFixture  			testling_->onWriteData.connect(boost::bind(&XMPPLayerTest::handleWriteData, this, _1));  			testling_->writeHeader("example.com"); -			CPPUNIT_ASSERT_EQUAL(String("<?xml version='1.0'?><stream:stream to='example.com' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0' >"), dataReceived_); +			CPPUNIT_ASSERT_EQUAL(String("<?xml version=\"1.0\"?><stream:stream xmlns=\"jabber:client\" xmlns:stream=\"http://etherx.jabber.org/streams\" version=\"1.0\" to=\"example.com\">"), dataReceived_);  		}  		void testWriteElement() { diff --git a/Swiften/StreamStack/XMPPLayer.cpp b/Swiften/StreamStack/XMPPLayer.cpp index 464d4b0..73d763a 100644 --- a/Swiften/StreamStack/XMPPLayer.cpp +++ b/Swiften/StreamStack/XMPPLayer.cpp @@ -20,8 +20,12 @@ XMPPLayer::~XMPPLayer() {  	delete xmppParser_;  } -void XMPPLayer::writeHeader(const String& domain) { -	onWriteData(ByteArray(xmppSerializer_->serializeHeader(domain))); +void XMPPLayer::writeHeader(const String& to) { +	onWriteData(ByteArray(xmppSerializer_->serializeHeader("", to))); +} + +void XMPPLayer::writeHeader(const String& from, const String& id) { +	onWriteData(ByteArray(xmppSerializer_->serializeHeader(from, "", id)));  }  void XMPPLayer::writeFooter() { @@ -56,8 +60,8 @@ void XMPPLayer::doResetParser() {  	resetParserAfterParse_ = false;  } -void XMPPLayer::handleStreamStart(const String& domain) { -	onStreamStart(domain); +void XMPPLayer::handleStreamStart(const String& from, const String& to, const String& id) { +	onStreamStart(from, to, id);  }  void XMPPLayer::handleElement(boost::shared_ptr<Element> stanza) { diff --git a/Swiften/StreamStack/XMPPLayer.h b/Swiften/StreamStack/XMPPLayer.h index e064d94..7437112 100644 --- a/Swiften/StreamStack/XMPPLayer.h +++ b/Swiften/StreamStack/XMPPLayer.h @@ -22,7 +22,8 @@ namespace Swift {  					PayloadSerializerCollection* payloadSerializers);  			~XMPPLayer(); -			void writeHeader(const String& domain); +			void writeHeader(const String& from, const String& id); +			void writeHeader(const String& to);  			void writeFooter();  			void writeElement(boost::shared_ptr<Element>);  			void writeData(const String& data); @@ -31,14 +32,14 @@ namespace Swift {  			void resetParser();  		public: -			boost::signal<void (const String& domain)> onStreamStart; +			boost::signal<void (const String& /* from */, const String& /* to */ , const String& /* id */)> onStreamStart;  			boost::signal<void (boost::shared_ptr<Element>)> onElement;  			boost::signal<void (const ByteArray&)> onWriteData;  			boost::signal<void (const ByteArray&)> onDataRead;  			boost::signal<void ()> onError;  		private: -			void handleStreamStart(const String&); +			void handleStreamStart(const String&, const String&, const String&);  			void handleElement(boost::shared_ptr<Element>);  			void handleStreamEnd(); | 
 Swift
 Swift