mirror of
https://github.com/curl/curl.git
synced 2026-04-14 23:51:42 +03:00
proxy-auth: additional tests
Also eliminate the special handling for socks proxy match. Closes #20837
This commit is contained in:
parent
e47b6e657a
commit
5f13a7645e
3 changed files with 42 additions and 24 deletions
28
lib/url.c
28
lib/url.c
|
|
@ -590,29 +590,15 @@ static bool proxy_info_matches(const struct proxy_info *data,
|
|||
{
|
||||
if((data->proxytype == needle->proxytype) &&
|
||||
(data->port == needle->port) &&
|
||||
curl_strequal(data->host.name, needle->host.name))
|
||||
curl_strequal(data->host.name, needle->host.name)) {
|
||||
|
||||
if(Curl_timestrcmp(data->user, needle->user) ||
|
||||
Curl_timestrcmp(data->passwd, needle->passwd))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static bool socks_proxy_info_matches(const struct proxy_info *data,
|
||||
const struct proxy_info *needle)
|
||||
{
|
||||
if(!proxy_info_matches(data, needle))
|
||||
return FALSE;
|
||||
|
||||
/* the user information is case-sensitive
|
||||
or at least it is not defined as case-insensitive
|
||||
see https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1 */
|
||||
|
||||
/* curl_strequal does a case insensitive comparison,
|
||||
so do not use it here! */
|
||||
if(Curl_timestrcmp(data->user, needle->user) ||
|
||||
Curl_timestrcmp(data->passwd, needle->passwd))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* A connection has to have been idle for less than 'conn_max_idle_ms'
|
||||
|
|
@ -923,7 +909,7 @@ static bool url_match_proxy_use(struct connectdata *conn,
|
|||
return FALSE;
|
||||
|
||||
if(m->needle->bits.socksproxy &&
|
||||
!socks_proxy_info_matches(&m->needle->socks_proxy, &conn->socks_proxy))
|
||||
!proxy_info_matches(&m->needle->socks_proxy, &conn->socks_proxy))
|
||||
return FALSE;
|
||||
|
||||
if(m->needle->bits.httpproxy) {
|
||||
|
|
|
|||
|
|
@ -169,3 +169,23 @@ class TestProxyAuth:
|
|||
'--negotiate', '--proxy-user', 'proxy:proxy'
|
||||
])
|
||||
r1.check_response(count=1, http_status=200)
|
||||
|
||||
def test_13_10_tunnels_mixed_auth(self, env: Env, httpd, configures_httpd):
|
||||
self.httpd_configure(env, httpd)
|
||||
curl = CurlClient(env=env)
|
||||
url1 = f'http://localhost:{env.http_port}/data.json?1'
|
||||
url2 = f'http://localhost:{env.http_port}/data.json?2'
|
||||
url3 = f'http://localhost:{env.http_port}/data.json?3'
|
||||
xargs1 = curl.get_proxy_args(proxys=False, tunnel=True)
|
||||
xargs1.extend(['--proxy-user', 'proxy:proxy']) # good auth
|
||||
xargs2 = curl.get_proxy_args(proxys=False, tunnel=True)
|
||||
xargs2.extend(['--proxy-user', 'ungood:ungood']) # bad auth
|
||||
xargs3 = curl.get_proxy_args(proxys=False, tunnel=True)
|
||||
# no auth
|
||||
r = curl.http_download(urls=[url1, url2, url3], alpn_proto='http/1.1', with_stats=True,
|
||||
url_options={url1: xargs1, url2: xargs2, url3: xargs3})
|
||||
# only url1 succeeds, others fail, no connection reuse
|
||||
assert r.stats[0]['http_code'] == 200, f'{r.dump_logs()}'
|
||||
assert r.stats[1]['http_code'] == 0, f'{r.dump_logs()}'
|
||||
assert r.stats[2]['http_code'] == 0, f'{r.dump_logs()}'
|
||||
assert r.total_connects == 3, f'{r.dump_logs()}'
|
||||
|
|
|
|||
|
|
@ -724,7 +724,8 @@ class CurlClient:
|
|||
with_tcpdump: bool = False,
|
||||
no_save: bool = False,
|
||||
limit_rate: Optional[str] = None,
|
||||
extra_args: Optional[List[str]] = None):
|
||||
extra_args: Optional[List[str]] = None,
|
||||
url_options: Optional[Dict[str,List[str]]] = None):
|
||||
if extra_args is None:
|
||||
extra_args = []
|
||||
if no_save:
|
||||
|
|
@ -742,6 +743,7 @@ class CurlClient:
|
|||
])
|
||||
return self._raw(urls, alpn_proto=alpn_proto, options=extra_args,
|
||||
with_stats=with_stats,
|
||||
url_options=url_options,
|
||||
with_headers=with_headers,
|
||||
with_profile=with_profile,
|
||||
with_tcpdump=with_tcpdump)
|
||||
|
|
@ -1083,6 +1085,7 @@ class CurlClient:
|
|||
|
||||
def _raw(self, urls, intext='', timeout=None, options=None, insecure=False,
|
||||
alpn_proto: Optional[str] = None,
|
||||
url_options=None,
|
||||
force_resolve=True,
|
||||
with_stats=False,
|
||||
with_headers=True,
|
||||
|
|
@ -1092,7 +1095,8 @@ class CurlClient:
|
|||
args = self._complete_args(
|
||||
urls=urls, timeout=timeout, options=options, insecure=insecure,
|
||||
alpn_proto=alpn_proto, force_resolve=force_resolve,
|
||||
with_headers=with_headers, def_tracing=def_tracing)
|
||||
with_headers=with_headers, def_tracing=def_tracing,
|
||||
url_options=url_options)
|
||||
r = self._run(args, intext=intext, with_stats=with_stats,
|
||||
with_profile=with_profile, with_tcpdump=with_tcpdump)
|
||||
if r.exit_code == 0 and with_headers:
|
||||
|
|
@ -1102,8 +1106,10 @@ class CurlClient:
|
|||
def _complete_args(self, urls, timeout=None, options=None,
|
||||
insecure=False, force_resolve=True,
|
||||
alpn_proto: Optional[str] = None,
|
||||
url_options=None,
|
||||
with_headers: bool = True,
|
||||
def_tracing: bool = True):
|
||||
url_sep = []
|
||||
if not isinstance(urls, list):
|
||||
urls = [urls]
|
||||
|
||||
|
|
@ -1129,7 +1135,13 @@ class CurlClient:
|
|||
active_options = options[options.index('--next') + 1:]
|
||||
|
||||
for url in urls:
|
||||
u = urlparse(urls[0])
|
||||
args.extend(url_sep)
|
||||
if url_options is not None:
|
||||
url_sep = ['--next']
|
||||
|
||||
u = urlparse(url)
|
||||
if url_options is not None and url in url_options:
|
||||
args.extend(url_options[url])
|
||||
if options:
|
||||
args.extend(options)
|
||||
if alpn_proto is not None:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue