# `Storehouse.S3`
[🔗](https://github.com/hattoriai/storehouse/blob/v0.1.0/lib/storehouse/s3.ex#L1)

A `Storehouse.Adapter` for Amazon S3, and the stores that speak its API:
Cloudflare R2, MinIO, Tigris, Backblaze B2, DigitalOcean Spaces, Google
Cloud Storage's interoperability. With no dependency: it signs its
requests itself (AWS Signature Version 4).

    # config/runtime.exs
    config :storehouse, adapter: Storehouse.S3

    config :storehouse, Storehouse.S3,
      bucket: "my-app-uploads",
      region: "eu-west-1",
      access_key_id: System.fetch_env!("AWS_ACCESS_KEY_ID"),
      secret_access_key: System.fetch_env!("AWS_SECRET_ACCESS_KEY")

For another store, its `endpoint` (whose URLs name the bucket in the
path, `path_style`, unless told otherwise):

    config :storehouse, Storehouse.S3,
      bucket: "uploads",
      region: "auto",
      endpoint: "https://<account>.r2.cloudflarestorage.com",
      access_key_id: System.fetch_env!("R2_ACCESS_KEY_ID"),
      secret_access_key: System.fetch_env!("R2_SECRET_ACCESS_KEY"),
      public_url: "https://files.example.com"

## Options

  * `:bucket`, `:region`, `:access_key_id`, `:secret_access_key`
    (required), and `:session_token` for temporary credentials.
  * `:endpoint` - the store's URL. The default is AWS's,
    `https://s3.<region>.amazonaws.com`.
  * `:path_style` - whether URLs name the bucket in their path
    (`https://endpoint/bucket/key`) rather than their host
    (`https://bucket.endpoint/key`). The default is `false` for AWS,
    `true` with an `:endpoint`.
  * `:public_url` - the base URL of the files for `url/1`: a CDN, a
    custom domain. The default is the bucket's URL. A bucket that is not
    public serves its files at signed URLs (`Storehouse.signed_url/2`).

Each file is stored with its checked content type, and with
`Content-Disposition: attachment` for every type a browser should not
show (`Storehouse.Check.inline?/1`): the store never serves an
uploaded page as a page.

## Uploads straight to the bucket

`presign_upload/3` signs a `PUT` of one file, of its type and its size
exactly, which the browser sends to the bucket without going through
the app (`Storehouse.Live.allow/3`). The bucket must allow it with CORS:

    [{"AllowedOrigins": ["https://my-app.example.com"],
      "AllowedMethods": ["PUT"],
      "AllowedHeaders": ["content-type", "content-disposition"],
      "MaxAgeSeconds": 3600}]

---

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