Skip to content

Commit 664249d

Browse files
committed
ws: initial websockets support
Closes #8995
1 parent 60a3b25 commit 664249d

29 files changed

+1238
-52
lines changed

CMakeLists.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1176,6 +1176,16 @@ endif()
11761176

11771177
set(CMAKE_REQUIRED_FLAGS)
11781178

1179+
option(ENABLE_WEBSOCKETS "Set to ON to enable EXPERIMENTAL websockets" OFF)
1180+
1181+
if(ENABLE_WEBSOCKETS)
1182+
if(${SIZEOF_CURL_OFF_T} GREATER "4")
1183+
set(USE_WEBSOCKETS ON)
1184+
else()
1185+
message(WARNING "curl_off_t is too small to enable WebSockets")
1186+
endif()
1187+
endif()
1188+
11791189
foreach(CURL_TEST
11801190
HAVE_GLIBC_STRERROR_R
11811191
HAVE_POSIX_STRERROR_R
@@ -1486,6 +1496,8 @@ _add_if("SFTP" USE_LIBSSH2 OR USE_LIBSSH)
14861496
_add_if("RTSP" NOT CURL_DISABLE_RTSP)
14871497
_add_if("RTMP" USE_LIBRTMP)
14881498
_add_if("MQTT" NOT CURL_DISABLE_MQTT)
1499+
_add_if("WS" USE_WEBSOCKETS)
1500+
_add_if("WSS" USE_WEBSOCKETS)
14891501
if(_items)
14901502
list(SORT _items)
14911503
endif()

configure.ac

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4192,14 +4192,21 @@ AS_HELP_STRING([--disable-websockets],[Disable WebSockets support]),
41924192
no)
41934193
AC_MSG_RESULT(no)
41944194
;;
4195-
*) AC_MSG_RESULT(yes)
4196-
curl_ws_msg="enabled"
4197-
AC_DEFINE_UNQUOTED(USE_WEBSOCKETS, [1], [enable websockets support])
4198-
SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS WS"
4199-
if test "x$SSL_ENABLED" = "x1"; then
4200-
SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS WSS"
4195+
*)
4196+
if test ${ac_cv_sizeof_curl_off_t} -gt 4; then
4197+
AC_MSG_RESULT(yes)
4198+
curl_ws_msg="enabled"
4199+
AC_DEFINE_UNQUOTED(USE_WEBSOCKETS, [1], [enable websockets support])
4200+
SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS WS"
4201+
if test "x$SSL_ENABLED" = "x1"; then
4202+
SUPPORT_PROTOCOLS="$SUPPORT_PROTOCOLS WSS"
4203+
fi
4204+
experimental="$experimental Websockets"
4205+
else
4206+
dnl websockets requires >32 bit curl_off_t
4207+
AC_MSG_RESULT(no)
4208+
AC_MSG_WARN([Websockets disabled due to lack of >32 bit curl_off_t])
42014209
fi
4202-
experimental="$experimental Websockets"
42034210
;;
42044211
esac ],
42054212
AC_MSG_RESULT(no)

docs/WebSockets.md

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,20 @@ The Websockets API is described in the individual man pages for the new API.
1212

1313
Websockets with libcurl can be done two ways.
1414

15-
1. Get the websockets frames from the server sent to a WS write callback. You
16-
can then respond with `curl_ws_send()` from within the callback or outside
17-
of it.
15+
1. Get the websockets frames from the server sent to the write callback. You
16+
can then respond with `curl_ws_send()` from within the callback (or outside
17+
of it).
1818

1919
2. Set `CURLOPT_CONNECT_ONLY` to 2L (new for websockets), which makes libcurl
20-
do the `Upgrade:` dance in the `curl_easy_perform()` call and then you can
21-
use `curl_ws_recv()` and `curl_ws_send()` to receive and send websocket
22-
frames from and to the server.
20+
do a HTTP GET + `Upgrade:` request plus response in the
21+
`curl_easy_perform()` call before it returns and then you can use
22+
`curl_ws_recv()` and `curl_ws_send()` to receive and send websocket frames
23+
from and to the server.
2324

