[go: up one dir, main page]

Call

Struct Call 

Source
pub struct Call<State> { /* private fields */ }
Expand description

A state machine for an HTTP request/response cycle.

This type represents a state machine that transitions through various states during the lifecycle of an HTTP request/response.

The type parameters are:

  • State: The current state of the state machine (e.g., Prepare, SendRequest, etc.)

See the state graph in the client module documentation for a visual representation of the state transitions.

Implementations§

Source§

impl Call<Prepare>

Source

pub fn new(request: Request<()>) -> Result<Self, Error>

Create a new Call instance from an HTTP request.

This initializes a new Call state machine in the Prepare state, setting up the necessary internal state based on the request properties.

Source

pub fn method(&self) -> &Method

Inspect call method

Source

pub fn uri(&self) -> &Uri

Inspect call URI

Source

pub fn version(&self) -> Version

Inspect call HTTP version

Source

pub fn headers(&self) -> &HeaderMap

Inspect call headers

Source

pub fn allow_non_standard_methods(&mut self, v: bool)

Set whether to allow non-standard HTTP methods.

By default the methods are limited by the HTTP version.

Source

pub fn header<K, V>(&mut self, key: K, value: V) -> Result<(), Error>

Add more headers to the call

Source

pub fn force_send_body(&mut self)

Convert the state to send body despite method.

Methods like GET, HEAD and DELETE should not have a request body. Some broken APIs use bodies anyway, and this is an escape hatch to interoperate with such services.

Source

pub fn proceed(self) -> Call<SendRequest>

Continue to the next call state.

Source§

impl Call<SendRequest>

Source

pub fn write(&mut self, output: &mut [u8]) -> Result<usize, Error>

Write the request to the buffer.

Writes incrementally, it can be called repeatedly in situations where the output buffer is small.

This includes the first row, i.e. GET / HTTP/1.1 and all headers. The output buffer needs to be large enough for the longest row.

Example:

POST /bar HTTP/1.1\r\n
Host: my.server.test\r\n
User-Agent: myspecialthing\r\n
\r\n
<body data>

The buffer would need to be at least 28 bytes big, since the User-Agent row is 28 bytes long.

If the output is too small for the longest line, the result is an OutputOverflow error.

The Ok(usize) is the number of bytes of the output buffer that was used.

Source

pub fn method(&self) -> &Method

The configured method.

Source

pub fn uri(&self) -> &Uri

The uri being requested.

Source

pub fn version(&self) -> Version

Version of the request.

This can only be 1.0 or 1.1.

Source

pub fn headers_map(&mut self) -> Result<HeaderMap, Error>

The configured headers.

Source

pub fn can_proceed(&self) -> bool

Check whether the entire request has been sent.

This is useful when the output buffer is small and we need to repeatedly call write() to send the entire request.

Source

pub fn proceed(self) -> Result<Option<SendRequestResult>, Error>

Attempt to proceed from this state to the next.

Returns None if the entire request has not been sent. It is guaranteed that if can_proceed() returns true, this will return Some.

Source§

impl Call<Await100>

Source

pub fn try_read_100(&mut self, input: &[u8]) -> Result<usize, Error>

Attempt to read a 100-continue response.

Tries to interpret bytes sent by the server as a 100-continue response. The expect-100 mechanic means we hope the server will give us an indication on whether to upload a potentially big request body, before we start doing it.

  • If the server supports expect-100, it will respond HTTP/1.1 100 Continue\r\n\r\n, or some other response code (such as 403) if we are not allowed to post the body.
  • If the server does not support expect-100, it will not respond at all, in which case we will proceed to sending the request body after some timeout.

The results are:

  • Ok(0) - not enough data yet, continue waiting (or proceed() if you think we waited enough)
  • Ok(n) - n number of input bytes were consumed. Call proceed() next
  • Err(e) - some error that is not recoverable
Source

pub fn can_keep_await_100(&self) -> bool

Tell if there is any point in waiting for more data from the server.

Becomes false as soon as try_read_100() got enough data to determine what to do next. This might become false even if try_read_100 returns Ok(0).

If this returns false, the user should continue with proceed().

Source

pub fn proceed(self) -> Result<Await100Result, Error>

Proceed to the next state.

Source§

impl Call<SendBody>

Source

pub fn write( &mut self, input: &[u8], output: &mut [u8], ) -> Result<(usize, usize), Error>

Write request body from input to output.

This is called repeatedly until the entire body has been sent. The output buffer is filled as much as possible for each call.

Depending on request headers, the output might be transfer-encoding: chunked. Chunking means the output is slightly larger than the input due to the extra length headers per chunk. When not doing chunked, the input/output will be the same per call.

The result (usize, usize) is (input consumed, output used).

Important

To indicate that the body is fully sent, you call write with an input parameter set to &[]. This ends the transfer-encoding: chunked and ensures the state is correct to proceed.

Source

pub fn consume_direct_write(&mut self, amount: usize) -> Result<(), Error>

Helper to avoid copying memory.

When the transfer is NOT chunked, write() just copies the input to the output. This memcopy might be possible to avoid if the user can use the input buffer directly against the transport.

