1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
---
c: Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
SPDX-License-Identifier: curl
Title: curl_ws_send
Section: 3
Source: libcurl
See-also:
- curl_easy_getinfo (3)
- curl_easy_perform (3)
- curl_easy_setopt (3)
- curl_ws_recv (3)
- libcurl-ws (3)
Protocol:
- WS
Added-in: 7.86.0
---
# NAME
curl_ws_send - send WebSocket data
# SYNOPSIS
~~~c
#include <curl/curl.h>
CURLcode curl_ws_send(CURL *curl, const void *buffer, size_t buflen,
size_t *sent, curl_off_t fragsize,
unsigned int flags);
~~~
# DESCRIPTION
Send the specific message chunk over an established WebSocket
connection. *buffer* must point to a valid memory location containing
(at least) *buflen* bytes of payload memory.
*sent* is set to the number of payload bytes actually sent. If the return value
is **CURLE_OK** but *sent* is less than the given *buflen*, libcurl was unable
to consume the complete payload in a single call. In this case the application
must call this function again until all payload is processed. *buffer* and
*buflen* must be updated on every following invocation to only point to the
remaining piece of the payload.
*fragsize* should always be set to zero unless a (huge) frame shall be sent
using multiple calls with partial content per call explicitly. In that
case you must set the *CURLWS_OFFSET* bit and set the *fragsize* as documented
in the section on *CURLWS_OFFSET* below.
*flags* must contain at least one flag indicating the type of the message.
To send a fragmented message consisting of multiple frames, additionally set
the *CURLWS_CONT* bit in all frames except the final one. The appropriate
message type bit should be set in every frame of a fragmented message without
exemption. Omitting the message type for continuation frames of a fragmented
message is only supported for backwards compatibility and highly discouraged.
For more details on the supported flags see below and in curl_ws_meta(3).
If *CURLWS_RAW_MODE* is enabled in CURLOPT_WS_OPTIONS(3), the
*flags* argument should be set to 0.
Warning: while it is possible to invoke this function from a callback,
such a call is blocking in this situation, e.g. only returns after all data
has been sent or an error is encountered.
# FLAGS
Supports all flags documented in curl_ws_meta(3) and additionally the following
flags.
## CURLWS_OFFSET
The provided data is only a partial frame and there is more coming in a
following call to *curl_ws_send()*. When sending only a piece of the
frame like this, the *fragsize* must be provided with the total
expected frame size in the first call and must be zero in all subsequent
calls.
# %PROTOCOLS%
# EXAMPLE
~~~c
#include <string.h> /* for strlen */
int main(void)
{
const char *buffer = "PAYLOAD";
size_t offset = 0;
CURLcode res = CURLE_OK;
CURL *curl = curl_easy_init();
curl_easy_setopt(curl, CURLOPT_URL, "wss://example.com/");
curl_easy_setopt(curl, CURLOPT_CONNECT_ONLY, 2L);
/* start HTTPS connection and upgrade to WSS, then return control */
curl_easy_perform(curl);
while(!res) {
size_t sent;
res = curl_ws_send(curl, buffer + offset, strlen(buffer) - offset, &sent,
0, CURLWS_TEXT);
offset += sent;
if(res == CURLE_OK) {
if(offset == strlen(buffer))
break; /* finished sending */
}
if(res == CURLE_AGAIN)
/* in real application: wait for socket here, e.g. using select() */
res = CURLE_OK;
}
curl_easy_cleanup(curl);
return (int)res;
}
~~~
# %AVAILABILITY%
# RETURN VALUE
This function returns a CURLcode indicating success or error.
CURLE_OK (0) means everything was OK, non-zero means an error occurred, see
libcurl-errors(3). If CURLOPT_ERRORBUFFER(3) was set with curl_easy_setopt(3)
there can be an error message stored in the error buffer when non-zero is
returned.
Instead of blocking, the function returns **CURLE_AGAIN**. The correct
behavior is then to wait for the socket to signal readability before calling
this function again.
Any other non-zero return value indicates an error. See the libcurl-errors(3)
man page for the full list with descriptions.
|