← Commit list

77e4e5b86d

Stefan Eissing
Stefan Eissing
2026-05-20
SUCCESS Duration: 222s

Subject

websockets: auto-tunnel through http proxy

Binary

No binary (build failed)

Architecture & Compiler Flags

Architecture: x86_64-linux-gnu Compiler: gcc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0

—

Build Log

(log yok)

Commit Diff GitHub →

lib/protocol.c+4 -3
@@ -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 */
};
lib/protocol.h+2 -0
@@ -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 {
lib/url.c+5 -2
@@ -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;
tests/http/test_20_websockets.py+14 -0
@@ -206,3 +206,17 @@ class TestWebsockets:
large = 0
r = client.run(args=[f'-{model}', '-c', str(count), '-m', str(large), url])
r.check_exit_code(0)
+
+ # use ws:// url with HTTP proxy, check that it tunnels automatically
+ def test_20_10_proxy_http(self, env: Env, httpd, ws_echo):
+ curl = CurlClient(env=env)
+ url = f'ws://127.0.0.1:{env.ws_port}/'
+ xargs = curl.get_proxy_args(proxys=False)
+ xargs.extend([
+ '--max-time', '2'
+ ])
+ r = curl.http_download(urls=[url], alpn_proto='http/1.1', with_stats=True,
+ extra_args=xargs)
+ # The CONNECT through the proxy fails as it does not allow it
+ r.check_exit_code(7) # CURLE_COULDNT_CONNECT
+ assert r.stats[0]['http_connect'] == 403, f'{r}'