bool Protocol::write(SizedWriter& writer) { // End any current write. writer.stopWrite(); // Skip if this connection is not active (e.g. when there are several // logical mcast connections but only one write is actually needed). if (!getConnection().isActive()) return false; this->writer = &writer; bool replied = false; yAssert(delegate != nullptr); getStreams().beginPacket(); // Message begins. bool ok = delegate->write(*this, writer); getStreams().endPacket(); // Message ends. PortReader* reply = writer.getReplyHandler(); if (reply != nullptr) { if (!delegate->supportReply()) { // We are expected to get a reply, but cannot. YARP_INFO(log, std::string("connection ") + getRoute().toString() + " does not support replies (try \"tcp\" or \"text_ack\")"); } if (ok) { // Read reply. reader.reset(is(), &getStreams(), getRoute(), messageLen, delegate->isTextMode(), delegate->isBareMode()); replied = reply->read(reader); } } expectAck(); // Expect acknowledgement (carrier-specific). this->writer = nullptr; return replied; }
bool AbstractCarrier::write(ConnectionState& proto, SizedWriter& writer) { bool ok = sendIndex(proto,writer); if (!ok) { return false; } writer.write(proto.os()); proto.os().flush(); return proto.os().isOk(); }
bool AbstractCarrier::defaultSendIndex(ConnectionState& proto, SizedWriter& writer) { writeYarpInt(10, proto); int len = (int)writer.length(); char lens[] = { (char)len, (char)1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1 }; Bytes b(lens, 10); OutputStream& os = proto.os(); os.write(b); NetInt32 numberSrc; Bytes number((char*)&numberSrc, sizeof(NetInt32)); for (int i=0; i<len; i++) { NetType::netInt((int)writer.length(i), number); os.write(number); } NetType::netInt(0, number); os.write(number); return os.isOk(); }
bool yarp::os::impl::NameserCarrier::write(Protocol& proto, SizedWriter& writer) { String target = firstSend?"VER ":"NAME_SERVER "; Bytes b((char*)target.c_str(),target.length()); proto.os().write(b); String txt; // ancient nameserver can't deal with quotes for (size_t i=0; i<writer.length(); i++) { for (size_t j=0; j<writer.length(i); j++) { char ch = writer.data(i)[j]; if (ch!='\"') { txt += ch; } } } Bytes b2((char*)txt.c_str(),txt.length()); proto.os().write(b2); proto.os().flush(); firstSend = false; return proto.os().isOk(); }
bool yarp::os::impl::HttpCarrier::write(Protocol& proto, SizedWriter& writer) { DummyConnector con; con.setTextMode(true); for (size_t i=writer.headerLength(); i<writer.length(); i++) { con.getWriter().appendBlock(writer.data(i),writer.length(i)); } Bottle b; b.read(con.getReader()); ConstString body = b.find("web").toString(); if (body.length()!=0) { ConstString header; header += NetType::toHexString(body.length()).c_str(); header += "\r\n"; Bytes b2((char*)header.c_str(),header.length()); proto.os().write(b2); Bytes b3((char*)body.c_str(),body.length()); proto.os().write(b3); proto.os().write('\r'); proto.os().write('\n'); } else { ConstString txt = b.toString() + "\r\n"; ConstString header; header += NetType::toHexString(txt.length()).c_str(); header += "\r\n"; Bytes b2((char*)header.c_str(),header.length()); proto.os().write(b2); Bytes b3((char*)txt.c_str(),txt.length()); proto.os().write(b3); proto.os().write('\r'); proto.os().write('\n'); } proto.os().flush(); return proto.os().isOk(); }
bool WireTwiddler::write(yarp::os::Bottle& bot, yarp::os::ManagedBytes& data) { StringOutputStream sos; if (!writer) { writer = ConnectionWriter::createBufferedConnectionWriter(); } if (!writer) { return false; } SizedWriter *buf = writer->getBuffer(); if (!buf) { return false; } buf->clear(); bot.write(*writer); WireTwiddlerWriter twiddled_output(*buf,*this); twiddled_output.write(sos); std::string result = sos.toString(); data = ManagedBytes(Bytes((char*)result.c_str(),result.length()),false); data.copy(); return true; }
bool yarp::os::impl::LocalCarrier::write(ConnectionState& proto, SizedWriter& writer) { YARP_UNUSED(proto); yarp::os::Portable *ref = writer.getReference(); if (ref != nullptr) { peerMutex.lock(); if (peer != nullptr) { peer->accept(ref); } else { YARP_ERROR(Logger::get(), "local send failed - write without peer"); } peerMutex.unlock(); } else { YARP_ERROR(Logger::get(), "local send failed - no object"); } return true; }
void Protocol::reply(SizedWriter& writer) { writer.stopWrite(); delegate->reply(*this, writer); pendingReply = false; }
virtual bool write(Protocol& proto, SizedWriter& writer) { bool ok = sendIndex(proto); if (!ok) return false; writer.write(proto.os()); return proto.os().isOk(); }
bool yarp::os::impl::HttpCarrier::reply(Protocol& proto, SizedWriter& writer) { DummyConnector con; con.setTextMode(true); for (size_t i=writer.headerLength(); i<writer.length(); i++) { con.getWriter().appendBlock(writer.data(i),writer.length(i)); } Bottle b; b.read(con.getReader()); ConstString mime = b.check("mime",Value("text/html")).asString(); ConstString body; bool using_json = false; if (stream!=NULL) { if (stream->useJson()) { mime = "text/json"; asJson(body,&b,stream->typeHint()); using_json = true; } } if (b.check("web")&&!using_json) { body = b.find("web").toString(); } if (b.check("stream")&&!using_json) { String header("HTTP/1.1 200 OK\r\nContent-Type: "); header += mime; header += "\r\n"; header += "Transfer-Encoding: chunked\r\n"; header += "\r\n"; int N = 2*1024; header += NetType::toHexString(body.length()+N); header += "\r\n"; Bytes b2((char*)header.c_str(),header.length()); proto.os().write(b2); // chrome etc won't render until enough chars are received. for (int i=0; i<N; i++) { proto.os().write(' '); } Bytes b3((char*)body.c_str(),body.length()); proto.os().write(b3); proto.os().write('\r'); proto.os().write('\n'); if (stream!=NULL) { stream->flip(); } return true; } if (stream!=NULL) { stream->finish(); } // Could check response codes, mime types here. if (body.length()!=0 || using_json) { ConstString mime = b.check("mime",Value("text/html")).asString(); String header("HTTP/1.1 200 OK\nContent-Type: "); header += mime; header += "\n"; header += "Access-Control-Allow-Origin: *\n"; header += "\n"; Bytes b2((char*)header.c_str(),header.length()); proto.os().write(b2); //body = b.toString(); Bytes b3((char*)body.c_str(),body.length()); proto.os().write(b3); } else { writer.write(proto.os()); } proto.os().flush(); return proto.os().isOk(); }
bool TcpRosCarrier::reply(Protocol& proto, SizedWriter& writer) { // don't need to do anything special for now. writer.write(proto.os()); return proto.os().isOk(); }
bool XmlRpcCarrier::write(Protocol& proto, SizedWriter& writer) { //XmlRpc::setVerbosity(10); StringOutputStream sos; StringInputStream sis; writer.write(sos); sis.reset(sos.toString()); String header; if (sender) { header = NetType::readLine(sis); } String body = NetType::readLine(sis); //printf("Asked to write: hdr %s body %s\n", // header.c_str(), body.c_str()); Value v; //printf("HEADER %s\n", header.c_str()); if (header[0]=='q') { body = "yarp.quit"; // XMLRPC does not need a quit message, this should get stripped return false; } Bottle *bot = v.asList(); //Bottle aux; bot->fromString(body.c_str()); ConstString methodName; if (sender) { methodName = bot->get(0).toString(); *bot = bot->tail(); } XmlRpcValue args; if (bot->size()==1) { toXmlRpcValue(bot->get(0),args); } else { toXmlRpcValue(v,args); } //printf("xmlrpc block to write is %s\n", args.toXml().c_str()); std::string req; if (sender) { const Address& addr = host.isValid()?host:proto.getStreams().getRemoteAddress(); XmlRpcClient c(addr.getName().c_str(),(addr.getPort()>0)?addr.getPort():80); c.generateRequest(methodName.c_str(),args); req = c.getRequest(); } else { XmlRpcServerConnection c(0,NULL); c.generateResponse(args.toXml()); req = c.getResponse(); } int start = 0; //printf("converts to %s\n", req.c_str()); if (sender) { if (req.length()<8) { fprintf(stderr, "XmlRpcCarrier fail, %s:%d\n", __FILE__, __LINE__); return false; } for (int i=0; i<(int)req.length(); i++) { if (req[i] == '\n') { start++; break; } start++; } if (!firstRound) { Bytes b((char*)http.c_str(),http.length()); proto.os().write(b); } firstRound = false; } Bytes b((char*)req.c_str()+start,req.length()-start); //printf("WRITING [%s]\n", req.c_str()+start); proto.os().write(b); return proto.os().isOk(); }
bool Carrier::reply(ConnectionState& proto, SizedWriter& writer) { writer.write(proto.os()); return proto.os().isOk(); }
bool XmlRpcCarrier::write(ConnectionState& proto, SizedWriter& writer) { StringOutputStream sos; StringInputStream sis; writer.write(sos); sis.reset(sos.toString()); ConstString header; if (sender) { header = sis.readLine(); } ConstString body = sis.readLine(); Value v; if (header.length()>0 && header[0]=='q') { body = "yarp.quit"; // XMLRPC does not need a quit message, this should get stripped return false; } Bottle *bot = v.asList(); bot->fromString(body.c_str()); ConstString methodName; if (sender) { methodName = bot->get(0).toString(); *bot = bot->tail(); } XmlRpcValue args; if (bot->size()==1) { toXmlRpcValue(bot->get(0),args); } else { toXmlRpcValue(v,args); } std::string req; if (sender) { const Contact& addr = host.isValid()?host:proto.getStreams().getRemoteAddress(); XmlRpcClient c(addr.getHost().c_str(),(addr.getPort()>0)?addr.getPort():80); c.generateRequest(methodName.c_str(),args); req = c.getRequest(); } else { XmlRpcServerConnection c(0,NULL); c.generateResponse(args.toXml()); req = c.getResponse(); } int start = 0; if (sender) { if (req.length()<8) { fprintf(stderr, "XmlRpcCarrier fail, %s:%d\n", __FILE__, __LINE__); return false; } for (int i=0; i<(int)req.length(); i++) { if (req[i] == '\n') { start++; break; } start++; } if (!firstRound) { Bytes b((char*)http.c_str(),http.length()); proto.os().write(b); } firstRound = false; } Bytes b((char*)req.c_str()+start,req.length()-start); proto.os().write(b); return proto.os().isOk(); }