void BOSHConnectionPool::handleConnectFinished(bool error, BOSHConnection::ref connection) {
	if (error) {
		onSessionTerminated(boost::make_shared<BOSHError>(BOSHError::UndefinedCondition));
		/*TODO: We can probably manage to not terminate the stream here and use the rid/ack retry
		 * logic to just swallow the error and try again (some number of tries).
		 */
	}
	else {
		if (sid.empty()) {
			connection->startStream(to, rid);
		}
		if (pendingRestart) {
			restartStream();
		}
		tryToSendQueuedData();
	}
}
Exemple #2
0
void BOSHConnection::handleDataRead(std::shared_ptr<SafeByteArray> data) {
    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"));
            onSessionTerminated(errorType == BOSHError::NoError ? std::shared_ptr<BOSHError>() : std::make_shared<BOSHError>(errorType));
        }
        buffer_.clear();
        if (waitingForStartResponse_) {
            waitingForStartResponse_ = false;
            sid_ = parser.getBody()->attributes.getAttribute("sid");
            std::string requestsString = parser.getBody()->attributes.getAttribute("requests");
            size_t requests = 2;
            if (!requestsString.empty()) {
                try {
                    requests = boost::lexical_cast<size_t>(requestsString);
                }
                catch (const boost::bad_lexical_cast&) {
                }
            }
            onSessionStarted(sid_, requests);
        }
        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);
    }

}
void JingleSession::setInitiated(IJingleApplication *AApplication)
{
    FStatus=IJingle::Initiated;
    disconnect(parent());
    setParent(AApplication->instance());
    connect(this,SIGNAL(sessionInitiated(Jid,QString)),parent(),SLOT(onSessionInitiated(Jid,QString)));
    connect(this,SIGNAL(sessionAccepted(Jid,QString)),parent(),SLOT(onSessionAccepted(Jid,QString)));
    connect(this,SIGNAL(sessionConnected(Jid,QString)),parent(),SLOT(onSessionConnected(Jid,QString)));
    connect(this,SIGNAL(sessionTerminated(Jid,QString,IJingle::SessionStatus,IJingle::Reason)),parent(),SLOT(onSessionTerminated(Jid,QString,IJingle::SessionStatus,IJingle::Reason)));
    connect(this,SIGNAL(sessionInformed(QDomElement)),parent(),SLOT(onSessionInformed(QDomElement)));
    connect(this,SIGNAL(receivingData(Jid,QString)),parent(),SLOT(onDataReceived(Jid,QString)));
    connect(this,SIGNAL(actionAcknowledged(Jid,QString,IJingle::Action,IJingle::CommandRespond,IJingle::SessionStatus,Jid,IJingle::Reason)),parent(),SLOT(onActionAcknowledged(Jid,QString,IJingle::Action,IJingle::CommandRespond,IJingle::SessionStatus,Jid,IJingle::Reason)));
    emit sessionInitiated(FThisParty, FSid);
}
JingleSession::JingleSession(const JingleStanza &AStanza):
    FValid(false),FOutgoing(false),FThisParty(AStanza.to()),FOtherParty(AStanza.from()),FActionId(),FAction(IJingle::NoAction)
{
    QDomElement jingle=AStanza.firstElement("jingle", NS_JINGLE);
    if (!jingle.isNull())
    {
        QString action=jingle.attribute("action");
        if (action=="session-initiate")
        {
            FSid=jingle.attribute("sid");
            for (QDomElement content=jingle.firstChildElement("content"); !content.isNull(); content=content.nextSiblingElement("content"))
            {
                QDomElement description=content.firstChildElement("description");
                if (!description.isNull())
                {
                    FApplicationNamespace = description.namespaceURI();
                    QDomElement transport=content.firstChildElement("transport");
                    if (!transport.isNull())
                    {
                        setParent(FJingle->appByNS(FApplicationNamespace)->instance());
                        if (!addContent(content.attribute("name"), description, transport, content.attribute("initiator")==QString("responder")))
                            qWarning() << "addContent() failed!";
                        FValid=true;
                        connect(this,SIGNAL(sessionAccepted(Jid,QString)),parent(), SLOT(onSessionAccepted(Jid,QString)));
                        connect(this,SIGNAL(sessionTerminated(Jid,QString,IJingle::SessionStatus,IJingle::Reason)),parent(),SLOT(onSessionTerminated(Jid,QString,IJingle::SessionStatus,IJingle::Reason)));                        
                        connect(this,SIGNAL(sessionInformed(QDomElement)),parent(),SLOT(onSessionInformed(QDomElement)));                        
                        connect(this,SIGNAL(receivingData(Jid,QString)),parent(),SLOT(onDataReceived(Jid,QString)));
                        connect(this,SIGNAL(actionAcknowledged(Jid,QString,IJingle::Action,IJingle::CommandRespond,IJingle::SessionStatus,Jid,IJingle::Reason)),parent(),SLOT(onActionAcknowledged(Jid,QString,IJingle::Action,IJingle::CommandRespond,IJingle::SessionStatus,Jid,IJingle::Reason)));
                    }
                }
            }
            if (!FSessions.contains(FThisParty) || !FSessions[FThisParty].contains(FSid))
                FSessions[FThisParty].insert(FSid, this);
            else
                qWarning() << "Session exists!";
        }
    }
}
JingleSession::JingleSession(const Jid &AThisParty, const Jid &AOtherParty, const QString &AApplicationNS):
    QObject(FJingle->appByNS(AApplicationNS)->instance()),FValid(false), FOutgoing(true),
    FApplicationNamespace(AApplicationNS),FThisParty(AThisParty), FOtherParty(AOtherParty),
    FSid(getSid(AThisParty)), FActionId(), FAction(IJingle::NoAction), FReason(IJingle::NoReason)
{
    FSessions[FThisParty].insert(FSid, this);
    if (FThisParty.isValid() && FOtherParty.isValid())
    {
        FValid=true;
        connect(this,SIGNAL(sessionInitiated(Jid,QString)),parent(),SLOT(onSessionInitiated(Jid,QString)));
        connect(this,SIGNAL(sessionAccepted(Jid,QString)),parent(),SLOT(onSessionAccepted(Jid,QString)));
        connect(this,SIGNAL(sessionConnected(Jid,QString)),parent(),SLOT(onSessionConnected(Jid,QString)));
        connect(this,SIGNAL(sessionTerminated(Jid,QString,IJingle::SessionStatus,IJingle::Reason)),parent(),SLOT(onSessionTerminated(Jid,QString,IJingle::SessionStatus,IJingle::Reason)));
        connect(this,SIGNAL(sessionInformed(QDomElement)),parent(),SLOT(onSessionInformed(QDomElement)));
        connect(this,SIGNAL(receivingData(Jid,QString)),parent(),SLOT(onDataReceived(Jid,QString)));
        connect(this,SIGNAL(actionAcknowledged(Jid,QString,IJingle::Action,IJingle::CommandRespond,IJingle::SessionStatus,Jid,IJingle::Reason)),parent(),SLOT(onActionAcknowledged(Jid,QString,IJingle::Action,IJingle::CommandRespond,IJingle::SessionStatus,Jid,IJingle::Reason)));
    }
}