summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThilo Cestonaro <thilo@cestona.ro>2011-09-28 22:03:14 (GMT)
committerKevin Smith <git@kismith.co.uk>2011-12-13 08:17:58 (GMT)
commitfd17fe0d239f97cedebe4ceffa234155bd299b68 (patch)
tree010ae5155e6e807b548861304657a25699487e1f /Swiften/Network
parent7d19f0d81371d86d530d0e7083a04db914ce6745 (diff)
downloadswift-fd17fe0d239f97cedebe4ceffa234155bd299b68.zip
swift-fd17fe0d239f97cedebe4ceffa234155bd299b68.tar.bz2
BOSH implementation started
License: This patch is BSD-licensed, see http://www.opensource.org/licenses/bsd-license.php
Diffstat (limited to 'Swiften/Network')
-rw-r--r--Swiften/Network/BOSHConnection.cpp132
-rw-r--r--Swiften/Network/BOSHConnection.h52
-rw-r--r--Swiften/Network/BOSHConnectionFactory.cpp21
-rw-r--r--Swiften/Network/BOSHConnectionFactory.h22
-rw-r--r--Swiften/Network/SConscript2
5 files changed, 229 insertions, 0 deletions
diff --git a/Swiften/Network/BOSHConnection.cpp b/Swiften/Network/BOSHConnection.cpp
new file mode 100644
index 0000000..549c652
--- /dev/null
+++ b/Swiften/Network/BOSHConnection.cpp
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2011 Thilo Cestonaro
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include "BOSHConnection.h"
+#include <boost/bind.hpp>
+#include <boost/thread.hpp>
+#include <string>
+
+#include <Swiften/Network/ConnectionFactory.h>
+#include <Swiften/Base/Log.h>
+#include <Swiften/Base/String.h>
+#include <Swiften/Base/ByteArray.h>
+#include <Swiften/Network/HostAddressPort.h>
+#include <Swiften/Parser/BOSHParser.h>
+
+namespace Swift {
+
+ BOSHConnection::BOSHConnection(ConnectionFactory* connectionFactory)
+ : connectionFactory_(connectionFactory), server_(HostAddressPort(HostAddress("0.0.0.0"), 0)), sid_()
+ {
+ reopenAfterAction = true;
+ }
+
+ BOSHConnection::~BOSHConnection() {
+ if (newConnection_) {
+ newConnection_->onDataRead.disconnect(boost::bind(&BOSHConnection::handleDataRead, shared_from_this(), _1));
+ newConnection_->onDisconnected.disconnect(boost::bind(&BOSHConnection::handleDisconnected, shared_from_this(), _1));
+ }
+ if (currentConnection_) {
+ currentConnection_->onDataRead.disconnect(boost::bind(&BOSHConnection::handleDataRead, shared_from_this(), _1));
+ currentConnection_->onDisconnected.disconnect(boost::bind(&BOSHConnection::handleDisconnected, shared_from_this(), _1));
+ }
+ }
+
+ void BOSHConnection::connect(const HostAddressPort& server) {
+ server_ = server;
+ newConnection_ = connectionFactory_->createConnection();
+ newConnection_->onConnectFinished.connect(boost::bind(&BOSHConnection::handleConnectionConnectFinished, shared_from_this(), _1));
+ newConnection_->onDataRead.connect(boost::bind(&BOSHConnection::handleDataRead, shared_from_this(), _1));
+ newConnection_->onDisconnected.connect(boost::bind(&BOSHConnection::handleDisconnected, shared_from_this(), _1));
+ SWIFT_LOG(debug) << "connect to server " << server.getAddress().toString() << ":" << server.getPort() << std::endl;
+ newConnection_->connect(HostAddressPort(HostAddress("85.10.192.88"), 5280));
+ }
+
+ void BOSHConnection::listen() {
+ assert(false);
+ }
+
+ void BOSHConnection::disconnect() {
+ if(newConnection_)
+ newConnection_->disconnect();
+
+ if(currentConnection_)
+ currentConnection_->disconnect();
+ }
+
+ void BOSHConnection::write(const SafeByteArray& data) {
+ SWIFT_LOG(debug) << "write data: " << safeByteArrayToString(data) << std::endl;
+ }
+
+ void BOSHConnection::handleConnectionConnectFinished(bool error) {
+ newConnection_->onConnectFinished.disconnect(boost::bind(&BOSHConnection::handleConnectionConnectFinished, shared_from_this(), _1));
+ if(error) {
+ onConnectFinished(true);
+ return;
+ }
+
+ if(sid_.size() == 0) {
+ // Session Creation Request
+ std::stringstream content;
+ std::stringstream header;
+
+ content << "<body content='text/xml; charset=utf-8'"
+ << " from='ephraim@0x10.de'"
+ << " hold='1'"
+ << " to='0x10.de'"
+ << " ver='1.6'"
+ << " wait='60'"
+ << " ack='1'"
+ << " xml:lang='en'"
+ << " xmlns='http://jabber.org/protocol/httpbind' />\r\n";
+
+ header << "POST /http-bind HTTP/1.1\r\n"
+ << "Host: 0x10.de:5280\r\n"
+ << "Accept-Encoding: deflate\r\n"
+ << "Content-Type: text/xml; charset=utf-8\r\n"
+ << "Content-Length: " << content.str().size() << "\r\n\r\n"
+ << content.str();
+
+ SWIFT_LOG(debug) << "request: ";
+ newConnection_->write(createSafeByteArray(header.str()));
+ }
+ }
+
+ void BOSHConnection::handleDataRead(const SafeByteArray& data) {
+ std::string response = safeByteArrayToString(data);
+ assert(response.find("\r\n\r\n") != std::string::npos);
+
+ SWIFT_LOG(debug) << "response: " << response.substr(response.find("\r\n\r\n") + 4) << std::endl;
+
+ BOSHParser parser;
+ if(parser.parse(response.substr(response.find("\r\n\r\n") + 4))) {
+ sid_ = parser.getAttribute("sid");
+ onConnectFinished(false);
+ int bodyStartElementLength = 0;
+ bool inQuote = false;
+ for(size_t i= 0; i < response.size(); i++) {
+ if(response.c_str()[i] == '\'' || response.c_str()[i] == '"') {
+ inQuote = !inQuote;
+ }
+ else if(!inQuote && response.c_str()[i] == '>') {
+ bodyStartElementLength = i + 1;
+ break;
+ }
+ }
+ SafeByteArray payload = createSafeByteArray(response.substr(bodyStartElementLength, response.size() - bodyStartElementLength - 7));
+ SWIFT_LOG(debug) << "payload: " << safeByteArrayToString(payload) << std::endl;
+ onDataRead(payload);
+ }
+ }
+
+ void BOSHConnection::handleDisconnected(const boost::optional<Error>& error) {
+ onDisconnected(error);
+ }
+
+ HostAddressPort BOSHConnection::getLocalAddress() const {
+ return newConnection_->getLocalAddress();
+ }
+}
diff --git a/Swiften/Network/BOSHConnection.h b/Swiften/Network/BOSHConnection.h
new file mode 100644
index 0000000..0da92ba
--- /dev/null
+++ b/Swiften/Network/BOSHConnection.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2011 Thilo Cestonaro
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <boost/enable_shared_from_this.hpp>
+
+#include <Swiften/Network/Connection.h>
+#include <Swiften/Network/HostAddressPort.h>
+#include <Swiften/Base/String.h>
+
+namespace boost {
+ class thread;
+ namespace system {
+ class error_code;
+ }
+}
+
+namespace Swift {
+ class ConnectionFactory;
+
+ class BOSHConnection : public Connection, public boost::enable_shared_from_this<BOSHConnection> {
+ public:
+ typedef boost::shared_ptr<BOSHConnection> ref;
+ static ref create(ConnectionFactory* connectionFactory) {
+ return ref(new BOSHConnection(connectionFactory));
+ }
+ virtual ~BOSHConnection();
+ virtual void listen();
+ virtual void connect(const HostAddressPort& address);
+ virtual void disconnect();
+ virtual void write(const SafeByteArray& data);
+ virtual HostAddressPort getLocalAddress() const;
+
+ private:
+ BOSHConnection(ConnectionFactory* connectionFactory);
+
+ void handleConnectionConnectFinished(bool error);
+ void handleDataRead(const SafeByteArray& data);
+ void handleDisconnected(const boost::optional<Error>& error);
+
+ bool reopenAfterAction;
+ ConnectionFactory* connectionFactory_;
+ HostAddressPort server_;
+ boost::shared_ptr<Connection> newConnection_;
+ boost::shared_ptr<Connection> currentConnection_;
+ std::string sid_;
+ };
+}
diff --git a/Swiften/Network/BOSHConnectionFactory.cpp b/Swiften/Network/BOSHConnectionFactory.cpp
new file mode 100644
index 0000000..4c49cae
--- /dev/null
+++ b/Swiften/Network/BOSHConnectionFactory.cpp
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2011 Thilo Cestonaro
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include "BOSHConnectionFactory.h"
+#include <Swiften/Network/BOSHConnection.h>
+
+namespace Swift {
+
+BOSHConnectionFactory::BOSHConnectionFactory(ConnectionFactory* connectionFactory) {
+ connectionFactory_ = connectionFactory;
+
+}
+
+boost::shared_ptr<Connection> BOSHConnectionFactory::createConnection() {
+ return BOSHConnection::create(connectionFactory_);
+}
+
+}
diff --git a/Swiften/Network/BOSHConnectionFactory.h b/Swiften/Network/BOSHConnectionFactory.h
new file mode 100644
index 0000000..7431cf4
--- /dev/null
+++ b/Swiften/Network/BOSHConnectionFactory.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2011 Thilo Cestonaro
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Network/ConnectionFactory.h>
+#include <Swiften/Network/HostAddressPort.h>
+
+namespace Swift {
+ class BOSHConnectionFactory : public ConnectionFactory {
+ public:
+ BOSHConnectionFactory(ConnectionFactory* connectionFactory);
+
+ virtual boost::shared_ptr<Connection> createConnection();
+
+ private:
+ ConnectionFactory* connectionFactory_;
+ };
+}
diff --git a/Swiften/Network/SConscript b/Swiften/Network/SConscript
index 49df18f..399cec8 100644
--- a/Swiften/Network/SConscript
+++ b/Swiften/Network/SConscript
@@ -15,6 +15,8 @@ sourceList = [
"BoostConnectionServer.cpp",
"BoostConnectionServerFactory.cpp",
"BoostIOServiceThread.cpp",
+ "BOSHConnection.cpp",
+ "BOSHConnectionFactory.cpp"
"ConnectionFactory.cpp",
"ConnectionServer.cpp",
"ConnectionServerFactory.cpp",