Skip to main content

ReqwestClient

Struct ReqwestClient 

Source
pub struct ReqwestClient { /* private fields */ }
Available on crate feature did-web and crate feature reqwest and (crate features did-jwk or did-key or did-web) only.
Expand description

An HttpClient over reqwest hardened for fetching DID documents from the public web.

ReqwestClient::new builds a client that:

  • speaks HTTPS only, with the platform’s root certificates and rustls;
  • follows no redirect, so a document is fetched from the URL its DID maps to and nowhere else: a 3xx response is returned with its Location in HttpResponse::location, for a caller that follows redirects to fetch each target through this client again;
  • sends Accept when asked through HttpClient::get_accepting, and Accept-Encoding: gzip, decoding a gzip-encoded body;
  • resolves host names itself and refuses loopback, private, link-local and other non-public addresses, so a DID cannot point the resolver at internal services;
  • uses no proxy, whatever HTTPS_PROXY, HTTP_PROXY, ALL_PROXY or the platform’s settings say: a proxy resolves the host itself, so it would reach the addresses refused above;
  • stops reading a body over DEFAULT_MAX_BODY bytes, counted after decoding, so a small compressed body cannot expand past the limit;
  • times out after DEFAULT_TIMEOUT.

ReqwestClient::from_client wraps a client the application configured itself, keeping only the HTTPS-only rule, the refusal of non-public IP literals and the body limit; the other protections are then the application’s. That is also how to fetch through an egress proxy: configure it on that client, and have the proxy refuse non-public targets, since it resolves the host names.

§Local development and tests

With the feature local-network, ReqwestClient::builder can let a client reach a did:web served from the local machine or a private network, such as a test server on 127.0.0.1 or a development deployment in a docker-compose network. It is for development and tests only; enable the feature under [dev-dependencies], or behind a feature of the application’s own, so that a release build does not contain it.

  • dangerous_allow_loopback allows 127.0.0.0/8 and ::1, and dangerous_allow_private_network allows RFC 1918 and fc00::/7. Neither takes a bool: the choice is made in code.
  • The client resolves the host first. When every address is in an allowed range, it fetches the URL over plain http, on the port the URL names (443 when it names none), connecting to exactly the addresses it checked. Otherwise the rules above apply unchanged: a host with public and local addresses is held to them.
  • Link-local addresses (including cloud metadata endpoints such as 169.254.169.254) and every other non-public range stay refused; redirects, the timeout and the body limit are unchanged.

Implementations§

Source§

impl ReqwestClient

Source

pub const fn local_network(&self) -> LocalNetwork

The local ranges this client may reach; LocalNetwork::NONE unless built with ReqwestClient::builder.

Source§

impl ReqwestClient

Source

pub const DEFAULT_MAX_BODY: usize

The largest body new reads: 1 MiB, far above any DID document.

Source

pub const DEFAULT_TIMEOUT: Duration

The request timeout of new.

Source

pub fn new() -> Result<Self, HttpError>

A hardened client with the defaults above.

§Errors

HttpError when the TLS backend cannot be initialized.

Source

pub const fn from_client(client: Client) -> Self

A client over client as the application configured it, still HTTPS-only, refusing non-public IP literals, and reading at most DEFAULT_MAX_BODY bytes of body.

Host names are resolved as client resolves them, so refusing the non-public addresses they resolve to is the application’s: with a DNS resolver like the one new installs, and, when client uses a proxy, by the proxy itself, which resolves the host names it is asked to reach.

Source

pub const fn builder() -> ReqwestClientBuilder

Available on crate feature local-network only.

A builder for a client that may also reach the local network, for development and tests; see Local development and tests.

Source

pub const fn with_max_body(self, max_body: usize) -> Self

This client reading at most max_body bytes of body.

Source

pub const fn max_body(&self) -> usize

The body limit.

Source

pub const fn client(&self) -> &Client

The underlying client.

Trait Implementations§

Source§

impl Clone for ReqwestClient

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for ReqwestClient

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl HttpClient for ReqwestClient

Source§

fn get<'life0, 'life1, 'async_trait>( &'life0 self, url: &'life1 Url, ) -> Pin<Box<dyn Future<Output = Result<HttpResponse, HttpError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Fetches url, returning the status and the body of the response. Read more
Source§

fn get_accepting<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, url: &'life1 Url, media_type: &'life2 str, ) -> Pin<Box<dyn Future<Output = Result<HttpResponse, HttpError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Fetches url asking for a body of media_type, sent as the Accept header. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more