From d2a3f2cedd7c00d0933222aed9c06b3149aa4db4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= Date: Wed, 4 Apr 2018 13:13:37 +0200 Subject: Cowboy 2.3.0 --- docs/en/cowboy/2.3/guide/multipart/index.html | 330 ++++++++++++++++++++++++++ 1 file changed, 330 insertions(+) create mode 100644 docs/en/cowboy/2.3/guide/multipart/index.html (limited to 'docs/en/cowboy/2.3/guide/multipart/index.html') diff --git a/docs/en/cowboy/2.3/guide/multipart/index.html b/docs/en/cowboy/2.3/guide/multipart/index.html new file mode 100644 index 00000000..c049ef65 --- /dev/null +++ b/docs/en/cowboy/2.3/guide/multipart/index.html @@ -0,0 +1,330 @@ + + + + + + + + + + + + Nine Nines: Multipart requests + + + + + + + + + + + + + + + + +
+
+
+
+ +

Multipart requests

+ +

Multipart originates from MIME, an Internet standard that +extends the format of emails.

+

A multipart message is a list of parts. A part contains +headers and a body. The body of the parts may be +of any media type, and contain text or binary data. +It is possible for parts to contain a multipart media +type.

+

In the context of HTTP, multipart is most often used +with the multipart/form-data media type. It is what +browsers use to upload files through HTML forms.

+

The multipart/byteranges is also common. It is the +media type used to send arbitrary bytes from a resource, +enabling clients to resume downloads.

+
+

Form-data

+
+

In the normal case, when a form is submitted, the +browser will use the application/x-www-form-urlencoded +content-type. This type is just a list of keys and +values and is therefore not fit for uploading files.

+

That’s where the multipart/form-data content-type +comes in. When the form is configured to use this +content-type, the browser will create a multipart +message where each part corresponds to a field on +the form. For files, it also adds some metadata in +the part headers, like the file name.

+

A form with a text input, a file input and a select +choice box will result in a multipart message with +three parts, one for each field.

+

The browser does its best to determine the media type +of the files it sends this way, but you should not +rely on it for determining the contents of the file. +Proper investigation of the contents is recommended.

+
+
+
+

Checking for multipart messages

+
+

The content-type header indicates the presence of +a multipart message:

+
+
+
{<<"multipart">>, <<"form-data">>, _}
+    = cowboy_req:parse_header(<<"content-type">>, Req).
+
+
+
+

Reading a multipart message

+
+

Cowboy provides two sets of functions for reading +request bodies as multipart messages.

+

The cowboy_req:read_part/1,2 functions return the +next part’s headers, if any.

+

The cowboy_req:read_part_body/1,2 functions return +the current part’s body. For large bodies you may +need to call the function multiple times.

+

To read a multipart message you need to iterate over +all its parts:

+
+
+
multipart(Req0) ->
+    case cowboy_req:read_part(Req0) of
+        {ok, _Headers, Req1} ->
+            {ok, _Body, Req} = cowboy_req:read_part_body(Req1),
+            multipart(Req);
+        {done, Req} ->
+            Req
+    end.
+

When part bodies are too large, Cowboy will return +a more tuple, and allow you to loop until the part +body has been fully read.

+

The function cow_multipart:form_data/1 can be used +to quickly obtain information about a part from a +multipart/form-data message. The function returns +a data or a file tuple depending on whether this +is a normal field or a file being uploaded.

+

The following snippet will use this function and +use different strategies depending on whether the +part is a file:

+
+
+
multipart(Req0) ->
+    case cowboy_req:read_part(Req0) of
+        {ok, Headers, Req1} ->
+            Req = case cow_multipart:form_data(Headers) of
+                {data, _FieldName} ->
+                    {ok, _Body, Req2} = cowboy_req:read_part_body(Req1),
+                    Req2;
+                {file, _FieldName, _Filename, _CType} ->
+                    stream_file(Req1)
+            end,
+            multipart(Req);
+        {done, Req} ->
+            Req
+    end.
+
+stream_file(Req0) ->
+    case cowboy_req:read_part_body(Req0) of
+        {ok, _LastBodyChunk, Req} ->
+            Req;
+        {more, _BodyChunk, Req} ->
+            stream_file(Req)
+    end.
+

Both the part header and body reading functions can take +options that will be given to the request body reading +functions. By default, cowboy_req:read_part/1 reads +up to 64KB for up to 5 seconds. cowboy_req:read_part_body/1 +has the same defaults as cowboy_req:read_body/1.

+

To change the defaults for part headers:

+
+
+
cowboy_req:read_part(Req, #{length => 128000}).
+

And for part bodies:

+
+
+
cowboy_req:read_part_body(Req, #{length => 1000000, period => 7000}).
+
+
+
+

Skipping unwanted parts

+
+

Part bodies do not have to be read. Cowboy will automatically +skip it when you request the next part’s body.

+

The following snippet reads all part headers and skips +all bodies:

+
+
+
multipart(Req0) ->
+    case cowboy_req:read_part(Req0) of
+        {ok, _Headers, Req} ->
+            multipart(Req);
+        {done, Req} ->
+            Req
+    end.
+

Similarly, if you start reading the body and it ends up +being too big, you can simply continue with the next part. +Cowboy will automatically skip what remains.

+

While Cowboy can skip part bodies automatically, the read +rate is not configurable. Depending on your application +you may want to skip manually, in particular if you observe +poor performance while skipping.

+

You do not have to read all parts either. You can stop +reading as soon as you find the data you need.

+
+
+ + + + + + + + + + + + + + + +
+ +
+ + +

+ Cowboy + 2.3 + + User Guide +

+ + + +

Navigation

+ +

Version select

+ + +
+
+
+
+ + + + + + + + + -- cgit v1.2.3