form_data/
state.rs

1use std::fmt;
2
3#[cfg(feature = "async")]
4use std::task::Waker;
5
6use bytes::{Buf, Bytes, BytesMut};
7use memchr::memmem;
8
9use crate::{
10    utils::{CRLF, CRLFS, DASHES},
11    Limits,
12};
13
14#[derive(Debug, PartialEq)]
15pub(crate) enum Flag {
16    Delimiting(bool),
17    Heading(usize),
18    Headed,
19    Header,
20    Next,
21    Eof,
22}
23
24/// IO State
25pub struct State<T> {
26    io: T,
27    pub(crate) eof: bool,
28    pub(crate) flag: Flag,
29    pub(crate) length: u64,
30    pub(crate) buffer: BytesMut,
31    delimiter: Bytes,
32    pub(crate) is_readable: bool,
33    #[cfg(feature = "async")]
34    waker: Option<Waker>,
35    pub(crate) total: usize,
36    pub(crate) files: usize,
37    pub(crate) fields: usize,
38    pub(crate) limits: Limits,
39}
40
41impl<T> State<T> {
42    /// Creates new State.
43    pub fn new(io: T, boundary: &[u8], limits: Limits) -> Self {
44        // `\r\n--boundary`
45        let mut delimiter = BytesMut::with_capacity(4 + boundary.len());
46        delimiter.extend_from_slice(&CRLF);
47        delimiter.extend_from_slice(&DASHES);
48        delimiter.extend_from_slice(boundary);
49
50        // `\r\n`
51        let mut buffer = BytesMut::with_capacity(limits.buffer_size);
52        buffer.extend_from_slice(&CRLF);
53
54        Self {
55            io,
56            limits,
57            total: 0,
58            files: 0,
59            fields: 0,
60            length: 0,
61
62            #[cfg(feature = "async")]
63            waker: None,
64            eof: false,
65            is_readable: false,
66
67            buffer,
68            flag: Flag::Delimiting(false),
69            delimiter: delimiter.freeze(),
70        }
71    }
72
73    /// Gets io.
74    pub fn io_mut(&mut self) -> &mut T {
75        &mut self.io
76    }
77
78    /// Gets waker.
79    #[cfg(feature = "async")]
80    pub fn waker(&self) -> Option<&Waker> {
81        self.waker.as_ref()
82    }
83
84    /// Gets waker.
85    #[cfg(feature = "async")]
86    pub fn waker_mut(&mut self) -> &mut Option<Waker> {
87        &mut self.waker
88    }
89
90    /// Gets limits.
91    pub fn limits_mut(&mut self) -> &mut Limits {
92        &mut self.limits
93    }
94
95    /// Splits buffer.
96    pub fn split_buffer(&mut self, n: usize) -> Bytes {
97        self.buffer.split_to(n).freeze()
98    }
99
100    /// Gets the index of the field.
101    pub fn index(&mut self) -> usize {
102        let index = self.total;
103        self.total += 1;
104        index
105    }
106
107    /// Gets the length of the form-data.
108    pub fn len(&self) -> u64 {
109        self.length
110    }
111
112    /// Gets bool of the form-data's length is zero.
113    pub fn is_empty(&self) -> bool {
114        self.length == 0
115    }
116
117    /// Gets EOF.
118    pub fn eof(&self) -> bool {
119        self.eof
120    }
121
122    /// Counts the fields.
123    pub fn total(&self) -> usize {
124        self.total
125    }
126
127    /// Gets the boundary.
128    pub fn boundary(&self) -> &[u8] {
129        &self.delimiter[4..]
130    }
131
132    pub(crate) fn decode(&mut self) -> Option<Bytes> {
133        if let Flag::Delimiting(boding) = self.flag {
134            if let Some(n) = memmem::find(&self.buffer, &self.delimiter) {
135                self.flag = Flag::Heading(n);
136            } else {
137                // Empty Request Body
138                if self.eof && self.buffer.len() == 2 && self.buffer[..2] == CRLF {
139                    self.buffer.advance(2);
140                    self.flag = Flag::Eof;
141                    return None;
142                }
143
144                // Empty Part Body
145                if memmem::find(&self.buffer, &self.delimiter[2..]).is_some() {
146                    self.flag = Flag::Next;
147                    self.buffer.advance(self.delimiter.len() - 2);
148                    return None;
149                }
150
151                // Reading Part Body
152                if boding {
153                    // Returns buffer with `max_buf_size`
154                    if self.limits.buffer_size + self.delimiter.len() < self.buffer.len() {
155                        return Some(self.buffer.split_to(self.limits.buffer_size).freeze());
156                    }
157                }
158            }
159        }
160
161        if let Flag::Heading(ref mut n) = self.flag {
162            // first part
163            if self.total == 0 {
164                if *n > 0 {
165                    // consume data
166                    self.buffer.advance(*n);
167                }
168                self.buffer.advance(self.delimiter.len());
169                self.flag = Flag::Headed;
170            } else {
171                // prev part is ended
172                if *n == 0 {
173                    // field'stream need to stop
174                    self.flag = Flag::Next;
175                    self.buffer.advance(self.delimiter.len());
176                    return None;
177                }
178                // prev part last data
179                let buf = self.buffer.split_to(*n).freeze();
180                *n = 0;
181                return Some(buf);
182            }
183        }
184
185        if Flag::Next == self.flag {
186            self.flag = Flag::Headed;
187        }
188
189        if Flag::Headed == self.flag && self.buffer.len() > 1 {
190            if self.buffer[..2] == CRLF {
191                self.buffer.advance(2);
192                self.flag = Flag::Header;
193            } else if self.buffer[..2] == DASHES {
194                self.buffer.advance(2);
195                self.flag = Flag::Eof;
196                return None;
197            } else {
198                // We dont parse other format, like `\n`
199                self.length -= (self.delimiter.len() - 2) as u64;
200                self.flag = Flag::Eof;
201                return None;
202            }
203        }
204
205        if Flag::Header == self.flag {
206            if let Some(n) = memmem::find(&self.buffer, &CRLFS) {
207                self.flag = Flag::Delimiting(true);
208                return Some(self.buffer.split_to(n + CRLFS.len()).freeze());
209            }
210        }
211
212        None
213    }
214}
215
216impl<T> fmt::Debug for State<T> {
217    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
218        f.debug_struct("State")
219            .field("eof", &self.eof)
220            .field("flag", &self.flag)
221            .field("total", &self.total)
222            .field("files", &self.files)
223            .field("fields", &self.fields)
224            .field("length", &self.length)
225            .field("limits", &self.limits)
226            .field("is_readable", &self.is_readable)
227            .field("boundary", &String::from_utf8_lossy(self.boundary()))
228            .finish_non_exhaustive()
229    }
230}