YARP
Yet Another Robot Platform
HttpCarrier.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2006-2020 Istituto Italiano di Tecnologia (IIT)
3  * Copyright (C) 2006-2010 RobotCub Consortium
4  * All rights reserved.
5  *
6  * This software may be modified and distributed under the terms of the
7  * BSD-3-Clause license. See the accompanying LICENSE file for details.
8  */
9 
11 
12 #include <yarp/os/Bottle.h>
14 #include <yarp/os/DummyConnector.h>
15 #include <yarp/os/ManagedBytes.h>
16 #include <yarp/os/Property.h>
17 #include <yarp/os/Route.h>
18 #include <yarp/os/SizedWriter.h>
20 
21 using namespace yarp::os;
22 using namespace yarp::os::impl;
23 
24 static std::string quoteFree(const std::string& src)
25 {
26  std::string result;
27  for (char ch : src) {
28  if (ch == '"') {
29  result += "&quot;";
30  } else {
31  result += ch;
32  }
33  }
34  return result;
35 }
36 
37 static bool asJson(std::string& accum,
38  yarp::os::Bottle* bot,
39  std::string* hint = nullptr);
40 
41 static bool asJson(std::string& accum,
42  yarp::os::Value& v)
43 {
44  if (v.isInt32() || v.isFloat64()) {
45  accum += v.toString();
46  return true;
47  }
48  if (v.isString() || v.isVocab()) {
49  std::string x = v.toString();
50  accum += "\"";
51  for (char ch : x) {
52  if (ch == '\n') {
53  accum += '\\';
54  accum += 'n';
55  } else if (ch == '\r') {
56  accum += '\\';
57  accum += 'r';
58  } else if (ch == '\0') {
59  accum += '\\';
60  accum += '0';
61  } else {
62  if (ch == '\\' || ch == '\"') {
63  accum += '\\';
64  }
65  accum += ch;
66  }
67  }
68  accum += "\"";
69  }
70  if (v.isList()) {
71  yarp::os::Bottle* bot = v.asList();
72  return asJson(accum, bot);
73  }
74  return false;
75 }
76 
77 static bool asJson(std::string& accum,
78  yarp::os::Bottle* bot,
79  std::string* hint)
80 {
81  if (bot == nullptr) {
82  return false;
83  }
84  bool struc = false;
85  bool struc_set = false;
86  int offset = 0;
87  int offset2 = 0;
88  std::string tag = bot->get(0).asString();
89  if (hint != nullptr) {
90  if ((*hint) == "list") {
91  struc = false;
92  struc_set = true;
93  } else if ((*hint) == "dict") {
94  struc = true;
95  struc_set = true;
96  }
97  }
98  if (!struc_set) {
99  if (tag == "list") {
100  struc = false;
101  offset = 1;
102  } else if (tag == "dict") {
103  struc = true;
104  offset = 1;
105  } else {
106  // auto-detect
107  struc = (bot->size() > 1);
108  if (bot->size() > 0) {
109  yarp::os::Value& v0 = bot->get(0);
110  if (!v0.isList()) {
111  offset2 = 1;
112  offset = 1;
113  }
114  }
115  for (size_t i = offset2; i < bot->size(); i++) {
116  yarp::os::Value& vi = bot->get(i);
117  if (!vi.isList()) {
118  struc = false;
119  break;
120  }
121  if (vi.asList()->size() != 2) {
122  struc = false;
123  break;
124  }
125  }
126  }
127  }
128  if (struc) {
129  // { ... }
130  accum += "{";
131  bool need_comma = false;
132  if (offset2 != 0) {
133  accum += "\"type\": ";
134  asJson(accum, bot->get(0));
135  need_comma = true;
136  }
137  for (size_t i = offset; i < bot->size(); i++) {
138  yarp::os::Bottle* boti = bot->get(i).asList();
139  if (boti == nullptr) {
140  continue;
141  }
142  if (need_comma) {
143  accum += ", ";
144  }
145  asJson(accum, boti->get(0));
146  accum += ": ";
147  asJson(accum, boti->get(1));
148  need_comma = true;
149  }
150  accum += "}";
151  return true;
152  }
153 
154  // [ ... ]
155  accum += "[";
156  if (offset2 != 0) {
157  offset--;
158  }
159  for (int i = offset; (size_t)i < bot->size(); i++) {
160  if (i > offset) {
161  accum += ", ";
162  }
163  asJson(accum, bot->get(i));
164  }
165  accum += "]";
166  return true;
167 }
168 
169 
170 yarp::os::impl::HttpTwoWayStream::HttpTwoWayStream(TwoWayStream* delegate, const char* txt, const char* prefix, yarp::os::Property& prop, bool writer) :
171  delegate(delegate)
172 {
173  this->isWriter = writer;
174  data = false;
175  filterData = false;
176  chunked = false;
177  if (writer) {
178  Bottle b;
179  b.addString(txt);
180  sis.add(b.toString());
181  sis.add("\n");
182  return;
183  }
184  std::string s(txt);
185  std::string sData;
186  Property& p = prop;
187  //p.fromQuery(txt);
188  format = p.check("format", Value("html")).asString();
189  outer = p.check("outer", Value("auto")).asString();
190  bool admin = p.check("admin");
191  bool req = p.check("req");
192  if (p.check("cmd")) {
193  s = p.check("cmd", Value("")).asString();
194  } else if (p.check("data") || req) {
195  if (req) {
196  s = p.check("req", Value("")).asString();
197  if (!p.check("format")) {
198  format = "json";
199  p.put("format", "json");
200  }
201  } else {
202  s = p.check("data", Value("")).asString();
203  }
204  s += " ";
205  std::string sFixed;
206  std::string var;
207  bool arg = false;
208  for (unsigned int i = 0; i < s.length(); i++) {
209  char ch = s[i];
210  if (arg) {
211  if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9') || (ch == '_')) {
212  var += ch;
213  } else {
214  arg = false;
215  sFixed += p.check(var, Value("")).toString();
216  if (i != s.length() - 1) {
217  sFixed += ch; // omit padding
218  }
219  var = "";
220  }
221  } else {
222  if (ch == '$') {
223  arg = true;
224  } else {
225  if (i != s.length() - 1) {
226  sFixed += ch; // omit padding
227  }
228  }
229  }
230  }
231 
232  sData = sFixed;
233  if (admin) {
234  s = std::string("a\n") + sFixed;
235  } else {
236  s = std::string("d\n") + sFixed;
237  }
238  }
239 
240 
241  std::string from = prefix;
242  from += "<input type=text name=data value=\"";
243  from += quoteFree(sData);
244 
245  from += "\"><input type=submit value=\"send data\"></form></p>\n";
246  from += "<pre>\n";
247 
248  bool classic = false;
249  // support old-style messages
250  if (s.length() <= 1) {
251  classic = true;
252  }
253  if (s.length() > 1) {
254  if (s[0] == '?' || s[1] == '?') {
255  classic = true;
256  }
257  if (s[0] == 'd' && s[1] == '\n') {
258  classic = true;
259  }
260  }
261  if (s.length() >= 4) {
262  if (s[0] == 'f' && s[1] == 'o' && s[2] == 'r' && s[3] == 'm') {
263  classic = true;
264  }
265  if (s[0] == 'd' && s[1] == 'a' && s[2] == 't' && s[3] == 'a') {
266  classic = true;
267  }
268  if (s[0] == 'f' && s[1] == 'a' && s[2] == 'v' && s[3] == 'i') {
269  // kill favicon.ico, sorry
270  classic = true;
271  }
272  }
273  if (req) {
274  classic = false;
275  }
276 
277  if (classic) {
278  std::string header = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n";
279  chunked = false;
280  if (s[0] == 'r') {
281  header += "Transfer-Encoding: chunked\r\n";
282  chunked = true;
283  }
284  header += "\r\n";
285  int N = 2 * 1024;
286  std::string body = from;
287  if (chunked) {
288  body += "Reading data from port...\n";
289  header += NetType::toHexString((int)(body.length() + N));
290  header += "\r\n";
291  }
292 
293  Bytes b1((char*)header.c_str(), header.length());
294  delegate->getOutputStream().write(b1);
295 
296  if (chunked) {
297  // chrome etc won't render until enough chars are received.
298  for (int i = 0; i < N; i++) {
299  delegate->getOutputStream().write(' ');
300  }
301  }
302 
303  Bytes b2((char*)body.c_str(), body.length());
304  delegate->getOutputStream().write(b2);
305  delegate->getOutputStream().write('\r');
306  delegate->getOutputStream().write('\n');
307  delegate->getOutputStream().flush();
308 
309  if (s.empty()) {
310  s = "*";
311  }
312  if (chunked) {
313  filterData = true;
314  }
315  for (char& ch : s) {
316  if (ch == ',') {
317  ch = '\n';
318  }
319  if (ch == '+') {
320  ch = ' ';
321  }
322  }
323  if (chunked) {
324  sis.add("r\n");
325  } else {
326  sis.add(s);
327  sis.add("\nq\n");
328  }
329 
330  } else {
331  chunked = true;
332  if (!req) {
333  if (admin) {
334  sis.add("a\n");
335  } else {
336  sis.add("d\n");
337  }
338  for (int i = 0; i < (int)s.length(); i++) {
339  if (s[i] == '/') {
340  s[i] = ' ';
341  }
342  if (s[i] == '?') {
343  s = s.substr(0, i);
344  break;
345  }
346  }
347  }
348  sis.add(s);
349  sis.add(" ");
350  sis.add(p.toString());
351  sis.add("\n");
352  }
353 }
354 
356 {
357  if (delegate != nullptr) {
358  delete delegate;
359  delegate = nullptr;
360  }
361 }
362 
364 {
365  return sis;
366 }
367 
369 {
370  return *this;
371 }
372 
374 {
375  return delegate->getLocalAddress();
376 }
377 
379 {
380  return delegate->getRemoteAddress();
381 }
382 
384 {
385  return true; //delegate->isOk();
386 }
387 
389 {
390  delegate->reset();
391 }
392 
394 { // throws
395  if (chunked || isWriter) {
396  delegate->getOutputStream().write(b);
397  } else {
398  for (size_t i = 0; i < b.length(); i++) {
399  apply(b.get()[i]);
400  }
401  }
402 }
403 
405 {
406  if (ch == '\r') {
407  return;
408  }
409  if (ch == '\n') {
410  proc = "";
412  if (addr.isValid()) {
413  if (addr.getCarrier() == "tcp" && (addr.getRegName().find("/quit") == std::string::npos)) {
414  proc += "<a href=\"http://";
415  proc += addr.getHost();
416  proc += ":";
417  proc += NetType::toString(addr.getPort());
418  proc += "\">";
419  proc += addr.getRegName();
420  proc += "</A> ";
421  size_t len = addr.getRegName().length();
422  size_t target = 30;
423  if (len < target) {
424  for (size_t i = 0; i < target - len; i++) {
425  proc += " ";
426  }
427  }
428  proc += "(";
429  proc += addr.toString();
430  proc += ")";
431  proc += "\n";
432  } else {
433  // Don't show non tcp connections
434  //proc += part;
435  //proc += "\n";
436  }
437  } else {
438  if ((part[0] == '\"' && part[1] == '[') || (part[0] == '+')) {
439  // translate this to a form
440  if (part[0] == '+') {
441  part[0] = ' ';
442  }
443  std::string org = part;
444  part = "<p><form method=post action='/form'>";
445  size_t i = 0;
446  for (i = 0; i < org.length(); i++) {
447  if (org[i] == '"') {
448  org[i] = ' ';
449  }
450  }
451  part += "<input type=hidden name=data value=\"";
452  part += org;
453  part += "\">";
454  part += org;
455  org += " ";
456  bool arg = false;
457  std::string var;
458  for (i = 0; i < org.length(); i++) {
459  char ch = org[i];
460  if (arg) {
461  if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9') || (ch == '_')) {
462  var += ch;
463  } else {
464  arg = false;
465  part += "\n ";
466  part += var;
467  part += " ";
468  part += "<input type=text name=";
469  part += var;
470  part += " size=5 value=\"\">";
471  var = "";
472  }
473  }
474  if (ch == '$') {
475  arg = true;
476  }
477  }
478  part += "<input type=submit value=\"go\">";
479  part += "</form></p>";
480  }
481  proc += part;
482  proc += "\n";
483  }
484  if (data || !filterData) {
485  Bytes tmp((char*)proc.c_str(), proc.length());
486  delegate->getOutputStream().write(tmp);
487  delegate->getOutputStream().flush();
488  }
489  data = false;
490  if (proc[0] == 'd' || proc[0] == 'D') {
491  data = true;
492  }
493  part = "";
494  } else {
495  part += ch;
496  }
497 }
498 
500 {
501  apply('\n');
502  apply('\n');
503  delegate->close();
504 }
505 
507 {
508  delegate->beginPacket();
509 }
510 
512 {
513  delegate->endPacket();
514 }
515 
517 {
518  sis.add("r\n");
519 }
520 
522 {
523  sis.add("q\n");
524 }
525 
527 {
528  return format == "json";
529 }
530 
532 {
533  return &outer;
534 }
535 
536 
538  url(""),
539  input(""),
540  urlDone(false),
541  expectPost(false),
542  contentLength(0),
543  stream(nullptr)
544 {
545 }
546 
548 {
549  return new HttpCarrier();
550 }
551 
553 {
554  return "http";
555 }
556 
557 bool yarp::os::impl::HttpCarrier::checkHeader(const Bytes& header, const char* prefix)
558 {
559  if (header.length() == 8) {
560  std::string target = prefix;
561  for (unsigned int i = 0; i < target.length(); i++) {
562  if (!(target[i] == header.get()[i])) {
563  return false;
564  }
565  }
566  return true;
567  }
568  return false;
569 }
570 
572 {
573  bool ok = checkHeader(header, "GET /");
574  if (!ok) {
575  // http carrier accepts POST /form but not general posts
576  // (leave that to xmlrpc carrier)
577  ok = checkHeader(header, "POST /fo");
578  } else {
579  // make sure it isn't a MJPEG stream get
580  ok = !checkHeader(header, "GET /?ac");
581  }
582  return ok;
583 }
584 
586 {
587  if (header.length() == 8) {
588  bool adding = false;
589  for (unsigned int j = 0; j < 8; j++) {
590  char ch = header.get()[j];
591  if (adding) {
592  if (ch != ' ') {
593  url += ch;
594  } else {
595  urlDone = true;
596  break;
597  }
598  }
599  if (ch == '/') {
600  adding = true;
601  }
602  }
603  }
604 }
605 
607 {
608  if (header.length() == 8) {
609  std::string target = "GET / HT";
610  for (int i = 0; i < 8; i++) {
611  header.get()[i] = target[i];
612  }
613  }
614 }
615 
617 {
618  return false;
619 }
620 
622 {
623  return true;
624 }
625 
626 
628 {
629  return true;
630 }
631 
633 {
634  std::string target = "GET / HTTP/1.0\r\n";
635  std::string path = proto.getRoute().getToName();
636  if (path.size() >= 2) {
637  target = "GET " + path + " HTTP/1.0\r\n";
638  }
639  Contact host = proto.getRoute().getToContact();
640  if (!host.getHost().empty()) {
641  target += "Host: ";
642  target += host.getHost();
643  target += "\r\n";
644  }
645  target += "\r\n";
646  Bytes b((char*)target.c_str(), target.length());
647  proto.os().write(b);
648  return true;
649 }
650 
652 {
653  Route route = proto.getRoute();
654  route.setFromName("web");
655  proto.setRoute(route);
656  std::string remainder = proto.is().readLine();
657  if (!urlDone) {
658  for (char i : remainder) {
659  if (i != ' ') {
660  url += i;
661  } else {
662  break;
663  }
664  }
665  }
666 
667  bool done = false;
668  expectPost = false;
669  contentLength = 0;
670  while (!done) {
671  std::string result = proto.is().readLine();
672  if (result.empty()) {
673  done = true;
674  } else {
675  //printf(">>> %s\n", result.c_str());
676  Bottle b;
677  b.fromString(result);
678  if (b.get(0).asString() == "Content-Length:") {
679  //printf("]]] got length %d\n", b.get(1).asInt32());
680  contentLength = b.get(1).asInt32();
681  }
682  if (b.get(0).asString() == "Content-Type:") {
683  //printf("]]] got type %s\n", b.get(1).asString());
684  if (b.get(1).asString() == "application/x-www-form-urlencoded") {
685  expectPost = true;
686  }
687  }
688  }
689  }
690 
691  if (expectPost) {
692  //printf("[[[this is a post message of length %d]]]\n", contentLength);
693  ManagedBytes blk(contentLength + 1);
694  Bytes start(blk.get(), contentLength);
695  proto.is().readFull(start);
696  blk.get()[contentLength] = '\0';
697  //printf("message: %s\n", blk.get());
698  input = blk.get();
699  } else {
700  //printf("message: %s\n", url.c_str());
701  input = url;
702  }
703  prop.fromQuery(input.c_str());
704  prop.put("REQUEST_URI", url);
705  //printf("Property %s\n", prop.toString().c_str());
706 
708  Contact me = proto.getStreams().getLocalAddress();
709 
710  std::string from = "<html><head><link href=\"http://";
711  from += home.getHost();
712  from += ":";
713  from += NetType::toString(home.getPort());
714  from += R"(/web/main.css" rel="stylesheet" type="text/css"/></head><body bgcolor='#ffffcc'><h1>yarp port )";
715  from += proto.getRoute().getToName();
716  from += "</h1>\n";
717 
718  from += "<p>(<a href=\"http://";
719  from += home.getHost();
720  from += ":";
721  from += NetType::toString(home.getPort());
722  from += "/data=list\">All ports</a>)&nbsp;&nbsp;\n";
723 
724  from += "(<a href=\"http://";
725  from += me.getHost();
726  from += ":";
727  from += NetType::toString(me.getPort());
728  from += "/\">connections</a>)&nbsp;&nbsp;\n";
729 
730  from += "(<a href=\"http://";
731  from += me.getHost();
732  from += ":";
733  from += NetType::toString(me.getPort());
734  from += "/data=help\">help</a>)&nbsp;&nbsp;\n";
735 
736  from += "(<a href=\"http://";
737  from += me.getHost();
738  from += ":";
739  from += NetType::toString(me.getPort());
740  from += "/r\">read</a>)&nbsp;&nbsp;\n";
741 
742  from += "</p>\n";
743  from += "<p>\n";
744  from += R"(<form method="post" action="http://)";
745  from += me.getHost();
746  from += ":";
747  from += NetType::toString(me.getPort());
748  from += "/form\">";
749 
750  prefix = from;
751 
752 
753  //Bytes b2((char*)from.c_str(), from.length());
754  //proto.os().write(b2);
755  //proto.os().flush();
756  // Message gets finished by the stream
757 
758  return proto.os().isOk();
759 }
760 
762 {
763  input = "";
764  yarp::conf::ssize_t len = 1;
765  while (len > 0) {
766  char buf[2];
767  Bytes b((char*)&buf[0], 1);
768  len = proto.is().read(b);
769  if (len > 0) {
770  buf[len] = '\0';
771  input += std::string(buf, len);
772  }
773  }
774  stream = new HttpTwoWayStream(proto.giveStreams(),
775  input.c_str(),
776  prefix.c_str(),
777  prop,
778  true);
779  proto.takeStreams(stream);
780  return true;
781 }
782 
783 
785 {
786  YARP_UNUSED(proto);
787  YARP_UNUSED(writer);
788  // no index
789  return true;
790 }
791 
793 {
794  YARP_UNUSED(proto);
795  // no index
796  return true;
797 }
798 
800 {
801  YARP_UNUSED(proto);
802  // no acknowledgement
803  return true;
804 }
805 
807 {
808  YARP_UNUSED(proto);
809  // no acknowledgement
810  return true;
811 }
812 
814 {
815  stream = new HttpTwoWayStream(proto.giveStreams(),
816  input.c_str(),
817  prefix.c_str(),
818  prop,
819  false);
820  proto.takeStreams(stream);
821  return true;
822 }
823 
825 {
826  DummyConnector con;
827  con.setTextMode(true);
828  for (size_t i = writer.headerLength(); i < writer.length(); i++) {
829  con.getWriter().appendBlock(writer.data(i), writer.length(i));
830  }
831  Bottle b;
832  b.read(con.getReader());
833 
834  std::string body = b.find("web").toString();
835  if (body.length() != 0) {
836  std::string header;
837  header += NetType::toHexString((int)body.length());
838  header += "\r\n";
839 
840  Bytes b2((char*)header.c_str(), header.length());
841  proto.os().write(b2);
842 
843  Bytes b3((char*)body.c_str(), body.length());
844  proto.os().write(b3);
845 
846  proto.os().write('\r');
847  proto.os().write('\n');
848 
849  } else {
850  std::string txt = b.toString() + "\r\n";
851  std::string header;
852  header += NetType::toHexString((int)txt.length());
853  header += "\r\n";
854  Bytes b2((char*)header.c_str(), header.length());
855  proto.os().write(b2);
856  Bytes b3((char*)txt.c_str(), txt.length());
857  proto.os().write(b3);
858  proto.os().write('\r');
859  proto.os().write('\n');
860  }
861  proto.os().flush();
862  return proto.os().isOk();
863 }
864 
866 {
867  DummyConnector con;
868  con.setTextMode(true);
869  for (size_t i = writer.headerLength(); i < writer.length(); i++) {
870  con.getWriter().appendBlock(writer.data(i), writer.length(i));
871  }
872  Bottle b;
873  b.read(con.getReader());
874 
875  std::string mime = b.check("mime", Value("text/html")).asString();
876 
877  std::string body;
878 
879  bool using_json = false;
880  if (stream != nullptr) {
881  if (stream->useJson()) {
882  mime = "text/json";
883  asJson(body, &b, stream->typeHint());
884  using_json = true;
885  }
886  }
887 
888  if (b.check("web") && !using_json) {
889  body = b.find("web").toString();
890  }
891 
892  if (b.check("stream") && !using_json) {
893  std::string header("HTTP/1.1 200 OK\r\nContent-Type: ");
894  header += mime;
895  header += "\r\n";
896  header += "Transfer-Encoding: chunked\r\n";
897  header += "\r\n";
898  int N = 2 * 1024;
899  header += NetType::toHexString((int)body.length() + N);
900  header += "\r\n";
901 
902  Bytes b2((char*)header.c_str(), header.length());
903  proto.os().write(b2);
904 
905  // chrome etc won't render until enough chars are received.
906  for (int i = 0; i < N; i++) {
907  proto.os().write(' ');
908  }
909 
910  Bytes b3((char*)body.c_str(), body.length());
911  proto.os().write(b3);
912 
913  proto.os().write('\r');
914  proto.os().write('\n');
915 
916 
917  if (stream != nullptr) {
918  stream->flip();
919  }
920  return true;
921  }
922 
923  if (stream != nullptr) {
924  stream->finish();
925  }
926 
927  // Could check response codes, mime types here.
928 
929  if (body.length() != 0 || using_json) {
930  std::string mime = b.check("mime", Value(using_json ? "application/json" : "text/html")).asString();
931  std::string header("HTTP/1.1 200 OK\nContent-Type: ");
932  header += mime;
933  header += "\n";
934  header += "Access-Control-Allow-Origin: *\n";
935  header += "\n";
936  Bytes b2((char*)header.c_str(), header.length());
937  proto.os().write(b2);
938 
939  //body = b.toString();
940  Bytes b3((char*)body.c_str(), body.length());
941  proto.os().write(b3);
942  } else {
943  writer.write(proto.os());
944  }
945  proto.os().flush();
946  return proto.os().isOk();
947 }
yarp::os::DummyConnector
A dummy connection to test yarp::os::Portable implementations.
Definition: DummyConnector.h:35
yarp::os::TwoWayStream::getLocalAddress
virtual const Contact & getLocalAddress() const =0
Get the address of the local side of the stream.
yarp::os::TwoWayStream
A stream which can be asked to perform bidirectional communication.
Definition: TwoWayStream.h:29
yarp::os::Bottle
A simple collection of objects that can be described and transmitted in a portable way.
Definition: Bottle.h:73
yarp::os::SizedWriter::length
virtual size_t length() const =0
yarp::os::impl::HttpCarrier::expectSenderSpecifier
bool expectSenderSpecifier(ConnectionState &proto) override
Expect the name of the sending port.
Definition: HttpCarrier.cpp:651
yarp::os::impl::HttpTwoWayStream
Minimal http connection support.
Definition: HttpCarrier.h:51
yarp::os::Bottle::toString
std::string toString() const override
Gives a human-readable textual representation of the bottle.
Definition: Bottle.cpp:214
yarp::os::Property::put
void put(const std::string &key, const std::string &value)
Associate the given key with the given string.
Definition: Property.cpp:998
yarp::os::ConnectionWriter::appendBlock
virtual void appendBlock(const char *data, size_t len)=0
Send a block of data to the network connection.
yarp::os::Bottle::size
size_type size() const
Gets the number of elements in the bottle.
Definition: Bottle.cpp:254
yarp::os::impl::HttpTwoWayStream::reset
void reset() override
Reset the stream.
Definition: HttpCarrier.cpp:388
yarp::os::Carrier
A base class for connection types (tcp, mcast, shmem, ...) which are called carriers in YARP.
Definition: Carrier.h:48
yarp::os::impl::HttpTwoWayStream::finish
void finish()
Definition: HttpCarrier.cpp:521
yarp::os::ConnectionState::giveStreams
virtual TwoWayStream * giveStreams()=0
Take ownership of the streams associated with the connection.
yarp::os::OutputStream::write
virtual void write(char ch)
Write a single byte to the stream.
Definition: OutputStream.cpp:17
yarp::os::impl::HttpTwoWayStream::typeHint
std::string * typeHint()
Definition: HttpCarrier.cpp:531
yarp::os::OutputStream
Simple specification of the minimum functions needed from output streams.
Definition: OutputStream.h:25
yarp::os::impl::HttpCarrier::expectAck
bool expectAck(ConnectionState &proto) override
Receive an acknowledgement, if expected for this carrier.
Definition: HttpCarrier.cpp:806
yarp::os::impl::HttpTwoWayStream::beginPacket
void beginPacket() override
Mark the beginning of a logical packet.
Definition: HttpCarrier.cpp:506
yarp::os::impl::HttpCarrier::sendHeader
bool sendHeader(ConnectionState &proto) override
Write a header appropriate to the carrier to the connection, followed by any carrier-specific data.
Definition: HttpCarrier.cpp:632
yarp::os::impl::HttpTwoWayStream::getRemoteAddress
const Contact & getRemoteAddress() const override
Get the address of the remote side of the stream.
Definition: HttpCarrier.cpp:378
yarp::os::impl::HttpCarrier::HttpCarrier
HttpCarrier()
Definition: HttpCarrier.cpp:537
yarp::os::StringInputStream::add
void add(const std::string &txt)
Definition: StringInputStream.h:47
yarp::os::impl::HttpTwoWayStream::~HttpTwoWayStream
virtual ~HttpTwoWayStream()
Definition: HttpCarrier.cpp:355
yarp::os::Bottle::fromString
void fromString(const std::string &text)
Initializes bottle from a string.
Definition: Bottle.cpp:207
YARP_UNUSED
#define YARP_UNUSED(var)
Definition: api.h:159
yarp::os::impl::HttpTwoWayStream::close
void close() override
Terminate the stream.
Definition: HttpCarrier.cpp:499
yarp::os::impl::HttpTwoWayStream::getOutputStream
OutputStream & getOutputStream() override
Get an OutputStream to write to.
Definition: HttpCarrier.cpp:368
yarp::os::SizedWriter::write
virtual void write(OutputStream &os)
Definition: SizedWriter.cpp:19
yarp::os::Route
Information about a connection between two ports.
Definition: Route.h:32
yarp::os::DummyConnector::getReader
ConnectionReader & getReader(ConnectionWriter *replyWriter=nullptr)
Get the dummy ConnectionReader loaded with whatever was written the ConnectionWriter since it was las...
Definition: DummyConnector.cpp:117
yarp::os::Contact::getRegName
std::string getRegName() const
Get the name associated with this Contact.
Definition: Contact.cpp:220
yarp::os::Bottle::find
Value & find(const std::string &key) const override
Gets a value corresponding to a given keyword.
Definition: Bottle.cpp:290
yarp::os::impl::HttpCarrier::getHeader
void getHeader(Bytes &header) const override
Provide 8 bytes describing this connection sufficiently to allow the other side of a connection to se...
Definition: HttpCarrier.cpp:606
yarp::os::TwoWayStream::getOutputStream
virtual OutputStream & getOutputStream()=0
Get an OutputStream to write to.
yarp::os::Contact::toString
std::string toString() const
Get a textual representation of the Contact.
Definition: Contact.cpp:306
yarp::os::Bottle::check
bool check(const std::string &key) const override
Check if there exists a property of the given name.
Definition: Bottle.cpp:280
yarp::os::impl::HttpCarrier::sendIndex
bool sendIndex(ConnectionState &proto, SizedWriter &writer) override
Definition: HttpCarrier.cpp:784
yarp::os::Value::isString
virtual bool isString() const
Checks if value is a string.
Definition: Value.cpp:159
quoteFree
static std::string quoteFree(const std::string &src)
Definition: HttpCarrier.cpp:24
yarp::os::impl::HttpCarrier::requireAck
bool requireAck() const override
Check if carrier has flow control, requiring sent messages to be acknowledged by recipient.
Definition: HttpCarrier.cpp:616
yarp::os::SizedWriter::headerLength
virtual size_t headerLength() const =0
yarp::os::impl::HttpTwoWayStream::getInputStream
InputStream & getInputStream() override
Get an InputStream to read from.
Definition: HttpCarrier.cpp:363
yarp::os::ConnectionState::takeStreams
virtual void takeStreams(TwoWayStream *streams)=0
Provide streams to be used with the connection.
yarp::os::ConnectionState::os
OutputStream & os()
Shorthand for getOutputStream()
Definition: ConnectionState.h:117
yarp::os::ConnectionState::getRoute
virtual const Route & getRoute() const =0
Get the route associated with this connection.
ManagedBytes.h
yarp::os::ManagedBytes
An abstraction for a block of bytes, with optional responsibility for allocating/destroying that bloc...
Definition: ManagedBytes.h:25
Route.h
yarp::os::Bottle::get
Value & get(size_type index) const
Reads a Value v from a certain part of the list.
Definition: Bottle.cpp:249
ConnectionState.h
yarp::os::Contact::getPort
int getPort() const
Get the port number associated with this Contact for socket communication.
Definition: Contact.cpp:242
yarp::os::Property::toString
std::string toString() const override
Return a standard text representation of the content of the object.
Definition: Property.cpp:1052
Property.h
asJson
static bool asJson(std::string &accum, yarp::os::Bottle *bot, std::string *hint=nullptr)
Definition: HttpCarrier.cpp:77
yarp::os::Value::isFloat64
virtual bool isFloat64() const
Checks if value is a 64-bit floating point number.
Definition: Value.cpp:153
DummyConnector.h
yarp::os::Bytes::get
const char * get() const
Definition: Bytes.cpp:30
yarp::os::DummyConnector::getWriter
ConnectionWriter & getWriter()
Get the dummy ConnectionWriter loaded with whatever was written the ConnectionWriter since it was las...
Definition: DummyConnector.cpp:112
yarp::os::Contact::getCarrier
std::string getCarrier() const
Get the carrier associated with this Contact for socket communication.
Definition: Contact.cpp:253
yarp::os::ConnectionState::setRoute
virtual void setRoute(const Route &route)=0
Set the route associated with this connection.
yarp::os::NetType::toHexString
static std::string toHexString(int x)
Definition: NetType.cpp:116
yarp::os::Bytes::length
size_t length() const
Definition: Bytes.cpp:25
yarp::os::Value::asString
virtual std::string asString() const
Get string value.
Definition: Value.cpp:237
yarp::os::impl::HttpTwoWayStream::write
void write(const Bytes &b) override
Write a block of bytes to the stream.
Definition: HttpCarrier.cpp:393
yarp::os::impl::HttpCarrier::getName
std::string getName() const override
Get the name of this connection type ("tcp", "mcast", "shmem", ...)
Definition: HttpCarrier.cpp:552
yarp::conf::ssize_t
::ssize_t ssize_t
Definition: numeric.h:60
yarp::os::InputStream::readLine
std::string readLine(const char terminal='\n', bool *success=nullptr)
Read a block of text terminated with a specific marker (or EOF).
Definition: InputStream.cpp:57
yarp::os::impl::HttpTwoWayStream::flip
void flip()
Definition: HttpCarrier.cpp:516
yarp::os::OutputStream::flush
virtual void flush()
Make sure all pending write operations are finished.
Definition: OutputStream.cpp:28
yarp::os::impl::HttpCarrier::checkHeader
bool checkHeader(const Bytes &header, const char *prefix)
Definition: HttpCarrier.cpp:557
yarp::os::impl::HttpCarrier::create
Carrier * create() const override
Factory method.
Definition: HttpCarrier.cpp:547
yarp::os::impl::HttpCarrier::reply
bool reply(ConnectionState &proto, SizedWriter &writer) override
Definition: HttpCarrier.cpp:865
NameClient.h
yarp::os::Property::check
bool check(const std::string &key) const override
Check if there exists a property of the given name.
Definition: Property.cpp:1024
yarp::os::impl::HttpTwoWayStream::getLocalAddress
const Contact & getLocalAddress() const override
Get the address of the local side of the stream.
Definition: HttpCarrier.cpp:373
yarp::os::ConnectionState::getStreams
virtual TwoWayStream & getStreams()=0
Access the streams associated with the connection.
yarp::os::Bottle::addString
void addString(const char *str)
Places a string in the bottle, at the end of the list.
Definition: Bottle.cpp:173
yarp::os::Bytes
A simple abstraction for a block of bytes.
Definition: Bytes.h:28
yarp::os::impl::HttpCarrier::expectIndex
bool expectIndex(ConnectionState &proto) override
Expect a message header, if there is one for this carrier.
Definition: HttpCarrier.cpp:792
yarp::os::impl::HttpTwoWayStream::apply
virtual void apply(char ch)
Definition: HttpCarrier.cpp:404
yarp::os::impl::HttpTwoWayStream::isOk
bool isOk() const override
Check if the stream is ok or in an error state.
Definition: HttpCarrier.cpp:383
yarp::os::Value::isList
virtual bool isList() const
Checks if value is a list.
Definition: Value.cpp:165
yarp::os::impl::HttpCarrier::write
bool write(ConnectionState &proto, SizedWriter &writer) override
Write a message.
Definition: HttpCarrier.cpp:824
HttpCarrier.h
yarp::os::NetType::toString
static std::string toString(int x)
Definition: NetType.cpp:138
yarp::os::ConnectionState
The basic state of a connection - route, streams in use, etc.
Definition: ConnectionState.h:31
yarp::os::impl::HttpCarrier::isTextMode
bool isTextMode() const override
Check if carrier is textual in nature.
Definition: HttpCarrier.cpp:621
yarp::os::OutputStream::isOk
virtual bool isOk() const =0
Check if the stream is ok or in an error state.
yarp::os::impl::HttpCarrier::sendAck
bool sendAck(ConnectionState &proto) override
Send an acknowledgement, if needed for this carrier.
Definition: HttpCarrier.cpp:799
yarp::os::Value::asInt32
virtual std::int32_t asInt32() const
Get 32-bit integer value.
Definition: Value.cpp:207
yarp::os::impl::HttpCarrier::respondToHeader
bool respondToHeader(ConnectionState &proto) override
Respond to the header.
Definition: HttpCarrier.cpp:813
yarp::os::impl::HttpCarrier
Communicating via http.
Definition: HttpCarrier.h:100
yarp::os::InputStream::readFull
yarp::conf::ssize_t readFull(Bytes &b)
Keep reading until buffer is full.
Definition: InputStream.cpp:99
yarp::os::DummyConnector::setTextMode
void setTextMode(bool textmode)
Set the textMode of the dummy connection.
Definition: DummyConnector.cpp:102
yarp::os::InputStream::read
virtual int read()
Read and return a single byte.
Definition: InputStream.cpp:23
yarp::os
An interface to the operating system, including Port based communication.
Definition: AbstractCarrier.h:17
yarp::os::impl::HttpCarrier::expectReplyToHeader
bool expectReplyToHeader(ConnectionState &proto) override
Process reply to header, if one is expected for this carrier.
Definition: HttpCarrier.cpp:761
yarp::os::Route::setFromName
void setFromName(const std::string &fromName)
Set the source of the route.
Definition: Route.cpp:101
yarp::os::Contact::isValid
bool isValid() const
Checks if a Contact is tagged as valid.
Definition: Contact.cpp:301
yarp::os::impl::HttpCarrier::supportReply
bool supportReply() const override
This flag is used by YARP to determine whether the connection can carry RPC traffic,...
Definition: HttpCarrier.cpp:627
yarp::os::Route::getToContact
const Contact & getToContact() const
Get the destination contact of the route, if available.
Definition: Route.cpp:116
yarp::os::Contact::getHost
std::string getHost() const
Get the host name associated with this Contact for socket communication.
Definition: Contact.cpp:231
yarp::os::ConnectionState::is
InputStream & is()
Shorthand for getInputStream()
Definition: ConnectionState.h:125
yarp::os::Bottle::read
bool read(ConnectionReader &reader) override
Set the bottle's value based on input from a network connection.
Definition: Bottle.cpp:243
yarp::os::Contact
Represents how to reach a part of a YARP network.
Definition: Contact.h:39
yarp::os::Route::getToName
const std::string & getToName() const
Get the destination of the route.
Definition: Route.cpp:106
yarp::os::ManagedBytes::get
const char * get() const
Definition: ManagedBytes.cpp:154
yarp::os::Value::asList
virtual Bottle * asList() const
Get list value.
Definition: Value.cpp:243
yarp::os::SizedWriter::data
virtual const char * data(size_t index) const =0
yarp::os::impl::NameClient::extractAddress
static Contact extractAddress(const std::string &txt)
Extract an address from its text representation.
Definition: NameClient.cpp:273
yarp::os::Value::toString
std::string toString() const override
Return a standard text representation of the content of the object.
Definition: Value.cpp:359
yarp::os::Value
A single value (typically within a Bottle).
Definition: Value.h:47
yarp::os::NetworkBase::getNameServerContact
static Contact getNameServerContact()
Get the contact information for the port associated with the nameserver (usually "/root",...
Definition: Network.cpp:1363
yarp::os::impl::HttpTwoWayStream::endPacket
void endPacket() override
Mark the end of a logical packet (see beginPacket).
Definition: HttpCarrier.cpp:511
yarp::os::InputStream
Simple specification of the minimum functions needed from input streams.
Definition: InputStream.h:29
yarp::os::impl::HttpTwoWayStream::useJson
bool useJson()
Definition: HttpCarrier.cpp:526
yarp::os::impl
The components from which ports and connections are built.
yarp::os::impl::HttpCarrier::setParameters
void setParameters(const Bytes &header) override
Configure this carrier based on the first 8 bytes of the connection.
Definition: HttpCarrier.cpp:585
SizedWriter.h
Bottle.h
yarp::os::SizedWriter
Minimal requirements for an efficient Writer.
Definition: SizedWriter.h:36
yarp::os::Value::isVocab
virtual bool isVocab() const
Checks if value is a vocabulary identifier.
Definition: Value.cpp:177
yarp::os::Property
A class for storing options and configuration information.
Definition: Property.h:37
yarp::os::Value::isInt32
virtual bool isInt32() const
Checks if value is a 32-bit integer.
Definition: Value.cpp:135
yarp::os::impl::HttpTwoWayStream::HttpTwoWayStream
HttpTwoWayStream(TwoWayStream *delegate, const char *txt, const char *prefix, yarp::os::Property &prop, bool writer)
Definition: HttpCarrier.cpp:170