This function is used to “report” how much of the input that has been used. It’s effectively the same as the first usize in the pair returned by write().

Source

pub fn calculate_max_input(&self, output_len: usize) -> usize

Calculate the max amount of input we can transfer to fill the output_len.

For chunked transfer, the input is less than the output.

Source

pub fn is_chunked(&self) -> bool

Test if call is chunked.

This might need some processing, hence the &mut and

Source

pub fn can_proceed(&self) -> bool

Check whether the request body is fully sent.

For requests with a content-length header set, this will only become true once the number of bytes communicated have been sent. For chunked transfer, this becomes true after calling write() with an input of &[].

Source

pub fn proceed(self) -> Option<Call<RecvResponse>>

Proceed to the next state.

Returns None if it’s not possible to proceed. It’s guaranteed that if can_proceed() returns true, this will result in Some.

Source§

impl Call<RecvResponse>

Source

pub fn try_response( &mut self, input: &[u8], allow_partial_redirect: bool, ) -> Result<(usize, Option<Response<()>>), Error>

Try reading a response from the input.

  • allow_partial_redirect - if true, we can accept to find the Location header and proceed without reading the entire header. This is useful for broken servers that don’t send an entire \r\n at the end of the preamble.

The (usize, Option<Response()>) is (input amount consumed, response).

Notice that it’s possible that we get an input amount consumed despite not returning a Some(Response). This can happen if the server returned a 100-continue, and due to timing reasons we did not receive it while we were in the Await100 call state. This “spurios” 100 will be discarded before we parse the actual response.

Source

pub fn can_proceed(&self) -> bool

Tell if we have finished receiving the response.

Source

pub fn proceed(self) -> Option<RecvResponseResult>

Proceed to the next state.

This returns None if we have not finished receiving the response. It is guaranteed that if can_proceed() returns true, this will return Some.

Source

pub fn force_recv_body(&mut self)

Convert the state to receive a body despite method.

Methods like HEAD and CONNECT should not have attached bodies. Some broken APIs use bodies anyway and this is an escape hatch to interoperate with such services.

Source§

impl Call<RecvBody>

Source

pub fn read( &mut self, input: &[u8], output: &mut [u8], ) -> Result<(usize, usize), Error>

Read the response body from input to output.

Depending on response headers, we can be in transfer-encoding: chunked or not. If we are, there will be less output bytes than input.

The result (usize, usize) is (input consumed, output buffer used).

Source

pub fn stop_on_chunk_boundary(&mut self, enabled: bool)

Set if we are stopping on chunk boundaries.

If false, we try to fill entire output on each read() call. Has no meaning unless the response in chunked.

Defaults to false

Source

pub fn is_on_chunk_boundary(&self) -> bool

Tell if the reading is on a chunk boundary.

Used when we want to read exactly chunk-by-chunk.

Only releveant if we first enabled stop_on_chunk_boundary().

Source

pub fn body_mode(&self) -> BodyMode

Tell which kind of mode the response body is.

Source

pub fn can_proceed(&self) -> bool

Check if the response body has been fully received.

Source

pub fn is_ended_chunked(&self) -> bool

Tell if we got an end chunk when reading chunked.

A normal chunk ending is:

0\r\n
\r\n

However there are cases where the server abruptly does a FIN after sending 0\r\n. This means we still got the entire response body, and could use it, but not reuse the connection.

This returns true as soon as we got the 0\r\n.

Source

pub fn proceed(self) -> Option<RecvBodyResult>

Proceed to the next state.

Returns None if we are not fully received the body. It is guaranteed that if can_proceed() returns true, this will return Some.

Source§

impl Call<Redirect>

Source

pub fn as_new_call( &mut self, redirect_auth_headers: RedirectAuthHeaders, ) -> Result<Option<Call<Prepare>>, Error>

Construct a new Call by following the redirect.

There are some rules when following a redirect.

  • For 307/308
  • Other redirect (301, 302, etc)
    • HEAD results in HEAD in the redirect
    • All other methods becomes GET
Source

pub fn status(&self) -> StatusCode

The redirect status code.

Source

pub fn must_close_connection(&self) -> bool

Whether we must close the connection corresponding to the current call.

This is used to inform connection pooling.

Source

pub fn close_reason(&self) -> Option<&'static str>

If we are closing the connection, give a reason why.

Source

pub fn proceed(self) -> Call<Cleanup>

Proceed to the cleanup state.

Source§

impl Call<Cleanup>

Source

pub fn must_close_connection(&self) -> bool

Tell if we must close the connection.

Source

pub fn close_reason(&self) -> Option<&'static str>

If we are closing the connection, give a reason.

Trait Implementations§

Source§

impl<State: Named> Debug for Call<State>

Source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<State> !Freeze for Call<State>

§

impl<State> !RefUnwindSafe for Call<State>

§

impl<State> Send for Call<State>
where State: Send,

§

impl<State> Sync for Call<State>
where State: Sync,

§

impl<State> Unpin for Call<State>
where State: Unpin,

§

impl<State> !UnwindSafe for Call<State>

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, 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, 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.