fix(139): upload failed (#2950)

fix: The file size is exceeded and cannot be uploaded
fix: File name has special characters, signature fails
improve: optimize memory usage
Signed-off-by: aimuz <mr.imuz@gmail.com>

Signed-off-by: aimuz <mr.imuz@gmail.com>
This commit is contained in:
aimuz 2023-01-08 16:31:00 +08:00 committed by GitHub
parent 40ef233d24
commit 99a186d01b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 51 additions and 34 deletions

View File

@ -1,11 +1,9 @@
package _139 package _139
import ( import (
"bytes"
"context" "context"
"fmt" "fmt"
"io" "io"
"math"
"net/http" "net/http"
"strconv" "strconv"
@ -229,10 +227,10 @@ func (d *Yun139) Put(ctx context.Context, dstDir model.Obj, stream model.FileStr
"manualRename": 2, "manualRename": 2,
"operation": 0, "operation": 0,
"fileCount": 1, "fileCount": 1,
"totalSize": stream.GetSize(), "totalSize": 0, // 去除上传大小限制
"uploadContentList": []base.Json{{ "uploadContentList": []base.Json{{
"contentName": stream.GetName(), "contentName": stream.GetName(),
"contentSize": stream.GetSize(), "contentSize": 0, // 去除上传大小限制
// "digest": "5a3231986ce7a6b46e408612d385bafa" // "digest": "5a3231986ce7a6b46e408612d385bafa"
}}, }},
"parentCatalogID": dstDir.GetID(), "parentCatalogID": dstDir.GetID(),
@ -250,10 +248,10 @@ func (d *Yun139) Put(ctx context.Context, dstDir model.Obj, stream model.FileStr
"operation": 0, "operation": 0,
"path": "", "path": "",
"seqNo": "", "seqNo": "",
"totalSize": stream.GetSize(), "totalSize": 0,
"uploadContentList": []base.Json{{ "uploadContentList": []base.Json{{
"contentName": stream.GetName(), "contentName": stream.GetName(),
"contentSize": stream.GetSize(), "contentSize": 0,
// "digest": "5a3231986ce7a6b46e408612d385bafa" // "digest": "5a3231986ce7a6b46e408612d385bafa"
}}, }},
}) })
@ -265,51 +263,47 @@ func (d *Yun139) Put(ctx context.Context, dstDir model.Obj, stream model.FileStr
if err != nil { if err != nil {
return err return err
} }
// Progress
p := driver.NewProgress(stream.GetSize(), up)
var Default int64 = 104857600 var Default int64 = 104857600
part := int(math.Ceil(float64(stream.GetSize()) / float64(Default))) part := (stream.GetSize() + Default - 1) / Default
var start int64 = 0 for i := int64(0); i < part; i++ {
for i := 0; i < part; i++ {
if utils.IsCanceled(ctx) { if utils.IsCanceled(ctx) {
return ctx.Err() return ctx.Err()
} }
start := i * Default
byteSize := stream.GetSize() - start byteSize := stream.GetSize() - start
if byteSize > Default { if byteSize > Default {
byteSize = Default byteSize = Default
} }
byteData := make([]byte, byteSize)
_, err = io.ReadFull(stream, byteData) limitReader := io.LimitReader(stream, byteSize)
if err != nil { // Update Progress
return err r := io.TeeReader(limitReader, p)
} req, err := http.NewRequest("POST", resp.Data.UploadResult.RedirectionURL, r)
req, err := http.NewRequest("POST", resp.Data.UploadResult.RedirectionURL, bytes.NewBuffer(byteData))
if err != nil { if err != nil {
return err return err
} }
req = req.WithContext(ctx) req = req.WithContext(ctx)
headers := map[string]string{ req.Header.Set("Content-Type", "text/plain;name="+unicode(stream.GetName()))
"Accept": "*/*", req.Header.Set("contentSize", strconv.FormatInt(stream.GetSize(), 10))
"Content-Type": "text/plain;name=" + unicode(stream.GetName()), req.Header.Set("range", fmt.Sprintf("bytes=%d-%d", start, start+byteSize-1))
"contentSize": strconv.FormatInt(stream.GetSize(), 10), req.Header.Set("uploadtaskID", resp.Data.UploadResult.UploadTaskID)
"range": fmt.Sprintf("bytes=%d-%d", start, start+byteSize-1), req.Header.Set("rangeType", "0")
"content-length": strconv.FormatInt(byteSize, 10), req.ContentLength = byteSize
"uploadtaskID": resp.Data.UploadResult.UploadTaskID,
"rangeType": "0",
"Referer": "https://yun.139.com/",
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36 Edg/95.0.1020.44",
"x-SvcType": "1",
}
for k, v := range headers {
req.Header.Set(k, v)
}
res, err := base.HttpClient.Do(req) res, err := base.HttpClient.Do(req)
if err != nil { if err != nil {
return err return err
} }
log.Debugf("%+v", res) log.Debugf("%+v", res)
res.Body.Close() res.Body.Close()
start += byteSize
up(i * 100 / part)
} }
return nil return nil
} }

View File

@ -28,12 +28,15 @@ func (d *Yun139) isFamily() bool {
func encodeURIComponent(str string) string { func encodeURIComponent(str string) string {
r := url.QueryEscape(str) r := url.QueryEscape(str)
r = strings.Replace(r, "+", "%20", -1) r = strings.Replace(r, "+", "%20", -1)
r = strings.Replace(r, "%21", "!", -1)
r = strings.Replace(r, "%27", "'", -1)
r = strings.Replace(r, "%28", "(", -1)
r = strings.Replace(r, "%29", ")", -1)
r = strings.Replace(r, "%2A", "*", -1)
return r return r
} }
func calSign(body, ts, randStr string) string { func calSign(body, ts, randStr string) string {
body = strings.ReplaceAll(body, "\n", "")
body = strings.ReplaceAll(body, " ", "")
body = encodeURIComponent(body) body = encodeURIComponent(body)
strs := strings.Split(body, "") strs := strings.Split(body, "")
sort.Strings(strs) sort.Strings(strs)

View File

@ -105,3 +105,23 @@ type PutResult interface {
} }
type UpdateProgress func(percentage int) type UpdateProgress func(percentage int)
type Progress struct {
Total int64
Done int64
up UpdateProgress
}
func (p *Progress) Write(b []byte) (n int, err error) {
n = len(b)
p.Done += int64(n)
p.up(int(float64(p.Done) / float64(p.Total) * 100))
return
}
func NewProgress(total int64, up UpdateProgress) *Progress {
return &Progress{
Total: total,
up: up,
}
}