void BoshTransport::connect(const sf::Url & url, const StringMap & additionalArgs, int timeOutMs, const ResultCallback & callback){ if (mState != Unconnected) { Log (LogError) << LOGID << "Wrong State " << toString (mState) << std::endl; return xcall (abind (callback, error::WrongState)); } mUrl = url; mRid = randomRid(); mRidRecv = mRid; // Setting Parameters StringMap args = additionalArgs; args["rid"] = toString (mRid); setIfNotSet (&args, "ver", "1.10"); setIfNotSet (&args, "wait", "60"); setIfNotSet (&args, "hold", "1"); setIfNotSet (&args, "xmlns", "http://jabber.org/protocol/httpbind"); BoshNodeBuilder builder; for (StringMap::const_iterator i = args.begin(); i != args.end(); i++){ builder.addAttribute(i->first,i->second); } // Send it out... mState = Connecting; executeRequest (sf::createByteArrayPtr(builder.toString()), timeOutMs, abind (dMemFun (this, &BoshTransport::onConnectReply), callback)); }
void BoshTransport::startNextRequest (const StringMap & additionalArgs, const ResultCallback & callback) { if (mState != Connected && mState != Closing){ Log (LogWarning) << LOGID << "Strange state" << std::endl; notifyAsync (callback, error::WrongState); return; } // Building Message mRid++; BoshNodeBuilder builder; builder.addAttribute("rid", toString(mRid)); builder.addAttribute("sid", mSid); builder.addAttribute("xmlns", "http://jabber.org/protocol/httpbind"); for (StringMap::const_iterator i = additionalArgs.begin(); i != additionalArgs.end(); i++) { builder.addAttribute(i->first.c_str(), i->second); } // Adding data.. for (std::deque<ByteArrayPtr>::const_iterator i = mOutputBuffer.begin(); i != mOutputBuffer.end(); i++) { builder.addContent(*i); } mOutputBuffer.clear(); // Sending sf::ByteArrayPtr data = sf::createByteArrayPtr (builder.toString()); mOpenRids[mRid] = data; mOpenRidCount++; executeRequest (data, mLongPollTimeoutMs, abind (dMemFun (this, &BoshTransport::onRequestReply), mRid, callback)); }
int testNodeBuildAndParse () { BoshNodeBuilder builder; builder.addAttribute("hello", "world"); builder.addAttribute("and", "anotherone"); builder.addContent (sf::createByteArrayPtr ("<bla>Hi dude</bla>")); builder.addContent (sf::createByteArrayPtr ("<bli></bli>")); String s = builder.toString(); printf ("Serialized code: %s\n", s.c_str()); BoshNodeParser parser; Error e = parser.parse(s); tcheck1(!e); tcheck1(parser.attribute("hello") == "world"); tcheck1(parser.attribute("and") == "anotherone"); String back = parser.content(); XMLChunk chunk = xml::parseDocument(back.c_str(), back.length()); tcheck1 (chunk.getChild("bla").text() == "Hi dude"); tcheck1 (chunk.getHasChild("bli")); return 0; }
int testReuse () { // Connections shall be kept open... // Note: Prosody itself doesn't seem to do that // but NGINX does it. HttpContext httpContext; BoshNodeBuilder builder; builder.addAttribute("content", "text/xml; charset=utf-8"); builder.addAttribute("from", "autotest1@localhost"); builder.addAttribute("hold", "1"); builder.addAttribute("to", "localhost"); builder.addAttribute ("rid", "3000"); builder.addAttribute ("xmlns","http://jabber.org/protocol/httpbind"); HttpRequest req; req.start ("POST", "https://localhost/http-bind/"); req.addHeader("Content-Type", "text/xml; charset=utf-8"); req.addContent (sf::createByteArrayPtr(builder.toString())); req.end(); std::pair<Error, HttpResponsePtr> res = httpContext.syncRequest(req, 60000); tcheck1(!res.first); test::millisleep_locked(1000); tcheck1 (httpContext.pendingConnections() == 1); return 0; }