2425
The new options to `curl_easy_setopt()`:
2526

26-
`CURLOPT_WS_OPTIONS` - to control specific behavior (no bits implemented yet)
27+
`CURLOPT_WS_OPTIONS` - to control specific behavior. `CURLWS_RAW_MODE` makes
28+
libcurl provide all websocket traffic raw in the callback.
2729

2830
The new function calls:
2931

docs/libcurl/curl_easy_setopt.3

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -675,6 +675,9 @@ Custom pointer to pass to ssh key callback. See \fICURLOPT_SSH_KEYDATA(3)\fP
675675
Callback for checking host key handling. See \fICURLOPT_SSH_HOSTKEYFUNCTION(3)\fP
676676
.IP CURLOPT_SSH_HOSTKEYDATA
677677
Custom pointer to pass to ssh host key callback. See \fICURLOPT_SSH_HOSTKEYDATA(3)\fP
678+
.SH WEBSOCKETS
679+
.IP CURLOPT_WS_OPTIONS
680+
Set Websockets options. See \fICURLOPT_WS_OPTIONS(3)\fP
678681
.SH OTHER OPTIONS
679682
.IP CURLOPT_PRIVATE
680683
Private pointer to store. See \fICURLOPT_PRIVATE(3)\fP

docs/libcurl/curl_ws_recv.3

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
.\" **************************************************************************
2+
.\" * _ _ ____ _
3+
.\" * Project ___| | | | _ \| |
4+
.\" * / __| | | | |_) | |
5+
.\" * | (__| |_| | _ <| |___
6+
.\" * \___|\___/|_| \_\_____|
7+
.\" *
8+
.\" * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
9+
.\" *
10+
.\" * This software is licensed as described in the file COPYING, which
11+
.\" * you should have received as part of this distribution. The terms
12+
.\" * are also available at https://curl.se/docs/copyright.html.
13+
.\" *
14+
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15+
.\" * copies of the Software, and permit persons to whom the Software is
16+
.\" * furnished to do so, under the terms of the COPYING file.
17+
.\" *
18+
.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19+
.\" * KIND, either express or implied.
20+
.\" *
21+
.\" * SPDX-License-Identifier: curl
22+
.\" *
23+
.\" **************************************************************************
24+
.\"
25+
.TH curl_ws_recv 3 "12 Jun 2022" "libcurl 7.85.0" "libcurl Manual"
26+
.SH NAME
27+
curl_ws_recv - receive websocket data
28+
.SH SYNOPSIS
29+
.nf
30+
#include <curl/easy.h>
31+
32+
CURLcode curl_ws_recv(CURL *curl, void *buffer, size_t buflen,
33+
size_t *nread, unsigned int *recvflags);
34+
.fi
35+
.SH DESCRIPTION
36+
This function call is EXPERIMENTAL.
37+
38+
Retrives as much as possible of a received WebSockets data fragment into the
39+
\fBbuffer\fP, but not more than \fBbuflen\fP bytes. The provide
40+
\fIrecvflags\fP argument gets bits set to help characterize the fragment.
41+
.IP RECVFLAGS
42+
.IP CURLWS_TEXT
43+
The buffer contains text data. Note that this makes a difference to WebSockets
44+
but libcurl itself will not make any verification of the content or
45+
precautions that you actually receive valid UTF-8 content.
46+
.IP CURLWS_BINARY
47+
This is binary data.
48+
.IP CURLWS_FINAL
49+
This is the final fragment of the message, if this is not set, it implies that
50+
there will be another fragment coming as part of the same message.
51+
.IP CURLWS_CLOSE
52+
This transfer is now closed.
53+
.IP CURLWS_PING
54+
This as an incoming ping message, that expects a pong response.
55+
.SH EXAMPLE
56+
.nf
57+
58+
.fi
59+
.SH AVAILABILITY
60+
Added in 7.85.0.
61+
.SH RETURN VALUE
62+
63+
.SH "SEE ALSO"
64+
.BR curl_easy_setopt "(3), " curl_easy_perform "(3), "
65+
.BR curl_easy_getinfo "(3), "
66+
.BR curl_ws_send "(3) "

