77 "fmt"
88 "io"
99 "io/fs"
10- "io/ioutil"
1110 "net"
1211 "net/http"
1312 "os"
@@ -79,7 +78,7 @@ type GetRequestConfig struct {
7978 Headers map [string ]string
8079}
8180
82- type ProxyReader func (size , offset int64 , r io.Reader ) io.Reader
81+ type ProxyReader func (offset int64 , r io.Reader ) io.Reader
8382
8483// PutObjectConfig provides a configuration to Put method.
8584type PutObjectConfig struct {
@@ -281,17 +280,18 @@ func getPartInfo(partSize, fsize int64) (int64, int64, error) {
281280 return partSize , partNum , nil
282281}
283282
284- func (up * UpYun ) getMultipartUploadProcess (config * PutObjectConfig , fsize int64 ) (* ResumeProcessResult , error ) {
283+ func (up * UpYun ) getMultipartUploadProcess (config * PutObjectConfig , fileinfo os. FileInfo ) (* ResumeProcessResult , error ) {
285284 resumeProcessResult , _ := up .GetResumeProcess (config .Path )
286- if resumeProcessResult != nil {
287- if resumeProcessResult .Order {
285+ if resumeProcessResult != nil && resumeProcessResult .Order {
286+ if fileinfo .Size () == resumeProcessResult .Size && fileinfo .ModTime ().Unix () <= resumeProcessResult .CreateTime .Unix () {
287+ // fmt.Printf("continue process: %s next: %d\n", config.Path, resumeProcessResult.NextPartID)
288288 return resumeProcessResult , nil
289289 }
290290 }
291291
292292 initMultipartUploadConfig := & InitMultipartUploadConfig {
293293 Path : config .Path ,
294- ContentLength : fsize ,
294+ ContentLength : fileinfo . Size () ,
295295 PartSize : config .ResumePartSize ,
296296 ContentType : config .Headers ["Content-Type" ],
297297 OrderUpload : true ,
@@ -341,7 +341,7 @@ func (up *UpYun) resumePut(config *PutObjectConfig) error {
341341 maxPartID := int ((fsize + config .ResumePartSize - 1 )/ config .ResumePartSize - 1 )
342342
343343 if breakpoint == nil || isRecordExpired (fileinfo , breakpoint ) {
344- uploadProcess , err := up .getMultipartUploadProcess (config , fsize )
344+ uploadProcess , err := up .getMultipartUploadProcess (config , fileinfo )
345345 if err != nil {
346346 return err
347347 }
@@ -532,7 +532,7 @@ func (up *UpYun) ListMultipartUploads(config *ListMultipartConfig) (*ListMultipa
532532 return nil , errorOperation ("list multipart" , err )
533533 }
534534
535- body , err := ioutil .ReadAll (res .Body )
535+ body , err := io .ReadAll (res .Body )
536536 if err != nil {
537537 return nil , errorOperation ("list multipart read body" , err )
538538 }
@@ -563,7 +563,7 @@ func (up *UpYun) ListMultipartParts(intiResult *InitMultipartUploadResult, confi
563563 return nil , errorOperation ("list multipart parts" , err )
564564 }
565565
566- body , err := ioutil .ReadAll (res .Body )
566+ body , err := io .ReadAll (res .Body )
567567 if err != nil {
568568 return nil , errorOperation ("list multipart parts read body" , err )
569569 }
@@ -688,7 +688,7 @@ func (up *UpYun) List(config *GetObjectsConfig) error {
688688 return errorOperation ("list" , err )
689689 }
690690
691- b , err := ioutil .ReadAll (resp .Body )
691+ b , err := io .ReadAll (resp .Body )
692692 resp .Body .Close ()
693693 if err != nil {
694694 return errorOperation ("list read body" , err )
@@ -796,7 +796,7 @@ func (up *UpYun) ListObjects(config *ListObjectsConfig) (fileInfos []*FileInfo,
796796 }
797797
798798 // 读取列表
799- b , err := ioutil .ReadAll (resp .Body )
799+ b , err := io .ReadAll (resp .Body )
800800 resp .Body .Close ()
801801 if err != nil {
802802 return nil , "" , errorOperation ("list read body" , err )
@@ -898,7 +898,7 @@ func (up *UpYun) doRESTRequest(config *restReqConfig) (*http.Response, error) {
898898 }
899899
900900 if config .closeBody {
901- io .Copy (ioutil .Discard , resp .Body )
901+ io .Copy (io .Discard , resp .Body )
902902 resp .Body .Close ()
903903 }
904904
@@ -914,16 +914,19 @@ type BreakPointConfig struct {
914914 LastTime time.Time
915915}
916916
917- func (up * UpYun ) resumeUploadPart (config * PutObjectConfig , breakpoint * BreakPointConfig , f io.Reader , fileInfo fs.FileInfo ) (* BreakPointConfig , error ) {
917+ func (up * UpYun ) resumeUploadPart (config * PutObjectConfig , breakpoint * BreakPointConfig , f io.ReadSeeker , fileInfo fs.FileInfo ) (* BreakPointConfig , error ) {
918918 fsize := fileInfo .Size ()
919919 partID := breakpoint .PartID
920920 curSize , partSize := int64 (partID )* breakpoint .PartSize , breakpoint .PartSize
921921 bytesLeft := fsize - curSize
922922 ch := make (chan * Chunk , 1 )
923923 var err error
924+ if curSize > 0 {
925+ f .Seek (curSize , 0 )
926+ }
924927 var reader io.Reader
925928 if config .ProxyReader != nil {
926- reader = config .ProxyReader (fsize , curSize , f )
929+ reader = config .ProxyReader (curSize , f )
927930 } else {
928931 reader = f
929932 }
@@ -974,17 +977,19 @@ type ResumeDisorderResult struct {
974977}
975978
976979type ResumeProcessResult struct {
980+ CreateTime time.Time
977981 UploadID string
978982 Path string
979983 Order bool
984+ Size int64
980985 NextPartSize int64
981986 NextPartID int64
982987 Parts []* DisorderPart
983988}
984989
985990func (up * UpYun ) GetResumeProcess (path string ) (* ResumeProcessResult , error ) {
986- var partID int64
987- var partSize int64
991+ var partID , partSize , size int64
992+ var createTime time. Time
988993
989994 headers := make (map [string ]string )
990995 headers ["X-Upyun-Multi-Info" ] = "true"
@@ -1002,7 +1007,9 @@ func (up *UpYun) GetResumeProcess(path string) (*ResumeProcessResult, error) {
10021007 partSizeStr := resp .Header .Get ("X-Upyun-Next-Part-Size" )
10031008 partIDStr := resp .Header .Get ("X-Upyun-Next-Part-Id" )
10041009 uploadID := resp .Header .Get ("X-Upyun-Multi-Uuid" )
1010+ sizeStr := resp .Header .Get ("X-Upyun-Multi-Length" )
10051011 order := resp .Header .Get ("X-Upyun-Meta-Order" )
1012+ createStr := resp .Header .Get ("X-Upyun-Created-Date" )
10061013 o := true
10071014 if order == "false" {
10081015 o = false
@@ -1020,6 +1027,20 @@ func (up *UpYun) GetResumeProcess(path string) (*ResumeProcessResult, error) {
10201027 return nil , errorOperation (fmt .Sprintf ("GetResumeProcess parse partIDStr %s" , partIDStr ), err )
10211028 }
10221029 }
1030+
1031+ if sizeStr != "" {
1032+ size , err = strconv .ParseInt (sizeStr , 10 , 64 )
1033+ if err != nil {
1034+ return nil , errorOperation (fmt .Sprintf ("GetResumeProcess parse size %s" , sizeStr ), err )
1035+ }
1036+ }
1037+ if createStr != "" {
1038+ createTime , err = time .Parse (time .RFC1123 , createStr )
1039+ if err != nil {
1040+ return nil , errorOperation (fmt .Sprintf ("GetResumeProcess parse time %s" , createStr ), err )
1041+ }
1042+ }
1043+
10231044 var disorderRes ResumeDisorderResult
10241045
10251046 b , err := io .ReadAll (resp .Body )
@@ -1038,6 +1059,8 @@ func (up *UpYun) GetResumeProcess(path string) (*ResumeProcessResult, error) {
10381059 NextPartID : partID ,
10391060 Path : path ,
10401061 Order : o ,
1062+ Size : size ,
1063+ CreateTime : createTime ,
10411064 Parts : disorderRes .Parts ,
10421065 }, nil
10431066}
0 commit comments