# HTTPX
[![Hex.pm](https://img.shields.io/hexpm/v/httpx.svg "Hex")](https://hex.pm/packages/httpx)
[![Build Status](https://travis-ci.org/IanLuites/httpx.svg?branch=master)](https://travis-ci.org/IanLuites/httpx)
[![Coverage Status](https://coveralls.io/repos/github/IanLuites/httpx/badge.svg?branch=master)](https://coveralls.io/github/IanLuites/httpx?branch=master)
[![Hex.pm](https://img.shields.io/hexpm/l/httpx.svg "License")](LICENSE)
Elixir HTTP client with plug like processors.
## Quick Setup
```elixir
> HTTPX.get("http://ifconfig.co", headers: [{"user-agent", "curl"}])
{:ok,
%HTTPX.Response{
body: "91.181.146.99\n",
headers: [
{"Date", "Sun, 28 Apr 2019 07:08:25 GMT"},
{"Content-Type", "text/plain; charset=utf-8"},
{"Content-Length", "14"},
{"Connection", "keep-alive"},
{"Set-Cookie",
"__cfduid=...; expires=Mon, 27-Apr-20 07:08:25 GMT; path=/; domain=.ifconfig.co; HttpOnly"},
{"Via", "1.1 vegur"},
{"Expect-CT",
"max-age=604800, report-uri=\"https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct\""},
{"Server", "cloudflare"},
{"CF-RAY", "...-LHR"}
],
status: 200
}}
```
## Installation
The package can be installed
by adding `httpx` to your list of dependencies in `mix.exs`:
```elixir
def deps do
[{:httpx, "~> 0.1.0"}]
end
```
The docs can
be found at [https://hexdocs.pm/httpx](https://hexdocs.pm/httpx).
## Settings
### Pool
HTTPX will by default use a connection pool named `:default`
to reuse connections.
Sometimes reusing connections can lead to unexpected results,
therefore it is possible to disable to the default pool by setting:
```elixir
config :httpx, default_pool: false
```
It is also possible to chang the default pool name by setting:
```elixir
config :httpx, default_pool: :custom_pool_name
```
_(Note: the name needs to be an atom.)_
### SSL / TLS
SSL options can be passed as `:ssl_options`.
Certificate validation is always performed with the CA bundle adapted from Mozilla by https://certifi.io in the [certifi](https://hex.pm/packages/certifi) package.
By default certificates are verified to a a depth of level 2, which means the path can be PEER, CA, CA, ROOT-CA, and so on.
To disable verification pass `verify: :verify_none`.
For more options see
[Erlang SSL Options (COMMON)](http://erlang.org/doc/man/ssl.html#TLS/DTLS%20OPTION%20DESCRIPTIONS%20-%20COMMON%20for%20SERVER%20and%20CLIENT)
and
[Erlang SSL Options (CLIENT)](http://erlang.org/doc/man/ssl.html#TLS/DTLS%20OPTION%20DESCRIPTIONS%20-%20CLIENT)
documentation.
## Logging
## Processors
Processors allow users to change or update requests,
during a request lifetime.
Processors are applied to all requests by `HTTPX` and
are an ideal way to insert tracking or metrics.
### Configure
The processors can be given as a list, which will be applied in order.
```
config :httpx, processors: [Example.Processor]
```
Processors will be optimized on startup and can't be dynamically added or removed.
If such functionality is required, then the following flag needs to be set:
```
config :httpx, dynamic: true
```
### Processor Lifetime
The lifetime of a processor is:
`init/1` => `pre_request/2` => `post_request/2` => `post_parse/2`.
The `init/1`, might be called multiple times,
but no more than once per request.
### Hooks
Each processor can use the following hooks:
#### init/1
The `init/1` hook is called to let the processor configure itself.
In the optimized version the `init/1` hook is only called once.
The `init/1` can be called once per request,
when `:httpx` is running in dynamic mode.
For example configuring a tracking header:
```
@impl HTTPX.Processor
def init(opts) do
header = Keyword.get(opts, :tracking_header, "example")
{:ok, %{header: header}}
end
```
#### pre_request/2
The `pre_request/2` hook is called before the request is performed.
It can be used to change
or add to the details of a request, before it is
performed.
For example this adds a custom tracking header to all requests:
```
@impl HTTPX.Processor
def pre_request(req = %{headers: req_headers}, %{header: header}) do
{:ok, %{req | headers: [{header, "..."} | req_headers]}}
end
```
(Note the `header` comes from the `init/1` above.)
#### post_request/2
The `post_request/2` hook is called after the request is performed,
but before the response is parsed.
#### post_parse/2
The `post_parse/2` hook is called after the response is parsed.
### Example
This module will redirect all requests to
`https://ifconfig.co` and parse only the IP
in the result.
This module has no real life use and is just
an example.
```
defmodule MyProcessor do
use HTTPX.Processor
@impl HTTPX.Processor
def pre_request(req, opts) do
{:ok, %{req | url: "https://ifconfig.co"}}
end
@match ~r/<code class=\"ip\">(.*)<\/code>/
@impl HTTPX.Processor
def post_parse(%{body: body}, _opts) do
case Regex.run(@match, body) do
[_, m] -> {:ok, m}
_ -> :ok
end
end
def post_parse(_, _), do: :ok
end
```
## Streaming
## Changelog
### 0.1.9 (2023-03-24)
New features:
- [`OpenTelemetry`](https://opentelemetry.io/docs/languages/erlang/) integration.
### 0.1.0 (2020-06-17)
New features:
- `HTTPX.Request` module to store request information and allow for request replays.
- `HTTPX.Auth` can now modify more than headers.
- Processors that allow for modifications to requests on a project/application level.
- Configure (or disable) the default pool.
Changes:
- `HTTPX.Auth` now applies to a `HTTPX.Request` and not a tuple.
- `HTTPX.Auth` now returns a [modified] `HTTPX.Request` and not a list of headers.
- SSL certificates are now verified by default. Use `config :httpx, ssl_verify: false` to disable verification.
Optimizations:
- On load HTTPX optimizes the configured processors.
Bug fixes:
- ...
## License
_HTTPX_ source code is released under [the MIT License](LICENSE).
Check [LICENSE](LICENSE) file for more information.