# `JSV.Resolver.Httpc`
[🔗](https://github.com/lud/jsv/blob/v0.23.0/lib/jsv/resolver/httpc.ex#L1)

A `JSV.Resolver` implementation that will fetch the schemas from the web with
the help of the `:httpc` module.

This resolver requires a list of allowed URL prefixes to download from. It
also needs a proper JSON library to decode fetched schemas:

* From Elixir 1.18, the `JSON` module is automatically available in the
  standard library.
* JSV can use [Jason](https://hex.pm/packages/jason) if listed in your
  dependencies with the  `"~> 1.0"` requirement.

Schemas known by the `JSV.Resolver.Embedded` will be fetched from that module
instead of being fetched from the web. Allowed prefixes are not needed for
those schemas.

HTTPS downloads verify the server certificate and hostname against the
operating system CA store, using `:public_key.cacerts_get/0`. Redirect
responses fail the resolution with an error tuple; use the final URL directly
in your schema references and allowed prefixes.

### Options

This resolver supports the following options:

- `:allowed_prefixes` - This option is mandatory and contains the allowed
  prefixes to download from. Each prefix must be a full URL with the scheme,
  host and at least the root path, like `https://example.com/`. A URL is
  allowed when it begins with one of the prefixes. A prefix is validated when
  it is matched against a URL, and raises an `ArgumentError` at that point if
  it is malformed.
- `:cache_dir` - The path of a directory to cache downloaded resources. The
  default value can be retrieved with `default_cache_dir/0` and is a
  JSV-specific directory in the user cache, given by
  `:filename.basedir(:user_cache, "jsv")`, with a fallback on the system
  temporary directory when the user cache location is undefined. The option
  also accepts `false` to disable that cache. Cache directories are created
  with `0700` permissions and files are written atomically. Note that there
  is no cache expiration mechanism.

  The `0700` permissions rely on Unix mode bits and have no effect on
  Windows, where filesystem access is governed by ACLs instead.

- `:max_body_size` - The maximum size in bytes of a response body. Larger
  responses produce a `{:body_too_large, url}` error. Defaults to
  `10485760` (10 MiB).
- `:request_timeout` - The request timeout in milliseconds. Defaults to
  `30000`.

### Example

    iex> resolver_opts = [allowed_prefixes: ["https://www.schemastore.org/"], cache_dir: "_build/custom/dir"]
    iex> {:ok, _root} = JSV.build(%{"$ref": "https://www.schemastore.org/github-action.json"}, resolver: {JSV.Resolver.Httpc, resolver_opts})

# `default_cache_dir`

```elixir
@spec default_cache_dir() :: binary()
```

Returns the default directory used by the disk-based cache, a JSV-specific
subdirectory of the user cache directory given by `:filename.basedir/2`.

When the user cache directory is undefined, typically in minimal production
environments where the `HOME` environment variable is not set, the returned
directory is based on `System.tmp_dir!/0`.

---

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