Publishing with curl
The HTTP side writes one file per request. Reads are public; a write carries a short-lived token that the SSH login issues for the user whose GitHub key it verified.
Get a token
ssh -p 8022 alice@cdn.si token
The token is HMAC-SHA256 over the user, an expiry and a nonce. It is valid for
CDN_TOKEN_TTL, 15 minutes unless the instance sets another value, and it can
be used more than once before it expires.
Write one file
PUT /<user>/<path> replaces or creates the file. The token goes in
Authorization: Bearer.
TOKEN=$(ssh -p 8022 alice@cdn.si token)
curl -T coverage.html \
-H "Authorization: Bearer $TOKEN" \
https://cdn.si/alice/docs/coverage.html
curl -T sends a PUT. A stored file answers 201 Created.
The body is written to a temporary file in the target folder and renamed into place, so a reader never sees half a file.
Upload several files
POST /upload takes a multipart form: user, path, token and one or more
file parts. It answers 303 with the folder listing as Location, and the
listing says how many files arrived.
curl -F user=alice \
-F path=docs \
-F token="$TOKEN" \
-F file=@README.md \
-F file=@docs/usage-curl.md \
https://cdn.si/upload
Answers
| Status | Meaning |
|---|---|
201 |
the PUT stored the file |
303 |
the multipart upload stored the files |
400 |
the user, the path or a file name is not valid |
401 |
the token is missing, expired or belongs to another user |
413 |
the write would exceed the 50 MiB quota, or the body is too large |
409 |
a directory already exists where the file would go |
A write is checked against the quota before anything is renamed into place, so a refused write leaves the tree as it was.
A .md file is rendered as an HTML page at the address it was uploaded to,
so https://cdn.si/alice/docs/README.md serves the document and not its source.
Other files read by type: an image is drawn, text arrives as text/plain, and
a binary is downloaded. An .html file is text, never a page.
Publishing with rsync covers a whole folder.