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; empty value → ProxyEntry::Disabled; 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 actually 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,
so this reads std::env::vars_os instead: one unrelated variable elsewhere in
the process must not be able to take the whole snapshot down. What that costs is
split by half: a variable whose name is not valid Unicode is none of the ones
read here, so it is dropped, while a mangled value is kept and refused — it
lands in rejected rather than reading as unset.
§Errors
Error::CgiHttpProxy in a CGI environment carrying an http_proxy
variable. A malformed value is no longer 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).
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 — something the environment asked for, as opposed to something it merely mentioned.
This neither implies is_empty nor follows from it, which is why
both exist. is_empty answers “was any scheme variable set”, counting a value that
failed to parse and ignoring no_proxy; this one ignores the failures and counts
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 last two rows are the ones with consequences, and both follow 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” — and a value that fails to parse is logged and then treated
exactly as if the variable were unset. A malformed value is a diagnostic, kept in
rejected; reading 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.
Trait Implementations§
Auto Trait Implementations§
impl Freeze for ProxyEnv
impl RefUnwindSafe for ProxyEnv
impl Send for ProxyEnv
impl Sync for ProxyEnv
impl Unpin for ProxyEnv
impl UnsafeUnpin for ProxyEnv
impl UnwindSafe for ProxyEnv
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
impl<T> ErasedDestructor for Twhere
T: 'static,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
Source§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
Source§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
Source§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
Source§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self, then passes self.as_ref() into the pipe function.Source§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self, then passes self.as_mut() into the pipe
function.Source§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self, then passes self.deref() into the pipe function.impl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
Source§impl<T> Tap for T
impl<T> Tap for T
Source§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B> of a value. Read moreSource§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B> of a value. Read moreSource§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R> view of a value. Read moreSource§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R> view of a value. Read moreSource§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap() only in debug builds, and is erased in release builds.Source§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut() only in debug builds, and is erased in release
builds.Source§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref() only in debug builds, and is erased in release
builds.Source§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut() only in debug builds, and is erased in release
builds.Source§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref() only in debug builds, and is erased in release
builds.