|
SharkSSL C/C++ Reference
TLS, cryptography, certificates, and PSA integration
|
A compact WebSocket client library.
The client WebSocket library enables you to establish a persistent bi-directional communication channel with any WebSocket enabled application/web server.
WebSocket is a frame based protocol requiring some logic for managing the connections and typically requires a full HTTPS client library. This client WebSocket library includes all logic required, including a minimalistic HTTPS client library, for establishing and maintaining a WebSocket connection in a very compact package. In order to keep the HTTPS client library at a minimum (only a few code lines), the logic in our WebSocket library makes a few assumptions. In particular, read the limitations in the documentation for the WebSocket handshake function (wscProtocolHandshake).
The WebSocket specification: http://tools.ietf.org/html/rfc6455
The following diagram shows the WebSocket frame header:
RFC6455: 5.2. Base Framing Protocol
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
8 7 6 5 4 3 2 1 8 7 6 5 4 3 2 1 8 7 6 5 4 3 2 1 8 7 6 5 4 3 2 1
+-+-+-+-+-------+-+-------------+-------------------------------+
|F|R|R|R| opcode|M| Payload len | Extended payload length |
|I|S|S|S| (4) |A| (7) | (16/64) |
|N|V|V|V| |S| | (if payload len==126/127) |
| |1|2|3| |K| | |
+-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
| Extended payload length continued, if payload len == 127 |
+ - - - - - - - - - - - - - - - +-------------------------------+
| |Masking-key, if MASK set to 1 |
+-------------------------------+-------------------------------+
| Masking-key (continued) | Payload Data |
+-------------------------------- - - - - - - - - - - - - - - - +
: Payload Data continued ... :
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| Payload Data continued ... |
+---------------------------------------------------------------+
The following code snippet is from WsEchoClient.c. The code example shows how to use the client WebSocket library for connecting to the echo server echo.websocket.org.
Modules | |
| WebSocket Opcodes | |
| WebSocket Opcodes. | |
Data Structures | |
| struct | WscState |
| WebSocket Client State Information, initialize using: WscState wss={0}; however, several members must be set. More... | |
Macros | |
| #define | WSC_TLS_AUTH_FAILED -105 |
| TLS peer certificate or reference name was not fully authenticated. More... | |
Functions | |
| int | wscProtocolHandshake (WscState *wss, U32 tmo, const char *host, const char *path, const char *origin) |
| Upgrades (morphs) an HTTPS request/response pair to a WebSocket connection. More... | |
| int | wscSendBin (WscState *wss, U8 *buf, int len) |
| Sends binary data to server. More... | |
| int | wscSendCtrl (WscState *wss, U8 opCode, const U8 *buf, int len) |
| Sends a WebSocket control frame. More... | |
| int | wscClose (WscState *wss, int statusCode) |
| Sends a WebSocket close control frame to the server and closes the connection. More... | |
| int | wscRead (WscState *wss, U8 **buf, U32 timeout) |
| Wait for WebSocket frames sent by the server. More... | |
| #define WSC_TLS_AUTH_FAILED -105 |
TLS peer certificate or reference name was not fully authenticated.
| int wscClose | ( | WscState * | wss, |
| int | statusCode | ||
| ) |
Sends a WebSocket close control frame to the server and closes the connection.
Attempts the close frame and closes the socket.
| wss | WscState *; required connected WebSocket client state with its socket/send buffer initialized. |
| statusCode | int; WebSocket close status to encode when nonnegative; negative values represent a local failure. |
An application-owned SharkSslCon must still be terminated separately.
| int wscProtocolHandshake | ( | WscState * | wss, |
| U32 | tmo, | ||
| const char * | host, | ||
| const char * | path, | ||
| const char * | origin | ||
| ) |
Upgrades (morphs) an HTTPS request/response pair to a WebSocket connection.
Sends the HTTP request header to the server and validates the server's HTTP response header – the function simulates a very basic HTTP client library. The function is designed to be as simple as possible and the code is, for this reason, making a few assumptions that could fail when used with a non traditional HTTP server. Read the comments in the source code file WsClientLib.c if you should experience problems.
| wss | the WebSocket Client State information is stored in this structure. All WscState members must be initially initialized to zero and then the following members must be set: WscState::scon, WscState::sock. When in non secure mode, the following members must be set: WscState::sock, WscState::recBuf, WscState::sendBuf, WscState::recBufLen, WscState::sendBufLen. |
| tmo | in milliseconds. The timeout can be set to INFINITE_TMO. |
| host | is the server's host name |
| path | is the path component of the wss URL and the path must be to the server's WebSocket service. |
| origin | some WebSocket server's may require an origin URL: http://tools.ietf.org/html/rfc6455#section-10.2. Set the parameter to NULL if it's not required by the server. The Origin header should only be required by a server when the request is sent from a browser. |
| int wscRead | ( | WscState * | wss, |
| U8 ** | buf, | ||
| U32 | timeout | ||
| ) |
Wait for WebSocket frames sent by the server.
The function returns when data is available or on timeout. The function returns zero on timeout, but the peer can send zero length frames so you must verify that it is a timeout by checking the status of WscState::isTimeout.
The WebSocket protocol is frame based, but the function can return a fragment before the complete WebSocket frame is received if the frame sent by the peer is larger than the SharkSSL receive buffer. The frame length is returned in WscState::frameLen and the data consumed thus far is returned in WscState::bytesRead. The complete frame is consumed when frameLen == bytesRead.
| wss | is the WebSocket state. |
| buf | is a pointer set to the SharkSSL receive buffer offset to the start of the WebSocket payload data. |
| timeout | in milliseconds. The timeout can be set to INFINITE_TMO. |
| int wscSendBin | ( | WscState * | wss, |
| U8 * | buf, | ||
| int | len | ||
| ) |
Sends binary data to server.
The function sets the WS frame header's opcode to binary. The WS protocol supports two payload frame types, UTF8 and binary (RFC6455: 5.6 Data Frames). We are assuming that you will be using the binary protocol for all data exchange.
| wss | WscState *; required connected WebSocket client state with its socket/send buffer initialized. |
| buf | U8 *; payload borrowed for this call; valid for len bytes. Requires an initialized cryptographic RNG. Each frame uses a fresh masking key; RNG failure sends nothing. An incomplete transport write closes the socket. |
| len | int; payload length from 0 to 65535; payload plus the 6-byte header (len<=125) or 8-byte header (larger payload) must fit the send buffer. |
| int wscSendCtrl | ( | WscState * | wss, |
| U8 | opCode, | ||
| const U8 * | buf, | ||
| int | len | ||
| ) |
Sends a WebSocket control frame.
The code is used internally by the WebSocket functions. You can also use this function to send your own control frames such as WSOP_Ping.
See RFC6455: 5.5. Control Frames
| wss | WscState *; required connected WebSocket client state with its socket/send buffer initialized. |
| opCode | U8; a control-frame opcode: WSOP_Close, WSOP_Ping, or WSOP_Pong. |
| buf | const U8 *; payload borrowed for this call; required when len is nonzero. |
| len | int; control payload byte count from 0 to 125; frame must fit the send buffer. Requires an initialized cryptographic RNG for a fresh masking key. RNG failure sends nothing; an incomplete transport write closes the socket. |