# `Kotoba.Storage.Local.Plug`
[🔗](https://github.com/hattoriai/kotoba/blob/v0.5.0/lib/kotoba/storage/local/plug.ex#L1)

Serves the files of `Kotoba.Storage.Local`, read only.

In the endpoint, before the router:

    plug Kotoba.Storage.Local.Plug

The plug answers `GET` and `HEAD` requests under the `:at` path (by
default the configured `:url_prefix` of `Kotoba.Storage.Local`), and
passes every other request on. In a router, `forward` strips the path, so
give `at: "/"`:

    forward "/uploads/kotoba", Kotoba.Storage.Local.Plug, at: "/"

## Options

  * `:at` - the request path of the files. The default is the configured
    `:url_prefix`.
  * `:root` - the directory. The default is the configured `:root`.
  * `:max_age` - the `max-age` of the `Cache-Control` header, in seconds.
    The default is `3600`.

## Responses

  * The content type comes from the file extension, through the allow-list
    of `Kotoba.Attachments.content_type/1`: an extension that is not in it
    (`.html`, `.svg`, …) is sent as `application/octet-stream`.
  * `Cache-Control: private, max-age=…`, `X-Content-Type-Options: nosniff`
    and `Content-Security-Policy: default-src 'none'; sandbox`, so a file
    cannot run a script on the app's origin.
  * PNG, JPEG, GIF and WebP images, PDF files and MP4 and WebM videos
    are served inline; every other file has
    `Content-Disposition: attachment`.
  * `Accept-Ranges: bytes`, and a `GET` with a single `Range`
    (`bytes=0-99`, `bytes=100-`, `bytes=-100`) gives `206` with that part
    of the file and `Content-Range`. A range that starts after the end of
    the file gives `416`. Several ranges, or a header that is not valid,
    give the whole file. Browsers need ranges to seek in a video, and
    Safari to play one.
  * A path with a segment that is not a valid key segment (`..`, `.`, or
    a character other than ASCII letters, digits, `.`, `-` and `_`) gives
    `400`. A key with no regular file gives `404`: a directory, a symbolic
    link to a file, and a path through a symbolic link to a directory
    included.

---

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