zf

zenflows testing
git clone https://s.sonu.ch/~srfsh/zf.git
Log | Files | Refs | Submodules | README | LICENSE

http.ex (41580B)


      1 defmodule Mint.HTTP do
      2   @moduledoc """
      3   Processless HTTP connection data structure and functions.
      4 
      5   Single interface for `Mint.HTTP1` and `Mint.HTTP2` with support for version
      6   negotiation and proxies.
      7 
      8   ## Usage
      9 
     10   To establish a connection with a given server, use `connect/4`. This will
     11   return an opaque data structure that represents the connection
     12   to the server. To send a request, you can use `request/5`. Sending a request
     13   does not take care of the response to that request, instead we use `Mint.HTTP.stream/2`
     14   to process the response, which we will look at in just a bit. The connection is a
     15   wrapper around a TCP (`:gen_tcp` module) or SSL (`:ssl` module) socket that is
     16   set in **active mode** (with `active: :once`). This means that TCP/SSL messages
     17   will be delivered to the process that started the connection.
     18 
     19   The process that owns the connection is responsible for receiving the messages
     20   (for example, a GenServer is responsible for defining `handle_info/2`). However,
     21   `Mint.HTTP` makes it easy to identify TCP/SSL messages that are coming from the
     22   connection with the server with the `stream/2` function. This function takes the
     23   connection and a term and returns `:unknown` if the term is not a TCP/SSL message
     24   belonging to the connection. If the term *is* a message for the connection, then
     25   a response and a new connection are returned. It's important to store the new
     26   returned connection data structure over the old one since the connection is an
     27   immutable data structure.
     28 
     29   Let's see an example of a common workflow of connecting to a server, sending a
     30   request, and processing the response. We start by using `connect/3` to connect
     31   to a server.
     32 
     33       {:ok, conn} = Mint.HTTP.connect(:http, "httpbin.org", 80)
     34 
     35   `conn` is a data structure that represents the connection.
     36 
     37   To send a request, we use `request/5`.
     38 
     39       {:ok, conn, request_ref} = Mint.HTTP.request(conn, "GET", "/", [], nil)
     40 
     41   As you can see, sending a request returns a new updated `conn` struct and a
     42   `request_ref`. The updated connection struct is returned because the connection
     43   is an immutable structure keeping the connection state, so every action we do on it must return a new,
     44   possibly updated, connection that we're responsible for storing over the old
     45   one. `request_ref` is a unique reference that can be used to identify which
     46   request a given response belongs to.
     47 
     48   Now that we sent our request, we're responsible for receiving the messages that
     49   the TCP/SSL socket will send to our process. For example, in a GenServer
     50   we would do that with a `handle_info/2` callback. In our case, we're going to
     51   use a simple `receive`. `Mint.HTTP` provides a way to tell if a message comes
     52   from the socket wrapped by our connection or not: the `stream/2` function. If
     53   the message we pass to it is not destined for our connection, this function returns
     54   `:unknown`. Otherwise, it returns an updated connection and one or more responses.
     55 
     56       receive do
     57         message ->
     58           case Mint.HTTP.stream(conn, message) do
     59             :unknown -> handle_normal_message(message)
     60             {:ok, conn, responses} -> handle_responses(conn, responses)
     61           end
     62       end
     63 
     64   `responses` is a list of possible responses. The most common responses are:
     65 
     66     * `{:status, request_ref, status_code}` for the status code
     67     * `{:headers, request_ref, headers}` for the response headers
     68     * `{:data, request_ref, binary}` for pieces of the response body
     69     * `{:done, request_ref}` for the end of the response
     70 
     71   As you can see, all responses have the unique request reference as the second
     72   element of the tuple, so that we know which request the response belongs to.
     73   See `t:Mint.Types.response/0` for the full list of responses returned by `Mint.HTTP.stream/2`.
     74 
     75   ## Architecture
     76 
     77   A processless architecture like the one here requires a few modifications to how
     78   we use this HTTP client. Usually, you will want to create this data structure
     79   in a process that acts as *connection manager*. Sometimes, you might want to
     80   have a single process responsible for multiple connections, either to just one
     81   host or multiple hosts. For more discussion on architectures based off of this
     82   HTTP client, see the [*Architecture*](architecture.html) page in the docs.
     83 
     84   ## SSL certificates
     85 
     86   When using SSL, you can pass in your own CA certificate store or use one provided by Mint. Mint
     87   doesn't ship with the certificate store itself, but it has an optional dependency on
     88   [CAStore](https://github.com/elixir-mint/castore), which provides an up-to-date certificate store. If
     89   you don't want to use your own certificate store, just add `:castore` to your dependencies.
     90 
     91   Starting [from OTP
     92   25](https://www.erlang.org/blog/my-otp-25-highlights/#ca-certificates-can-be-fetched-from-the-os-standard-place),
     93   you can also load certificates from a file
     94   ([`:public_key.cacerts_load/1`](https://www.erlang.org/doc/man/public_key.html#cacerts_load-1))
     95   or from the OS
     96   ([`:public_key.cacerts_load/0`](https://www.erlang.org/doc/man/public_key.html#cacerts_load-0)).
     97   You can then use the certificates with
     98   [`:public_key.cacerts_get/0`](https://www.erlang.org/doc/man/public_key.html#cacerts_get-0):
     99 
    100       Mint.connect(:https, host, port, transport_opts: [cacerts: :public_key.cacerts_get()])
    101 
    102   ## Mode
    103 
    104   By default Mint operates in **active mode** meaning that the process that started the
    105   connection receives socket messages. Mint also supports **passive mode**, where no messages
    106   are sent to the process and the process needs to fetch data out of the socket manually.
    107   The mode can be controlled at connection time through the `:mode` option in `connect/4`
    108   or changed dynamically through `set_mode/2`. Passive mode is generally only recommended
    109   for special use cases.
    110   """
    111 
    112   import Mint.Core.Util
    113 
    114   alias Mint.{Types, TunnelProxy, UnsafeProxy}
    115   alias Mint.Core.Transport
    116 
    117   @behaviour Mint.Core.Conn
    118 
    119   @opaque t() :: Mint.HTTP1.t() | Mint.HTTP2.t()
    120 
    121   @doc """
    122   Macro to check that a given received `message` is intended for the given connection `conn`.
    123 
    124   This guard is useful in `receive` loops or in callbacks that handle generic messages (such as a
    125   `c:GenServer.handle_info/2` callback) so that you don't have to hand the `message` to
    126   `Mint.HTTP.stream/2` and check for the `:unknown_message` return value.
    127 
    128   This macro can be used in guards.
    129 
    130   **Note**: this macro is only available if you compile Mint with Elixir 1.10.0 or greater (and
    131   OTP 21+, which is required by Elixir 1.10.0 and on).
    132 
    133   ## Examples
    134 
    135       require Mint.HTTP
    136 
    137       {:ok, conn, request_ref} = Mint.HTTP.request(conn, "POST", "/", headers, "")
    138 
    139       receive do
    140         message when Mint.HTTP.is_connection_message(conn, message) ->
    141           Mint.HTTP.stream(conn, message)
    142 
    143         other ->
    144           # This message is related to something else or to some other connection
    145       end
    146 
    147   """
    148   define_is_connection_message_guard()
    149 
    150   @doc """
    151   Creates a new connection to a given server.
    152 
    153   Creates a new connection struct and establishes the connection to the given server,
    154   identified by the given `host` and `port` combination. Both HTTP and HTTPS are supported
    155   by passing respectively `:http` and `:https` as the `scheme`.
    156 
    157   The connection struct wraps a socket, which is created once the connection
    158   is established inside this function. If HTTP is used, then the created socket is a TCP
    159   socket and the `:gen_tcp` module is used to create that socket. If HTTPS is used, then
    160   the created socket is an SSL socket and the `:ssl` module is used to create that socket.
    161   The socket is created in active mode (with `active: :once`), which is why it is important
    162   to know the type of the socket: messages from the socket will be delivered directly to the
    163   process that creates the connection and tagged appropriately by the socket module (see the
    164   `:gen_tcp` and `:ssl` modules). See `stream/2` for more information on the messages and
    165   how to process them and on the socket mode.
    166 
    167   ## Options
    168 
    169     * `:hostname` - (string) explicitly provide the hostname used for the `Host` header,
    170       hostname verification, SNI, and so on. **Required when `address` is not a string.**
    171 
    172     * `:transport_opts` - (keyword) options to be given to the transport being used.
    173       These options will be merged with some default options that cannot be overridden.
    174       For more details, refer to the "Transport options" section below.
    175 
    176     * `:mode` - (`:active` or `:passive`) whether to set the socket to active or
    177       passive mode. See the "Mode" section in the module documentation and `set_mode/2`.
    178 
    179     * `:protocols` - (list of atoms) a list of protocols to try when connecting to the
    180       server. The possible values in the list are `:http1` for HTTP/1 and HTTP/1.1 and
    181       `:http2` for HTTP/2. If only one protocol is present in the list, then the connection
    182       will be forced to use that protocol. If both `:http1` and `:http2` are present in the
    183       list, then Mint will negotiate the protocol. See the section "Protocol negotiation"
    184       below for more information. Defaults to `[:http1, :http2]`.
    185 
    186     * `:proxy_headers` - a list of headers (`t:Mint.Types.headers/0`) to pass when using
    187       a proxy. They will be used for the `CONNECT` request in tunnel proxies or merged
    188       with every request for forward proxies.
    189 
    190   The following options are HTTP/1-specific and will force the connection
    191   to be an HTTP/1 connection.
    192 
    193     * `:proxy` - a `{scheme, address, port, opts}` tuple that identifies a proxy to
    194       connect to. See the "Proxying" section below for more information.
    195 
    196   The following options are HTTP/2-specific and will only be used on HTTP/2 connections.
    197 
    198     * `:client_settings` - (keyword) a list of client HTTP/2 settings to send to the
    199       server. See `Mint.HTTP2.put_settings/2` for more information. This is only used
    200       in HTTP/2 connections.
    201 
    202   ## Protocol negotiation
    203 
    204   If both `:http1` and `:http2` are present in the list passed in the `:protocols` option,
    205   the protocol negotiation happens in the following way:
    206 
    207     * If the scheme used to connect to the server is `:http`, then HTTP/1 or HTTP/1.1 is used.
    208 
    209     * If the scheme is `:https`, then ALPN negotiation is used to determine the right
    210       protocol. This means that the server will decide whether to use HTTP/1 or
    211       HTTP/2. If the server doesn't support protocol negotiation, we will fall back to
    212       HTTP/1. If the server negotiates a protocol that we don't know how to handle,
    213       `{:error, {:bad_alpn_protocol, protocol}}` is returned.
    214 
    215   ## Proxying
    216 
    217   You can set up proxying through the `:proxy` option, which is a tuple
    218   `{scheme, address, port, opts}` that identifies the proxy to connect to.
    219   Once a proxied connection is returned, the proxy is transparent to you and you
    220   can use the connection like a normal HTTP/1 connection.
    221 
    222   If the `scheme` is `:http`, we will connect to the host in the most compatible
    223   way, supporting older proxy servers. Data will be sent in clear text.
    224 
    225   If the connection scheme is `:https`, we will connect to the host with a tunnel
    226   through the proxy. Using `:https` for both the proxy and the connection scheme
    227   is not supported, it is recommended to use `:https` for the end host connection
    228   instead of the proxy.
    229 
    230   ## Transport options
    231 
    232   The options specified in `:transport_opts` are passed to the module that
    233   implements the socket interface: `:gen_tcp` when the scheme is `:http`, and
    234   `:ssl` when the scheme is `:https`. Please refer to the documentation for those
    235   modules, as well as for `:inet.setopts/2`, for a detailed description of all
    236   available options.
    237 
    238   The behaviour of some options is modified by Mint, as described below.
    239 
    240   A special case is the `:timeout` option, which is passed to the transport
    241   module's `connect` function to limit the amount of time to wait for the
    242   network connection to be established.
    243 
    244   Common options for `:http` and `:https`:
    245 
    246     * `:active` - controlled by the `:mode` option. Cannot be overridden.
    247 
    248     * `:mode` - set to `:binary`. Cannot be overridden.
    249 
    250     * `:packet` - set to `:raw`. Cannot be overridden.
    251 
    252     * `:timeout` - connect timeout in milliseconds. Defaults to `30_000` (30
    253       seconds), and may be overridden by the caller. Set to `:infinity` to
    254       disable the connect timeout.
    255 
    256   Options for `:https` only:
    257 
    258     * `:alpn_advertised_protocols` - managed by Mint. Cannot be overridden.
    259 
    260     * `:cacertfile` - if `:verify` is set to `:verify_peer` (the default) and
    261       no CA trust store is specified using the `:cacertfile` or `:cacerts`
    262       option, Mint will attempt to use the trust store from the
    263       [CAStore](https://github.com/elixir-mint/castore) package or raise an
    264       exception if this package is not available. Due to caching the
    265       `:cacertfile` option is more efficient than `:cacerts`.
    266 
    267     * `:ciphers` - defaults to the lists returned by
    268       `:ssl.filter_cipher_suites(:ssl.cipher_suites(:all, version), [])`
    269       where `version` is each value in the `:versions` setting. This list is
    270       then filtered according to the blocklist in
    271       [RFC7540 appendix A](https://tools.ietf.org/html/rfc7540#appendix-A);
    272       May be overridden by the caller. See the "Supporting older cipher suites"
    273       section below for some examples.
    274 
    275     * `:depth` - defaults to `4`. May be overridden by the caller.
    276 
    277     * `:partial_chain` - unless a custom `:partial_chain` function is specified,
    278       Mint will enable its own partial chain handler, which accepts server
    279       certificate chains containing a certificate that was issued by a
    280       CA certificate in the CA trust store, even if that certificate is not
    281       last in the chain. This improves interoperability with some servers
    282       (for example, with a cross-signed intermediate CA or some misconfigured servers),
    283       but is a less strict interpretation of the TLS specification than the
    284       Erlang/OTP default behaviour.
    285 
    286     * `:reuse_sessions` - defaults to `true`. May be overridden by the caller. If
    287       `:"tlsv1.3"` is the only TLS version specified, `:reuse_sessions` will be
    288       removed from the options.
    289 
    290     * `:secure_renegotiate` - defaults to `true`. May be overridden by the
    291       caller. If `:"tlsv1.3"` is the only TLS version specified, `:secure_renegotiate`
    292       will be removed from the options.
    293 
    294     * `:server_name_indication` - defaults to specified destination hostname.
    295       May be overridden by the caller.
    296 
    297     * `:verify` - defaults to `:verify_peer`. May be overridden by the caller.
    298 
    299     * `:verify_fun` - unless a custom `:verify_fun` is specified, or `:verify`
    300       is set to `:verify_none`, Mint will enable hostname verification with
    301       support for wildcards in the server's 'SubjectAltName' extension, similar
    302       to the behaviour implemented in
    303       `:public_key.pkix_verify_hostname_match_fun(:https)` in recent Erlang/OTP
    304       releases. This improves compatibility with recently issued wildcard
    305       certificates also on older Erlang/OTP releases.
    306 
    307     * `:versions` - defaults to `[:"tlsv1.2"]` (TLS v1.2 only). May be
    308       overridden by the caller.
    309 
    310   ### Supporting older cipher suites
    311 
    312   By default only a small list of modern cipher suites is enabled, in compliance
    313   with the HTTP/2 specification. Some servers, in particular HTTP/1 servers, may
    314   not support any of these cipher suites, resulting in TLS handshake failures or
    315   closed connections.
    316 
    317   To select the default cipher suites of Erlang/OTP (including for example
    318   AES-CBC), use the following `:transport_opts`:
    319 
    320       # Erlang/OTP 20.3 or later:
    321       transport_opts: [ciphers: :ssl.cipher_suites(:default, :"tlsv1.2")]
    322       # Older versions:
    323       transport_opts: [ciphers: :ssl.cipher_suites()]
    324 
    325   Recent Erlang/OTP releases do not enable RSA key exchange by default, due to
    326   known weaknesses. If necessary, you can build a cipher list with RSA exchange
    327   and use it in `:transport_opts`:
    328 
    329       ciphers =
    330         :ssl.cipher_suites(:all, :"tlsv1.2")
    331         |> :ssl.filter_cipher_suites(
    332           key_exchange: &(&1 == :rsa),
    333           cipher: &(&1 in [:aes_256_gcm, :aes_128_gcm, :aes_256_cbc, :aes_128_cbc])
    334         )
    335         |> :ssl.append_cipher_suites(:ssl.cipher_suites(:default, :"tlsv1.2"))
    336 
    337   ## Examples
    338 
    339       {:ok, conn} = Mint.HTTP.connect(:http, "httpbin.org", 80)
    340 
    341   Using a proxy:
    342 
    343       proxy = {:http, "myproxy.example.com", 80, []}
    344       {:ok, conn} = Mint.HTTP.connect(:https, "httpbin.org", 443, proxy: proxy)
    345 
    346   Forcing the connection to be an HTTP/2 connection:
    347 
    348       {:ok, conn} = Mint.HTTP.connect(:https, "httpbin.org", 443, protocols: [:http2])
    349 
    350   Enable all default cipher suites of Erlang/OTP (release 20.3 or later):
    351 
    352       opts = [transport_opts: [ciphers: :ssl.cipher_suites(:default, :"tlsv1.2")]]
    353       {:ok, conn} = Mint.HTTP.connect(:https, "httpbin.org", 443, opts)
    354 
    355   """
    356   @spec connect(Types.scheme(), Types.address(), :inet.port_number(), keyword()) ::
    357           {:ok, t()} | {:error, Types.error()}
    358   def connect(scheme, address, port, opts \\ []) do
    359     case Keyword.fetch(opts, :proxy) do
    360       {:ok, {proxy_scheme, proxy_address, proxy_port, proxy_opts}} ->
    361         case scheme_to_transport(scheme) do
    362           Transport.TCP ->
    363             proxy = {proxy_scheme, proxy_address, proxy_port}
    364             host = {scheme, address, port}
    365             opts = Keyword.merge(opts, proxy_opts)
    366             UnsafeProxy.connect(proxy, host, opts)
    367 
    368           Transport.SSL ->
    369             proxy = {proxy_scheme, proxy_address, proxy_port, proxy_opts}
    370             host = {scheme, address, port, opts}
    371             TunnelProxy.connect(proxy, host)
    372         end
    373 
    374       :error ->
    375         Mint.Negotiate.connect(scheme, address, port, opts)
    376     end
    377   end
    378 
    379   @doc false
    380   @spec upgrade(
    381           module(),
    382           Mint.Types.socket(),
    383           Types.scheme(),
    384           String.t(),
    385           :inet.port_number(),
    386           keyword()
    387         ) :: {:ok, t()} | {:error, Types.error()}
    388   def upgrade(old_transport, transport_state, scheme, hostname, port, opts),
    389     do: Mint.Negotiate.upgrade(old_transport, transport_state, scheme, hostname, port, opts)
    390 
    391   @doc """
    392   Returns the protocol used by the current connection.
    393 
    394   ## Examples
    395 
    396       iex> Mint.HTTP.protocol(%Mint.HTTP1{})
    397       :http1
    398 
    399       iex> Mint.HTTP.protocol(%Mint.HTTP2{})
    400       :http2
    401   """
    402   if Version.compare(System.version(), "1.7.0") in [:eq, :gt] do
    403     @doc since: "1.4.0"
    404   end
    405 
    406   @spec protocol(t()) :: :http1 | :http2
    407   def protocol(%Mint.HTTP1{}), do: :http1
    408   def protocol(%Mint.HTTP2{}), do: :http2
    409   def protocol(%Mint.UnsafeProxy{state: internal_conn}), do: protocol(internal_conn)
    410 
    411   @doc false
    412   @impl true
    413   @spec initiate(
    414           module(),
    415           Types.socket(),
    416           String.t(),
    417           :inet.port_number(),
    418           keyword()
    419         ) :: {:ok, t()} | {:error, Types.error()}
    420   def initiate(transport, transport_state, hostname, port, opts),
    421     do: Mint.Negotiate.initiate(transport, transport_state, hostname, port, opts)
    422 
    423   @doc """
    424   Closes the given connection.
    425 
    426   This function closes the socket wrapped by the given connection. Once the socket
    427   is closed, the connection goes into the "closed" state and `open?/1` returns `false`.
    428   You can throw away a closed connection.
    429 
    430   Closing a connection does not guarantee that data that is in flight gets delivered
    431   to the server.
    432 
    433   Always returns `{:ok, conn}` where `conn` is the updated connection.
    434 
    435   ## Examples
    436 
    437       {:ok, conn} = Mint.HTTP.close(conn)
    438 
    439   """
    440   @impl true
    441   @spec close(t()) :: {:ok, t()}
    442   def close(conn), do: conn_module(conn).close(conn)
    443 
    444   @doc """
    445   Checks whether the connection is open.
    446 
    447   This function returns `true` if the connection is open, `false` otherwise. It should
    448   be used to check that a connection is open before sending requests or performing
    449   operations that involve talking to the server.
    450 
    451   The `type` argument can be used to tell whether the connection is closed only for reading,
    452   only for writing, or for both. In HTTP/1, a closed connection is always closed for
    453   both reading and writing. In HTTP/2, the connection can be closed only for writing but
    454   not for reading, meaning that you cannot send any more data to the server but you can
    455   still receive data from the server. See the "Closed connection" section in the module
    456   documentation of `Mint.HTTP2`.
    457 
    458   If a connection is not open for reading and writing, it has become useless and you should
    459   get rid of it. If you still need a connection to the server, start a new connection
    460   with `connect/4`.
    461 
    462   ## Examples
    463 
    464       {:ok, conn} = Mint.HTTP.connect(:http, "httpbin.org", 80)
    465       Mint.HTTP.open?(conn)
    466       #=> true
    467 
    468   """
    469   @impl true
    470   @spec open?(t(), :read | :write | :read_write) :: boolean()
    471   def open?(conn, type \\ :read_write), do: conn_module(conn).open?(conn, type)
    472 
    473   @doc """
    474   Sends a request to the connected server.
    475 
    476   This function sends a new request to the server that `conn` is connected to.
    477   `method` is a string representing the method for the request, such as `"GET"`
    478   or `"POST"`. `path` is the path on the host to send the request to. `headers`
    479   is a list of request headers in the form `{header_name, header_value}` with
    480   `header_name` and `header_value` being strings. `body` can have one of three
    481   values:
    482 
    483     * `nil` - no body is sent with the request.
    484 
    485     * iodata - the body to send for the request.
    486 
    487     * `:stream` - when the value of the body is `:stream` the request
    488       body can be streamed on the connection. See `stream_request_body/3`.
    489       In HTTP/1, you can't open a request if the body of another request is
    490       streaming.
    491 
    492   If the request is sent correctly, this function returns `{:ok, conn, request_ref}`.
    493   `conn` is an updated connection that should be stored over the old connection.
    494   `request_ref` is a unique reference that can be used to match on responses for this
    495   request that are returned by `stream/2`. See `stream/2` for more information.
    496 
    497   If there's an error with sending the request, `{:error, conn, reason}` is returned.
    498   `reason` is the cause of the error. `conn` is an updated connection. It's important
    499   to store the returned connection over the old connection in case of errors too, because
    500   the state of the connection might change when there are errors as well. An error when
    501   sending a request **does not** necessarily mean that the connection is closed. Use
    502   `open?/1` to verify that the connection is open.
    503 
    504   Requests can be pipelined so the full response does not have to received
    505   before the next request can be sent. It is up to users to verify that the
    506   server supports pipelining and that the request is safe to pipeline.
    507 
    508   In HTTP/1, you can't open a request if the body of another request is streaming.
    509   See `Mint.HTTP1.request/5` for more information.
    510 
    511   For a quick discussion on HTTP/2 streams and requests, see the `Mint.HTTP2` module and
    512   `Mint.HTTP2.request/5`.
    513 
    514   ## The `content-length` header
    515 
    516   If you don't set the `content-length` header and you send a body with the request (that
    517   is, not `nil` and not `:stream`), then Mint will add a default `content-length` header
    518   to your request. If you're using HTTP/2 and streaming the request, you may provide the
    519   `content-length` header yourself. If you're using HTTP/1, Mint will do chunked
    520   transfer-encoding when a content-length is not provided (see `Mint.HTTP1.request/5`).
    521 
    522   ## Examples
    523 
    524       Mint.HTTP.request(conn, "GET", "/", _headers = [], _body = nil)
    525       Mint.HTTP.request(conn, "POST", "/path", [{"content-type", "application/json"}], "{}")
    526 
    527   """
    528   @impl true
    529   @spec request(
    530           t(),
    531           method :: String.t(),
    532           path :: String.t(),
    533           Types.headers(),
    534           body :: iodata() | nil | :stream
    535         ) ::
    536           {:ok, t(), Types.request_ref()}
    537           | {:error, t(), Types.error()}
    538 
    539   def request(conn, method, path, headers, body),
    540     do: conn_module(conn).request(conn, method, path, headers, body)
    541 
    542   @doc """
    543   Streams a chunk of the request body on the connection or signals the end of the body.
    544 
    545   If a request is opened (through `request/5`) with the body as `:stream`, then the
    546   body can be streamed through this function. The function takes a `conn`, a
    547   `request_ref` returned by `request/5` to identify the request to stream the body for,
    548   and a chunk of body to stream. The value of chunk can be:
    549 
    550     * iodata - a chunk of iodata is transmitted to the server as part of the body
    551       of the request. If the chunk is empty, in HTTP/1 it's a no-op, while in HTTP/2
    552       a `DATA` frame will be sent.
    553 
    554     * `:eof` - signals the end of the streaming of the request body for the given
    555       request. Usually the server won't send any reply until this is sent.
    556 
    557     * `{:eof, trailing_headers}` - sends **trailing headers** and signals the end
    558       of the streaming of the request body for the given request. This behaves the
    559       same way as `:eof` but first sends the trailing headers. See the "Trailing headers"
    560       section below.
    561 
    562   This function always returns an updated connection to be stored over the old connection.
    563 
    564   For information about transfer encoding and content length in HTTP/1, see
    565   `Mint.HTTP1.stream_request_body/3`.
    566 
    567   ## Trailing headers
    568 
    569   HTTP trailing headers can be sent after the body of a request. The behaviour is slightly
    570   different for HTTP/1 and HTTP/2.
    571 
    572   In HTTP/1, trailing headers are only supported if the transfer encoding is set to
    573   `chunked`. See `Mint.HTTP1.stream_request_body/3` for more information on chunked
    574   transfer encoding.
    575 
    576   In HTTP/2, trailing headers behave like normal headers. You don't need to care
    577   about the transfer encoding.
    578 
    579   ### The `trailer` header
    580 
    581   As specified in [section 4.4 of RFC 7230](https://tools.ietf.org/html/rfc7230#section-4.4),
    582   in HTTP/1 you need to specify which headers you're going to send as trailing
    583   headers using the `trailer` header. The `trailer` header applies to both HTTP/1
    584   and HTTP/2. See the examples below for more information.
    585 
    586   ### The `te` header
    587 
    588   As specified in  [section 4.3 of RFC 7230](https://tools.ietf.org/html/rfc7230#section-4.3),
    589   the `te` (or `TE`) header is used to specify which transfer-encodings the client
    590   is willing to accept (besides `chunked`). Mint supports decoding of trailing headers,
    591   but if you want to notify the server that you are accepting trailing headers,
    592   use the `trailers` value in the `te` header. For example:
    593 
    594       Mint.HTTP.request(conn, "GET", "/", [{"te", "trailers"}], "some body")
    595 
    596   Note that the `te` header can also be used to communicate which encodings you
    597   support to the server.
    598 
    599   ## Examples
    600 
    601   Let's see an example of streaming an empty JSON object (`{}`) by streaming one curly
    602   brace at a time.
    603 
    604       headers = [{"content-type", "application/json"}, {"content-length", "2"}]
    605       {:ok, conn, request_ref} = Mint.HTTP.request(conn, "POST", "/", headers, :stream)
    606       {:ok, conn} = Mint.HTTP.stream_request_body(conn, request_ref, "{")
    607       {:ok, conn} = Mint.HTTP.stream_request_body(conn, request_ref, "}")
    608       {:ok, conn} = Mint.HTTP.stream_request_body(conn, request_ref, :eof)
    609 
    610   Here's an example of sending trailing headers:
    611 
    612       headers = [{"content-type", "application/json"}, {"trailer", "my-trailer, x-expires"}]
    613       {:ok, conn, request_ref} = Mint.HTTP.request(conn, "POST", "/", headers, :stream)
    614 
    615       {:ok, conn} = Mint.HTTP.stream_request_body(conn, request_ref, "{}")
    616 
    617       trailing_headers = [{"my-trailer", "xxx"}, {"x-expires", "10 days"}]
    618       {:ok, conn} = Mint.HTTP.stream_request_body(conn, request_ref, {:eof, trailing_headers})
    619 
    620   """
    621   @impl true
    622   @spec stream_request_body(
    623           t(),
    624           Types.request_ref(),
    625           iodata() | :eof | {:eof, trailing_headers :: Types.headers()}
    626         ) ::
    627           {:ok, t()} | {:error, t(), Types.error()}
    628   def stream_request_body(conn, ref, body),
    629     do: conn_module(conn).stream_request_body(conn, ref, body)
    630 
    631   @doc """
    632   Streams the next batch of responses from the given message.
    633 
    634   This function processes a "message" which can be any term, but should be
    635   a message received by the process that owns the connection. **Processing**
    636   a message means that this function will parse it and check if it's a message
    637   that is directed to this connection, that is, a TCP/SSL message received on the
    638   connection's socket. If it is, then this function will parse the message,
    639   turn it into a list of responses, and possibly take action given the responses.
    640   As an example of an action that this function could perform, if the server sends
    641   a ping request this function will transparently take care of pinging the server back.
    642 
    643   If there's no error, this function returns `{:ok, conn, responses}` where `conn` is
    644   the updated connection and `responses` is a list of responses. See the "Responses"
    645   section below. If there's an error, `{:error, conn, reason, responses}` is returned,
    646   where `conn` is the updated connection, `reason` is the error reason, and `responses`
    647   is a list of responses that were correctly parsed before the error.
    648 
    649   If the given `message` is not from the connection's socket,
    650   this function returns `:unknown`.
    651 
    652   ## Socket mode
    653 
    654   Mint sets the socket in `active: :once` mode. This means that a single socket
    655   message at a time is delivered to the process that owns the connection. After
    656   a message is delivered, then no other messages are delivered (we say the socket
    657   goes in *passive* mode). When `stream/2` is called to process the message that
    658   was received, Mint sets the socket back to `active: :once`. This is good to know
    659   in order to understand how the socket is handled by Mint, but in normal usage
    660   it just means that you will process one message at a time with `stream/2` and not
    661   pay too much attention to the socket mode.
    662 
    663   Mint also supports passive mode to avoid receiving messages. See the "Mode" section
    664   in the module documentation.
    665 
    666   ## Responses
    667 
    668   Each possible response returned by this function is a tuple with two or more elements.
    669   The first element is always an atom that identifies the kind of response. The second
    670   element is a unique reference `t:Mint.Types.request_ref/0` that identifies the request
    671   that the response belongs to. This is the term returned by `request/5`. After these
    672   two elements, there can be response-specific terms as well, documented below.
    673 
    674   These are the possible responses that can be returned.
    675 
    676     * `{:status, request_ref, status_code}` - returned when the server replied
    677       with a response status code. The status code is a non-negative integer.
    678       You can have zero or more `1xx` `:status` and `:headers` responses for a
    679       single request, but they all precede a single non-`1xx` `:status` response.
    680 
    681     * `{:headers, request_ref, headers}` - returned when the server replied
    682       with a list of headers. Headers are in the form `{header_name, header_value}`
    683       with `header_name` and `header_value` being strings. A single `:headers` response
    684       will come after the `:status` response. A single `:headers` response may come
    685       after all the `:data` responses if **trailing headers** are present.
    686 
    687     * `{:data, request_ref, binary}` - returned when the server replied with
    688       a chunk of response body (as a binary). The request shouldn't be considered done
    689       when a piece of body is received because multiple chunks could be received. The
    690       request is done when the `:done` response is returned.
    691 
    692     * `{:done, request_ref}` - returned when the server signaled the request
    693       as done. When this is received, the response body and headers can be considered
    694       complete and it can be assumed that no more responses will be received for this
    695       request. This means that for example, you can stop holding on to the request ref
    696       for this request.
    697 
    698     * `{:error, request_ref, reason}` - returned when there is an error that
    699       only affects the request and not the whole connection. For example, if the
    700       server sends bad data on a given request, that request will be closed and an error
    701       for that request will be returned among the responses, but the connection will
    702       remain alive and well.
    703 
    704     * `{:pong, request_ref}` - returned when a server replies to a ping
    705       request sent by the client. This response type is HTTP/2-specific
    706       and will never be returned by an HTTP/1 connection. See `Mint.HTTP2.ping/2`
    707       for more information.
    708 
    709     * `{:push_promise, request_ref, promised_request_ref, headers}` - returned when
    710       the server sends a server push to the client. This response type is HTTP/2 specific
    711       and will never be returned by an HTTP/1 connection. See `Mint.HTTP2` for more
    712       information on server pushes.
    713 
    714   ## Examples
    715 
    716   Let's assume we have a function called `receive_next_and_stream/1` that takes
    717   a connection and then receives the next message, calls `stream/2` with that message
    718   as an argument, and then returns the result of `stream/2`:
    719 
    720       defp receive_next_and_stream(conn) do
    721         receive do
    722           message -> Mint.HTTP.stream(conn, message)
    723         end
    724       end
    725 
    726   Now, we can see an example of a workflow involving `stream/2`.
    727 
    728       {:ok, conn, request_ref} = Mint.HTTP.request(conn, "GET", "/", _headers = [])
    729 
    730       {:ok, conn, responses} = receive_next_and_stream(conn)
    731       responses
    732       #=> [{:status, ^request_ref, 200}]
    733 
    734       {:ok, conn, responses} = receive_next_and_stream(conn)
    735       responses
    736       #=> [{:headers, ^request_ref, [{"Content-Type", "application/json"}]},
    737       #=>  {:data, ^request_ref, "{"}]
    738 
    739       {:ok, conn, responses} = receive_next_and_stream(conn)
    740       responses
    741       #=> [{:data, ^request_ref, "}"}, {:done, ^request_ref}]
    742 
    743   """
    744   @impl true
    745   @spec stream(t(), term()) ::
    746           {:ok, t(), [Types.response()]}
    747           | {:error, t(), Types.error(), [Types.response()]}
    748           | :unknown
    749   def stream(conn, message), do: conn_module(conn).stream(conn, message)
    750 
    751   @doc """
    752   Returns the number of open requests.
    753 
    754   Open requests are requests that have not yet received a `:done` response.
    755   This function returns the number of open requests for both HTTP/1 and HTTP/2,
    756   but for HTTP/2 only client-initiated requests are considered as open requests.
    757   See `Mint.HTTP2.open_request_count/1` for more information.
    758 
    759   ## Examples
    760 
    761       {:ok, conn, _ref} = Mint.HTTP.request(conn, "GET", "/", [])
    762       Mint.HTTP.open_request_count(conn)
    763       #=> 1
    764 
    765   """
    766   @impl true
    767   @spec open_request_count(t()) :: non_neg_integer()
    768   def open_request_count(conn), do: conn_module(conn).open_request_count(conn)
    769 
    770   @doc """
    771   Receives data from the socket in a blocking way.
    772 
    773   By default Mint operates in active mode, meaning that messages are delivered
    774   to the process that started the connection. However, Mint also supports passive
    775   mode (see the "Mode" section in the module documentation).
    776 
    777   In passive mode, you'll need to manually get bytes out of the socket. You can
    778   do that with this function.
    779 
    780   `byte_count` is the number of bytes you want out of the socket. If `byte_count`
    781   is `0`, all available bytes will be returned.
    782 
    783   `timeout` is the maximum time to wait before returning an error.
    784 
    785   This function will raise an error if the socket is in active mode.
    786 
    787   ## Examples
    788 
    789       {:ok, conn, responses} = Mint.HTTP.recv(conn, 0, 5000)
    790 
    791   """
    792   @impl true
    793   @spec recv(t(), non_neg_integer(), timeout()) ::
    794           {:ok, t(), [Types.response()]}
    795           | {:error, t(), Types.error(), [Types.response()]}
    796   def recv(conn, byte_count, timeout), do: conn_module(conn).recv(conn, byte_count, timeout)
    797 
    798   @doc """
    799   Changes the mode of the underlying socket.
    800 
    801   To use the connection in *active mode*, where the process that started the
    802   connection receives socket messages, set the mode to `:active` (see also `stream/2`).
    803   To use the connection in *passive mode*, where you need to manually receive data
    804   from the socket, set the mode to `:passive` (see also `recv/3`).
    805 
    806   The mode can also be controlled at connection time by the `:mode` option passed
    807   to `connect/4`.
    808 
    809   Note that if you're switching from active to passive mode, you still might have
    810   socket messages in the process mailbox that you need to consume before doing
    811   any other operation on the connection.
    812 
    813   See the "Mode" section in the module documentation for more information on modes.
    814 
    815   ## Examples
    816 
    817       {:ok, conn} = Mint.HTTP.set_mode(conn, :passive)
    818 
    819   """
    820   @impl true
    821   @spec set_mode(t(), :active | :passive) :: {:ok, t()} | {:error, Types.error()}
    822   def set_mode(conn, mode), do: conn_module(conn).set_mode(conn, mode)
    823 
    824   @doc """
    825   Changes the *controlling process* of the given connection to `new_pid`.
    826 
    827   The **controlling process** is a concept that comes from the Erlang TCP and
    828   SSL implementations. The controlling process of a connection is the process
    829   that started the connection and that receives the messages for that connection.
    830   You can change the controlling process of a connection through this function.
    831 
    832   This function also takes care of "transferring" all the connection messages
    833   that are in the mailbox of the current controlling process to the new
    834   controlling process.
    835 
    836   Remember that the connection is a data structure, so if you
    837   change the controlling process it doesn't mean you "transferred" the
    838   connection data structure itself to the other process, which you have
    839   to do manually (for example by sending the connection data structure to the
    840   new controlling process). If you do that, be careful of race conditions
    841   and be sure to retrieve the connection in the new controlling process
    842   before accepting connection messages in the new controlling process.
    843   In fact, this function is guaranteed to return the connection unchanged,
    844   so you are free to ignore the connection entry returned in `{:ok, conn}`.
    845 
    846   ## Examples
    847 
    848       send(new_pid, {:conn, conn})
    849       {:ok, conn} = Mint.HTTP.controlling_process(conn, new_pid)
    850 
    851       # In the "new_pid" process
    852       receive do
    853         {:conn, conn} ->
    854           # Will receive connection messages.
    855       end
    856 
    857   """
    858   @impl true
    859   @spec controlling_process(t(), pid()) :: {:ok, t()} | {:error, Types.error()}
    860   def controlling_process(conn, new_pid), do: conn_module(conn).controlling_process(conn, new_pid)
    861 
    862   @doc """
    863   Assigns a new private key and value in the connection.
    864 
    865   This storage is meant to be used to associate metadata with the connection and
    866   it can be useful when handling multiple connections.
    867 
    868   The given `key` must be an atom, while the given `value` can be an arbitrary
    869   term. The return value of this function is an updated connection.
    870 
    871   See also `get_private/3` and `delete_private/2`.
    872 
    873   ## Examples
    874 
    875   Let's see an example of putting a value and then getting it:
    876 
    877       conn = Mint.HTTP.put_private(conn, :client_name, "Mint")
    878       Mint.HTTP.get_private(conn, :client_name)
    879       #=> "Mint"
    880 
    881   """
    882   @impl true
    883   @spec put_private(t(), atom(), term()) :: t()
    884   def put_private(conn, key, value), do: conn_module(conn).put_private(conn, key, value)
    885 
    886   @doc """
    887   Gets a private value from the connection.
    888 
    889   Retrieves a private value previously set with `put_private/3` from the connection.
    890   `key` is the key under which the value to retrieve is stored. `default` is a default
    891   value returned in case there's no value under the given key.
    892 
    893   See also `put_private/3` and `delete_private/2`.
    894 
    895   ## Examples
    896 
    897       conn = Mint.HTTP.put_private(conn, :client_name, "Mint")
    898 
    899       Mint.HTTP.get_private(conn, :client_name)
    900       #=> "Mint"
    901 
    902       Mint.HTTP.get_private(conn, :non_existent)
    903       #=> nil
    904 
    905   """
    906   @impl true
    907   @spec get_private(t(), atom(), term()) :: term()
    908   def get_private(conn, key, default \\ nil),
    909     do: conn_module(conn).get_private(conn, key, default)
    910 
    911   @doc """
    912   Deletes a value in the private store.
    913 
    914   Deletes the private value stored under `key` in the connection. Returns the
    915   updated connection.
    916 
    917   See also `put_private/3` and `get_private/3`.
    918 
    919   ## Examples
    920 
    921       conn = Mint.HTTP.put_private(conn, :client_name, "Mint")
    922 
    923       Mint.HTTP.get_private(conn, :client_name)
    924       #=> "Mint"
    925 
    926       conn = Mint.HTTP.delete_private(conn, :client_name)
    927       Mint.HTTP.get_private(conn, :client_name)
    928       #=> nil
    929 
    930   """
    931   @impl true
    932   @spec delete_private(t(), atom()) :: t()
    933   def delete_private(conn, key), do: conn_module(conn).delete_private(conn, key)
    934 
    935   @doc """
    936   Gets the socket associated with the connection.
    937 
    938   Do not use the returned socket to change its internal state. Only read information from the socket.
    939   For instance, use `:ssl.connection_information/2` to retrieve TLS-specific information from the
    940   socket.
    941   """
    942   @impl true
    943   @spec get_socket(t()) :: Mint.Types.socket()
    944   def get_socket(conn), do: conn_module(conn).get_socket(conn)
    945 
    946   @doc """
    947   Gets the proxy headers associated with the connection in the `CONNECT` method.
    948 
    949   When using tunnel proxy and HTTPs, the only way to exchange data with
    950   the proxy is through headers in the `CONNECT` method.
    951   """
    952   if Version.compare(System.version(), "1.7.0") in [:eq, :gt] do
    953     @doc since: "1.4.0"
    954   end
    955 
    956   @impl true
    957   @spec get_proxy_headers(t()) :: Mint.Types.headers()
    958   def get_proxy_headers(conn), do: conn_module(conn).get_proxy_headers(conn)
    959 
    960   ## Helpers
    961 
    962   defp conn_module(%UnsafeProxy{}), do: UnsafeProxy
    963   defp conn_module(%Mint.HTTP1{}), do: Mint.HTTP1
    964   defp conn_module(%Mint.HTTP2{}), do: Mint.HTTP2
    965 end