= cowboy_req:read_part(3)

== Name

cowboy_req:read_part - Read the next multipart headers

== Description

[source,erlang]
----
read_part(Req :: cowboy_req:req())
    -> read_part(Req, #{})

read_part(Req :: cowboy_req:req(), Opts)
    -> {ok, Headers, Req} | {done, Req}

Opts    :: cowboy_req:read_body_opts()
Headers :: #{binary() => binary()}
----

Read the next part of a multipart body.

This function reads the request body and parses it as
multipart. Each parts of a multipart representation have
their own headers and body. This function parses and returns
headers. Examples of multipart media types are
`multipart/form-data` and `multipart/byteranges`.

Cowboy will skip any data remaining until the beginning of
the next part. This includes the preamble to the multipart
message but also the body of a previous part if it hasn't
been read. Both are skipped automatically when calling this
function.

Cowboy will read the body before parsing in chunks of size
up to 64KB, with a period of 5 seconds. This is tailored for
reading part headers and might not be the most efficient for
skipping the previous part's body.

The headers returned are MIME headers, *NOT* HTTP headers.
They can be parsed using the functions from the `cow_multipart`
module. In addition, the `cow_multipart:form_data/1` function
can be used to quickly extract information from `multipart/form-data`
representations.

// @todo Proper link to cow_multipart:form_data.

Once a part has been read, it can not be read again.

Once the body has been read, Cowboy sets the content-length
header if it was not previously provided.

// @todo Limit the maximum size of multipart headers.

== Arguments

Req::

The Req object.

Opts::

A map of body reading options. Please refer to
link:man:cowboy_req:read_body(3)[cowboy_req:read_body(3)]
for details about each option.
+
This function defaults the `length` to 64KB and the `period`
to 5 seconds.

== Return value

An `ok` tuple is returned containing the next part's headers
as a map.

A `done` tuple is returned if there are no more parts to read.

The Req object returned in the tuple must be used from that point
onward. It contains a more up to date representation of the request.
For example it may have an added content-length header once the
body has been read.

== Changelog

* *2.0*: Function introduced. Replaces `part/1,2`.

== Examples

.Read all parts
[source,erlang]
----
acc_multipart(Req0, Acc) ->
    case cowboy_req:read_part(Req0) of
        {ok, Headers, Req1} ->
            {ok, Body, Req} = stream_body(Req1, <<>>),
            acc_multipart(Req, [{Headers, Body}|Acc]);
        {done, Req} ->
            {lists:reverse(Acc), Req}
    end.

stream_body(Req0, Acc) ->
    case cowboy_req:read_part_body(Req0) of
        {more, Data, Req} ->
            stream_body(Req, << Acc/binary, Data/binary >>);
        {ok, Data, Req} ->
            {ok, << Acc/binary, Data/binary >>, Req}
    end.
----

.Read all part headers, skipping bodies
[source,erlang]
----
skip_body_multipart(Req0, Acc) ->
    case cowboy_req:read_part(Req0) of
        {ok, Headers, Req} ->
            skip_body_multipart(Req, [Headers|Acc]);
        {done, Req} ->
            {lists:reverse(Acc), Req}
    end.
----

.Read a part header in larger chunks
[source,erlang]
----
{ok, Headers, Req} = cowboy_req:read_part(Req0, #{length => 1000000}).
----

== See also

link:man:cowboy_req(3)[cowboy_req(3)],
link:man:cowboy_req:has_body(3)[cowboy_req:has_body(3)],
link:man:cowboy_req:body_length(3)[cowboy_req:body_length(3)],
link:man:cowboy_req:read_body(3)[cowboy_req:read_body(3)],
link:man:cowboy_req:read_urlencoded_body(3)[cowboy_req:read_urlencoded_body(3)],
link:man:cowboy_req:read_and_match_urlencoded_body(3)[cowboy_req:read_and_match_urlencoded_body(3)],
link:man:cowboy_req:read_part_body(3)[cowboy_req:read_part_body(3)]
