You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Filed as the download-side counterpart to #136. The earlier triage on #136 assumed Rocket's FileServer already supports HTTP Range, so no server change was needed. That assumption is wrong for Rocket 0.5.
What is wrong
/filedownload is mounted via Rocket's FileServer::from(config.data_dir()) (src/main.rs:1015). Under the hood:
FileServer resolves the path and returns a NamedFile.
NamedFile::respond_to defers to tokio::fs::File's responder.
That responder is Response::build().sized_body(None, self).ok() — a plain 200 OK with Content-Length, no Accept-Ranges, and no handling of an inbound Range request header.
Browsers send Range: bytes=...- to resume an interrupted download. Cryptify ignores it and returns the full body with 200.
Modern browsers detect the missing Accept-Ranges: bytes and disable the resume button on a failed download. A flaky link on a multi-GB recipient download means the user restarts from byte 0.
Custom range-aware handler. Replace the FileServer mount with a route that opens the file, parses Range, and streams a 206 with Content-Range. A small amount of code; no extra dependency if we want to keep the responder narrow.
rocket-seek-stream or equivalent crate. Off-the-shelf Range-aware responder.
Reverse-proxy offload. Put nginx/Caddy in front and let it serve /filedownload directly with native Range support. Operationally simple but assumes the deployment topology — postguard-ops currently exposes cryptify directly per the helm chart.
Option 1 is small and keeps cryptify self-contained, which matches the rest of the codebase.
Out of scope
Client-side download UX (progress bar / resume button surfacing) — tracked on the website side: postguard-website#138.
Range support for files served while still uploading. The current download flow only serves finalized files, so no interaction.
Suggested next step
Confirm the symptom with a real download (curl with -H 'Range: bytes=100-' against a finalized file — expect 200 + full body, not 206). If confirmed, scope to design #1.
Filed as the download-side counterpart to #136. The earlier triage on #136 assumed Rocket's
FileServeralready supports HTTP Range, so no server change was needed. That assumption is wrong for Rocket 0.5.What is wrong
/filedownloadis mounted via Rocket'sFileServer::from(config.data_dir())(src/main.rs:1015). Under the hood:FileServerresolves the path and returns aNamedFile.NamedFile::respond_todefers totokio::fs::File's responder.Response::build().sized_body(None, self).ok()— a plain200 OKwithContent-Length, noAccept-Ranges, and no handling of an inboundRangerequest header.Source: rocket-0.5.1 named_file.rs and
response/responder.rs:455.Consequence
Range: bytes=...-to resume an interrupted download. Cryptify ignores it and returns the full body with200.Accept-Ranges: bytesand disable the resume button on a failed download. A flaky link on a multi-GB recipient download means the user restarts from byte 0.Possible designs
FileServermount with a route that opens the file, parsesRange, and streams a 206 withContent-Range. A small amount of code; no extra dependency if we want to keep the responder narrow.rocket-seek-streamor equivalent crate. Off-the-shelf Range-aware responder./filedownloaddirectly with native Range support. Operationally simple but assumes the deployment topology — postguard-ops currently exposes cryptify directly per the helm chart.Option 1 is small and keeps cryptify self-contained, which matches the rest of the codebase.
Out of scope
Suggested next step
Confirm the symptom with a real download (curl with
-H 'Range: bytes=100-'against a finalized file — expect200+ full body, not206). If confirmed, scope to design #1.