pub struct Reply<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.,RecvRequest,SendResponse, etc.)B: The type of the response body (defaults to())
See the state graph in the server module documentation for a visual representation of the state transitions.
Implementations§
Source§impl Reply<RecvRequest>
impl Reply<RecvRequest>
Sourcepub fn new() -> Result<Self, Error>
pub fn new() -> Result<Self, Error>
Create a new Reply in the RecvRequest state.
This is the entry point for the server state machine. It creates a new Reply in the RecvRequest state, ready to receive an HTTP request from a client.
Returns an error if the Reply cannot be created.
Sourcepub fn try_request(
&mut self,
input: &[u8],
) -> Result<(usize, Option<Request<()>>), Error>
pub fn try_request( &mut self, input: &[u8], ) -> Result<(usize, Option<Request<()>>), Error>
Try reading a request from the input.
Attempts to parse an HTTP request from the input buffer. If the input buffer
doesn’t contain a complete request, this method will return Ok((0, None)).
Returns a tuple with the number of bytes consumed from the input and the parsed request (or None if incomplete).
Returns an error if there’s a problem parsing the request.
Sourcepub fn can_proceed(&self) -> bool
pub fn can_proceed(&self) -> bool
Check if the Reply can proceed to the next state.
This method is currently not implemented and will panic if called. In a real implementation, it would check if the request has been fully received and is ready to proceed to the next state.
Sourcepub fn proceed(self) -> Option<RecvRequestResult>
pub fn proceed(self) -> Option<RecvRequestResult>
Proceed to the next state.
This returns None if we have not finished receiving the request. It is guaranteed that if
can_proceed() returns true, this will return Some.
Returns one of the following variants of RecvRequestResult:
Send100if the request included an “Expect: 100-continue” headerRecvBodyif the request has a body to receiveProvideResponseif the request doesn’t have a body
Sourcepub fn force_recv_body(&mut self)
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 Reply<Send100>
impl Reply<Send100>
Sourcepub fn accept(
self,
output: &mut [u8],
) -> Result<(usize, Reply<RecvBody>), Error>
pub fn accept( self, output: &mut [u8], ) -> Result<(usize, Reply<RecvBody>), Error>
Sends a 100 Continue response and proceeds to receiving the body.
This method sends an HTTP 100 Continue response to the client, indicating that the server is willing to accept the request body. After sending the response, it transitions to the RecvBody state to receive the request body.
Returns a tuple with the number of bytes written to the output buffer and the Reply in the RecvBody state.
Returns an Error::OutputOverflow if the output buffer isn’t large enough to
contain the 100 Continue status line.
Sourcepub fn reject(self) -> Reply<ProvideResponse>
pub fn reject(self) -> Reply<ProvideResponse>
Rejects the 100 Continue request and proceeds to providing a response.
This method rejects the client’s “Expect: 100-continue” request and transitions to the ProvideResponse state. The server should then provide an error response (typically a 4xx or 5xx status code) to indicate why the request was rejected.
Source§impl Reply<ProvideResponse>
impl Reply<ProvideResponse>
Sourcepub fn provide(
self,
response: Response<()>,
) -> Result<Reply<SendResponse>, Error>
pub fn provide( self, response: Response<()>, ) -> Result<Reply<SendResponse>, Error>
Provide a response to the client’s request.
Takes a Response object and transitions to the SendResponse state. Handles setting appropriate headers for the response body if they weren’t already set.
Sourcepub fn force_send_body(&mut self)
pub fn force_send_body(&mut self)
Convert the state to send a body despite the 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 Reply<RecvBody>
impl Reply<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 input as a request body.
This method reads data from the input buffer (the request body from the client) and writes it to the output buffer. It handles different transfer encodings (chunked, content-length, etc.) automatically.
input- A byte slice containing the input data from the clientoutput- A mutable byte slice to write the decoded body data to
Returns a tuple (usize, usize) where:
- The first element is the number of bytes consumed from the input
- The second element is the number of bytes written to the output
Sourcepub fn stop_on_chunk_boundary(&mut self, enabled: bool)
pub fn stop_on_chunk_boundary(&mut self, enabled: bool)
Set whether we are stopping on chunk boundaries.
If false, we are trying to fill the entire output in each read() call.
This is useful when processing chunked transfer encoding and you want to handle each chunk separately.
enabled- Whether to stop reading at chunk boundaries
Defaults to false (read as much as possible).
Sourcepub fn is_on_chunk_boundary(&self) -> bool
pub fn is_on_chunk_boundary(&self) -> bool
Tell if we are currently on a chunk boundary.
This method is useful when you’ve enabled stop_on_chunk_boundary() to
determine if the current position is at a chunk boundary.
Returns true if the current position is at a chunk boundary, false otherwise.
Only relevant if you are using chunked transfer encoding and have enabled
stop_on_chunk_boundary().
Source§impl Reply<SendResponse>
impl Reply<SendResponse>
Sourcepub fn write(&mut self, output: &mut [u8]) -> Result<usize, Error>
pub fn write(&mut self, output: &mut [u8]) -> Result<usize, Error>
Write the response headers to the output buffer.
Writes the response status line and headers to the output buffer. May need to be called multiple times if the output buffer isn’t large enough.
Returns the number of bytes written to the output buffer.
Sourcepub fn is_finished(&self) -> bool
pub fn is_finished(&self) -> bool
Whether the response headers have been fully written.
Returns true if all response headers have been written and the state is ready to proceed to sending the response body.
Sourcepub fn proceed(self) -> SendResponseResult
pub fn proceed(self) -> SendResponseResult
Proceed to sending a response body or cleanup.
Transitions to either:
- SendBody state if the response needs a body (based on status code and method)
- Cleanup state if no response body should be sent (e.g., HEAD requests)
This is only possible when the response headers are fully written.
Panics if the response headers have not been fully written.
Source§impl Reply<SendBody>
impl Reply<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 response 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 response 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_max_input(&self, output_len: usize) -> usize
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.
Sourcepub fn is_chunked(&self) -> bool
pub fn is_chunked(&self) -> bool
Test if the response is using chunked transfer encoding.
Sourcepub fn is_finished(&self) -> bool
pub fn is_finished(&self) -> bool
Check whether the response body is fully sent.
For responses 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 Reply<Cleanup>
impl Reply<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.