mirror of
https://github.com/GopeedLab/gopeed.git
synced 2026-11-13 11:53:41 +00:00
fix: non-range HTTP downloaded bytes exceeding total file size (#1317)
This commit is contained in:
8 files changed
+124
-8
No files matched your search
@@ -618,6 +618,7 @@ func (f *Fetcher) doStart() error {
|
||||
for _, conn := range f.connections {
|
||||
// Reset connections that can be retried
|
||||
if !conn.Completed && conn.State != connCompleted {
|
||||
f.resetConnectionForRestart(conn)
|
||||
conn.State = connNotStarted
|
||||
conn.failed = false
|
||||
conn.retryTimes = 0
|
||||
@@ -1413,6 +1414,27 @@ func (f *Fetcher) helpOtherConnection(helper *connection) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (f *Fetcher) resetConnectionForRestart(conn *connection) {
|
||||
if f.meta.Res.Range {
|
||||
return
|
||||
}
|
||||
|
||||
// Without range support a new request always starts from byte 0,
|
||||
// so pause/retry must restart instead of continuing from the old offset.
|
||||
if conn.Chunk == nil {
|
||||
conn.Chunk = newChunk(0, 0)
|
||||
} else {
|
||||
conn.Chunk.Begin = 0
|
||||
conn.Chunk.End = 0
|
||||
conn.Chunk.Downloaded = 0
|
||||
}
|
||||
conn.Downloaded = 0
|
||||
conn.Completed = false
|
||||
conn.speed = 0
|
||||
conn.lastSpeedCheck = 0
|
||||
conn.lastSpeedDownload = 0
|
||||
}
|
||||
|
||||
func (f *Fetcher) resumeConnections() {
|
||||
// Collect connections to resume while holding the lock
|
||||
var toResume []*connection
|
||||
@@ -1436,6 +1458,7 @@ func (f *Fetcher) resumeConnections() {
|
||||
continue
|
||||
}
|
||||
}
|
||||
f.resetConnectionForRestart(conn)
|
||||
// Reset the connection state for resume
|
||||
conn.ctx, conn.cancel = context.WithCancel(f.ctx)
|
||||
conn.State = connNotStarted
|
||||
@@ -1475,7 +1498,16 @@ func (f *Fetcher) onDownloadComplete() {
|
||||
// Check if all chunks are complete (no remaining bytes)
|
||||
allChunksComplete := true
|
||||
for _, conn := range f.connections {
|
||||
if conn.Chunk != nil && conn.Chunk.remain() > 0 && !conn.Completed && conn.State != connCompleted {
|
||||
needsMoreData := false
|
||||
if f.meta.Res.Range {
|
||||
needsMoreData = conn.Chunk != nil && conn.Chunk.remain() > 0
|
||||
} else if f.meta.Res.Size > 0 {
|
||||
needsMoreData = conn.Downloaded < f.meta.Res.Size
|
||||
} else {
|
||||
needsMoreData = !conn.Completed && conn.State != connCompleted
|
||||
}
|
||||
|
||||
if needsMoreData && !conn.Completed && conn.State != connCompleted {
|
||||
// This connection has remaining work and isn't done
|
||||
// Check if it failed with 403 (server limit) - these can be ignored if other connections completed the work
|
||||
if conn.State == connFailed && conn.failed {
|
||||
|
||||
Reference in new issue
Block a user