YARP
Yet Another Robot Platform
WebSocketCarrier.cpp
Go to the documentation of this file.
1 /*
2  * SPDX-FileCopyrightText: 2006-2021 Istituto Italiano di Tecnologia (IIT)
3  * SPDX-License-Identifier: BSD-3-Clause
4  */
5 
6 #include "WebSocketCarrier.h"
7 #include "WebSocketStream.h"
8 
9 #include <yarp/os/ManagedBytes.h>
10 #include <yarp/os/Route.h>
11 
12 
13 using namespace yarp::os;
14 
15 
17  "yarp.carrier.websocket",
21  nullptr)
22 
23 
25 {
26 }
27 
29 {
31  return new WebSocketCarrier();
32 }
33 
34 
35 std::string WebSocketCarrier::getName() const
36 {
38  return "websocket";
39 }
40 
41 
43 {
45  if (header.length() != header_lenght) {
46  return false;
47  }
48  const char* target = "GET /?ws";
49  for (size_t i = 0; i < header_lenght; i++) {
50  if (header.get()[i] != target[i]) {
51  return false;
52  }
53  }
54  return true;
55 }
56 
57 
59 {
61  const char* target = "GET /?ws";
62  if (header.length() == 8) {
63  for (int i = 0; i < 8; i++) {
64  header.get()[i] = target[i];
65  }
66  }
67 }
68 
69 
71 {
73  return false;
74 }
75 
76 
78 {
80  return false;
81 }
82 
83 
85 {
87  return false;
88 }
89 
90 
92 {
94  YARP_UNUSED(proto);
95  return true;
96 }
97 
98 
100 {
102  YARP_UNUSED(proto);
103  return true;
104 }
105 
106 
108 {
110  std::string url;
111  Route route = proto.getRoute();
112  route.setFromName("web");
113  proto.setRoute(route);
114  std::string remainder = proto.is().readLine();
115  std::string result = remainder;
116  result += "\r\n";
117 
118  for (char i : remainder) {
119  if (i != ' ') {
120  url += i;
121  } else {
122  break;
123  }
124  }
125 
126 
127  bool done = false;
128  while (!done) {
129  std::string line = proto.is().readLine();
130  result += line;
131  result += "\r\n";
132  if (line.empty()) {
133  done = true;
134  }
135  }
136  auto messagetype = messageHandler.parseHandshake(reinterpret_cast<unsigned char*>(const_cast<char*>(result.c_str())), result.size());
137  if (messagetype != WebSocketFrameType::OPENING_FRAME) {
138  yCError(WEBSOCKETCARRIER) << "error parsing handshake";
139  return false;
140  }
141  return true;
142 }
143 
144 
146 {
148  YARP_UNUSED(proto);
149  YARP_UNUSED(writer);
150  return true;
151 }
152 
153 
155 {
157  YARP_UNUSED(proto);
158  return true;
159 }
160 
161 
163 {
165  YARP_UNUSED(proto);
166  return true;
167 }
168 
169 
171 {
173  YARP_UNUSED(proto);
174  return true;
175 }
176 
177 
179 {
181  auto& outputStream = proto.os();
182  std::string reply = messageHandler.answerHandshake();
183  yarp::os::Bytes replySerialized(&reply[0], reply.length());
184  outputStream.write(replySerialized);
185  outputStream.flush();
186  WebSocketStream* stream = new WebSocketStream(proto.giveStreams());
187  proto.takeStreams(stream);
188  return proto.os().isOk();
189 }
190 
191 
193 {
195  writer.write(proto.getOutputStream());
196  return true;
197 }
198 
199 
201 {
203  return true;
204 }
const yarp::os::LogComponent & WEBSOCKETCARRIER()
bool expectReplyToHeader(ConnectionState &proto) override
Process reply to header, if one is expected for this carrier.
bool expectAck(ConnectionState &proto) override
Receive an acknowledgement, if expected for this carrier.
bool expectIndex(ConnectionState &proto) override
Expect a message header, if there is one for this carrier.
bool expectSenderSpecifier(ConnectionState &proto) override
Expect the name of the sending port.
Carrier * create() const override
Factory method.
bool isTextMode() const override
Check if carrier is textual in nature.
void getHeader(Bytes &header) const override
Provide 8 bytes describing this connection sufficiently to allow the other side of a connection to se...
bool sendHeader(ConnectionState &proto) override
Write a header appropriate to the carrier to the connection, followed by any carrier-specific data.
bool canOffer() const override
Check if writing is implemented for this carrier.
std::string getName() const override
Get the name of this connection type ("tcp", "mcast", "shmem", ...)
bool write(ConnectionState &proto, yarp::os::SizedWriter &writer) override
Write a message.
bool sendIndex(ConnectionState &proto, SizedWriter &writer) override
bool sendAck(ConnectionState &proto) override
Send an acknowledgement, if needed for this carrier.
bool checkHeader(const Bytes &header) override
Given the first 8 bytes received on a connection, decide if this is the right carrier type to use for...
bool supportReply() const override
This flag is used by YARP to determine whether the connection can carry RPC traffic,...
bool requireAck() const override
Check if carrier has flow control, requiring sent messages to be acknowledged by recipient.
bool respondToHeader(ConnectionState &proto) override
Respond to the header.
A simple abstraction for a block of bytes.
Definition: Bytes.h:25
size_t length() const
Definition: Bytes.cpp:22
const char * get() const
Definition: Bytes.cpp:27
A base class for connection types (tcp, mcast, shmem, ...) which are called carriers in YARP.
Definition: Carrier.h:45
The basic state of a connection - route, streams in use, etc.
virtual OutputStream & getOutputStream()=0
Access the output stream associated with this connection.
virtual const Route & getRoute() const =0
Get the route associated with this connection.
virtual TwoWayStream * giveStreams()=0
Take ownership of the streams associated with the connection.
virtual void takeStreams(TwoWayStream *streams)=0
Provide streams to be used with the connection.
InputStream & is()
Shorthand for getInputStream()
OutputStream & os()
Shorthand for getOutputStream()
virtual void setRoute(const Route &route)=0
Set the route associated with this connection.
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:54
static LogCallback printCallback()
Get current print callback.
Definition: Log.cpp:821
@ LogTypeReserved
Definition: Log.h:80
@ TraceType
Definition: Log.h:74
virtual bool isOk() const =0
Check if the stream is ok or in an error state.
Information about a connection between two ports.
Definition: Route.h:29
void setFromName(const std::string &fromName)
Set the source of the route.
Definition: Route.cpp:98
Minimal requirements for an efficient Writer.
Definition: SizedWriter.h:33
virtual void write(OutputStream &os)
Definition: SizedWriter.cpp:16
#define yCError(component,...)
Definition: LogComponent.h:154
#define yCTrace(component,...)
Definition: LogComponent.h:85
#define YARP_LOG_COMPONENT(name,...)
Definition: LogComponent.h:77
An interface to the operating system, including Port based communication.
#define YARP_UNUSED(var)
Definition: api.h:162