Skip to content

Commit 317d190

Browse files
authored
fix(ftp): create a new connection for each download (#989)
1 parent 52d7d81 commit 317d190

File tree

2 files changed

+24
-55
lines changed

2 files changed

+24
-55
lines changed

drivers/ftp/driver.go

Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,9 @@ package ftp
22

33
import (
44
"context"
5+
"errors"
56
"io"
67
stdpath "path"
7-
"sync"
8-
"time"
98

109
"github.com/OpenListTeam/OpenList/v4/internal/driver"
1110
"github.com/OpenListTeam/OpenList/v4/internal/errs"
@@ -72,53 +71,52 @@ func (d *FTP) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]m
7271
return res, nil
7372
}
7473

75-
func (d *FTP) Link(_ context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) {
76-
ctx, cancel := context.WithCancel(context.Background())
74+
func (d *FTP) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) {
7775
conn, err := d._login(ctx)
7876
if err != nil {
79-
cancel()
8077
return nil, err
8178
}
82-
close := func() error {
83-
_ = conn.Quit()
84-
cancel()
85-
return nil
86-
}
8779

8880
path := encode(file.GetPath(), d.Encoding)
8981
size := file.GetSize()
90-
mu := &sync.Mutex{}
9182
resultRangeReader := func(context context.Context, httpRange http_range.Range) (io.ReadCloser, error) {
9283
length := httpRange.Length
9384
if length < 0 || httpRange.Start+length > size {
9485
length = size - httpRange.Start
9586
}
96-
mu.Lock()
97-
defer mu.Unlock()
98-
r, err := conn.RetrFrom(path, uint64(httpRange.Start))
99-
if err != nil {
100-
_ = conn.Quit()
101-
conn, err = d._login(ctx)
102-
if err == nil {
103-
r, err = conn.RetrFrom(path, uint64(httpRange.Start))
104-
}
87+
var c *ftp.ServerConn
88+
if ctx == context {
89+
c = conn
90+
} else {
91+
var err error
92+
c, err = d._login(context)
10593
if err != nil {
10694
return nil, err
10795
}
10896
}
109-
r.SetDeadline(time.Now().Add(time.Second))
110-
return &FileReader{
111-
Response: r,
112-
Reader: io.LimitReader(r, length),
113-
ctx: context,
97+
resp, err := c.RetrFrom(path, uint64(httpRange.Start))
98+
if err != nil {
99+
return nil, err
100+
}
101+
var close utils.CloseFunc
102+
if context == ctx {
103+
close = resp.Close
104+
} else {
105+
close = func() error {
106+
return errors.Join(resp.Close(), c.Quit())
107+
}
108+
}
109+
return utils.ReadCloser{
110+
Reader: io.LimitReader(resp, length),
111+
Closer: close,
114112
}, nil
115113
}
116114

117115
return &model.Link{
118116
RangeReader: &model.FileRangeReader{
119117
RangeReaderIF: stream.RateLimitRangeReaderFunc(resultRangeReader),
120118
},
121-
SyncClosers: utils.NewSyncClosers(utils.CloseFunc(close)),
119+
SyncClosers: utils.NewSyncClosers(utils.CloseFunc(conn.Quit)),
122120
}, nil
123121
}
124122

drivers/ftp/util.go

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,10 @@ package ftp
22

33
import (
44
"context"
5-
"errors"
65
"fmt"
7-
"io"
8-
"os"
96
"time"
107

118
"github.com/OpenListTeam/OpenList/v4/pkg/singleflight"
12-
"github.com/OpenListTeam/OpenList/v4/pkg/utils"
139
"github.com/jlaffaye/ftp"
1410
)
1511

@@ -45,28 +41,3 @@ func (d *FTP) _login(ctx context.Context) (*ftp.ServerConn, error) {
4541
}
4642
return conn, nil
4743
}
48-
49-
type FileReader struct {
50-
*ftp.Response
51-
io.Reader
52-
ctx context.Context
53-
}
54-
55-
func (r *FileReader) Read(buf []byte) (int, error) {
56-
n := 0
57-
for n < len(buf) {
58-
w, err := r.Reader.Read(buf[n:])
59-
if utils.IsCanceled(r.ctx) {
60-
return n, r.ctx.Err()
61-
}
62-
n += w
63-
if errors.Is(err, os.ErrDeadlineExceeded) {
64-
r.Response.SetDeadline(time.Now().Add(time.Second))
65-
continue
66-
}
67-
if err != nil || w == 0 {
68-
return n, err
69-
}
70-
}
71-
return n, nil
72-
}

0 commit comments

Comments
 (0)