Resumable uploads through the app, by the tus protocol (1.0.0): for clients that speak it (Uppy's Tus plugin, tus-js-client, the mobile and desktop clients), and for stores the browser cannot send to straight (the local disk). A connection lost halfway carries on from the last byte the app has.
# lib/my_app_web/router.ex, behind your authentication
forward "/files/tus", Storehouse.Tus.Plug,
owner: &MyAppWeb.Files.owner/1,
room: &MyAppWeb.Files.room/1,
accept: ["video/mp4", "video/quicktime"],
max_bytes: 20_000_000_000,
then: &MyAppWeb.Files.uploaded/2and Storehouse.Tus in the app's supervision tree, where the uploads in
progress are kept. For a browser that can send straight to a bucket,
Storehouse.Plug.Multipart keeps the bytes out of the app altogether.
Extensions
creation (and creation-with-upload: the first bytes with the
POST), termination (DELETE) and expiration (Upload-Expires;
an upload not finished in :expires_in is given up). Upload-Metadata's
filename and filetype (or name and type) are the file's name and
claimed type.
Where the bytes go
On a store of multipart uploads (Storehouse.S3), into its multipart
upload as they come, a part at a time (:part_bytes); the bytes past
the last whole part wait in the upload's state until the next. On
another (Storehouse.Local), into a file of :dir on the app's disk,
stored when it is whole. Either way the file is checked as every upload
is: its claimed type, size and the owner's room when it is created, its
type by its first bytes when it is whole, and deleted when it is not
what it said.
Options
:owner,:room,:existing- functions of the conn, as forStorehouse.Plug.Presign. A request for an upload of another owner is answered404.:accept,:max_bytes(sent asTus-Max-Size),:max_pixels,:metadata,:cache_control,:adapter- as forStorehouse.store/2.:then- a function of the conn and the stored file, called when the upload is whole and checked, that gives the conn: to save the file in a record, to send its key in a header.:expires_in- seconds an upload has to finish. The default is a day.:max_uploads- the uploads one owner may have in progress at once: another is refused with429. The default is 10. Those in progress count against the owner's:roomtoo, by their sizes. (With a:statethat hasStorehouse.Tus.State.owned/1.):part_bytes- the parts of a multipart upload, at least 5 MiB. The default is 8 MiB.:dir- the directory of the uploads to a store without multipart uploads. The default isstorehouse-tusin the system's temporary directory: on several nodes, one they share.:state- where uploads are kept between requests, a module ofStorehouse.Tus.State. The default isStorehouse.Tus.State.ETS.
Why not tussle
tussle (a fork of the tus package) is a tus server for Elixir with
storage of its own (the disk, S3 through ExAws). Storehouse writes
through its own stores instead, with no dependency, and checks a file
as every other upload is checked; the protocol itself is small.