Fix non-range download bug: downloaded bytes exceeding total file size

When HTTP server doesn't return Content-Length or doesn't support Range
requests, the download can accumulate extra bytes on pause/resume because:
1. Each retry/resume re-downloads from the beginning but writes at the
   accumulated offset
2. No size limit enforcement for non-range downloads
3. onDownloadComplete incorrectly uses chunk.remain() for non-range
   downloads, which gives negative values for chunk(0,0)

Fixes:
- Reset chunk state in downloadChunkOnce and runConnectionFallback for
  non-range downloads since server will send from beginning
- Add size limit checks in download loops when Size is known
- Fix onDownloadComplete to use conn.Completed for non-range downloads
  instead of unreliable chunk.remain()
- Add test cases for non-range download, pause/resume, and size limit

Co-authored-by: monkeyWie <[email protected]>
This commit is contained in:
copilot-swe-agent[bot]andmonkeyWie committed 2026-03-11 02:50:48 +00:00
1 parent 27c0f81a1e
commit 2daa9c45df
3 files changed
+197 -9

No files matched your search

+19
View File
@@ -636,6 +636,25 @@ func StartTestRangeBugServer() net.Listener {
})
}
// StartTestNoRangeServer starts a server that returns Content-Length but does NOT support Range requests.
// This simulates servers where file size is known but range downloads are not supported.
func StartTestNoRangeServer() net.Listener {
return startTestServer(func(sl *shutdownListener) http.Handler {
mux := http.NewServeMux()
mux.HandleFunc("/"+BuildName, func(writer http.ResponseWriter, request *http.Request) {
file, err := os.Open(BuildFile)
if err != nil {
panic(err)
}
defer file.Close()
writer.Header().Set("Content-Length", fmt.Sprintf("%d", BuildSize))
writer.WriteHeader(200)
io.Copy(writer, file)
})
return mux
})
}
func rangeFileHandle(writer http.ResponseWriter, request *http.Request, modifyEnd func(end int64) int64, iocpN func(file *os.File, n int64)) {
r := request.Header.Get("Range")