Mint.HTTP.stream

You're seeing just the function 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} with header_name and header_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. See Mint.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. See Mint.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}]