docs/libcurl/curl_ws_send.3

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
.\" **************************************************************************
2+
.\" * _ _ ____ _
3+
.\" * Project ___| | | | _ \| |
4+
.\" * / __| | | | |_) | |
5+
.\" * | (__| |_| | _ <| |___
6+
.\" * \___|\___/|_| \_\_____|
7+
.\" *
8+
.\" * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
9+
.\" *
10+
.\" * This software is licensed as described in the file COPYING, which
11+
.\" * you should have received as part of this distribution. The terms
12+
.\" * are also available at https://curl.se/docs/copyright.html.
13+
.\" *
14+
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15+
.\" * copies of the Software, and permit persons to whom the Software is
16+
.\" * furnished to do so, under the terms of the COPYING file.
17+
.\" *
18+
.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19+
.\" * KIND, either express or implied.
20+
.\" *
21+
.\" * SPDX-License-Identifier: curl
22+
.\" *
23+
.\" **************************************************************************
24+
.\"
25+
.TH curl_ws_send 3 "12 Jun 2022" "libcurl 7.85.0" "libcurl Manual"
26+
.SH NAME
27+
curl_ws_send - receive websocket data
28+
.SH SYNOPSIS
29+
.nf
30+
#include <curl/easy.h>
31+
32+
CURLcode curl_ws_send(CURL *curl, char *buffer, size_t buflen, size_t *sent,
33+
unsigned int sendflags);
34+
.fi
35+
.SH DESCRIPTION
36+
This function call is EXPERIMENTAL.
37+
38+
Send the specific message fragment over the established websockets connection.
39+
40+
If \fBCURLWS_RAW_MODE\fP is enabled in \fICURLOPT_WS_OPTIONS(3)\fP, the
41+
\fBsendflags\fP argument should be set to 0.
42+
43+
.SH SENDFLAGS
44+
.IP CURLWS_TEXT
45+
The buffer contains text data. Note that this makes a difference to WebSockets
46+
but libcurl itself will not make any verification of the content or
47+
precautions that you actually send valid UTF-8 content.
48+
.IP CURLWS_BINARY
49+
This is binary data.
50+
.IP CURLWS_NOCOMPRESS
51+
No-op if there’s no compression anyway.
52+
.IP CURLWS_CONT
53+
This is not the final fragment of the message, which implies that there will
54+
be another fragment coming as part of the same message where this bit is not
55+
set.
56+
.IP CURLWS_CLOSE
57+
Close this transfer.
58+
.IP CURLWS_PING
59+
This as a ping.
60+
.IP CURLWS_PONG
61+
This as a pong.
62+
.SH EXAMPLE
63+
.nf
64+
65+
.fi
66+
.SH AVAILABILITY
67+
Added in 7.85.0.
68+
.SH RETURN VALUE
69+
70+
.SH "SEE ALSO"
71+
.BR curl_easy_setopt "(3), " curl_easy_perform "(3), "
72+
.BR curl_easy_getinfo "(3), "
73+
.BR curl_ws_recv "(3) "

docs/libcurl/opts/CURLOPT_CONNECT_ONLY.3

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ useful when used with the \fICURLINFO_ACTIVESOCKET(3)\fP option to
4242
the application can obtain the most recently used socket for special data
4343
transfers.
4444

