websockets: auto-tunnel through http proxy
No binary (build failed)
—
(log yok)
| @@ -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 */ | |
| }; | |
| @@ -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 { | |
| @@ -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; | |
| @@ -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}' |