Mint.HTTP.stream
stream
, go back to Mint.HTTP module for more information.
Specs
stream(t(), term()) :: {:ok, t(), [Mint.Types.response()]} | {:error, t(), Mint.Types.error(), [Mint.Types.response()]} | :unknown
Streams the next batch of responses from the given message.
This function processes a "message" which can be any term, but should be a message received by the process that owns the connection. Processing a message means that this function will parse it and check if it's a message that is directed to this connection, that is, a TCP/SSL message received on the connection's socket. If it is, then this function will parse the message, turn it into a list of responses, and possibly take action given the responses. As an example of an action that this function could perform, if the server sends a ping request this function will transparently take care of pinging the server back.
If there's no error, this function returns {:ok, conn, responses}
where conn
is
the updated connection and responses
is a list of responses. See the "Responses"
section below. If there's an error, {:error, conn, reason, responses}
is returned,
where conn
is the updated connection, reason
is the error reason, and responses
is a list of responses that were correctly parsed before the error.
If the given message
is not from the connection's socket,
this function returns :unknown
.
Socket mode
Mint sets the socket in active: :once
mode. This means that a single socket
message at a time is delivered to the process that owns the connection. After
a message is delivered, then no other messages are delivered (we say the socket
goes in passive mode). When stream/2
is called to process the message that
was received, Mint sets the socket back to active: :once
. This is good to know
in order to understand how the socket is handled by Mint, but in normal usage
it just means that you will process one message at a time with stream/2
and not
pay too much attention to the socket mode.
Mint also supports passive mode to avoid receiving messages. See the "Mode" section in the module documentation.
Responses
Each possible response returned by this function is a tuple with two or more elements.
The first element is always an atom that identifies the kind of response. The second
element is a unique reference Mint.Types.request_ref/0
that identifies the request
that the response belongs to. This is the term returned by request/5
. After these
two elements, there can be response-specific terms as well, documented below.
These are the possible responses that can be returned.
{:status, request_ref, status_code}
- returned when the server replied with a response status code. The status code is a non-negative integer.{:headers, request_ref, headers}
- returned when the server replied with a list of headers. Headers are in the form{header_name, header_value}
withheader_name
andheader_value
being strings. A single:headers
response will come after the:status
response. A single:headers
response may come after all the:data
responses if trailing headers are present.{:data, request_ref, binary}
- returned when the server replied with a chunk of response body (as a binary). The request shouldn't be considered done when a piece of body is received because multiple chunks could be received. The request is done when the:done
response is returned.{:done, request_ref}
- returned when the server signaled the request as done. When this is received, the response body and headers can be considered complete and it can be assumed that no more responses will be received for this request. This means that for example, you can stop holding on to the request ref for this request.{:error, request_ref, reason}
- returned when there is an error that only affects the request and not the whole connection. For example, if the server sends bad data on a given request, that request will be closed and an error for that request will be returned among the responses, but the connection will remain alive and well.{:pong, request_ref}
- returned when a server replies to a ping request sent by the client. This response type is HTTP/2-specific and will never be returned by an HTTP/1 connection. SeeMint.HTTP2.ping/2
for more information.{:push_promise, request_ref, promised_request_ref, headers}
- returned when the server sends a server push to the client. This response type is HTTP/2 specific and will never be returned by an HTTP/1 connection. SeeMint.HTTP2
for more information on server pushes.
Examples
Let's assume we have a function called receive_next_and_stream/1
that takes
a connection and then receives the next message, calls stream/2
with that message
as an argument, and then returns the result of stream/2
:
defp receive_next_and_stream(conn) do
receive do
message -> Mint.HTTP.stream(conn, message)
end
end
Now, we can see an example of a workflow involving stream/2
.
{:ok, conn, request_ref} = Mint.HTTP.request(conn, "GET", "/", _headers = [])
{:ok, conn, responses} = receive_next_and_stream(conn)
responses
#=> [{:status, ^request_ref, 200}]
{:ok, conn, responses} = receive_next_and_stream(conn)
responses
#=> [{:headers, ^request_ref, [{"Content-Type", "application/json"}]},
#=> {:data, ^request_ref, "{"}]
{:ok, conn, responses} = receive_next_and_stream(conn)
responses
#=> [{:data, ^request_ref, "}"}, {:done, ^request_ref}]