pub struct ProxyEnv { /* private fields */ }Expand description
Env snapshot of *_proxy / no_proxy (not a Stream;
ProxyWatcher does not merge these in, except where an OS
setting names them, which KDE’s ProxyType=4 does).
Lowercase beats uppercase, even when set empty: http_proxy= beside HTTP_PROXY=h is
ProxyEntry::Disabled, and an empty no_proxy hides NO_PROXY. Port explicit, else
the scheme:// default, else 80 (so all_proxy=socks5://h is 1080, http_proxy=h is
80), the rule ProxyEndpoint::parse states. On Windows only, any other letter case
the variable was set in (Http_Proxy) is read too, after both conventional spellings.
no_proxy via parse::no_proxy. Bad *_proxy → rejected. A
non-empty REQUEST_METHOD + http_proxy → Error::CgiHttpProxy. Merge with a
watcher is caller-defined precedence.
Implementations§
Source§impl ProxyEnv
impl ProxyEnv
Sourcepub fn from_env() -> Result<Self, Error>
pub fn from_env() -> Result<Self, Error>
Read the snapshot from the current process environment.
std::env::vars panics on a variable whose name or value is not valid Unicode.
This uses std::env::vars_os so an unrelated variable cannot cause the snapshot
to panic. A non-Unicode name cannot match a variable read here and is dropped. A
non-Unicode value is retained in rejected instead of being
treated as unset.
§Errors
Error::CgiHttpProxy in a CGI environment carrying an http_proxy
variable. A malformed value is never one of these, but the two kinds are
recorded apart: a dropped *_proxy endpoint lands in
rejected, a dropped no_proxy entry in
bypass().rejected. Reading only the first and finding it
empty says nothing about the second.
Sourcepub fn from_vars<I, K, V>(vars: I) -> Result<Self, Error>
pub fn from_vars<I, K, V>(vars: I) -> Result<Self, Error>
Explicit map for tests (avoids mutating the process-global env). A name given twice
keeps its first value, as getenv does.
let env = ProxyEnv::from_vars([
("HTTP_PROXY", "http://upper:8080"),
("http_proxy", "http://lower:8080"),
("no_proxy", "*.internal"),
])
.unwrap();
// Lowercase wins.
let endpoint = env.endpoint_for(Scheme::Http).unwrap();
assert_eq!(endpoint.host.to_string(), "lower");
assert!(env.bypass().matches_authority("api.internal"));§Errors
Error::CgiHttpProxy when a non-empty REQUEST_METHOD and an http_proxy are
both present. Malformed values are recorded instead of returned; see
from_env for which of the two lists each kind reaches.
Sourcepub fn per_scheme(&self) -> &HashMap<Scheme, ProxyEntry>
pub fn per_scheme(&self) -> &HashMap<Scheme, ProxyEntry>
Sourcepub fn bypass(&self) -> &BypassRules
pub fn bypass(&self) -> &BypassRules
The parsed no_proxy rules.
Sourcepub fn rejected(&self) -> &[RejectedValue]
pub fn rejected(&self) -> &[RejectedValue]
Redacted *_proxy values ProxyEndpoint::parse rejected (fail-open drop,
not whole-snapshot failure). Threaded into ProxyMode via to_mode.
Not the no_proxy drops: those are exclusions rather than endpoints and stay on
bypass().rejected. to_mode carries them
across inside the BypassRules, but only on the branch that returns a
Manual: a snapshot holding nothing but a no_proxy is
Direct, and an exclusion list with no proxy to be excluded
from does not outlive the conversion.
Sourcepub fn captured_at(&self) -> SystemTime
pub fn captured_at(&self) -> SystemTime
When the snapshot was taken. Excluded from equality comparisons.
Sourcepub fn is_empty(&self) -> bool
pub fn is_empty(&self) -> bool
No *_proxy set (malformed-but-present still counts as set via rejected).
Sourcepub fn is_configured(&self) -> bool
pub fn is_configured(&self) -> bool
Whether these variables specify a configuration, as opposed to only mentioning one.
This neither implies is_empty nor follows from it. is_empty
checks whether any scheme variable is set, including malformed values and ignoring
no_proxy; is_configured ignores malformed values and includes no_proxy:
| environment | is_empty | is_configured |
|---|---|---|
| nothing set | true | false |
http_proxy=http://p:8080 | false | true |
http_proxy= (a deliberate direct for http) | false | true |
no_proxy=.corp.example alone | true | true |
| every scheme variable malformed | false | false |
The treatment of no_proxy alone and malformed scheme variables follows Chromium’s
net/proxy_resolution/proxy_config_service_linux.cc. A no_proxy on its own is a
configuration there: “having no rules specified only means the user explicitly asks
for direct connections”. A value that fails to parse is logged and treated as if the
variable were unset. A malformed value is retained in rejected
as a diagnostic; treating it as an instruction would let a typo in http_proxy mask
a working OS proxy.
ProxyConfig::with_env is what acts on the
distinction. to_mode does not: a no_proxy with no proxy to
exclude from is still Direct, which is the same answer
Chromium’s config produces once it has no proxy servers in it.
Sourcepub fn endpoint_for(&self, scheme: Scheme) -> Option<&ProxyEndpoint>
pub fn endpoint_for(&self, scheme: Scheme) -> Option<&ProxyEndpoint>
The endpoint for scheme, under the same Scheme::All fallback as
ProxyMode::entry_for: All itself has none, and a
Disabled entry answers None instead of falling through.
Sourcepub fn to_config(&self) -> ProxyConfig
pub fn to_config(&self) -> ProxyConfig
Convert the snapshot into a ProxyConfig attributed to
ProxyConfigSource::Env, carrying this snapshot’s
captured_at rather than the time of the conversion.