#[non_exhaustive]pub enum ProxyMode {
Direct,
#[non_exhaustive] Manual {
per_scheme: HashMap<Scheme, ProxyEntry>,
bypass: BypassRules,
rejected: Vec<RejectedValue>,
},
#[non_exhaustive] Pac {
url: Url,
rejected: Vec<RejectedValue>,
},
#[non_exhaustive] PacInline {
script: String,
rejected: Vec<RejectedValue>,
},
WpadAutoDetect,
}Expand description
What a single configuration source says about proxying.
Hand-written Debug, because ProxyConfig’s is derived and
prints whatever this one does. The variants withhold different things: a
Pac URL is printed minus its userinfo (the location makes a report
actionable, and only the credentials are secret) while a
PacInline body is withheld whole and stands in as length plus
hash, because a script is not a locator and any part of it may be one.
Manual delegates: ProxyEntry masks auth.
Variants (Non-exhaustive)§
This enum is marked as non-exhaustive
Direct
No proxy at all (Windows ProxyEnable=0, GNOME mode=none, macOS all
*Enable keys zero). This is the Default.
#[non_exhaustive]Manual
Static per-scheme proxies plus bypass rules.
Sealed, like the other variants that carry fields: build it with
ProxyMode::manual, which keeps the rejected list and the
per_scheme entries mirroring it in step: the constructor reads the list back out
of the map, so the two cannot be handed in disagreeing. The enum’s own
#[non_exhaustive] does not seal a variant: it only forces a _ arm in a match,
so without this a caller could assemble a Manual whose two halves disagree, and
resolve answers from the mirror.
Fields
This variant is marked as non-exhaustive
per_scheme: HashMap<Scheme, ProxyEntry>Per-scheme proxy entries.
bypass: BypassRulesBypass rules.
rejected: Vec<RejectedValue>Fail-open drops (redacted); opposite of BypassRules::rejected.
#[non_exhaustive]Pac
PAC script at a URL (fetch/evaluate via pac / resolve_with_pac).
Sealed; build it with ProxyMode::pac.
Fields
This variant is marked as non-exhaustive
rejected: Vec<RejectedValue>Fail-open drops (redacted), as in Manual: a source can
reach a PAC answer having already lost an unrelated key. With no per_scheme to
mirror them into, they are reachable only through ProxyMode::rejected.
#[non_exhaustive]PacInline
Inline PAC script body.
Sealed; build it with ProxyMode::pac_inline.
Fields
This variant is marked as non-exhaustive
rejected: Vec<RejectedValue>Fail-open drops (redacted); see Pac’s field of the same name.
WpadAutoDetect
WPAD enabled (no DHCP/DNS probe in this crate).
Not sealed, and neither is Direct: a sealed unit variant
cannot be named by another crate, not only constructed by one, so sealing these
two would break every caller’s mode == ProxyMode::Direct. Direct could not be
sealed in any case: it is this enum’s Default, and a default variant must be
exhaustive. Neither carries fields, and neither will: a backend that dropped a
setting answers Manual so the record has somewhere to go.
Implementations§
Source§impl ProxyMode
impl ProxyMode
Sourcepub fn manual(
per_scheme: HashMap<Scheme, ProxyEntry>,
bypass: BypassRules,
) -> Self
pub fn manual( per_scheme: HashMap<Scheme, ProxyEntry>, bypass: BypassRules, ) -> Self
Build a ProxyMode::Manual value, taking the
rejected list from whatever drops per_scheme already holds.
Empty for the map a backend builds, which records its drops separately and attaches
them once the map is complete. A caller filtering or merging a parsed Manual
hands back a map already carrying ProxyEntry::Unusable entries, and the list is
recovered from them rather than left empty: an empty list beside a lookup that
answers Unusable would say nothing was lost about a request that cannot be
routed. Read in Scheme::ALL’s order, not the map’s, which is seeded per
instance. A record that named no scheme was never in the map and cannot come back
this way.
Sourcepub fn pac(url: Url) -> Self
pub fn pac(url: Url) -> Self
Build a ProxyMode::Pac value with an empty rejected list.
Sourcepub fn pac_inline(script: String) -> Self
pub fn pac_inline(script: String) -> Self
Build a ProxyMode::PacInline value with an empty rejected list.
Sourcepub fn bypass(&self) -> Option<&BypassRules>
pub fn bypass(&self) -> Option<&BypassRules>
The bypass rules, when the mode has any.
Sourcepub fn rejected(&self) -> Option<&[RejectedValue]>
pub fn rejected(&self) -> Option<&[RejectedValue]>
The redacted text of every scheme-endpoint entry the source dropped, when the
mode has any. See ProxyMode::Manual’s rejected field for what this
records and why.
Sourcepub fn entry_for(&self, scheme: Scheme) -> Option<&ProxyEntry>
pub fn entry_for(&self, scheme: Scheme) -> Option<&ProxyEntry>
Entry for scheme. Concrete schemes beat Scheme::All; All has no fallback.
None outside Manual or with no entry; Some(Disabled) suppresses All.
Unusable does not: a drop is the last resort, so a live
All still answers and the record surfaces only when nothing else covers scheme.
Backends may substitute before the map is built (macOS SOCKS fallback, Windows
socks= fill); this applies to the finished map.
Sourcepub fn endpoint_for(&self, scheme: Scheme) -> Option<&ProxyEndpoint>
pub fn endpoint_for(&self, scheme: Scheme) -> Option<&ProxyEndpoint>
The proxy endpoint that applies to scheme, or None.
None is “no endpoint to hand out”. Inside Manual that is
direct access when nothing covers the scheme and when what does is
Disabled, but not when it is
Unusable, a setting that was lost rather than an answer,
which resolve reports as
Error::ProxyEntryUnusable. A caller that has
to tell those two apart asks entry_for, which is the same
lookup with the entry left intact. Every other mode returns None for every scheme,
including the PAC and WPAD ones that keep their answer in a script this method
cannot run; that is Error::PacNotSupported, not
direct.
let per_scheme = parse::proxy_server("http=a:8080;https=b:8443");
let mode = ProxyMode::manual(per_scheme, BypassRules::new());
assert_eq!(mode.endpoint_for(Scheme::Http).unwrap().port, 8080);
// No `ftp=` and no catch-all entry: nothing applies.
assert!(mode.endpoint_for(Scheme::Ftp).is_none());Sourcepub fn websocket_entry(&self) -> Option<&ProxyEntry>
pub fn websocket_entry(&self) -> Option<&ProxyEntry>
Entry for ws/wss: socks → https → http (RFC 6455 §4.1.3, as Chromium reads it),
then all: a step this crate adds.
Unlike entry_for, intermediate Disabled entries do not stop
the chain: only terminal Scheme::All is returned as-is (e.g. empty
all_proxy=).
An intermediate Unusable does not stop it either, but is
remembered, and the earliest one is the answer when no step has a real one.
// Only `socks=` and `http=`: the WebSocket chain prefers the SOCKS proxy.
let per_scheme = parse::proxy_server("http=h:80;socks=s:1080");
let mode = ProxyMode::manual(per_scheme, BypassRules::new());
assert_eq!(mode.websocket_endpoint().unwrap().authority(), "s:1080");
// `https=` explicitly disabled: the chain keeps going to `http=` rather than
// stopping the way `entry_for(Scheme::Https)` would for an actual `https`
// request.
let per_scheme = parse::proxy_server("https=;http=h:80");
let mode = ProxyMode::manual(per_scheme, BypassRules::new());
assert_eq!(mode.websocket_endpoint().unwrap().authority(), "h:80");Sourcepub fn websocket_endpoint(&self) -> Option<&ProxyEndpoint>
pub fn websocket_endpoint(&self) -> Option<&ProxyEndpoint>
The proxy endpoint for a ws:///wss:// request; see
websocket_entry for the resolution order.