Uploads straight to the store, many at a time: what a frontend that is
not a LiveView (React, Vue, a native app) asks of the app around the
browser's PUTs. presign/2 signs a batch, register/2 checks the
files once they are there. Storehouse.Plug.Presign and
Storehouse.Plug.Register answer them in JSON.
Each gives one result per item, in order: some files are refused (their type, their size, the room left) and the others go ahead.
{:ok, upload}-presign/2: signed (Storehouse.presign_upload/4), with a:tokenthat the browser gives back with the key toregister/2.{:ok, file}-register/2: checked, aStorehouse.File.{:existing, file}- a file the app has already (:existing): nothing to upload, nothing kept twice.{:error, code}- an atom the frontend translates::not_accepted,:too_large,:storage_full,:invalid_checksum,:not_owner,:invalid_token,:invalid_item,:too_many, or the store's.
The token
Each upload presign/2 signs comes with a token: its key and owner,
signed with :secret (the endpoint's secret_key_base, which
Storehouse.Plug.Presign and Storehouse.Plug.Register take from the
conn). register/2 checks only a key whose token is valid, for the same
owner, and less than a day old: any other is {:error, :invalid_token},
and the file at it is left as it is. So a request can never name a
file already stored (to have it deleted when it fails a check), or one
of another person of the same owner.
The room
:room is shared by the batch: each file presigned (or registered)
takes its size from what the next one sees, so ten files that fit one
at a time but not together are not all signed. A file the app has
already takes none.
Summary
Functions
The most items a batch takes, by default.
Signs uploads of items, each a map with "name", "type", "bytes"
and, optionally, "checksum" (the SHA-256 the browser read, hex or
Base64). String or atom keys.
Checks the files a browser uploaded (Storehouse.verify_upload/2):
items are maps with "key" and "token" (those presign/2 gave)
and, optionally, "name". A key without its token (another's, a file
already stored) is refused with :invalid_token, and the file at it is
left as it is. Two files of the same
bytes in one batch are one: the second gives {:existing, first}, and
its copy is deleted.
Functions
@spec max_items() :: pos_integer()
The most items a batch takes, by default.
Signs uploads of items, each a map with "name", "type", "bytes"
and, optionally, "checksum" (the SHA-256 the browser read, hex or
Base64). String or atom keys.
Takes the options of Storehouse.presign_upload/4 (:accept,
:max_bytes, :owner, :existing, :key, :cache, :expires_in,
:adapter), with :room shared by the batch, :max_items
(100): a larger batch gives {:error, :too_many}, and
:secret, which signs each upload's token (required).
Checks the files a browser uploaded (Storehouse.verify_upload/2):
items are maps with "key" and "token" (those presign/2 gave)
and, optionally, "name". A key without its token (another's, a file
already stored) is refused with :invalid_token, and the file at it is
left as it is. Two files of the same
bytes in one batch are one: the second gives {:existing, first}, and
its copy is deleted.
Takes the options of Storehouse.verify_upload/2 (:accept,
:max_bytes, :max_pixels, :owner, :existing, :metadata,
:adapter), with :room shared by the batch (the sizes the store
gives), :max_items, and :secret, as for presign/2.