Struct salvo_core::http::multipart::Multipart[][src]

pub struct Multipart<S: TryStream> where
    S::Error: Into<ReadError>, 
{ /* fields omitted */ }

The server-side implementation of multipart/form-data requests.

After constructing with either the ::with_body() or ::try_from_request(), two different workflows for processing the request are provided, assuming any Poll::Pending and Ready(Err(_))/Ready(Some(Err(_))) results are handled in the typical fashion:

High-Level Flow

  1. Await the next field with .next_field().
  2. Read the field data via the Stream impl on Field::data.
  3. Repeat until .next_field() returns None.

Low-Level Flow

  1. Poll for the first field boundary with .poll_has_next_field(); if it returns true proceed to the next step, if false the request is at an end.

  2. Poll for the field’s headers containing its name, content-type and other info with .poll_field_headers().

  3. Poll for the field’s data chunks with [.poll_field_chunk()](#method.poll_field_chunk) until None` is returned, then loop back to step 2.

Any data before the first boundary and past the end of the terminating boundary is ignored as it is out-of-spec and should not be expected to be left in the underlying stream intact. Please open an issue if you have a legitimate use-case for extraneous data in a multipart request.

Implementations

impl<S> Multipart<S> where
    S: TryStream,
    S::Ok: BodyChunk,
    S::Error: Into<ReadError>, 
[src]

pub fn with_body<B: Into<String>>(stream: S, boundary: B) -> Self[src]

Construct a new Multipart with the given body reader and boundary.

The boundary should be taken directly from the Content-Type: multipart/form-data header of the request. This will add the requisite -- to the boundary as per IETF RFC 7578 section 4.1.

pub fn try_from_body_headers(
    body: S,
    headers: &HeaderMap
) -> Result<Self, ReadError>
[src]

pub fn next_field(&mut self) -> NextField<'_, S>

Notable traits for NextField<'a, S>

impl<'a, S: 'a> Future for NextField<'a, S> where
    S: TryStream,
    S::Ok: BodyChunk,
    S::Error: Into<ReadError>, 
type Output = Result<Option<Field<'a, S>>, ReadError>;
where
    Self: Unpin
[src]

pub fn next_field_pinned(self: Pin<&mut Self>) -> NextField<'_, S>

Notable traits for NextField<'a, S>

impl<'a, S: 'a> Future for NextField<'a, S> where
    S: TryStream,
    S::Ok: BodyChunk,
    S::Error: Into<ReadError>, 
type Output = Result<Option<Field<'a, S>>, ReadError>;
[src]

Same as .next_field() but with a receiver of Pin<&mut Self>.

pub fn poll_has_next_field(
    self: Pin<&mut Self>,
    cx: &mut Context<'_>
) -> Poll<Result<bool, ReadError>>
[src]

Poll for the next boundary, returning true if a field should follow that boundary, or false if the request is at an end. See above for the overall flow.

If this returns Ready(Ok(true)), you may then begin polling for the headers of the next field.

If a field was being read, its contents will be discarded.

This is a low-level call and is expected to be supplemented/replaced by a more ergonomic API once more design work has taken place.

pub fn poll_field_headers(
    self: Pin<&mut Self>,
    cx: &mut Context<'_>
) -> Poll<Result<FieldHeaders, ReadError>>
[src]

Poll for the headers of the next field, returning the headers or an error otherwise.

Once you have the field headers, you may then begin polling for field chunks.

In addition to bubbling up errors from the underlying stream, this will also return an error if:

  • the headers were corrupted, or:
  • did not contain a Content-Disposition: form-data header with a name parameter, or:
  • the end of stream was reached before the header segment terminator \r\n\r\n, or:
  • the buffer for the headers exceeds a preset size.

This is a low-level call and is expected to be supplemented/replaced by a more ergonomic API once more design work has taken place.

Note: Calling This Is Not Enforced

If this step is skipped then .poll_field_chunk() will return chunks of the header segment which may or may not be desirable depending on your use-case.

If you do want to inspect the raw field headers, they are separated by one CRLF (\r\n) and terminated by two CRLFs (\r\n\r\n) after which the field chunks follow.

pub fn poll_field_chunk(
    self: Pin<&mut Self>,
    cx: &mut Context<'_>
) -> Poll<Option<Result<S::Ok, ReadError>>>
[src]

Poll for the next chunk of the current field.

This returns Ready(Some(Ok(chunk))) as long as there are chunks in the field, yielding Ready(None) when the next boundary is reached.

You may then begin the next field with .poll_has_next_field().

This is a low-level call and is expected to be supplemented/replaced by a more ergonomic API once more design work has taken place.

Note: Call .poll_field_headers() First for Correct Data

If .poll_field_headers() is skipped then this call will return chunks of the header segment which may or may not be desirable depending on your use-case.

If you do want to inspect the raw field headers, they are separated by one CRLF (\r\n) and terminated by two CRLFs (\r\n\r\n) after which the field chunks follow.

Auto Trait Implementations

impl<S> RefUnwindSafe for Multipart<S> where
    S: RefUnwindSafe,
    <S as TryStream>::Ok: RefUnwindSafe

impl<S> Send for Multipart<S> where
    S: Send,
    <S as TryStream>::Ok: Send

impl<S> Sync for Multipart<S> where
    S: Sync,
    <S as TryStream>::Ok: Sync

impl<S> Unpin for Multipart<S> where
    S: Unpin,
    <S as TryStream>::Ok: Unpin

impl<S> UnwindSafe for Multipart<S> where
    S: UnwindSafe,
    <S as TryStream>::Ok: UnwindSafe

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T> Instrument for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> Same<T> for T

type Output = T

Should always be Self

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

impl<V, T> VZip<V> for T where
    V: MultiLane<T>,