From 92b54aacc0de5446dd5497c39897b0bbff72e626 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= Date: Wed, 13 Jun 2018 09:54:12 +0200 Subject: Rebuild using Asciideck --- docs/en/gun/1.0/guide/http/index.html | 514 +++++++++++++--------------------- 1 file changed, 199 insertions(+), 315 deletions(-) (limited to 'docs/en/gun/1.0/guide/http/index.html') diff --git a/docs/en/gun/1.0/guide/http/index.html b/docs/en/gun/1.0/guide/http/index.html index 6c32ab5d..0d132edc 100644 --- a/docs/en/gun/1.0/guide/http/index.html +++ b/docs/en/gun/1.0/guide/http/index.html @@ -62,395 +62,279 @@

HTTP

-

This chapter describes how to use the Gun client for -communicating with an HTTP/1.1 or HTTP/2 server.

-
+

This chapter describes how to use the Gun client for communicating with an HTTP/1.1 or HTTP/2 server.

Streams

-
-

Every time a request is initiated, Gun creates a stream. -A stream reference uniquely identifies a set of request and -response and must be used to perform additional operations -with a stream or to identify its messages.

-

Stream references use the Erlang reference data type and -are therefore unique.

-

Streams can be canceled at any time. This will stop any further -messages from being sent to the owner process. Depending on -its capabilities, the server will also be instructed to cancel -the request.

-

Canceling a stream may result in Gun dropping the connection -temporarily, to avoid uploading or downloading data that will -not be used.

-
-
Cancelling a stream
-
-
gun:cancel(ConnPid, StreamRef).
-
-
-
+
gun:cancel(ConnPid, StreamRef).
+

Sending requests

-
-

Gun provides many convenient functions for performing common -operations, like GET, POST or DELETE. It also provides a -general purpose function in case you need other methods.

-

The availability of these methods on the server can vary -depending on the software used but also on a per-resource -basis.

-

Gun will automatically set a few headers depending on the -method used. For all methods however it will set the host -header if it has not been provided in the request arguments.

-

This section focuses on the act of sending a request. The -handling of responses will be explained further on.

-
+

Gun provides many convenient functions for performing common operations, like GET, POST or DELETE. It also provides a general purpose function in case you need other methods.

+

The availability of these methods on the server can vary depending on the software used but also on a per-resource basis.

+

Gun will automatically set a few headers depending on the method used. For all methods however it will set the host header if it has not been provided in the request arguments.

+

This section focuses on the act of sending a request. The handling of responses will be explained further on.

GET and HEAD

-

Use gun:get/2,3,4 to request a resource.

-
-
GET "/organizations/ninenines"
-
-
StreamRef = gun:get(ConnPid, "/organizations/ninenines").
-
-
GET "/organizations/ninenines" with custom headers
-
-
StreamRef = gun:get(ConnPid, "/organizations/ninenines", [
-    {<<"accept">>, "application/json"},
-    {<<"user-agent">>, "revolver/1.0"}
-]).
-

Note that the list of headers has the field name as a binary. -The field value is iodata, which is either a binary or an -iolist.

-

Use gun:head/2,3,4 if you don’t need the response body.

-
-
HEAD "/organizations/ninenines"
-
-
StreamRef = gun:head(ConnPid, "/organizations/ninenines").
-
-
HEAD "/organizations/ninenines" with custom headers
-
-
StreamRef = gun:head(ConnPid, "/organizations/ninenines", [
-    {<<"accept">>, "application/json"},
-    {<<"user-agent">>, "revolver/1.0"}
-]).
-

It is not possible to send a request body with a GET or HEAD -request.

-
-
-

POST, PUT and PATCH

-

HTTP defines three methods to create or update a resource.

-

POST is generally used when the resource identifier (URI) isn’t known -in advance when creating a resource. POST can also be used to -replace an existing resource, although PUT is more appropriate -in that situation.

-

PUT creates or replaces a resource identified by the URI.

-

PATCH provides instructions on how to modify the resource.

-

Both POST and PUT send the entire resource representation in their -request body. The PATCH method can be used when this is not -desirable. The request body of a PATCH method may be a partial -representation or a list of instructions on how to update the -resource.

-

The gun:post/4,5, gun:put/4,5 and gun:patch/4,5 functions -take a body as their fourth argument. These functions do -not require any body-specific header to be set, although -it is always recommended to set the content-type header. -Gun will set the other headers automatically.

-

In this and the following examples in this section, gun:post -can be replaced by gun:put or gun:patch for performing -a PUT or PATCH request, respectively.

-
-
POST "/organizations/ninenines"
-
-
Body = "{\"msg\": \"Hello world!\"}",
-StreamRef = gun:post(ConnPid, "/organizations/ninenines", [
-    {<<"content-type">>, "application/json"}
-], Body).
-

