ureq_proto/server/
recvbody.rs

1use crate::{BodyMode, Error};
2
3use super::state::{ProvideResponse, RecvBody};
4use super::Reply;
5
6impl Reply<RecvBody> {
7    /// Read the input as a request body.
8    ///
9    /// This method reads data from the input buffer (the request body from the client)
10    /// and writes it to the output buffer. It handles different transfer encodings
11    /// (chunked, content-length, etc.) automatically.
12    ///
13    /// * `input` - A byte slice containing the input data from the client
14    /// * `output` - A mutable byte slice to write the decoded body data to
15    ///
16    /// Returns a tuple `(usize, usize)` where:
17    /// - The first element is the number of bytes consumed from the input
18    /// - The second element is the number of bytes written to the output
19    pub fn read(&mut self, input: &[u8], output: &mut [u8]) -> Result<(usize, usize), Error> {
20        let rbm = self.inner.state.reader.as_mut().unwrap();
21
22        if rbm.is_ended() {
23            return Ok((0, 0));
24        }
25
26        rbm.read(input, output, self.inner.state.stop_on_chunk_boundary)
27    }
28
29    /// Set whether we are stopping on chunk boundaries.
30    ///
31    /// If `false`, we are trying to fill the entire `output` in each `read()` call.
32    ///
33    /// This is useful when processing chunked transfer encoding and you want to
34    /// handle each chunk separately.
35    ///
36    /// * `enabled` - Whether to stop reading at chunk boundaries
37    ///
38    /// Defaults to `false` (read as much as possible).
39    pub fn stop_on_chunk_boundary(&mut self, enabled: bool) {
40        self.inner.state.stop_on_chunk_boundary = enabled;
41    }
42
43    /// Tell if we are currently on a chunk boundary.
44    ///
45    /// This method is useful when you've enabled `stop_on_chunk_boundary()` to
46    /// determine if the current position is at a chunk boundary.
47    ///
48    /// Returns `true` if the current position is at a chunk boundary, `false` otherwise.
49    ///
50    /// Only relevant if you are using chunked transfer encoding and have enabled
51    /// `stop_on_chunk_boundary()`.
52    pub fn is_on_chunk_boundary(&self) -> bool {
53        let rbm = self.inner.state.reader.as_ref().unwrap();
54        rbm.is_on_chunk_boundary()
55    }
56
57    /// Tell which kind of mode the response body is.
58    pub fn body_mode(&self) -> BodyMode {
59        self.inner.state.reader.as_ref().unwrap().body_mode()
60    }
61
62    /// Tell if the request body is over
63    ///
64    /// Returns `true` if the entire request body has been received, `false` otherwise.
65    pub fn is_ended(&self) -> bool {
66        let rbm = self.inner.state.reader.as_ref().unwrap();
67        rbm.is_ended()
68    }
69
70    /// Proceed to sending a response.
71    ///
72    /// This is only possible when the request body is fully read.
73    ///
74    /// Returns the Reply in the ProvideResponse state.
75    ///
76    /// Panics if the request body has not been fully read.
77    pub fn proceed(self) -> Result<Reply<ProvideResponse>, Error> {
78        assert!(self.is_ended());
79
80        Ok(Reply::wrap(self.inner))
81    }
82}