Mint.HTTP.connect

You're seeing just the function connect, go back to Mint.HTTP module for more information.
Link to this function

connect(scheme, address, port, opts \\ [])

View Source

Specs

connect(
  Mint.Types.scheme(),
  Mint.Types.address(),
  :inet.port_number(),
  keyword()
) :: {:ok, t()} | {:error, Mint.Types.error()}

Creates a new connection to a given server.

Creates a new connection struct and establishes the connection to the given server, identified by the given host and port combination. Both HTTP and HTTPS are supported by passing respectively :http and :https as the scheme.

The connection struct wraps a socket, which is created once the connection is established inside this function. If HTTP is used, then the created socket is a TCP socket and the :gen_tcp module is used to create that socket. If HTTPS is used, then the created socket is an SSL socket and the :ssl module is used to create that socket. The socket is created in active mode (with active: :once), which is why it is important to know the type of the socket: messages from the socket will be delivered directly to the process that creates the connection and tagged appropriately by the socket module (see the :gen_tcp and :ssl modules). See stream/2 for more information on the messages and how to process them and on the socket mode.

Options

  • :hostname - (string) explicitly provide the hostname used for the Host header, hostname verification, SNI, and so on. Required when address is not a string.

  • :transport_opts - (keyword) options to be given to the transport being used. These options will be merged with some default options that cannot be overridden. For more details, refer to the "Transport options" section below.

  • :mode - (:active or :passive) whether to set the socket to active or passive mode. See the "Mode" section in the module documentation and set_mode/2.

  • :protocols - (list of atoms) a list of protocols to try when connecting to the server. The possible values in the list are :http1 for HTTP/1 and HTTP/1.1 and :http2 for HTTP/2. If only one protocol is present in the list, then the connection will be forced to use that protocol. If both :http1 and :http2 are present in the list, then Mint will negotiate the protocol. See the section "Protocol negotiation" below for more information. Defaults to [:http1, :http2].

  • :proxy_headers - a list of headers (Mint.Types.headers/0) to pass when using a proxy. They will be used for the CONNECT request in tunnel proxies or merged with every request for forward proxies.

The following options are HTTP/1-specific and will force the connection to be an HTTP/1 connection.

  • :proxy - a {scheme, address, port, opts} tuple that identifies a proxy to connect to. See the "Proxying" section below for more information.

The following options are HTTP/2-specific and will only be used on HTTP/2 connections.

  • :client_settings - (keyword) a list of client HTTP/2 settings to send to the server. See Mint.HTTP2.put_settings/2 for more information. This is only used in HTTP/2 connections.

Protocol negotiation

If both :http1 and :http2 are present in the list passed in the :protocols option, the protocol negotiation happens in the following way:

  • If the scheme used to connect to the server is :http, then HTTP/1 or HTTP/1.1 is used.

  • If the scheme is :https, then ALPN negotiation is used to determine the right protocol. This means that the server will decide whether to use HTTP/1 or HTTP/2. If the server doesn't support protocol negotiation, we will fall back to HTTP/1. If the server negotiates a protocol that we don't know how to handle, {:error, {:bad_alpn_protocol, protocol}} is returned.

Proxying

You can set up proxying through the :proxy option, which is a tuple {scheme, address, port, opts} that identifies the proxy to connect to. Once a proxied connection is returned, the proxy is transparent to you and you can use the connection like a normal HTTP/1 connection.

If the scheme is :http, we will connect to the host in the most compatible way, supporting older proxy servers. Data will be sent in clear text.

If the connection scheme is :https, we will connect to the host with a tunnel through the proxy. Using :https for both the proxy and the connection scheme is not supported, it is recommended to use :https for the end host connection instead of the proxy.

Transport options

The options specified in :transport_opts are passed to the module that implements the socket interface: :gen_tcp when the scheme is :http, and :ssl when the scheme is :https. Please refer to the documentation for those modules, as well as for :inet.setopts/2, for a detailed description of all available options.

The behaviour of some options is modified by Mint, as described below.

A special case is the :timeout option, which is passed to the transport module's connect function to limit the amount of time to wait for the network connection to be established.

