pub fn proxy_override(spec: &str) -> BypassRulesExpand description
Parse a Windows ProxyOverride registry value into BypassRules.
Like no_proxy, but entries are separated by ;, , or whitespace, as WinHTTP
documents, and a bare name matches that name alone rather than the domain under it:
contoso.com here does not bypass api.contoso.com. Write *.contoso.com for the
subdomains, which is also what Windows asks for; .contoso.com is rejected rather than
read, because no measured reader grants it. A CIDR entry is rejected too, because
Windows answers a / with the whole list: write the range as the wildcard Windows does
read, 10.*. <local> → HostPattern::Local and
<-loopback> (IE9+) →
HostPattern::SubtractImplicit are read by
no_proxy as well as by this one, the way Chromium reads them (“we allow it on all
platforms and interpret it the same way”, proxy_host_matching_rules.cc:113). Malformed
entries skipped into BypassRules::rejected.
An IPv4 address entry is read only as four decimal octets. WinINet and WinHTTP compare
an address entry with the destination as text, so 012.1.2.3 there is not 10.1.2.3 in
either position; such an entry is rejected, where no_proxy reads it as the address a
URL parser would. Limitation: every entry point reads the destination folded (a Url or
a Host already holds 012.1.2.3 as 10.1.2.3, and
matches_authority parses its text the same
way), so an entry 10.1.2.3 or 10.* reports a bypass for a destination written
012.1.2.3, which Windows hands to the proxy.
The bare-name rule is measured against WinINet and WinHTTP. The reimplementations this
crate reads alongside, Chromium and libproxy, answer the question differently, so
neither could settle it. The readings are the rows of
a_bare_name_in_a_windows_list_is_the_one_host in tests/bypass.rs.
The implicit set is measured the same way, and is ImplicitBypass::WinInet:
localhost, loopback, 127.0.0.1, ::1 and the link-local ranges. It excludes the
rest of 127.0.0.0/8, *.localhost and IPv4-mapped spellings. WinHTTP agrees on the
link-local ranges and bypasses all of 127.0.0.0/8 even under <-loopback>. The store
is WinINet’s, so this follows WinINet, and a WinHTTP client is therefore told “proxy”
for loopback it sends direct. The rows are
wininet_implicit_bypass_is_the_measured_six in tests/bypass.rs.
let rules = parse::proxy_override("<local>;*.contoso.com;<-loopback>");
assert!(rules.excludes_simple_hostnames());
assert!(!rules.bypass_loopback());
assert!(rules.matches_authority("www.contoso.com"));
// Whitespace separates too, so this is two rules and not one dead one.
let rules = parse::proxy_override("*.contoso.com intranet");
assert!(rules.matches_authority("www.contoso.com"));
assert!(rules.matches_authority("intranet"));
// A bare name is the host itself. The same text in `no_proxy` takes the subdomains.
let rules = parse::proxy_override("contoso.com");
assert!(rules.matches_authority("contoso.com"));
assert!(!rules.matches_authority("api.contoso.com"));
assert!(parse::no_proxy("contoso.com").matches_authority("api.contoso.com"));
// A `/` is recorded, not read. `no_proxy` takes the same text as a mask.
let rules = parse::proxy_override("10.0.0.0/8");
assert!(!rules.matches_authority("10.1.2.3"));
assert_eq!(rules.rejected.len(), 1);
assert!(parse::no_proxy("10.0.0.0/8").matches_authority("10.1.2.3"));