Skip to main content

HttpResponse

Struct HttpResponse 

Source
pub struct HttpResponse { /* private fields */ }
Expand description

HTTP response wrapper with body-reading helpers

Provides a reqwest-like API for reading response bodies:

  • resp.error_for_status()? - Check status without reading body
  • resp.bytes().await? - Read raw bytes
  • resp.checked_bytes().await? - Read bytes with status check
  • resp.json::<T>().await? - Parse as JSON with status check

All body reads enforce the configured max_body_size limit.

Implementations§

Source§

impl HttpResponse

Source

pub fn status(&self) -> StatusCode

Get the response status code

Source

pub fn headers(&self) -> &HeaderMap

Get the response headers

Source

pub fn into_inner(self) -> Response<ResponseBody>

Consume the wrapper and return the inner response with boxed body

Useful for advanced callers who need direct access to the response. Note: The body has already been through the decompression layer, so it contains decompressed bytes if the server sent compressed data.

Source

pub fn error_for_status(self) -> Result<Self, HttpError>

Check status and return error for non-2xx responses

Does NOT read the response body. For non-2xx status, returns HttpError::HttpStatus with an empty body preview.

§Errors

Returns HttpError::HttpStatus if the response status is not 2xx.

§Example
let resp = client.get("https://example.com/api").send().await?;
let resp = resp.error_for_status()?;  // Fails if not 2xx
let body = resp.bytes().await?;
Source

pub async fn bytes(self) -> Result<Bytes, HttpError>

Read response body as bytes without status check

Enforces max_body_size limit.

§Errors

Returns HttpError::BodyTooLarge if body exceeds limit.

Source

pub async fn checked_bytes(self) -> Result<Bytes, HttpError>

Read response body as bytes with status check

Returns HttpError::HttpStatus for non-2xx responses (with body preview). Enforces max_body_size limit for successful responses.

§Errors

Returns HttpError::HttpStatus if status is not 2xx. Returns HttpError::BodyTooLarge if body exceeds limit.

Source

pub async fn json<T: DeserializeOwned>(self) -> Result<T, HttpError>

Parse response body as JSON with status check

Equivalent to resp.checked_bytes().await? followed by JSON parsing.

§Errors

Returns HttpError::HttpStatus if status is not 2xx. Returns HttpError::BodyTooLarge if body exceeds limit. Returns HttpError::Json if parsing fails.

Source

pub async fn text(self) -> Result<String, HttpError>

Read response body as text (UTF-8) with status check

Equivalent to resp.checked_bytes().await? followed by UTF-8 conversion. Invalid UTF-8 sequences are replaced with the Unicode replacement character.

§Errors

Returns HttpError::HttpStatus if status is not 2xx. Returns HttpError::BodyTooLarge if body exceeds limit.

§Example
let body = client
    .get("https://example.com/text")
    .send()
    .await?
    .text()
    .await?;
println!("Response: {}", body);
Source

pub fn into_body(self) -> ResponseBody

Returns the response body as a stream for incremental processing.

§Warning: No Size Limit Enforcement

This method does NOT enforce max_body_size. For untrusted responses (especially compressed), prefer into_limited_body() to protect against decompression bombs and memory exhaustion.

Unlike bytes(), json(), or text(), this method does NOT:

  • Check the HTTP status code (use error_for_status() first if needed)
  • Enforce the max_body_size limit (caller is responsible for limiting)
  • Buffer the entire body in memory

Use this only when:

  • You trust the response source AND have external size limits
  • You’re implementing custom streaming logic with your own limits
  • Performance is critical and you can guarantee bounded responses
§Example
use http_body_util::BodyExt;

let response = client.get("https://example.com/large-file").send().await?;

// Check status first (optional)
if !response.status().is_success() {
    return Err(/* handle error */);
}

// Get the body stream (WARNING: no size limit!)
let mut body = response.into_body();

// Process frames incrementally
while let Some(frame) = body.frame().await {
    let frame = frame?;
    if let Some(chunk) = frame.data_ref() {
        process_chunk(chunk);
    }
}
Source

pub fn into_limited_body(self) -> LimitedBody

Returns the response body as a size-limited stream.

Unlike into_body(), this method wraps the body in a LimitedBody that enforces the configured max_body_size limit during streaming. This protects against decompression bombs where a small compressed payload expands to gigabytes of memory.

The limit is enforced on decompressed bytes, so a 1KB gzip payload that decompresses to 1GB will be rejected.

§Errors

When the limit is exceeded, the next poll_frame() call returns HttpError::BodyTooLarge.

§Example
use http_body_util::BodyExt;

let response = client.get("https://example.com/large-file").send().await?;
let mut body = response.into_limited_body();

while let Some(frame) = body.frame().await {
    let frame = frame?; // Returns BodyTooLarge if limit exceeded
    if let Some(chunk) = frame.data_ref() {
        process_chunk(chunk);
    }
}

println!("Total bytes read: {}", body.bytes_read());
Source

pub fn max_body_size(&self) -> usize

Returns the configured max body size for this response.

This is the limit that would be applied by bytes(), checked_bytes(), json(), and text() methods.

Trait Implementations§

Source§

impl Debug for HttpResponse

Source§

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

Formats the value using the given formatter. 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> 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: 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: 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> ServiceExt for T

Source§

fn decompression(self) -> Decompression<Self>
where Self: Sized,

Decompress response bodies. Read more
Source§

fn trace_for_http(self) -> Trace<Self, SharedClassifier<ServerErrorsAsFailures>>
where Self: Sized,

High level tracing that classifies responses using HTTP status codes. Read more
Source§

fn trace_for_grpc(self) -> Trace<Self, SharedClassifier<GrpcErrorsAsFailures>>
where Self: Sized,

High level tracing that classifies responses using gRPC headers. Read more
Source§

fn follow_redirects(self) -> FollowRedirect<Self>
where Self: Sized,

Follow redirect resposes using the Standard policy. Read more
Source§

fn set_request_id<M>( self, header_name: HeaderName, make_request_id: M, ) -> SetRequestId<Self, M>
where Self: Sized, M: MakeRequestId,

Add request id header and extension. Read more
Source§

fn set_x_request_id<M>(self, make_request_id: M) -> SetRequestId<Self, M>
where Self: Sized, M: MakeRequestId,

Add request id header and extension, using x-request-id as the header name. Read more
Source§

fn propagate_request_id( self, header_name: HeaderName, ) -> PropagateRequestId<Self>
where Self: Sized,

Propgate request ids from requests to responses. Read more
Source§

fn propagate_x_request_id(self) -> PropagateRequestId<Self>
where Self: Sized,

Propgate request ids from requests to responses, using x-request-id as the header name. Read more
Source§

fn request_body_limit(self, limit: usize) -> RequestBodyLimit<Self>
where Self: Sized,

Intercept requests with over-sized payloads and convert them into 413 Payload Too Large responses. Read more
Source§

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

Source§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

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<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

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