Common options for :http and :https:

  • :active - controlled by the :mode option. Cannot be overridden.

  • :mode - set to :binary. Cannot be overriden.

  • :packet - set to :raw. Cannot be overridden.

  • :timeout - connect timeout in milliseconds. Defaults to 30_000 (30 seconds), and may be overridden by the caller. Set to :infinity to disable the connect timeout.

Options for :https only:

  • :alpn_advertised_protocols - managed by Mint. Cannot be overridden.

  • :cacertfile - if :verify is set to :verify_peer (the default) and no CA trust store is specified using the :cacertfile or :cacerts option, Mint will attempt to use the trust store from the CAStore package or raise an exception if this package is not available. Due to caching the :cacertfile option is more efficient than :cacerts.

  • :ciphers - defaults to the lists returned by :ssl.filter_cipher_suites(:ssl.cipher_suites(:all, version), []) where version is each value in the :versions setting. This list is then filtered according to the blocklist in RFC7540 appendix A; May be overridden by the caller. See the "Supporting older cipher suites" section below for some examples.

  • :depth - defaults to 4. May be overridden by the caller.

  • :partial_chain - unless a custom :partial_chain function is specified, Mint will enable its own partial chain handler, which accepts server certificate chains containing a certificate that was issued by a CA certificate in the CA trust store, even if that certificate is not last in the chain. This improves interoperability with some servers (for example, with a cross-signed intermediate CA or some misconfigured servers), but is a less strict interpretation of the TLS specification than the Erlang/OTP default behaviour.

  • :reuse_sessions - defaults to true. May be overridden by the caller. If :"tlsv1.3" is the only TLS version specified, :reuse_sessions will be removed from the options.

  • :secure_renegotiate - defaults to true. May be overridden by the caller. If :"tlsv1.3" is the only TLS version specified, :secure_renegotiate will be removed from the options.

  • :server_name_indication - defaults to specified destination hostname. May be overridden by the caller.

  • :verify - defaults to :verify_peer. May be overridden by the caller.

  • :verify_fun - unless a custom :verify_fun is specified, or :verify is set to :verify_none, Mint will enable hostname verification with support for wildcards in the server's 'SubjectAltName' extension, similar to the behaviour implemented in :public_key.pkix_verify_hostname_match_fun(:https) in recent Erlang/OTP releases. This improves compatibility with recently issued wildcard certificates also on older Erlang/OTP releases.

  • :versions - defaults to [:"tlsv1.2"] (TLS v1.2 only). May be overridden by the caller.

Supporting older cipher suites

By default only a small list of modern cipher suites is enabled, in compliance with the HTTP/2 specification. Some servers, in particular HTTP/1 servers, may not support any of these cipher suites, resulting in TLS handshake failures or closed connections.

To select the default cipher suites of Erlang/OTP (including for example AES-CBC), use the following :transport_opts:

# Erlang/OTP 20.3 or later:
transport_opts: [ciphers: :ssl.cipher_suites(:default, :"tlsv1.2")]
# Older versions:
transport_opts: [ciphers: :ssl.cipher_suites()]

Recent Erlang/OTP releases do not enable RSA key exchange by default, due to known weaknesses. If necessary, you can build a cipher list with RSA exchange and use it in :transport_opts:

ciphers =
  :ssl.cipher_suites(:all, :"tlsv1.2")
  |> :ssl.filter_cipher_suites(
    key_exchange: &(&1 == :rsa),
    cipher: &(&1 in [:aes_256_gcm, :aes_128_gcm, :aes_256_cbc, :aes_128_cbc])
  )
  |> :ssl.append_cipher_suites(:ssl.cipher_suites(:default, :"tlsv1.2"))

Examples

{:ok, conn} = Mint.HTTP.connect(:http, "httpbin.org", 80)

Using a proxy:

proxy = {:http, "myproxy.example.com", 80, []}
{:ok, conn} = Mint.HTTP.connect(:https, "httpbin.org", 443, proxy: proxy)

Forcing the connection to be an HTTP/2 connection:

{:ok, conn} = Mint.HTTP.connect(:https, "http2.golang.org", 443, protocols: [:http2])

Enable all default cipher suites of Erlang/OTP (release 20.3 or later):

opts = [transport_opts: [ciphers: :ssl.cipher_suites(:default, :"tlsv1.2")]]
{:ok, conn} = Mint.HTTP.connect(:https, "httpbin.org", 443, opts)