B8What the client asks
“Our staff photograph things on their phones.”
Rotated, ten megabytes each, with the GPS of a client site in the EXIF. Uploaded over a connection that drops.
What actually goes wrong
The naive version stores what arrives and serves it back at full size, so a list of fifty rows is half a gigabyte of thumbnails.
It also stores what the photograph knows: the orientation flag that makes a portrait picture sideways, and the coordinates of the house it was taken in.
What Grit does about it
- Images are resized, re-encoded, stripped of metadata and given a thumbnail on the way in. A 5.3 MB phone photo stores at about 147 KB including the thumbnail.
- The stored reference carries the dimensions, the type and the thumbnail URL, so a page can reserve space and a list can use the small version.
- A decompression bomb is refused from its header, before any pixels are allocated.
The commands
One field, the whole pipeline
grit generate resource Site --fields "name:string, photo:file, gallery:files"
No object store needed to start
STORAGE_DRIVER=local grit start
What it does not do
Resumable uploads over a dropping connection are the one part this does not solve for you: large files go direct to storage with a presigned URL, and the retry behaviour is the client’s.
