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::{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_ok: bool,
61 #[cfg(feature = "fs")]
63 disk_used: u64,
64}
65
66impl<R: Read> Drop for MultipartReader<R> {
67 fn drop(&mut self) {
68 crate::wipe::wipe(self.buf.get_mut(..self.buf_used).unwrap_or(&mut []));
69 crate::wipe::wipe_vec(&mut self.pending);
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_ok: true,
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 declared_ok =
177 crate::multipart::parser::declared_readable(self.parser.declared_charset());
178 let step = self.parser.parse(input, self.eof)?;
179 self.start = self.start.saturating_add(step.consumed);
180 match step.event {
181 Event::PartStart(head) => {
182 self.head.copy_from(&head);
183 self.declared_ok = declared_ok;
184 return Ok(Got::Start);
185 }
186 Event::Data(bytes) => {
187 crate::wipe::wipe(&mut self.pending);
188 self.pending.clear();
189 crate::wipe::append_wiping(&mut self.pending, bytes, 4096, usize::MAX);
190 self.pending_at = 0;
191 return Ok(Got::Data);
192 }
193 Event::PartEnd(s) => return Ok(Got::End(s)),
194 Event::End => return Ok(Got::Done),
195 _ => {}
196 }
197 }
198 }
199
200 pub fn next_part(&mut self) -> Result<Option<PartReader<'_, R>>, FormError> {
210 if self.in_part {
211 self.parser.skip_part();
212 self.pending.clear();
213 while self.in_part {
214 if let Got::End(s) = self.step()? {
215 self.end_part(s);
216 }
217 }
218 }
219 while !self.done {
220 match self.step()? {
221 Got::Start => {
222 self.in_part = true;
223 return Ok(Some(PartReader { inner: self }));
224 }
225 Got::Done => {
226 self.done = true;
227 self.drain_epilogue()?;
228 }
229 _ => {}
230 }
231 }
232 Ok(None)
233 }
234
235 fn drain_epilogue(&mut self) -> Result<(), FormError> {
238 loop {
239 self.fill()?;
240 if self.start >= self.end {
242 return Ok(());
243 }
244 let input = self.buf.get(self.start..self.end).unwrap_or(&[]);
245 let step = self.parser.parse(input, self.eof)?;
246 if step.consumed == 0 {
247 return Ok(());
248 }
249 self.start = self.start.saturating_add(step.consumed);
250 }
251 }
252
253 fn end_part(&mut self, summary: PartSummary) {
254 self.in_part = false;
255 self.last = Some(summary);
256 self.pending.clear();
257 }
258}
259
260pub struct PartReader<'r, R: Read> {
265 inner: &'r mut MultipartReader<R>,
266}
267
268impl<R: Read> fmt::Debug for PartReader<'_, R> {
269 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
270 f.debug_struct("PartReader")
271 .field("head", &self.inner.head)
272 .finish_non_exhaustive()
273 }
274}
275
276impl<R: Read> PartReader<'_, R> {
277 #[must_use]
279 pub fn head(&self) -> &OwnedPartHead {
280 &self.inner.head
281 }
282
283 pub fn text(&mut self) -> Result<String, FormError> {
292 let own = self.inner.head.view().charset();
293 let cap = self.inner.parser.limits().value() as usize;
294 let mut out = Vec::new();
295 let read = (|| {
296 while let Some(chunk) = self.next_chunk()? {
297 if out.len().saturating_add(chunk.len()) > cap {
298 return Err(FormError::limit(
299 crate::Limit::ValueLength,
300 Location::in_part(
301 Some(self.inner.head.view().index()),
302 self.inner.parser.bytes_seen(),
303 ),
304 ));
305 }
306 crate::wipe::append_wiping(&mut out, chunk, 4096, cap);
307 }
308 Ok(())
309 })();
310 if let Err(e) = read {
311 crate::wipe::wipe_vec(&mut out);
312 return Err(e);
313 }
314 let at = Location::in_part(
315 Some(self.inner.head.view().index()),
316 self.inner.parser.bytes_seen(),
317 );
318 if !own.readable(self.inner.declared_ok) {
319 crate::wipe::wipe_vec(&mut out);
320 return Err(FormError::encoding(EncodingError::UnsupportedCharset, at));
321 }
322 String::from_utf8(out).map_err(|e| {
323 let mut bytes = e.into_bytes();
324 crate::wipe::wipe_vec(&mut bytes);
325 FormError::encoding(EncodingError::InvalidUtf8, at)
326 })
327 }
328
329 pub fn skip(&mut self) -> Result<u64, FormError> {
335 self.inner.parser.skip_part();
336 self.inner.pending.clear();
337 while self.inner.in_part {
338 if let Got::End(s) = self.inner.step()? {
339 self.inner.end_part(s);
340 }
341 }
342 Ok(self.inner.last.map_or(0, |s| s.bytes))
343 }
344
345 #[cfg(feature = "fs")]
351 #[cfg_attr(docsrs, doc(cfg(feature = "fs")))]
352 pub fn save(&mut self, store: &crate::Store) -> Result<crate::StoredFile, FormError> {
353 use crate::hook::Sink;
354 let mut sink = store
357 .sink(self.inner.parser.limits())
358 .with_used_disk(self.inner.disk_used);
359 let head = self.inner.head.clone();
360 sink.open(&head.view())?;
361 let r = (|| {
362 while let Some(chunk) = self.next_chunk()? {
363 sink.write(chunk)?;
364 }
365 sink.close()
366 })();
367 if r.is_err() {
368 sink.abort();
369 } else {
370 self.inner.disk_used = sink.used_disk();
371 }
372 r
373 }
374
375 fn next_chunk(&mut self) -> Result<Option<&[u8]>, FormError> {
377 let inner = &mut *self.inner;
378 if inner.pending_at < inner.pending.len() {
379 let chunk = inner.pending.get(inner.pending_at..).unwrap_or(&[]);
380 inner.pending_at = inner.pending.len();
381 return Ok(Some(chunk));
382 }
383 while inner.in_part {
384 match inner.step()? {
385 Got::Data => {
386 inner.pending_at = inner.pending.len();
387 return Ok(Some(&inner.pending));
388 }
389 Got::End(s) => inner.end_part(s),
390 _ => {}
391 }
392 }
393 Ok(None)
394 }
395}
396
397impl<R: Read> Read for PartReader<'_, R> {
398 fn read(&mut self, out: &mut [u8]) -> io::Result<usize> {
399 let inner = &mut *self.inner;
400 loop {
401 if inner.pending_at < inner.pending.len() {
402 let src = inner.pending.get(inner.pending_at..).unwrap_or(&[]);
403 let n = src.len().min(out.len());
404 if let (Some(dst), Some(src)) = (out.get_mut(..n), src.get(..n)) {
405 dst.copy_from_slice(src);
406 }
407 inner.pending_at = inner.pending_at.saturating_add(n);
408 return Ok(n);
409 }
410 if !inner.in_part {
411 return Ok(0);
412 }
413 match inner.step() {
414 Ok(Got::End(s)) => inner.end_part(s),
415 Ok(_) => {}
416 Err(e) => return Err(io::Error::new(io::ErrorKind::InvalidData, e)),
417 }
418 }
419 }
420}