Skip to content

fix: concurrent range requests return 500 (multi-threaded resume download broken)#13

Merged
scanfing merged 4 commits intomainfrom
copilot/check-multiple-concurrent-resume-logic
Apr 28, 2026
Merged

fix: concurrent range requests return 500 (multi-threaded resume download broken)#13
scanfing merged 4 commits intomainfrom
copilot/check-multiple-concurrent-resume-logic

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 28, 2026

Thunder (迅雷) and other multi-threaded download managers send concurrent Range requests per file. All but the first would return 500, because the file was opened with FileShare.None (the implicit default for the 3-arg FileStream constructor), causing every parallel reader after the first to throw IOException.

Root causes fixed

  • FileShare.NoneFileShare.Read in GetResponseContentTypeAndStream — the primary cause of 500s on concurrent range requests
    // before: FileShare.None by default, locks out all concurrent readers
    stream = new FileStream(path, FileMode.Open, FileAccess.Read);
    // after
    stream = new FileStream(safePath, FileMode.Open, FileAccess.Read, FileShare.Read);
  • FileAccessHelper.LimitCount 2 → 32 — a limit of 2 concurrent file handles meant Thunder's 8+ worker threads were indefinitely queued; connections would time out before being admitted
  • Missing Content-Length on 206 responsesresponse.ContentLength64 = bytesNeeds was never set in ResponseContentPartial, leaving clients unable to know how many bytes to expect per chunk
  • Missing Accept-Ranges: bytes header — server never advertised range support; added to both full and partial content responses

Security fix (incidental)

Path traversal was possible since URL-derived paths were passed directly to FileStream without containment validation. GetResponseContentTypeAndStream now normalizes via Path.GetFullPath and verifies the resolved path stays within SourceDir before any file I/O. Path.GetFullPath calls are wrapped in try-catch to handle malformed paths gracefully.

@scanfing scanfing marked this pull request as ready for review April 28, 2026 09:43
@scanfing scanfing merged commit 47c47ed into main Apr 28, 2026
@scanfing scanfing deleted the copilot/check-multiple-concurrent-resume-logic branch April 28, 2026 09:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants