From 6ca206b0d0645e50a8a2c59ebd134f9c0f164b9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remko=20Tron=C3=A7on?= Date: Mon, 13 Jul 2009 09:17:57 +0200 Subject: Server stream header support. 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 #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 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 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 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(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("")); + CPPUNIT_ASSERT(testling.parse("")); + + CPPUNIT_ASSERT_EQUAL(1, static_cast(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) : 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; }; 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) { 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) = 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(new StreamFeaturesSerializer())); } -String XMPPSerializer::serializeHeader(const String& domain) const { - return ""; +String XMPPSerializer::serializeHeader(const String& from, const String& to, const String& id) const { + String result = " 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 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 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) { } 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 #include +#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 connection, PayloadParserFactoryCollection* payloadParserFactories, PayloadSerializerCollection* payloadSerializers); @@ -31,11 +33,13 @@ namespace Swift { void handleStreamStart(const String& domain); private: + String id_; boost::shared_ptr 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(""); + testling_->parseData(""); testling_->resetParser(); - testling_->parseData(""); + testling_->parseData(""); testling_->parseData(""); 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(""); - testling_->parseData(""); + testling_->parseData(""); + testling_->parseData(""); 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(""), dataReceived_); + CPPUNIT_ASSERT_EQUAL(String(""), 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 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); void writeData(const String& data); @@ -31,14 +32,14 @@ namespace Swift { void resetParser(); public: - boost::signal onStreamStart; + boost::signal onStreamStart; boost::signal)> onElement; boost::signal onWriteData; boost::signal onDataRead; boost::signal onError; private: - void handleStreamStart(const String&); + void handleStreamStart(const String&, const String&, const String&); void handleElement(boost::shared_ptr); void handleStreamEnd(); -- cgit v0.10.2-6-g49f6