websockets: auto-tunnel through http proxy

When using a ws: or wss: url with a http proxy, automatically
switch to tunneling operation mode.

Add test_20_10 to check.

Fixes #21663
Closes #21691
This commit is contained in:
Stefan Eissing 2026-05-20 10:30:25 +02:00 committed by Daniel Stenberg
parent b158d1c9f7
commit 77e4e5b86d
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2
4 changed files with 25 additions and 5 deletions

View file

@ -153,7 +153,8 @@ const struct Curl_scheme Curl_scheme_https = {
CURLPROTO_HTTPS, /* protocol */
CURLPROTO_HTTP, /* family */
PROTOPT_SSL | PROTOPT_CREDSPERREQUEST | PROTOPT_ALPN | /* flags */
PROTOPT_USERPWDCTRL | PROTOPT_CONN_REUSE,
PROTOPT_USERPWDCTRL | PROTOPT_CONN_REUSE |
PROTOPT_HTTP_PROXY_TUNNEL,
PORT_HTTPS, /* defport */
};
@ -442,7 +443,7 @@ const struct Curl_scheme Curl_scheme_ws = {
CURLPROTO_WS, /* protocol */
CURLPROTO_HTTP, /* family */
PROTOPT_CREDSPERREQUEST | /* flags */
PROTOPT_USERPWDCTRL,
PROTOPT_USERPWDCTRL | PROTOPT_HTTP_PROXY_TUNNEL,
PORT_HTTP /* defport */
};
@ -457,7 +458,7 @@ const struct Curl_scheme Curl_scheme_wss = {
CURLPROTO_WSS, /* protocol */
CURLPROTO_HTTP, /* family */
PROTOPT_SSL | PROTOPT_CREDSPERREQUEST | /* flags */
PROTOPT_USERPWDCTRL,
PROTOPT_USERPWDCTRL | PROTOPT_HTTP_PROXY_TUNNEL,
PORT_HTTPS /* defport */
};

View file

@ -237,6 +237,8 @@ struct Curl_protocol {
without having PROTOPT_SSL. */
#define PROTOPT_CONN_REUSE (1 << 16) /* this protocol can reuse connections */
#define PROTOPT_NO_TRANSFER (1 << 17) /* this protocol is not for transfers */
#define PROTOPT_HTTP_PROXY_TUNNEL (1 << 18) /* Using this protocol with a
* HTTP proxy requires tunneling */
/* Everything about a URI scheme. */
struct Curl_scheme {

View file

@ -2018,8 +2018,11 @@ static CURLcode url_set_conn_proxies(struct Curl_easy *data,
data->state.envproxy = curlx_strdup(proxy);
}
#endif
/* force this connection's protocol to become HTTP if compatible */
if(!(conn->scheme->protocol & PROTO_FAMILY_HTTP)) {
if(conn->scheme->flags & PROTOPT_HTTP_PROXY_TUNNEL) {
conn->bits.tunnel_proxy = TRUE;
}
else if(!(conn->scheme->protocol & PROTO_FAMILY_HTTP)) {
/* force this connection's protocol to become HTTP if compatible */
if((conn->scheme->flags & PROTOPT_PROXY_AS_HTTP) &&
!conn->bits.tunnel_proxy)
conn->scheme = &Curl_scheme_http;