plug_multipart_related v0.1.1 PlugMultipartRelated

Parses multipart/related request body.

This is a partial implementation of RFC2387. This implementation is heavily influence by Plug.Parsers.MULTIPART which is shipped with Plug.

Configure in a Phoenix.Endpoint for example: plug Plug.Parsers, parsers: [PlugMultipartRelated], pass: [“multipart/related”], read_length: 500_000, length: 4_000_000

The following choices have been made regarding support for the RFC2387 specification:

  • start-info parameter - The start-info parameter is ignored if specified.
  • If no start parameter is given the first MIME part is marked as the root part.
  • The Content-ID part header is REQUIRED for each part. If Content-ID is not present the part will be ignored.
  • Content-Disposition is used to create Plug.Upload structs in the output

A HTTP request with the following Content-Type header and body:

Content-Type: multipart/related; type="application/soap+xml"; boundary=----w58EW1cEpjzydSCq; start="part1"
------w58EW1cEpjzydSCq
Content-Disposition: form-data; name="info"; filename="foo.txt"
Content-ID: part1
Content-Type: text/plain

bar

------w58EW1cEpjzydSCq
Content-ID: part2
Content-Type: text/plain

foobar
------w58EW1cEpjzydSCq
Content-Type: text/plain

ignored
------w58EW1cEpjzydSCq--

Will be available in Plug.Conn as follows:

%{
  "part1" => %{
    "body" => %Plug.Upload{
      content_type: "text/plain",
      filename: "foo.txt",
      path: "/var/folders/hf/pd3rksm54wj6hfznxz9tv36c0000gn/T//plug-1540/multipart-1540203239-599604070647209-1"
    },
    "start" => true
},
  "part2" => %{
    "body" => "foobar"
  }
}

Options

All options supported by Plug.Conn.read_body/2 are also supported here. They are repeated here for convenience:

  • :length - sets the maximum number of bytes to read from the request, defaults to 8_000_000 bytes
  • :read_length - sets the amount of bytes to read at one time from the underlying socket to fill the chunk, defaults to 1_000_000 bytes
  • :read_timeout - sets the timeout for each socket read, defaults to 15_000ms

So by default, Plug.Parsers will read 1_000_000 bytes at a time from the socket with an overall limit of 8_000_000 bytes.

Besides the options supported by Plug.Conn.read_body/2, the multipart parser also checks for :headers option that contains the same :length, :read_length and :read_timeout options which are used explicitly for parsing multipart headers.

Link to this section Summary

Functions

Callback implementation for Plug.Parsers.init/1

Attempts to parse the connection’s request body given the content-type type, subtype, and its parameters

Link to this section Functions

Callback implementation for Plug.Parsers.init/1.

Link to this function parse(conn, arg2, arg3, headers, opts)

Attempts to parse the connection’s request body given the content-type type, subtype, and its parameters.

The arguments are:

  • the Plug.Conn connection
  • type, the content-type type (e.g., "x-sample" for the "x-sample/json" content-type)
  • subtype, the content-type subtype (e.g., "json" for the "x-sample/json" content-type)
  • params, the content-type parameters (e.g., %{"foo" => "bar"} for the "text/plain; foo=bar" content-type)

This function should return:

  • {:ok, body_params, conn} if the parser is able to handle the given content-type; body_params should be a map
  • {:next, conn} if the next parser should be invoked
  • {:error, :too_large, conn} if the request goes over the given limit

Callback implementation for Plug.Parsers.parse/5.