Skip to content

Commit 519f2a2

Browse files
committed
stop download if download speed is too slow
1 parent 069b1ed commit 519f2a2

File tree

1 file changed

+18
-2
lines changed

1 file changed

+18
-2
lines changed

download.go

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"net/http"
99
"os"
1010
"path/filepath"
11+
"time"
1112
)
1213

1314
type Download struct {
@@ -84,16 +85,22 @@ func (d *Download) Run(ctx context.Context) error {
8485
return err
8586
}
8687
}
88+
89+
ctx, cancel := context.WithCancel(ctx)
90+
defer cancel()
8791
rc, err := d.openRemote(ctx, d.state.Offset)
8892
if err != nil {
8993
return err
9094
}
9195
defer rc.Close()
9296

93-
// TODO fail download if download stream is stuck
97+
// Stop download if download speed is too slow.
98+
// Timer for cancelling the context will be reset after each successful read from stream.
99+
trw := &TimerResetWriter{timer: time.AfterFunc(defaultTimeout, cancel)}
100+
tr := io.TeeReader(rc, trw)
94101

95102
remaining := d.state.Size - d.state.Offset
96-
n, copyErr := io.CopyN(wc, rc, remaining)
103+
n, copyErr := io.CopyN(wc, tr, remaining)
97104

98105
err = wc.Close()
99106
if err != nil {
@@ -151,3 +158,12 @@ func (d *Download) openRemote(baseCtx context.Context, offset int64) (rc io.Read
151158
rc = resp.Body
152159
return
153160
}
161+
162+
type TimerResetWriter struct {
163+
timer *time.Timer
164+
}
165+
166+
func (w *TimerResetWriter) Write(p []byte) (int, error) {
167+
w.timer.Reset(defaultTimeout)
168+
return len(p), nil
169+
}

0 commit comments

Comments
 (0)