The gun:post/3, gun:put/3 and gun:patch/3 functions -do not take a body in their arguments. If a body is to be -provided later on, using the gun:data/4 function, then -the request headers must indicate this. This can be done -by setting the content-length or content-type request -headers. If these headers are not set then Gun will assume -the request has no body.

-

It is recommended to send the content-length header if you -know it in advance, although this is not required. If it -is not set, HTTP/1.1 will use the chunked transfer-encoding, -and HTTP/2 will continue normally as it is chunked by design.

-
-
POST "/organizations/ninenines" with delayed body
-
-
Body = "{\"msg\": \"Hello world!\"}",
-StreamRef = gun:post(ConnPid, "/organizations/ninenines", [
-    {<<"content-length">>, integer_to_binary(length(Body))},
-    {<<"content-type">>, "application/json"}
+
Body = "{\"msg\": \"Hello world!\"}",
+StreamRef = gun:post(ConnPid, "/organizations/ninenines", [
+    {<<"content-length">>, integer_to_binary(length(Body))},
+    {<<"content-type">>, "application/json"}
 ]),
-gun:data(ConnPid, StreamRef, fin, Body).
-

The atom fin indicates this is the last chunk of data to -be sent. You can call the gun:data/4 function as many -times as needed until you have sent the entire body. The -last call must use fin and all the previous calls must -use nofin. The last chunk may be empty.

-
-
Streaming the request body
-
-
sendfile(ConnPid, StreamRef, Filepath) ->
-    {ok, IoDevice} = file:open(Filepath, [read, binary, raw]),
-    do_sendfile(ConnPid, StreamRef, IoDevice).
-
-do_sendfile(ConnPid, StreamRef, IoDevice) ->
-    case file:read(IoDevice, 8000) of
-        eof ->
-            gun:data(ConnPid, StreamRef, fin, <<>>),
-            file:close(IoDevice);
-        {ok, Bin} ->
-            gun:data(ConnPid, StreamRef, nofin, Bin),
-            do_sendfile(ConnPid, StreamRef, IoDevice)
-    end.
-
-
+
sendfile(ConnPid, StreamRef, Filepath) ->
+    {ok, IoDevice} = file:open(Filepath, [read, binary, raw]),
+    do_sendfile(ConnPid, StreamRef, IoDevice).
+
+do_sendfile(ConnPid, StreamRef, IoDevice) ->
+    case file:read(IoDevice, 8000) of
+        eof ->
+            gun:data(ConnPid, StreamRef, fin, <<>>),
+            file:close(IoDevice);
+        {ok, Bin} ->
+            gun:data(ConnPid, StreamRef, nofin, Bin),
+            do_sendfile(ConnPid, StreamRef, IoDevice)
+    end.
+

DELETE

-

Use gun:delete/2,3,4 to delete a resource.

-
-
DELETE "/organizations/ninenines"
-
-
StreamRef = gun:delete(ConnPid, "/organizations/ninenines").
-
-
DELETE "/organizations/ninenines" with custom headers
-
-
StreamRef = gun:delete(ConnPid, "/organizations/ninenines", [
-    {<<"user-agent">>, "revolver/1.0"}
-]).
- -
+
StreamRef = gun:delete(ConnPid, "/organizations/ninenines", [
+    {<<"user-agent">>, "revolver/1.0"}
+]).
+

OPTIONS

-

Use gun:options/2,3 to request information about a resource.

-
-
OPTIONS "/organizations/ninenines"
-
-
StreamRef = gun:options(ConnPid, "/organizations/ninenines").
-
-
OPTIONS "/organizations/ninenines" with custom headers
-
-
StreamRef = gun:options(ConnPid, "/organizations/ninenines", [
-    {<<"user-agent">>, "revolver/1.0"}
-]).
-

You can also use this function to request information about -the server itself.

-
-
OPTIONS "*"
-
-
StreamRef = gun:options(ConnPid, "*").
- -
+
StreamRef = gun:options(ConnPid, "*").
+

Requests with an arbitrary method

-

The gun:request/4,5,6 function can be used to send requests -with a configurable method name. It is mostly useful when you -need a method that Gun does not understand natively.

-
-
Example of a TRACE request
-
-
gun:request(ConnPid, "TRACE", "/", [
-    {<<"max-forwards">>, "30"}
-]).
- - - -
+
gun:request(ConnPid, "TRACE", "/", [
+    {<<"max-forwards">>, "30"}
+]).
+

Processing responses

-
-

All data received from the server is sent to the owner -process as a message. First a gun_response message is sent, -followed by zero or more gun_data messages. If something goes wrong, -a gun_error message is sent instead.

-

The response message will inform you whether there will be -data messages following. If it contains fin there will be -no data messages. If it contains nofin then one or more data -messages will follow.

-

When using HTTP/2 this value is sent with the frame and simply -passed on in the message. When using HTTP/1.1 however Gun must -guess whether data will follow by looking at the response headers.

-

You can receive messages directly, or you can use the await -functions to let Gun receive them for you.

-
-
Receiving a response using receive
-
-
print_body(ConnPid, MRef) ->
-    StreamRef = gun:get(ConnPid, "/"),
-    receive
-        {gun_response, ConnPid, StreamRef, fin, Status, Headers} ->
-            no_data;
-        {gun_response, ConnPid, StreamRef, nofin, Status, Headers} ->
-            receive_data(ConnPid, MRef, StreamRef);
-        {'DOWN', MRef, process, ConnPid, Reason} ->
-            error_logger:error_msg("Oops!"),
-            exit(Reason)
-    after 1000 ->
-        exit(timeout)
-    end.
-
-receive_data(ConnPid, MRef, StreamRef) ->
-    receive
-        {gun_data, ConnPid, StreamRef, nofin, Data} ->
-            io:format("~s~n", [Data]),
-            receive_data(ConnPid, MRef, StreamRef);
-        {gun_data, ConnPid, StreamRef, fin, Data} ->
-            io:format("~s~n", [Data]);
-        {'DOWN', MRef, process, ConnPid, Reason} ->
-            error_logger:error_msg("Oops!"),
-            exit(Reason)
-    after 1000 ->
-        exit(timeout)
-    end.
-

While it may seem verbose, using messages like this has the -advantage of never locking your process, allowing you to -easily debug your code. It also allows you to start more than -one connection and concurrently perform queries on all of them -at the same time.

-

You can also use Gun in a synchronous manner by using the await -functions.

-

The gun:await/2,3,4 function will wait until it receives -a response to, a pushed resource related to, or data from -the given stream.

-

When calling gun:await/2,3 and not passing a monitor -reference, one is automatically created for you for the -duration of the call.

-

The gun:await_body/2,3,4 works similarly, but returns the -body received. Both functions can be combined to receive the -response and its body sequentially.

-
-
Receiving a response using await
-
-
StreamRef = gun:get(ConnPid, "/"),
-case gun:await(ConnPid, StreamRef) of
-    {response, fin, Status, Headers} ->
-        no_data;
-    {response, nofin, Status, Headers} ->
-        {ok, Body} = gun:await_body(ConnPid, StreamRef),
-        io:format("~s~n", [Body])
-end.
-
- -
+
StreamRef = gun:get(ConnPid, "/"),
+case gun:await(ConnPid, StreamRef) of
+    {response, fin, Status, Headers} ->
+        no_data;
+    {response, nofin, Status, Headers} ->
+        {ok, Body} = gun:await_body(ConnPid, StreamRef),
+        io:format("~s~n", [Body])
+end.
+

Handling streams pushed by the server

-
-

The HTTP/2 protocol allows the server to push more than one -resource for every request. It will start sending those -extra resources before it starts sending the response itself, -so Gun will send you gun_push messages before gun_response -when that happens.

-

You can safely choose to ignore gun_push messages, or -you can handle them. If you do, you can either receive the -messages directly or use await functions.

-

The gun_push message contains both the new stream reference -and the stream reference of the original request.

-
-
Receiving a pushed response using receive
-
-
receive
-    {gun_push, ConnPid, OriginalStreamRef, PushedStreamRef,
-            Method, Host, Path, Headers} ->
-        enjoy()
-end.
-

If you use the gun:await/2,3,4 function, however, Gun -will use the original reference to identify the message but -will return a tuple that doesn’t contain it.

-
-
Receiving a pushed response using await
-
-
{push, PushedStreamRef, Method, URI, Headers}
-    = gun:await(ConnPid, OriginalStreamRef).
-

The PushedStreamRef variable can then be used with gun:await/2,3,4 -and gun:await_body/2,3,4.

-
- -
+
{push, PushedStreamRef, Method, URI, Headers}
+    = gun:await(ConnPid, OriginalStreamRef).
+
+

The PushedStreamRef variable can then be used with gun:await/2,3,4 and gun:await_body/2,3,4.

Flushing unwanted messages

-
-

Gun provides the function gun:flush/1 to quickly get rid -of unwanted messages sitting in the process mailbox. You -can use it to get rid of all messages related to a connection, -or just the messages related to a stream.

-
-
Flush all messages from a Gun connection
-
-
gun:flush(ConnPid).
-
-
Flush all messages from a specific stream
-
-
gun:flush(StreamRef).
-
- -
+
gun:flush(StreamRef).
+

Redirecting responses to a different process

-
-

Gun allows you to specify which process will handle responses -to a request via the reply_to request option.

-
-
GET "/organizations/ninenines" to a different process
-
-
StreamRef = gun:get(ConnPid, "/organizations/ninenines", [],
-    #{reply_to => Pid}).
-
- +
StreamRef = gun:get(ConnPid, "/organizations/ninenines", [],
+    #{reply_to => Pid}).
+ + -- cgit v1.2.3