A token passed as `?token=` was accepted on every route, so it ended
up in the request log (and journald), browser history and Referer.
- drop `?token=` from _check_auth; API and download routes now take
only the cookie or an Authorization: Bearer header
- keep pre-authenticated links working: on the index route a valid
`?token=` is swapped for the cookie and redirected to a clean URL,
so the secret does not linger in the address bar
- redact `token=` from log output
- send Referrer-Policy: no-referrer, and mark the cookie Secure
Cyrillic names arrived as question marks and were stored that way.
Upload: BytesParser defaults to the compat32 policy, which wraps a
non-ASCII Content-Disposition in a Header with the unknown-8bit
charset, so get_filename() returned one replacement character per
UTF-8 byte and the mangled name was written to disk. Parse with
policy=HTTP, which decodes headers as UTF-8.
Download: send_header() encodes latin-1 strict, so a Cyrillic name
raised UnicodeEncodeError. Emit both Content-Disposition forms per
RFC 5987 — an ASCII fallback plus percent-encoded filename*.
Package the service for setup on a new machine:
- install.sh generates a token, writes share.config (mode 600, token
stored as a SHA-256 hash) and installs the systemd user unit from
share.service.template
- share.config is now gitignored, with share.config.example as the
tracked template — the config holds the secret and must not be in
the repo
- warn at startup when token is empty, since that means open access
- SETUP.md documents install, verification and security posture
- get_local_ip: use context manager to prevent socket leak
- _route_files: single stat() per file instead of two
- _safe_path helper: DRY path resolution for download/delete
- load_config: loop over vars(args) instead of 6 repetitive blocks
- Remove stale comment from index.html
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Server-side _file_type() now uses mimetypes for images/known text,
and falls back to null-byte check on first 8KB for everything else.
Client uses the "type" field from /files API instead of local extension sets.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>