Kotoba.Storage.Local.Plug (Kotoba v0.5.0)

Copy Markdown View Source

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.