@@ -2,7 +2,6 @@ package req
22
33import (
44 "bytes"
5- "errors"
65 "github.com/imroc/req/v3/internal/util"
76 "io"
87 "io/ioutil"
@@ -80,66 +79,82 @@ func writeMultipartFormFile(w *multipart.Writer, file *FileUpload, r *Request) e
8079 if err != nil {
8180 return err
8281 }
82+
83+ if r .uploadCallback != nil {
84+ pw = & callbackWriter {
85+ Writer : pw ,
86+ lastTime : lastTime ,
87+ interval : r .uploadCallbackInterval ,
88+ totalSize : file .FileSize ,
89+ callback : func (written int64 ) {
90+ r .uploadCallback (UploadInfo {
91+ ParamName : file .ParamName ,
92+ FileName : file .FileName ,
93+ FileSize : file .FileSize ,
94+ UploadedSize : written ,
95+ })
96+ },
97+ }
98+ }
99+
83100 if _ , err = pw .Write (cbuf [:size ]); err != nil {
84101 return err
85102 }
86103 if seeEOF {
87104 return nil
88105 }
89- if r .uploadCallback == nil {
90- _ , err = io .Copy (pw , content )
91- return err
92- }
93106
94- uploadedBytes := int64 (size )
95- progressCallback := func () {
96- r .uploadCallback (UploadInfo {
97- ParamName : file .ParamName ,
98- FileName : file .FileName ,
99- FileSize : file .FileSize ,
100- UploadedSize : uploadedBytes ,
101- })
102- }
103- if now := time .Now (); now .Sub (lastTime ) >= r .uploadCallbackInterval {
104- lastTime = now
105- progressCallback ()
106- }
107- buf := make ([]byte , 1024 )
108- for {
109- callback := false
110- nr , er := content .Read (buf )
111- if nr > 0 {
112- nw , ew := pw .Write (buf [:nr ])
113- if nw < 0 || nr < nw {
114- nw = 0
115- if ew == nil {
116- ew = errors .New ("invalid write result" )
117- }
118- }
119- uploadedBytes += int64 (nw )
120- if ew != nil {
121- return ew
122- }
123- if nr != nw {
124- return io .ErrShortWrite
125- }
126- if now := time .Now (); now .Sub (lastTime ) >= r .uploadCallbackInterval {
127- lastTime = now
128- progressCallback ()
129- callback = true
130- }
131- }
132- if er != nil {
133- if er == io .EOF {
134- if ! callback {
135- progressCallback ()
136- }
137- break
138- } else {
139- return er
140- }
141- }
142- }
107+ _ , err = io .Copy (pw , content )
108+ return err
109+ // uploadedBytes := int64(size)
110+ // progressCallback := func() {
111+ // r.uploadCallback(UploadInfo{
112+ // ParamName: file.ParamName,
113+ // FileName: file.FileName,
114+ // FileSize: file.FileSize,
115+ // UploadedSize: uploadedBytes,
116+ // })
117+ // }
118+ // if now := time.Now(); now.Sub(lastTime) >= r.uploadCallbackInterval {
119+ // lastTime = now
120+ // progressCallback()
121+ // }
122+ // buf := make([]byte, 1024)
123+ // for {
124+ // callback := false
125+ // nr, er := content.Read(buf)
126+ // if nr > 0 {
127+ // nw, ew := pw.Write(buf[:nr])
128+ // if nw < 0 || nr < nw {
129+ // nw = 0
130+ // if ew == nil {
131+ // ew = errors.New("invalid write result")
132+ // }
133+ // }
134+ // uploadedBytes += int64(nw)
135+ // if ew != nil {
136+ // return ew
137+ // }
138+ // if nr != nw {
139+ // return io.ErrShortWrite
140+ // }
141+ // if now := time.Now(); now.Sub(lastTime) >= r.uploadCallbackInterval {
142+ // lastTime = now
143+ // progressCallback()
144+ // callback = true
145+ // }
146+ // }
147+ // if er != nil {
148+ // if er == io.EOF {
149+ // if !callback {
150+ // progressCallback()
151+ // }
152+ // break
153+ // } else {
154+ // return er
155+ // }
156+ // }
157+ // }
143158 return nil
144159}
145160
@@ -266,6 +281,60 @@ func parseResponseBody(c *Client, r *Response) (err error) {
266281 return
267282}
268283
284+ type callbackWriter struct {
285+ io.Writer
286+ written int64
287+ totalSize int64
288+ lastTime time.Time
289+ interval time.Duration
290+ callback func (written int64 )
291+ }
292+
293+ func (w * callbackWriter ) Write (p []byte ) (n int , err error ) {
294+ n , err = w .Writer .Write (p )
295+ if n <= 0 {
296+ return
297+ }
298+ w .written += int64 (n )
299+ if w .written == w .totalSize {
300+ w .callback (w .written )
301+ } else if now := time .Now (); now .Sub (w .lastTime ) >= w .interval {
302+ w .lastTime = now
303+ w .callback (w .written )
304+ }
305+ return
306+ }
307+
308+ type callbackReader struct {
309+ io.ReadCloser
310+ read int64
311+ lastRead int64
312+ callback func (read int64 )
313+ lastTime time.Time
314+ interval time.Duration
315+ }
316+
317+ func (r * callbackReader ) Read (p []byte ) (n int , err error ) {
318+ n , err = r .ReadCloser .Read (p )
319+ if n <= 0 {
320+ if err == io .EOF && r .read > r .lastRead {
321+ r .callback (r .read )
322+ r .lastRead = r .read
323+ }
324+ return
325+ }
326+ r .read += int64 (n )
327+ if err == io .EOF {
328+ r .callback (r .read )
329+ r .lastRead = r .read
330+ } else if now := time .Now (); now .Sub (r .lastTime ) >= r .interval {
331+ r .lastTime = now
332+ r .callback (r .read )
333+ r .lastRead = r .read
334+ }
335+ return
336+ }
337+
269338func handleDownload (c * Client , r * Response ) (err error ) {
270339 if ! r .Request .isSaveResponse {
271340 return nil
@@ -302,6 +371,21 @@ func handleDownload(c *Client, r *Response) (err error) {
302371 body .Close ()
303372 closeq (output )
304373 }()
374+
375+ // if r.Request.downloadCallback != nil {
376+ // output = &callbackWriter{
377+ // Writer: output,
378+ // lastTime: time.Now(),
379+ // interval: r.Request.downloadCallbackInterval,
380+ // callback: func(written int64) {
381+ // r.Request.downloadCallback(DownloadInfo{
382+ // Response: r,
383+ // DownloadedSize: written,
384+ // })
385+ // },
386+ // }
387+ // }
388+
305389 _ , err = io .Copy (output , body )
306390 r .setReceivedAt ()
307391 return
0 commit comments