pub struct Flow<B, State> { /* private fields */ }Expand description
A flow of calls, in some state following the flow state graph
Implementations§
Source§impl<B> Flow<B, Prepare>
impl<B> Flow<B, Prepare>
Sourcepub fn header<K, V>(&mut self, key: K, value: V) -> Result<(), Error>where
HeaderName: TryFrom<K>,
<HeaderName as TryFrom<K>>::Error: Into<Error>,
HeaderValue: TryFrom<V>,
<HeaderValue as TryFrom<V>>::Error: Into<Error>,
pub fn header<K, V>(&mut self, key: K, value: V) -> Result<(), Error>where
HeaderName: TryFrom<K>,
<HeaderName as TryFrom<K>>::Error: Into<Error>,
HeaderValue: TryFrom<V>,
<HeaderValue as TryFrom<V>>::Error: Into<Error>,
Add more headers to the call
Sourcepub fn send_body_despite_method(&mut self)
pub fn send_body_despite_method(&mut self)
Convert the call 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§impl<B> Flow<B, SendRequest>
impl<B> Flow<B, SendRequest>
Sourcepub fn write(&mut self, output: &mut [u8]) -> Result<usize, Error>
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 prelude/first row i.e. GET / HTTP/1.1 and all headers.
The output buffer needs to be large enough for the longest row of the prelude
and headers.
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.
Sourcepub fn headers_map(&mut self) -> Result<HeaderMap, Error>
pub fn headers_map(&mut self) -> Result<HeaderMap, Error>
The configured headers.
Sourcepub fn can_proceed(&self) -> bool
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.
Sourcepub fn proceed(self) -> Option<SendRequestResult<B>>
pub fn proceed(self) -> Option<SendRequestResult<B>>
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<B> Flow<B, Await100>
impl<B> Flow<B, Await100>
Sourcepub fn try_read_100(&mut self, input: &[u8]) -> Result<usize, Error>
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 (orproceed()if you think we waited enough)Ok(n)-nnumber of input bytes were consumed. Callproceed()nextErr(e)- some error that is not recoverable
Sourcepub fn can_keep_await_100(&self) -> bool
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().
Sourcepub fn proceed(self) -> Await100Result<B>
pub fn proceed(self) -> Await100Result<B>
Proceed to the next state.
Source§impl<B> Flow<B, SendBody>
impl<B> Flow<B, SendBody>
Sourcepub fn write(
&mut self,
input: &[u8],
output: &mut [u8],
) -> Result<(usize, usize), Error>
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.
Sourcepub fn consume_direct_write(&mut self, amount: usize) -> Result<(), Error>
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().
Sourcepub fn calculate_output_overhead(
&mut self,
output_len: usize,
) -> Result<usize, Error>
pub fn calculate_output_overhead( &mut self, output_len: usize, ) -> Result<usize, Error>
Calculate the overhead for a certain output length.
For transfer-encoding: chunked, this can be used to calculate the amount of extra
bytes that are required to write() a certain output.
For non-chunked it returns 0.
Sourcepub fn can_proceed(&self) -> bool
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§impl<B> Flow<B, RecvResponse>
impl<B> Flow<B, RecvResponse>
Sourcepub fn try_response(
&mut self,
input: &[u8],
) -> Result<(usize, Option<Response<()>>), Error>
pub fn try_response( &mut self, input: &[u8], ) -> Result<(usize, Option<Response<()>>), Error>
Try reading a response from the input.
This requires the entire response, including all headers to be present in the input buffer.
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 flow state. This
“spurios” 100 will be discarded before we parse the actual response.
Sourcepub fn can_proceed(&self) -> bool
pub fn can_proceed(&self) -> bool
Tell if we have finished receiving the response.
Sourcepub fn proceed(self) -> Option<RecvResponseResult<B>>
pub fn proceed(self) -> Option<RecvResponseResult<B>>
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§impl<B> Flow<B, RecvBody>
impl<B> Flow<B, RecvBody>
Sourcepub fn read(
&mut self,
input: &[u8],
output: &mut [u8],
) -> Result<(usize, usize), Error>
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).
Sourcepub fn can_proceed(&self) -> bool
pub fn can_proceed(&self) -> bool
Check if the response body has been fully received.
Sourcepub fn proceed(self) -> Option<RecvBodyResult<B>>
pub fn proceed(self) -> Option<RecvBodyResult<B>>
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<B> Flow<B, Redirect>
impl<B> Flow<B, Redirect>
Sourcepub fn as_new_flow(
&mut self,
redirect_auth_headers: RedirectAuthHeaders,
) -> Result<Option<Flow<B, Prepare>>, Error>
pub fn as_new_flow( &mut self, redirect_auth_headers: RedirectAuthHeaders, ) -> Result<Option<Flow<B, Prepare>>, Error>
Construct a new Flow by following the redirect.
There are some rules when follwing a redirect.
- For 307/308
- POST/PUT results in
None, since we do not allow redirecting a request body - DELETE is intentionally excluded: https://stackoverflow.com/questions/299628
- All other methods retain the method in the redirect
- POST/PUT results in
- Other redirect (301, 302, etc)
- HEAD results in HEAD in the redirect
- All other methods becomes GET
Sourcepub fn status(&self) -> StatusCode
pub fn status(&self) -> StatusCode
The redirect status code.
Sourcepub fn must_close_connection(&self) -> bool
pub fn must_close_connection(&self) -> bool
Whether we must close the connection corresponding to the current flow.
This is used to inform connection pooling.
Sourcepub fn close_reason(&self) -> Option<&'static str>
pub fn close_reason(&self) -> Option<&'static str>
If we are closing the connection, give a reason why.
Source§impl<B> Flow<B, Cleanup>
impl<B> Flow<B, Cleanup>
Sourcepub fn must_close_connection(&self) -> bool
pub fn must_close_connection(&self) -> bool
Tell if we must close the connection.
Sourcepub fn close_reason(&self) -> Option<&'static str>
pub fn close_reason(&self) -> Option<&'static str>
If we are closing the connection, give a reason.