# 0.18.0

## Features

### Response Cache

https://gitlab.com/os85/httpx/-/wikis/Response-Cache

The `:response_cache` plugin handles transparent usage of HTTP caching and conditional requests to improve performance and bandwidth usage.

```ruby
client = HTTPX.plugin(:response_cache)
r1 = client.get("https://nghttp2.org/httpbin/cache")
r2 = client.get("https://nghttp2.org/httpbin/cache")

r1.status #=> 200
r2.status #=> 304
r1.body == r2.body #=> true
```

### jitter on "retry-after"

On the `:retries` plugin, jitter calculation is now applied to the value in seconds defined by user after which a request should be retried (i.e. if `:retry_after` option is set to `2`, the retry interval may be `1.5422312` seconds, for example). This is important to avoid cases of synchronized "thundering herd", where server rejects requests, but they all get retried at the same time because the retry interval is exactly the same.

You can override the jitter calculation function by using the [:retry_jitter](https://gitlab.com/os85/httpx/-/wikis/Retries#retry_jitter) option:

```ruby
HTTPX.plugin(:retries, retry_after: 2, retry_jitter: ->(interval) { interval + rand }) # interval is 3
```

You can opt out of this by setting `HTTPX_NO_JITTER=1` environment variable.

### Response#error

`HTTPX::Response#error` was added, to match `HTTPX::Response#error`. It returns an exception for 4xx/5xx responses (`HTTPX::HTTPError`), `nil` otherwise. It allows for end users to write such code:

```ruby
if (response = HTTPX.get(uri)).error
  # success
else
  #error
end
```

## Improvements

* `webmock` adapter: added support for "stub_http_request#to_timeout" (https://gitlab.com/os85/httpx/-/merge_requests/165).

## timers not a dependency

The functionality provided by the `timers` gem was replaced by a simpler custom implementation. Although powerful, its complexity was somewhat unnecessary for `httpx`'s simpler event loop, where user-defined timeouts are usually the same for a given batch of requests. The removal of `timers` reduces the number of dependencies to 1, which is `http-2-next` and is maintained by me.

## AWS plugins

* `aws_sdk_authentication` plugin: removed implementation relying on  `aws-sdk-s3`, replacing it with an `aws-sdk-core` relying implementation, which only uses credentials strategies and region discovery (the whole point of this SDK is to use a minimal subset of AWS SDK).


## Bugfixes

* Fixed Error class declaration on response decoders when mime type is invalid (https://gitlab.com/os85/httpx/-/merge_requests/166).
* `ErrorResponse#to_s` now removes ANSI escape sequences from error backtraces.
* Persistent connections were kept around both in the pool and in the selector; the first is necessary, but the second caused busy loop scenarios all over; they are now removed when no requests are being handled.
* Connections which failed connection handshake were removed from the pool, but not from the selector list, causing busy loop scenarios in a few cases; this has been fixed.
* Fixed issue where HTTP/2 streams were being closed twice (and signaling it also twice), messing connection accounting in the pool.
* DoH resolver was always subscribed to the default thread "connection pool", which broke scenarios were session was patched to use its custom pool; it now ensures that it subscribes to the pool it was created in.
* `:aws_sigv4` plugin: removed require of `aws-sdk-s3`, left there by mistake (the whole point of the plugin is to run without the AWS SDK).
## Chore

* `HTTPX::ErrorResponse#status` is now deprecated.