# `SSL`
[🔗](https://github.com/gsmlg-dev/http_fetch/blob/v0.16.7/apps/ex_ssl/lib/ssl.ex#L1)

OTP `:ssl`-compatible client facade for the implemented `ex_ssl` feature subset.

This experimental client supports TLS 1.3 and explicit bounded TLS 1.2, binary raw sockets, passive and
active-once delivery, application ownership transfer, authenticated ALPN,
bounded streaming writes, and mandatory peer verification. These restricted
defaults differ from OTP. Unsupported options return explicit
`{:error, {:options, reason}}` errors.

STARTTLS callers must own a passive binary/raw TCP socket, fully consume and
validate the application's upgrade response, and reject any buffered plaintext.
Supply `server_name_indication` as the certificate reference DNS name. Once
upgrade is attempted, an owned socket is closed on failure; plaintext must
never resume. A socket belonging to another process is left untouched.

# `close`

```elixir
@spec close(SSL.Socket.t()) :: :ok | {:error, term()}
```

Closes the connection. Closing an already closed handle succeeds.

# `connect`

```elixir
@spec connect(:gen_tcp.socket(), list()) :: {:ok, SSL.Socket.t()} | {:error, term()}
```

# `connect`

```elixir
@spec connect(term(), term(), term()) :: {:ok, SSL.Socket.t()} | {:error, term()}
```

# `connect`

```elixir
@spec connect(term(), :inet.port_number(), list(), timeout()) ::
  {:ok, SSL.Socket.t()} | {:error, term()}
```

# `connection_information`

```elixir
@spec connection_information(SSL.Socket.t()) :: {:ok, keyword()} | {:error, term()}
```

Returns the supported non-secret connection metadata.

# `connection_information`

```elixir
@spec connection_information(SSL.Socket.t(), term()) ::
  {:ok, keyword()} | {:error, term()}
```

# `controlling_process`

```elixir
@spec controlling_process(SSL.Socket.t(), pid()) :: :ok | {:error, term()}
```

Transfers application ownership while the TLS process retains the TCP socket.

# `negotiated_protocol`

```elixir
@spec negotiated_protocol(SSL.Socket.t()) :: {:ok, binary()} | {:error, term()}
```

Returns the authenticated ALPN selection, if the server negotiated one.

# `peercert`

```elixir
@spec peercert(SSL.Socket.t()) :: {:ok, binary()} | {:error, term()}
```

Returns the authenticated server leaf certificate as DER.

# `peername`

```elixir
@spec peername(SSL.Socket.t()) ::
  {:ok, {:inet.ip_address(), :inet.port_number()}} | {:error, term()}
```

Returns the live TCP peer address and port.

# `recv`

```elixir
@spec recv(SSL.Socket.t(), non_neg_integer(), timeout()) ::
  {:ok, binary()} | {:error, term()}
```

Receives available bytes for length 0, or exactly length bytes. Timeout retains buffered data.

# `send`

```elixir
@spec send(SSL.Socket.t(), iodata()) :: :ok | {:error, term()}
```

Writes iodata as one ordered logical write. Concurrent writes return `:busy`.

# `setopts`

```elixir
@spec setopts(SSL.Socket.t(), list()) :: :ok | {:error, term()}
```

Changes supported delivery, send, and mutable TCP options after validation.

# `sockname`

```elixir
@spec sockname(SSL.Socket.t()) ::
  {:ok, {:inet.ip_address(), :inet.port_number()}} | {:error, term()}
```

Returns the live local TCP address and port.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