45+
Since 7.85.0, this option can be set to '2' and if HTTP or WebSockets are
46+
used, libcurl will do the request and read all response headers before handing
47+
over control to the application.
48+
4549
Transfers marked connect only will not reuse any existing connections and
4650
connections marked connect only will not be allowed to get reused.
4751

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
.\" **************************************************************************
2+
.\" * _ _ ____ _
3+
.\" * Project ___| | | | _ \| |
4+
.\" * / __| | | | |_) | |
5+
.\" * | (__| |_| | _ <| |___
6+
.\" * \___|\___/|_| \_\_____|
7+
.\" *
8+
.\" * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
9+
.\" *
10+
.\" * This software is licensed as described in the file COPYING, which
11+
.\" * you should have received as part of this distribution. The terms
12+
.\" * are also available at https://curl.se/docs/copyright.html.
13+
.\" *
14+
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15+
.\" * copies of the Software, and permit persons to whom the Software is
16+
.\" * furnished to do so, under the terms of the COPYING file.
17+
.\" *
18+
.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19+
.\" * KIND, either express or implied.
20+
.\" *
21+
.\" * SPDX-License-Identifier: curl
22+
.\" *
23+
.\" **************************************************************************
24+
.\"
25+
.TH CURLOPT_WS_OPTIONS 3 "10 Jun 2022" "libcurl 7.85.0" "curl_easy_setopt options"
26+
.SH NAME
27+
CURLOPT_WS_OPTIONS \- WebSockets behavior options
28+
.SH SYNOPSIS
29+
.nf
30+
#include <curl/curl.h>
31+
32+
CURLcode curl_easy_setopt(CURL *handle, CURLOPT_WS_OPTIONS, long bitmask);
33+
.fi
34+
.SH DESCRIPTION
35+
Pass a long with a bitmask to tell libcurl about specific WebSockets
36+
behaviors.
37+
38+
To "detatch" a websockets connection and use the \fIcurl_ws_send(3)\fP and
39+
\fIcurl_ws_recv(3)\fP functions after the HTTP upgrade procedure, set the
40+
\fICURLOPT_CONNECT_ONLY(3)\fP option to 2L.
41+
42+
Available bits in the bitmask
43+
.IP "CURLWS_RAW_MODE (1)"
44+
Deliver "raw" websockets traffic to the \fICURLOPT_WRITEFUNCTION(3)\fP
45+
callback.
46+
47+
In raw mode, libcurl does not handle pings or any other frame for the
48+
application.
49+
.IP "CURLWS_COMPRESS_MODE (2)"
50+
Negotiate compression for this transfer. (NOT IMPLEMENTED YET)
51+
.IP "CURLWS_PINGOFF_MODE (4)"
52+
Disable automated ping/pong handling. (NOT IMPLEMENTED YET)
53+
.SH DEFAULT
54+
0
55+
.SH PROTOCOLS
56+
WebSockets
57+
.SH EXAMPLE
58+
.nf
59+
CURL *curl = curl_easy_init();
60+
if(curl) {
61+
curl_easy_setopt(curl, CURLOPT_URL, "ws://example.com/");
62+
/* use the stand alone API */
63+
curl_easy_setopt(curl, CURLOPT_WS_OPTIONS, CURLWS_ALONE);
64+
ret = curl_easy_perform(curl);
65+
curl_easy_cleanup(curl);
66+
}
67+
.fi
68+
.SH AVAILABILITY
69+
Added in 7.85.0
70+
.SH RETURN VALUE
71+
Returns CURLE_OK if the option is supported, and CURLE_UNKNOWN_OPTION if not.
72+
.SH "SEE ALSO"
73+
.BR curl_ws_recv "(3), " curl_ws_send "(3), "

docs/libcurl/opts/Makefile.inc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,7 @@ man_MANS = \
404404
CURLOPT_WILDCARDMATCH.3 \
405405
CURLOPT_WRITEDATA.3 \
406406
CURLOPT_WRITEFUNCTION.3 \
407+
CURLOPT_WS_OPTIONS.3 \
407408
CURLOPT_XFERINFODATA.3 \
408409
CURLOPT_XFERINFOFUNCTION.3 \
409410
CURLOPT_XOAUTH2_BEARER.3 \

docs/libcurl/symbols-in-versions

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -874,6 +874,7 @@ CURLOPT_WRITEDATA 7.9.7
874874
CURLOPT_WRITEFUNCTION 7.1
875875
CURLOPT_WRITEHEADER 7.1
876876
CURLOPT_WRITEINFO 7.1
877+
CURLOPT_WS_OPTIONS 7.85.0
877878
CURLOPT_XFERINFODATA 7.32.0
878879
CURLOPT_XFERINFOFUNCTION 7.32.0
879880
CURLOPT_XOAUTH2_BEARER 7.33.0

0 commit comments

Comments
 (0)