1use alloc::string::String;
5use alloc::vec::Vec;
6use core::fmt;
7use std::io::{self, Read};
8
9use crate::error::{EncodingError, FormError, Location};
10use crate::limits::{Limits, Policy};
11use crate::multipart::owned_head::OwnedPartHead;
12use crate::multipart::parser::{Charset, Event, MultipartParser, PartSummary};
13
14const READ_BUFFER: usize = 64 * 1024;
15
16pub struct MultipartReader<R: Read> {
43 reader: R,
44 parser: MultipartParser<Vec<u8>>,
45 buf: Vec<u8>,
46 buf_used: usize,
48 start: usize,
49 end: usize,
50 eof: bool,
51 head: OwnedPartHead,
52 pending: Vec<u8>,
53 pending_at: usize,
54 in_part: bool,
55 last: Option<PartSummary>,
56 done: bool,
57 declared: Option<Vec<u8>>,
58 #[cfg(feature = "fs")]
60 disk_used: u64,
61}
62
63impl<R: Read> Drop for MultipartReader<R> {
64 fn drop(&mut self) {
65 crate::wipe::wipe(self.buf.get_mut(..self.buf_used).unwrap_or(&mut []));
66 crate::wipe::wipe_vec(&mut self.pending);
67 if let Some(d) = self.declared.as_mut() {
68 crate::wipe::wipe_vec(d);
69 }
70 }
71}
72
73impl<R: Read> fmt::Debug for MultipartReader<R> {
74 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
75 f.debug_struct("MultipartReader")
76 .field("parser", &self.parser)
77 .field("in_part", &self.in_part)
78 .finish_non_exhaustive()
79 }
80}
81
82enum Got {
84 Start,
85 Data,
86 End(PartSummary),
87 Done,
88}
89
90impl<R: Read> MultipartReader<R> {
91 pub fn new(content_type: &[u8], reader: R) -> Result<Self, FormError> {
97 Self::with_limits(content_type, reader, &Limits::DEFAULT, &Policy::DEFAULT)
98 }
99
100 pub fn with_limits(
106 content_type: &[u8],
107 reader: R,
108 limits: &Limits,
109 policy: &Policy,
110 ) -> Result<Self, FormError> {
111 let boundary = crate::Boundary::parse(content_type)?;
112 let parser = MultipartParser::new(boundary, limits, policy)?;
113 Ok(MultipartReader {
114 reader,
115 parser,
116 buf: alloc::vec![0u8; READ_BUFFER],
117 buf_used: 0,
118 start: 0,
119 end: 0,
120 eof: false,
121 head: OwnedPartHead::with_capacity(limits.multipart_buffer_len(policy)),
122 pending: Vec::new(),
123 pending_at: 0,
124 in_part: false,
125 last: None,
126 done: false,
127 declared: None,
128 #[cfg(feature = "fs")]
129 disk_used: 0,
130 })
131 }
132
133 #[must_use]
135 pub fn captured_token(&self) -> Option<&str> {
136 self.parser.captured_token()
137 }
138
139 fn fill(&mut self) -> Result<(), FormError> {
140 if self.start < self.end || self.eof {
141 return Ok(());
142 }
143 loop {
144 match self.reader.read(&mut self.buf) {
145 Ok(0) => {
146 self.eof = true;
147 self.start = 0;
148 self.end = 0;
149 return Ok(());
150 }
151 Ok(n) => {
152 self.start = 0;
153 self.end = n.min(self.buf.len());
154 self.buf_used = self.buf_used.max(self.end);
155 return Ok(());
156 }
157 Err(e) if e.kind() == io::ErrorKind::Interrupted => {
158 self.buf_used = self.buf.len();
160 }
161 Err(e) => {
162 self.buf_used = self.buf.len();
163 return Err(FormError::Io { kind: e.kind() });
164 }
165 }
166 }
167 }
168
169 fn step(&mut self) -> Result<Got, FormError> {
171 loop {
172 self.fill()?;
173 let input = self.buf.get(self.start..self.end).unwrap_or(&[]);
174 let step = self.parser.parse(input, self.eof)?;
175 self.start = self.start.saturating_add(step.consumed);
176 match step.event {
177 Event::PartStart(head) => {
178 self.head.copy_from(&head);
179 return Ok(Got::Start);
180 }
181 Event::Data(bytes) => {
182 crate::wipe::wipe(&mut self.pending);
183 self.pending.clear();
184 crate::wipe::append_wiping(&mut self.pending, bytes, 4096, usize::MAX);
185 self.pending_at = 0;
186 return Ok(Got::Data);
187 }
188 Event::PartEnd(s) => return Ok(Got::End(s)),
189 Event::End => return Ok(Got::Done),
190 _ => {}
191 }
192 }
193 }
194
195 pub fn next_part(&mut self) -> Result<Option<PartReader<'_, R>>, FormError> {
202 if self.in_part {
203 self.parser.skip_part();
204 self.pending.clear();
205 while self.in_part {
206 if let Got::End(s) = self.step()? {
207 self.end_part(s);
208 }
209 }
210 }
211 while !self.done {
212 match self.step()? {
213 Got::Start => {
214 self.in_part = true;
215 return Ok(Some(PartReader { inner: self }));
216 }
217 Got::Done => self.done = true,
218 _ => {}
219 }
220 }
221 Ok(None)
222 }
223
224 fn end_part(&mut self, summary: PartSummary) {
225 self.in_part = false;
226 self.last = Some(summary);
227 self.pending.clear();
228 }
229}
230
231pub struct PartReader<'r, R: Read> {
236 inner: &'r mut MultipartReader<R>,
237}
238
239impl<R: Read> fmt::Debug for PartReader<'_, R> {
240 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
241 f.debug_struct("PartReader")
242 .field("head", &self.inner.head)
243 .finish_non_exhaustive()
244 }
245}
246
247impl<R: Read> PartReader<'_, R> {
248 #[must_use]
250 pub fn head(&self) -> &OwnedPartHead {
251 &self.inner.head
252 }
253
254 pub fn text(&mut self) -> Result<String, FormError> {
263 let own = self.inner.head.view().charset();
264 let is_charset = self.inner.head.view().name() == "_charset_";
265 let cap = self.inner.parser.limits().value() as usize;
266 let mut out = Vec::new();
267 let read = (|| {
268 while let Some(chunk) = self.next_chunk()? {
269 if out.len().saturating_add(chunk.len()) > cap {
270 return Err(FormError::limit(
271 crate::Limit::ValueLength,
272 Location::in_part(
273 Some(self.inner.head.view().index()),
274 self.inner.parser.bytes_seen(),
275 ),
276 ));
277 }
278 crate::wipe::append_wiping(&mut out, chunk, 4096, cap);
279 }
280 Ok(())
281 })();
282 if let Err(e) = read {
283 crate::wipe::wipe_vec(&mut out);
284 return Err(e);
285 }
286 let at = Location::in_part(
287 Some(self.inner.head.view().index()),
288 self.inner.parser.bytes_seen(),
289 );
290 let readable = match own {
291 Charset::Utf8 | Charset::Ascii => true,
292 Charset::Other => false,
293 Charset::Unspecified => self.inner.declared.as_deref().is_none_or(|l| {
294 l.eq_ignore_ascii_case(b"utf-8") || l.eq_ignore_ascii_case(b"us-ascii")
295 }),
296 };
297 if !readable {
298 crate::wipe::wipe_vec(&mut out);
299 return Err(FormError::encoding(EncodingError::UnsupportedCharset, at));
300 }
301 if is_charset {
302 self.inner.declared = Some(out.clone());
303 }
304 String::from_utf8(out).map_err(|e| {
305 let mut bytes = e.into_bytes();
306 crate::wipe::wipe_vec(&mut bytes);
307 FormError::encoding(EncodingError::InvalidUtf8, at)
308 })
309 }
310
311 pub fn skip(&mut self) -> Result<u64, FormError> {
317 self.inner.parser.skip_part();
318 self.inner.pending.clear();
319 while self.inner.in_part {
320 if let Got::End(s) = self.inner.step()? {
321 self.inner.end_part(s);
322 }
323 }
324 Ok(self.inner.last.map_or(0, |s| s.bytes))
325 }
326
327 #[cfg(feature = "fs")]
333 #[cfg_attr(docsrs, doc(cfg(feature = "fs")))]
334 pub fn save(&mut self, store: &crate::Store) -> Result<crate::StoredFile, FormError> {
335 use crate::hook::Sink;
336 let mut sink = store
339 .sink(self.inner.parser.limits())
340 .with_used_disk(self.inner.disk_used);
341 let head = self.inner.head.clone();
342 sink.open(&head.view())?;
343 let r = (|| {
344 while let Some(chunk) = self.next_chunk()? {
345 sink.write(chunk)?;
346 }
347 sink.close()
348 })();
349 if r.is_err() {
350 sink.abort();
351 } else {
352 self.inner.disk_used = sink.used_disk();
353 }
354 r
355 }
356
357 fn next_chunk(&mut self) -> Result<Option<&[u8]>, FormError> {
359 let inner = &mut *self.inner;
360 if inner.pending_at < inner.pending.len() {
361 let chunk = inner.pending.get(inner.pending_at..).unwrap_or(&[]);
362 inner.pending_at = inner.pending.len();
363 return Ok(Some(chunk));
364 }
365 while inner.in_part {
366 match inner.step()? {
367 Got::Data => {
368 inner.pending_at = inner.pending.len();
369 return Ok(Some(&inner.pending));
370 }
371 Got::End(s) => inner.end_part(s),
372 _ => {}
373 }
374 }
375 Ok(None)
376 }
377}
378
379impl<R: Read> Read for PartReader<'_, R> {
380 fn read(&mut self, out: &mut [u8]) -> io::Result<usize> {
381 let inner = &mut *self.inner;
382 loop {
383 if inner.pending_at < inner.pending.len() {
384 let src = inner.pending.get(inner.pending_at..).unwrap_or(&[]);
385 let n = src.len().min(out.len());
386 if let (Some(dst), Some(src)) = (out.get_mut(..n), src.get(..n)) {
387 dst.copy_from_slice(src);
388 }
389 inner.pending_at = inner.pending_at.saturating_add(n);
390 return Ok(n);
391 }
392 if !inner.in_part {
393 return Ok(0);
394 }
395 match inner.step() {
396 Ok(Got::End(s)) => inner.end_part(s),
397 Ok(_) => {}
398 Err(e) => return Err(io::Error::new(io::ErrorKind::InvalidData, e)),
399 }
400 }
401 }
402}