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}