@@ -2,10 +2,9 @@ package ftp
2
2
3
3
import (
4
4
"context"
5
+ "errors"
5
6
"io"
6
7
stdpath "path"
7
- "sync"
8
- "time"
9
8
10
9
"github.com/OpenListTeam/OpenList/v4/internal/driver"
11
10
"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
72
71
return res , nil
73
72
}
74
73
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 ) {
77
75
conn , err := d ._login (ctx )
78
76
if err != nil {
79
- cancel ()
80
77
return nil , err
81
78
}
82
- close := func () error {
83
- _ = conn .Quit ()
84
- cancel ()
85
- return nil
86
- }
87
79
88
80
path := encode (file .GetPath (), d .Encoding )
89
81
size := file .GetSize ()
90
- mu := & sync.Mutex {}
91
82
resultRangeReader := func (context context.Context , httpRange http_range.Range ) (io.ReadCloser , error ) {
92
83
length := httpRange .Length
93
84
if length < 0 || httpRange .Start + length > size {
94
85
length = size - httpRange .Start
95
86
}
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 )
105
93
if err != nil {
106
94
return nil , err
107
95
}
108
96
}
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 ,
114
112
}, nil
115
113
}
116
114
117
115
return & model.Link {
118
116
RangeReader : & model.FileRangeReader {
119
117
RangeReaderIF : stream .RateLimitRangeReaderFunc (resultRangeReader ),
120
118
},
121
- SyncClosers : utils .NewSyncClosers (utils .CloseFunc (close )),
119
+ SyncClosers : utils .NewSyncClosers (utils .CloseFunc (conn . Quit )),
122
120
}, nil
123
121
}
124
122
0 commit comments