Software Engineering
Resumable Downloads: Verify Ranges and File Identity
Test HTTP download resume with byte ranges, validators, content-range checks, changed files, compression behavior, and safe handling of full responses.
In this article
A resumed download is correct only if the new bytes belong to the same representation as the bytes already saved. Supporting a Range header is not enough. The client must interpret the response status, validate the selected range, and avoid appending a complete or changed file to an old partial copy.
The MDN range-request guide explains partial responses and validators. Use those semantics alongside the actual storage and CDN behavior. This workflow concerns authorized downloads, not bypassing access limits or retrieving data outside the viewer's permission.
Retain a partial-download record
Store the source identity, number of verified bytes saved, and relevant representation validator through the download client's supported mechanism. A filename alone is not a stable identity: a server can replace the content at the same URL.
Keep the file private until it is complete and validated. Another application should not treat an unfinished archive or installer as ready merely because the final extension is present. Use the application's supported temporary-file and completion conventions.
Do not retain credentials in a broadly readable sidecar. A signed URL can expire while the partial bytes remain useful. The retry process should obtain authorized access through the normal workflow rather than copying a secret URL into logs or tickets.
Inspect the server's real behavior
Use a small synthetic file whose contents and size are known. Request a bounded byte range and inspect the actual status and Content-Range information. A server advertising range support should still be tested through the delivery path used by clients.
A partial response normally uses 206 under the applicable semantics. A server can also ignore a range and return a complete response. The client must handle that distinction rather than unconditionally appending whatever bytes arrive.
For an invented ten-byte ASCII fixture abcdefghij, a request for bytes 4 through 7 asks for efgh. The example makes inclusive byte positions visible. It is not a production download command or a promise that character positions equal byte positions in arbitrary text encodings.
Bind the continuation to file identity
Review conditional range behavior, including an appropriate If-Range validator where supported. If the representation changed, the client should not splice the new tail onto the old head. Restart or follow the client's documented recovery path.
Test this deliberately in an owned staging environment: download an initial part, replace the fixture with different known bytes, and attempt to resume. Confirm that the final saved result is one complete valid representation, not a hybrid.
Keep weak and strong validator semantics distinct when selecting the mechanism. Do not assume that a timestamp with coarse precision uniquely identifies every revision. Use the exact HTTP and provider requirements for the supported validator.
Handle complete and unsatisfiable responses
When the server returns a complete response, the client should replace or restart according to its safe download logic, not append the entire body after the existing prefix. Test the outcome with a fixture so a doubled file is caught immediately.
For an unsatisfiable range, inspect the returned status and size information where available. The partial file might already be complete, the resource might have changed, or the local offset might be wrong. Do not interpret every 416 as proof of a finished successful download.
Test zero-byte resources, a range ending beyond the resource, and a resume offset at the end where the client's supported behavior makes these cases relevant. Expected outcomes should be explicit before testing rather than invented after a surprising response.
Keep representation transformations visible
Compression and intermediary transformations can complicate assumptions about byte offsets and saved bytes. Verify which representation is ranged and whether the client transparently decodes it. Use the actual client's documented behavior instead of combining manual offsets with an unrelated decoding layer.
Check CDN caching, object revision, and content-encoding settings together. A direct storage request and a public CDN request may not follow the same path. Retain headers and fixture results sufficient to explain the difference without exposing authorization data.
Our cache validator guide covers freshness and conditional retrieval more broadly. Resume testing needs the additional guarantee that the assembled byte sequence belongs to the intended complete representation.
Verify the completed artifact
Check the final byte count and the publisher's supported integrity mechanism where one exists. A completed network transfer is not proof that the file is the expected software release or safe to execute. Keep identity, integrity, authenticity, and authorization distinct.
Include interruption, retry, expired access, and changed-object cases in client regression tests. Test a supported cancellation path so users do not lose a valid existing file when stopping a retry. Preserve unrelated files during cleanup.
Text Diff can compare redacted header captures and test notes. It is not a binary range validator or download client. Use actual byte comparisons and the relevant provider tools for the downloaded artifact.
Conclusion
Reliable resume combines correct range interpretation with representation identity and final artifact checks. Test complete responses, changed files, and unsatisfiable ranges before trusting the happy path. The result must be one valid file, not merely the expected number of network requests.