diff options
| author | Remko Tronçon <git@el-tramo.be> | 2011-12-24 14:27:33 (GMT) |
|---|---|---|
| committer | Remko Tronçon <git@el-tramo.be> | 2011-12-24 14:44:44 (GMT) |
| commit | c060049e759571ae02a3a970c6a3088e099e5c9f (patch) | |
| tree | 8512e2ca0ae0fba16238651b9d0edbb74e085b16 /Swiften/Network/BOSHConnection.cpp | |
| parent | b453b3bf94dcd40d71c30fd0053f7110cb52b211 (diff) | |
| download | swift-contrib-c060049e759571ae02a3a970c6a3088e099e5c9f.zip swift-contrib-c060049e759571ae02a3a970c6a3088e099e5c9f.tar.bz2 | |
Some BOSH refactoring.
Diffstat (limited to 'Swiften/Network/BOSHConnection.cpp')
| -rw-r--r-- | Swiften/Network/BOSHConnection.cpp | 34 |
1 files changed, 15 insertions, 19 deletions
diff --git a/Swiften/Network/BOSHConnection.cpp b/Swiften/Network/BOSHConnection.cpp index 09548e9..ea84400 100644 --- a/Swiften/Network/BOSHConnection.cpp +++ b/Swiften/Network/BOSHConnection.cpp @@ -17,84 +17,79 @@ #include <boost/lexical_cast.hpp> #include <string> #include <Swiften/Network/ConnectionFactory.h> #include <Swiften/Base/Log.h> #include <Swiften/Base/String.h> #include <Swiften/Base/Concat.h> #include <Swiften/Base/ByteArray.h> #include <Swiften/Network/HostAddressPort.h> #include <Swiften/Network/TLSConnection.h> #include <Swiften/Parser/BOSHBodyExtractor.h> namespace Swift { BOSHConnection::BOSHConnection(const URL& boshURL, ConnectionFactory* connectionFactory, XMLParserFactory* parserFactory, TLSContextFactory* tlsFactory) : boshURL_(boshURL), connectionFactory_(connectionFactory), parserFactory_(parserFactory), sid_(), waitingForStartResponse_(false), pending_(false), tlsFactory_(tlsFactory), connectionReady_(false) { } BOSHConnection::~BOSHConnection() { if (connection_) { connection_->onConnectFinished.disconnect(boost::bind(&BOSHConnection::handleConnectionConnectFinished, shared_from_this(), _1)); connection_->onDataRead.disconnect(boost::bind(&BOSHConnection::handleDataRead, shared_from_this(), _1)); connection_->onDisconnected.disconnect(boost::bind(&BOSHConnection::handleDisconnected, shared_from_this(), _1)); } disconnect(); } -void BOSHConnection::connect(const HostAddressPort& server) { - /* FIXME: Redundant parameter */ +void BOSHConnection::connect() { Connection::ref rawConnection = connectionFactory_->createConnection(); connection_ = (boshURL_.getScheme() == "https") ? boost::make_shared<TLSConnection>(rawConnection, tlsFactory_) : rawConnection; connection_->onConnectFinished.connect(boost::bind(&BOSHConnection::handleConnectionConnectFinished, shared_from_this(), _1)); connection_->onDataRead.connect(boost::bind(&BOSHConnection::handleDataRead, shared_from_this(), _1)); connection_->onDisconnected.connect(boost::bind(&BOSHConnection::handleDisconnected, shared_from_this(), _1)); connection_->connect(HostAddressPort(HostAddress(boshURL_.getHost()), boshURL_.getPort())); } -void BOSHConnection::listen() { - assert(false); -} - void BOSHConnection::disconnect() { if(connection_) { connection_->disconnect(); sid_ = ""; } } void BOSHConnection::restartStream() { write(createSafeByteArray(""), true, false); } void BOSHConnection::terminateStream() { write(createSafeByteArray(""), false, true); } void BOSHConnection::write(const SafeByteArray& data) { write(data, false, false); } std::pair<SafeByteArray, size_t> BOSHConnection::createHTTPRequest(const SafeByteArray& data, bool streamRestart, bool terminate, long rid, const std::string& sid, const URL& boshURL) { size_t size; std::stringstream content; SafeByteArray contentTail = createSafeByteArray("</body>"); std::stringstream header; content << "<body rid='" << rid << "' sid='" << sid << "'"; if (streamRestart) { content << " xmpp:restart='true' xmlns:xmpp='urn:xmpp:xbosh'"; } if (terminate) { content << " type='terminate'"; } content << " xmlns='http://jabber.org/protocol/httpbind'>"; @@ -138,147 +133,148 @@ void BOSHConnection::handleConnectionConnectFinished(bool error) { void BOSHConnection::startStream(const std::string& to, unsigned long rid) { assert(connectionReady_); // Session Creation Request std::stringstream content; std::stringstream header; content << "<body content='text/xml; charset=utf-8'" << " hold='1'" << " to='" << to << "'" << " rid='" << rid << "'" << " ver='1.6'" << " wait='60'" /* FIXME: we probably want this configurable*/ /*<< " ack='0'" FIXME: support acks */ << " xml:lang='en'" << " xmlns:xmpp='urn:xmpp:bosh'" << " xmpp:version='1.0'" << " xmlns='http://jabber.org/protocol/httpbind' />"; std::string contentString = content.str(); header << "POST /" << boshURL_.getPath() << " HTTP/1.1\r\n" << "Host: " << boshURL_.getHost() << ":" << boshURL_.getPort() << "\r\n" /*<< "Accept-Encoding: deflate\r\n"*/ << "Content-Type: text/xml; charset=utf-8\r\n" << "Content-Length: " << contentString.size() << "\r\n\r\n" << contentString; waitingForStartResponse_ = true; SafeByteArray safeHeader = createSafeByteArray(header.str()); onBOSHDataWritten(safeHeader); connection_->write(safeHeader); SWIFT_LOG(debug) << "write stream header: " << safeByteArrayToString(safeHeader) << std::endl; } void BOSHConnection::handleDataRead(boost::shared_ptr<SafeByteArray> data) { - onBOSHDataRead(*data.get()); - buffer_ = concat(buffer_, *data.get()); + onBOSHDataRead(*data); + buffer_ = concat(buffer_, *data); std::string response = safeByteArrayToString(buffer_); if (response.find("\r\n\r\n") == std::string::npos) { onBOSHDataRead(createSafeByteArray("[[Previous read incomplete, pending]]")); return; } std::string httpCode = response.substr(response.find(" ") + 1, 3); if (httpCode != "200") { onHTTPError(httpCode); return; } BOSHBodyExtractor parser(parserFactory_, createByteArray(response.substr(response.find("\r\n\r\n") + 4))); if (parser.getBody()) { - if ((*parser.getBody()).attributes.getAttribute("type") == "terminate") { - BOSHError::Type errorType = parseTerminationCondition((*parser.getBody()).attributes.getAttribute("condition")); + if (parser.getBody()->attributes.getAttribute("type") == "terminate") { + BOSHError::Type errorType = parseTerminationCondition(parser.getBody()->attributes.getAttribute("condition")); onSessionTerminated(errorType == BOSHError::NoError ? boost::shared_ptr<BOSHError>() : boost::make_shared<BOSHError>(errorType)); } buffer_.clear(); if (waitingForStartResponse_) { waitingForStartResponse_ = false; - sid_ = (*parser.getBody()).attributes.getAttribute("sid"); - std::string requestsString = (*parser.getBody()).attributes.getAttribute("requests"); + sid_ = parser.getBody()->attributes.getAttribute("sid"); + std::string requestsString = parser.getBody()->attributes.getAttribute("requests"); int requests = 2; if (!requestsString.empty()) { - requests = boost::lexical_cast<size_t>(requestsString); + try { + requests = boost::lexical_cast<size_t>(requestsString); + } + catch (const boost::bad_lexical_cast&) { + } } onSessionStarted(sid_, requests); } - SafeByteArray payload = createSafeByteArray((*parser.getBody()).content); + SafeByteArray payload = createSafeByteArray(parser.getBody()->content); /* Say we're good to go again, so don't add anything after here in the method */ pending_ = false; onXMPPDataRead(payload); } } BOSHError::Type BOSHConnection::parseTerminationCondition(const std::string& text) { BOSHError::Type condition = BOSHError::UndefinedCondition; if (text == "bad-request") { condition = BOSHError::BadRequest; } else if (text == "host-gone") { condition = BOSHError::HostGone; } else if (text == "host-unknown") { condition = BOSHError::HostUnknown; } else if (text == "improper-addressing") { condition = BOSHError::ImproperAddressing; } else if (text == "internal-server-error") { condition = BOSHError::InternalServerError; } else if (text == "item-not-found") { condition = BOSHError::ItemNotFound; } else if (text == "other-request") { condition = BOSHError::OtherRequest; } else if (text == "policy-violation") { condition = BOSHError::PolicyViolation; } else if (text == "remote-connection-failed") { condition = BOSHError::RemoteConnectionFailed; } else if (text == "remote-stream-error") { condition = BOSHError::RemoteStreamError; } else if (text == "see-other-uri") { condition = BOSHError::SeeOtherURI; } else if (text == "system-shutdown") { condition = BOSHError::SystemShutdown; } else if (text == "") { condition = BOSHError::NoError; } return condition; } const std::string& BOSHConnection::getSID() { return sid_; } -void BOSHConnection::setRID(unsigned long rid) { +void BOSHConnection::setRID(unsigned long long rid) { rid_ = rid; } void BOSHConnection::setSID(const std::string& sid) { sid_ = sid; } -void BOSHConnection::handleDisconnected(const boost::optional<Error>& error) { +void BOSHConnection::handleDisconnected(const boost::optional<Connection::Error>& error) { onDisconnected(error); sid_ = ""; connectionReady_ = false; } -HostAddressPort BOSHConnection::getLocalAddress() const { - return connection_->getLocalAddress(); -} bool BOSHConnection::isReadyToSend() { /* Without pipelining you need to not send more without first receiving the response */ /* With pipelining you can. Assuming we can't, here */ return connectionReady_ && !pending_ && !waitingForStartResponse_ && !sid_.empty(); } } |
Swift