pub struct RequestBuilder { /* private fields */ }Expand description
Fluent outbound request builder produced by Client methods.
Implementations§
Source§impl RequestBuilder
impl RequestBuilder
Sourcepub const fn without_request_id(self) -> Self
pub const fn without_request_id(self) -> Self
Do not send the current request’s id as x-request-id.
By default, a request sent during an inbound request carries that request’s id (issue #3064). Use this for a host that must not see it.
Sourcepub const fn criticality(self, criticality: Criticality) -> Self
pub const fn criticality(self, criticality: Criticality) -> Self
Send this criticality in the X-Autumn-Criticality header (issue
#3068). Without this call, the client sends the criticality of the
inbound request that it serves, if any.
Sourcepub fn header(self, name: impl AsRef<str>, value: impl AsRef<str>) -> Self
pub fn header(self, name: impl AsRef<str>, value: impl AsRef<str>) -> Self
Append a request header.
Headers named authorization, cookie, or set-cookie are accepted
normally but are redacted in tracing events and log output.
Invalid header names or values emit a tracing::warn! and are skipped.
Sourcepub fn sign_web_bot_auth(self, signer: &WebBotAuthSigner) -> Self
pub fn sign_web_bot_auth(self, signer: &WebBotAuthSigner) -> Self
Sign this request with Web Bot Auth (RFC 9421 HTTP Message
Signatures), so the receiving site can verify that it comes from this
app. Adds Signature-Agent, Signature-Input, and Signature.
The URL must be absolute. Each attempt (a retry, a same-origin
redirect) sends a new signature, so a held builder or a late retry
never sends an expired one. See crate::aeo::web_bot_auth.
Sourcepub fn json<T: Serialize>(self, body: &T) -> Self
pub fn json<T: Serialize>(self, body: &T) -> Self
Serialise body as JSON and set Content-Type: application/json.
Serialisation errors are captured and returned when send
is called rather than being silently discarded.
Sourcepub fn bytes_body(self, body: impl Into<Bytes>) -> Self
pub fn bytes_body(self, body: impl Into<Bytes>) -> Self
Sourcepub const fn retries(self, max: u32) -> Self
pub const fn retries(self, max: u32) -> Self
Override the maximum retry count for this request.
This does not enable retries for POST and PATCH. Use
retry_non_idempotent for that.
Sourcepub const fn retry_non_idempotent(self) -> Self
pub const fn retry_non_idempotent(self) -> Self
Retry non-idempotent methods (POST, PATCH) too.
A retried POST can run two times on the server. So for a
non-idempotent method, the client sends an Idempotency-Key header
with a random value, the same on every attempt. A key you set with
header is kept.
Sourcepub const fn max_backoff(self, max: Duration) -> Self
pub const fn max_backoff(self, max: Duration) -> Self
Override the cap on the jittered backoff between attempts.
Sourcepub const fn max_retry_after(self, max: Duration) -> Self
pub const fn max_retry_after(self, max: Duration) -> Self
Override the maximum Retry-After sleep duration for this request.
Sourcepub fn no_redirect(self) -> Self
pub fn no_redirect(self) -> Self
Disable redirect following for this request.
A 3xx response is returned to the caller verbatim (status, headers and
body) rather than being followed. Routes the request through the custom
one-shot-client send path, which bypasses the process-wide circuit
breaker.
Sourcepub const fn discard_response_body(self) -> Self
pub const fn discard_response_body(self) -> Self
Return the status and headers without reading the response body.
Every other path collects the whole body into memory with no ceiling, which is the right default for an API call whose payload the caller wants. It is the wrong default when the remote host is untrusted and the caller needs only the status: a server that streams indefinitely then costs one unbounded allocation per request until the timeout fires.
Web Push is exactly that shape — the endpoint URL is chosen by the
client, and the transport only ever reads the status code — so it sets
this. Response::bytes then returns empty; dropping the underlying
response closes the connection without draining it.
Sourcepub fn follow_redirects<F>(self, max: usize, validator: F) -> Self
pub fn follow_redirects<F>(self, max: usize, validator: F) -> Self
Follow up to max redirects, validating each hop before following it.
Before following a 3xx, the Location header is resolved to an
absolute URL (relative locations are joined against the current URL) and
validator(&absolute_location) is called. If it returns false the
request fails with ClientError::RedirectRejected. If the chain would
exceed max hops the request fails with
ClientError::TooManyRedirects (so max == 0 turns the first 3xx
into an error). Routes the request through the custom one-shot-client
send path, which bypasses the process-wide circuit breaker.
TOCTOU / rebinding limitation. The validator receives the redirect
target as a string (not a resolved IP), and the subsequent connection
re-resolves that host via normal DNS. So a validator that inspects IP
literals sees only literal hosts, has a connect-time TOCTOU window
against a hostname that re-resolves between check and connect, and
provides no address pinning. When you need pinned, rebind-safe following
that validates every resolved IP and pins the connection per hop, use
Client::get_ssrf_safe instead.
Sourcepub fn pin_to(self, addr: SocketAddr) -> Self
pub fn pin_to(self, addr: SocketAddr) -> Self
Pin the connection to addr, skipping DNS resolution.
The original Host header and TLS SNI are preserved; only the
address the socket connects to is overridden. This protects against
DNS-rebinding / TOCTOU attacks where a hostname re-resolves to a
different (private) address between validation and connection.
Requires a domain (hostname) URL host. The pin is enforced via a DNS
resolve override, but reqwest/hyper treat an IP-literal URL host as
already-resolved and never consult the resolver — so the override is
skipped and the socket would connect to the literal in the URL, not the
pinned address. A pin_to request whose URL host is an IP literal
(IPv4 or IPv6) is therefore rejected at send time with
ClientError::PinRequiresDomainHost. Put the desired IP directly in the
URL (no pin needed), or use a domain host.
Pinning applies to the initial connection only. Redirects are not
followed under pin_to: a 3xx is returned to the caller verbatim (as if
no_redirect were set) rather than being
auto-followed to a possibly-different host that would be re-resolved via
normal DNS, silently escaping the pin. If you need pinned, rebind-safe
per-hop following, use Client::get_ssrf_safe instead.
Cannot be combined with follow_redirects.
Because the pin only covers the first hop while later hops would re-resolve
via DNS, chaining pin_to with follow_redirects (in either order) is
rejected at send time with ClientError::IncompatiblePinRedirect rather
than silently following a redirect off the pinned address. Use
Client::get_ssrf_safe for pinned, per-hop-revalidated redirect
following, pin_to alone (which returns the 3xx unfollowed), or
follow_redirects without pin_to.
Implemented via a one-shot reqwest::ClientBuilder::resolve(host, addr)
scoped to this request. Note that reqwest ignores the port in the
resolve override and connects to the port from the request URL, so
addr.port() is only honoured when it matches the URL’s port (which it
does for addresses obtained by resolving that same URL). Routes the
request through the custom one-shot-client send path, which bypasses the
process-wide circuit breaker.
Env proxies are bypassed. The pinned client is built with
.no_proxy(), so HTTP_PROXY / HTTPS_PROXY / ALL_PROXY are ignored
and the socket connects directly to addr. This is required for the pin
to hold: reqwest checks proxy interception before the connector where the
resolve() override applies, so a configured proxy would otherwise
receive the request and re-resolve the host — defeating the pin.
Sourcepub fn pin_to_addrs(self, addrs: impl IntoIterator<Item = SocketAddr>) -> Self
pub fn pin_to_addrs(self, addrs: impl IntoIterator<Item = SocketAddr>) -> Self
Like pin_to, but accepts several addresses for one
host.
All addresses go to one request. reqwest tries the next address only
if it cannot connect. A loop over pin_to could send a POST body
twice.
An empty set makes send fail. It never drops the pin. Every other
rule of pin_to applies.
Sourcepub const fn ssrf_safe(self) -> Self
pub const fn ssrf_safe(self) -> Self
Route this request through the SSRF-safe resolve→validate→pin send path
documented on Client::get_ssrf_safe, for any HTTP method.
Client::get_ssrf_safe only builds GET requests, but the guarantee
it describes — reject a resolved address on the built-in SSRF deny-list,
pin the connection to the validated set, re-validate on every redirect
hop — is implemented by Self::send purely from this flag and is not
GET-specific. Any outbound call whose destination is not a value the
app itself chose — a webhook subscriber’s target_url, a user-supplied
callback, an OAuth discovery endpoint — needs this on every verb it
uses, not only reads. Chain it after Client::post, Client::put,
etc.:
client.post(target_url).ssrf_safe().json(&payload).send().await?;Same incompatibility with pin_to as get_ssrf_safe:
this path performs its own per-hop resolve→validate→pin, so chaining an
explicit pin is rejected at send time with
ClientError::PinNotAllowedWithSsrfSafe.
Sourcepub async fn send(self) -> Result<Response, ClientError>
pub async fn send(self) -> Result<Response, ClientError>
Send the request, applying retries and returning a Response.
§Errors
Returns ClientError::Json if a prior .json() call failed to
serialise the body. Returns ClientError::Request for transport
errors that exhaust all retry attempts. Returns ClientError::NoMock
if the request is made in a test context without a matching mock entry.
§Panics
Contains an internal unreachable!() that guards against a logic error
in the retry loop; it cannot be reached in practice.
Auto Trait Implementations§
impl !Freeze for RequestBuilder
impl !RefUnwindSafe for RequestBuilder
impl !UnwindSafe for RequestBuilder
impl Send for RequestBuilder
impl Sync for RequestBuilder
impl Unpin for RequestBuilder
impl UnsafeUnpin for RequestBuilder
Blanket Implementations§
Source§impl<T> AggregateExpressionMethods for T
impl<T> AggregateExpressionMethods for T
Source§fn aggregate_distinct(self) -> Self::Outputwhere
Self: DistinctDsl,
fn aggregate_distinct(self) -> Self::Outputwhere
Self: DistinctDsl,
DISTINCT modifier for aggregate functions Read moreSource§fn aggregate_all(self) -> Self::Outputwhere
Self: AllDsl,
fn aggregate_all(self) -> Self::Outputwhere
Self: AllDsl,
ALL modifier for aggregate functions Read moreSource§fn aggregate_filter<P>(self, f: P) -> Self::Output
fn aggregate_filter<P>(self, f: P) -> Self::Output
Source§fn aggregate_order<O>(self, o: O) -> Self::Outputwhere
Self: OrderAggregateDsl<O>,
fn aggregate_order<O>(self, o: O) -> Self::Outputwhere
Self: OrderAggregateDsl<O>,
Source§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
Source§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
Source§impl<T> AutumnCounterCaches for Twhere
T: 'static,
impl<T> AutumnCounterCaches for Twhere
T: 'static,
Source§const HAS_COUNTER_CACHES: bool = false
const HAS_COUNTER_CACHES: bool = false
Source§fn counter_caches() -> &'static [CounterCacheSpec<Self>]
fn counter_caches() -> &'static [CounterCacheSpec<Self>]
Source§impl<T> AutumnDependents for Twhere
T: ?Sized,
impl<T> AutumnDependents for Twhere
T: ?Sized,
Source§fn dependents() -> &'static [RuntimeDependentSpec]
fn dependents() -> &'static [RuntimeDependentSpec]
#[model] overrides via an inherent shadow when dependents exist.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> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be
downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further
downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> DowncastSend for T
impl<T> DowncastSend for T
Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
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> IntoSql for T
impl<T> IntoSql for T
Source§fn into_sql<T>(self) -> Self::Expression
fn into_sql<T>(self) -> Self::Expression
self to an expression for Diesel’s query builder. Read moreSource§fn as_sql<'a, T>(&'a self) -> <&'a Self as AsExpression<T>>::Expression
fn as_sql<'a, T>(&'a self) -> <&'a Self as AsExpression<T>>::Expression
&self to an expression for Diesel’s query builder. Read moreSource§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
Source§impl<T, Conn> RunQueryDsl<Conn> for T
impl<T, Conn> RunQueryDsl<Conn> for T
Source§fn execute<'conn, 'query>(
self,
conn: &'conn mut Conn,
) -> <Conn as AsyncConnectionCore>::ExecuteFuture<'conn, 'query>
fn execute<'conn, 'query>( self, conn: &'conn mut Conn, ) -> <Conn as AsyncConnectionCore>::ExecuteFuture<'conn, 'query>
Source§fn load<'query, 'conn, U>(
self,
conn: &'conn mut Conn,
) -> AndThen<Self::LoadFuture<'conn>, TryCollect<Self::Stream<'conn>, Vec<U>>>
fn load<'query, 'conn, U>( self, conn: &'conn mut Conn, ) -> AndThen<Self::LoadFuture<'conn>, TryCollect<Self::Stream<'conn>, Vec<U>>>
Source§fn load_stream<'conn, 'query, U>(
self,
conn: &'conn mut Conn,
) -> Self::LoadFuture<'conn>where
Conn: AsyncConnectionCore,
U: 'conn,
Self: LoadQuery<'query, Conn, U> + 'query,
fn load_stream<'conn, 'query, U>(
self,
conn: &'conn mut Conn,
) -> Self::LoadFuture<'conn>where
Conn: AsyncConnectionCore,
U: 'conn,
Self: LoadQuery<'query, Conn, U> + 'query,
Stream] with the returned rows. Read moreSource§fn get_result<'query, 'conn, U>(
self,
conn: &'conn mut Conn,
) -> AndThen<Self::LoadFuture<'conn>, LoadNext<Pin<Box<Self::Stream<'conn>>>>>
fn get_result<'query, 'conn, U>( self, conn: &'conn mut Conn, ) -> AndThen<Self::LoadFuture<'conn>, LoadNext<Pin<Box<Self::Stream<'conn>>>>>
Source§fn get_results<'query, 'conn, U>(
self,
conn: &'conn mut Conn,
) -> AndThen<Self::LoadFuture<'conn>, TryCollect<Self::Stream<'conn>, Vec<U>>>
fn get_results<'query, 'conn, U>( self, conn: &'conn mut Conn, ) -> AndThen<Self::LoadFuture<'conn>, TryCollect<Self::Stream<'conn>, Vec<U>>>
Vec with the affected rows. Read moreSource§impl<T> Scoped for T
impl<T> Scoped for T
Source§fn scope(ctx: &PolicyContext) -> ScopeQuery<'_, Self>
fn scope(ctx: &PolicyContext) -> ScopeQuery<'_, Self>
ScopeQuery for this type. Resolves the
registered scope at .load() time, not here.