Repository navigation
fix(rpcclient): serve WebDAV Range requests to prevent large-file corruption - #449
Merged
Merged
Conversation
…ruption The WebDAV provider declared content_range=False and ignored the HTTP Range header, answering every GET with 200 and the entire file body. macOS Finder / webdavfs reads large files as a series of byte ranges; receiving the whole file in response to `Range: bytes=X-Y` makes the client write the full body at offset X, producing a corrupted file. Honor Range requests like asgi_webdav's own FileSystemProvider: advertise Accept-Ranges, return 206 Partial Content with a body generator that seeks to the requested offset and streams only the requested bytes (with 416 handling for a failed If-Range). Also widen File.seek to c_int64 so range offsets past 2 GiB are not truncated. Claude-Session: https://claude.ai/code/session_01X7BxNXzz1dJmtZngoj5kab
construct-typing 0.8.0 no longer re-exports the ParsedType TypeVar from the
top-level `construct`; it lives in construct-stubs/core.pyi. `from construct
import ParsedType` therefore fails pyright ("unknown import symbol"), turning
the type-check CI job red across all platforms. Import it from construct.core
instead. Type-checking only (guarded by TYPE_CHECKING); runtime is unaffected.
Claude-Session: https://claude.ai/code/session_01X7BxNXzz1dJmtZngoj5kab
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Copying large files over a mounted WebDAV volume produced corrupted files.
Root cause
RpcFsProvider(the bridge that serves a remote target's filesystem over WebDAV) declaredcontent_range=Falseand ignored the HTTPRangeheader, answering everyGETwith200 OKand the entire file body.macOS Finder /
webdavfsreads large files as a series of byte-range requests (Range: bytes=X-Y). When the server returns the whole file with status200instead of206+ the requested slice, the client writes the full body at offsetX— corrupting the result.Verified against a live
rpcserver_ios(vphone): aRange: bytes=1048576-1114111request returned status200with all 5 MiB of the file (body == full file), instead of the 64 KiB requested.Clean single-request transfers (e.g.
httpx.get) were always byte-correct, which is why the bug only showed up with real range-using clients on large files.Fix
Honor
Rangerequests, mirroring asgi_webdav's ownFileSystemProvider:feature = DAVProviderFeature(content_range=True, ...)soAccept-Ranges: bytesis advertised._do_getcomputes the response content-range and returns 206 Partial Content (with416handling for a failedIf-Range), falling back to200full-body when there's no range._body_generatorseeks to the range start and streams only the requested bytes.File.seekwidened toc_int64so range offsets past 2 GiB are not truncated.Verification
test_get_honors_range_request: assertsAccept-Ranges, a206with the exact requested bytes and correctContent-Range, and that reassembling sequential ranges reproduces the file byte-for-byte.tests/test_webdav.pysuite passes (23 passed) against a liverpcserver_ios.bytes=-N), and open-ended ranges (bytes=N-) all return206with correct bytes; fullGETstill returns200and matches.https://claude.ai/code/session_01X7BxNXzz1dJmtZngoj5kab