🎇 189cloud upload

pull/548/head
微凉 2022-01-08 19:31:12 +08:00
parent 86ff80885d
commit 3e7e9f354f
2 changed files with 116 additions and 85 deletions

View File

@ -1,6 +1,7 @@
package _89 package _89
import ( import (
"bytes"
"crypto/aes" "crypto/aes"
"crypto/hmac" "crypto/hmac"
"crypto/md5" "crypto/md5"
@ -18,9 +19,13 @@ import (
"github.com/Xhofe/alist/model" "github.com/Xhofe/alist/model"
"github.com/Xhofe/alist/utils" "github.com/Xhofe/alist/utils"
"github.com/go-resty/resty/v2" "github.com/go-resty/resty/v2"
"github.com/google/uuid"
jsoniter "github.com/json-iterator/go" jsoniter "github.com/json-iterator/go"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"io"
"math"
mathRand "math/rand" mathRand "math/rand"
"net/http"
"net/url" "net/url"
"path/filepath" "path/filepath"
"regexp" "regexp"
@ -342,13 +347,13 @@ func (driver Cloud189) UploadRequest(url string, form map[string]string, account
if err != nil { if err != nil {
return nil, err return nil, err
} }
xRId := "e007e99a-370c-4a14-a143-1b1541972fcf" xRId := uuid.New().String()
pkey := strings.ReplaceAll(xRId, "-", "") pkey := strings.ReplaceAll(xRId, "-", "")[:mathRand.Intn(16)+16]
params := aesEncrypt(qs(form), pkey[:16]) params := aesEncrypt(qs(form), pkey[:16])
date := strconv.FormatInt(time.Now().Unix(), 10) date := strconv.FormatInt(time.Now().Unix(), 10)
signature := hmacSha1(fmt.Sprintf("SessionKey=%s&Operate=GET&RequestURI=%s&Date=%s&params=%s", sessionKey, url, date, params), pkey) signature := hmacSha1(fmt.Sprintf("SessionKey=%s&Operate=GET&RequestURI=%s&Date=%s&params=%s", sessionKey, url, date, params), pkey)
encryptionText := RsaEncode([]byte(pkey), pubKey) encryptionText := RsaEncode([]byte(pkey), pubKey)
res, err := base.RestyClient.R().SetHeaders(map[string]string{ headers := map[string]string{
"signature": signature, "signature": signature,
"sessionKey": sessionKey, "sessionKey": sessionKey,
"encryptionText": encryptionText, "encryptionText": encryptionText,
@ -357,7 +362,9 @@ func (driver Cloud189) UploadRequest(url string, form map[string]string, account
"x-request-date": date, "x-request-date": date,
"origin": "https://cloud.189.cn", "origin": "https://cloud.189.cn",
"referer": "https://cloud.189.cn/", "referer": "https://cloud.189.cn/",
}).SetQueryParam("params", params).Get("https://upload.cloud.189.cn" + url) }
log.Debugf("%+v\n%s", headers, params)
res, err := base.RestyClient.R().SetHeaders(headers).SetQueryParam("params", params).Get("https://upload.cloud.189.cn" + url)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -369,6 +376,84 @@ func (driver Cloud189) UploadRequest(url string, form map[string]string, account
return data, nil return data, nil
} }
// Upload Error: decrypt encryptionText failed
func (driver Cloud189) NewUpload(file *model.FileStream, account *model.Account) error {
const DEFAULT uint64 = 10485760
var count = int64(math.Ceil(float64(file.GetSize()) / float64(DEFAULT)))
var finish uint64 = 0
parentFile, err := driver.File(file.ParentPath, account)
if err != nil {
return err
}
if !parentFile.IsDir() {
return base.ErrNotFolder
}
res, err := driver.UploadRequest("/person/initMultiUpload", map[string]string{
"parentFolderId": parentFile.Id,
"fileName": file.Name,
"fileSize": strconv.FormatInt(int64(file.Size), 10),
"sliceSize": strconv.FormatInt(int64(DEFAULT), 10),
"lazyCheck": "1",
}, account)
if err != nil {
return err
}
uploadFileId := jsoniter.Get(res, "data.uploadFileId").ToString()
var i int64
var byteSize uint64
md5s := make([]string, 0)
md5Sum := md5.New()
for i = 1; i <= count; i++ {
byteSize = file.GetSize() - finish
if DEFAULT < byteSize {
byteSize = DEFAULT
}
log.Debugf("%d,%d", byteSize, finish)
byteData := make([]byte, byteSize)
n, err := io.ReadFull(file, byteData)
log.Debug(err, n)
if err != nil {
return err
}
finish += uint64(n)
md5Bytes := getMd5(byteData)
md5Str := hex.EncodeToString(md5Bytes)
md5Base64 := base64.StdEncoding.EncodeToString(md5Bytes)
md5s = append(md5s, md5Str)
md5Sum.Write(byteData)
res, err = driver.UploadRequest("/person/getMultiUploadUrls", map[string]string{
"partInfo": fmt.Sprintf("%s-%s", strconv.FormatInt(i, 10), md5Base64),
"uploadFileId": uploadFileId,
}, account)
if err != nil {
return err
}
uploadData := jsoniter.Get(res, "uploadUrls.partNumber_"+strconv.FormatInt(i, 10))
headers := strings.Split(uploadData.Get("requestHeader").ToString(), "&")
req, err := http.NewRequest("PUT", uploadData.Get("requestURL").ToString(), bytes.NewBuffer(byteData))
if err != nil {
return err
}
for _, header := range headers {
kv := strings.Split(header, "=")
req.Header.Set(kv[0], strings.Join(kv[1:], "="))
}
res, err := base.HttpClient.Do(req)
if err != nil {
return err
}
log.Debugf("%+v", res)
}
id := md5Sum.Sum(nil)
res, err = driver.UploadRequest("/person/commitMultiUploadFile", map[string]string{
"uploadFileId": uploadFileId,
"fileMd5": hex.EncodeToString(id),
"sliceMd5": utils.GetMD5Encode(strings.Join(md5s, "\n")),
"lazyCheck": "1",
}, account)
return err
}
func random() string { func random() string {
return fmt.Sprintf("0.%17v", mathRand.New(mathRand.NewSource(time.Now().UnixNano())).Int63n(100000000000000000)) return fmt.Sprintf("0.%17v", mathRand.New(mathRand.NewSource(time.Now().UnixNano())).Int63n(100000000000000000))
} }

View File

@ -1,10 +1,7 @@
package _89 package _89
import ( import (
"bytes" "errors"
"crypto/md5"
"encoding/base64"
"encoding/hex"
"fmt" "fmt"
"github.com/Xhofe/alist/conf" "github.com/Xhofe/alist/conf"
"github.com/Xhofe/alist/drivers/base" "github.com/Xhofe/alist/drivers/base"
@ -13,12 +10,7 @@ import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
jsoniter "github.com/json-iterator/go" jsoniter "github.com/json-iterator/go"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"io"
"math"
"net/http"
"path/filepath" "path/filepath"
"strconv"
"strings"
) )
type Cloud189 struct{} type Cloud189 struct{}
@ -89,12 +81,15 @@ func (driver Cloud189) Save(account *model.Account, old *model.Account) error {
_ = model.SaveAccount(account) _ = model.SaveAccount(account)
return err return err
} }
account.Status = "work" sessionKey, err := driver.GetSessionKey(account)
err := model.SaveAccount(account)
if err != nil { if err != nil {
return err account.Status = err.Error()
} else {
account.Status = "work"
account.DriveId = sessionKey
} }
return nil _ = model.SaveAccount(account)
return err
} }
func (driver Cloud189) File(path string, account *model.Account) (*model.File, error) { func (driver Cloud189) File(path string, account *model.Account) (*model.File, error) {
@ -346,83 +341,34 @@ func (driver Cloud189) Delete(path string, account *model.Account) error {
return err return err
} }
// Upload Error: decrypt encryptionText failed
func (driver Cloud189) Upload(file *model.FileStream, account *model.Account) error { func (driver Cloud189) Upload(file *model.FileStream, account *model.Account) error {
return base.ErrNotImplement //return base.ErrNotImplement
const DEFAULT uint64 = 10485760 if file == nil {
var count = int64(math.Ceil(float64(file.GetSize()) / float64(DEFAULT))) return base.ErrEmptyFile
var finish uint64 = 0 }
client, ok := client189Map[account.Name]
if !ok {
return fmt.Errorf("can't find [%s] client", account.Name)
}
parentFile, err := driver.File(file.ParentPath, account) parentFile, err := driver.File(file.ParentPath, account)
if err != nil { if err != nil {
return err return err
} }
if !parentFile.IsDir() { // api refer to PanIndex
return base.ErrNotFolder res, err := client.R().SetMultipartFormData(map[string]string{
} "parentId": parentFile.Id,
res, err := driver.UploadRequest("/person/initMultiUpload", map[string]string{ "sessionKey": account.DriveId,
"parentFolderId": parentFile.Id, "opertype": "1",
"fileName": file.Name, "fname": file.GetFileName(),
"fileSize": strconv.FormatInt(int64(file.Size), 10), }).SetMultipartField("Filedata", file.GetFileName(), file.GetMIMEType(), file).Post("https://hb02.upload.cloud.189.cn/v1/DCIWebUploadAction")
"sliceSize": strconv.FormatInt(int64(DEFAULT), 10),
"lazyCheck": "1",
}, account)
if err != nil { if err != nil {
return err return err
} }
uploadFileId := jsoniter.Get(res, "data.uploadFileId").ToString() if jsoniter.Get(res.Body(), "MD5").ToString() != "" {
var i int64 return nil
var byteSize uint64
md5s := make([]string, 0)
md5Sum := md5.New()
for i = 1; i <= count; i++ {
byteSize = file.GetSize() - finish
if DEFAULT < byteSize {
byteSize = DEFAULT
} }
log.Debugf("%d,%d", byteSize, finish) log.Debugf(res.String())
byteData := make([]byte, byteSize) return errors.New(res.String())
n, err := io.ReadFull(file, byteData)
log.Debug(err, n)
if err != nil {
return err
}
finish += uint64(n)
md5Bytes := getMd5(byteData)
md5Str := hex.EncodeToString(md5Bytes)
md5Base64 := base64.StdEncoding.EncodeToString(md5Bytes)
md5s = append(md5s, md5Str)
md5Sum.Write(byteData)
res, err = driver.UploadRequest("/person/getMultiUploadUrls", map[string]string{
"partInfo": fmt.Sprintf("%s-%s", strconv.FormatInt(i, 10), md5Base64),
"uploadFileId": uploadFileId,
}, account)
if err != nil {
return err
}
uploadData := jsoniter.Get(res, "uploadUrls.partNumber_"+strconv.FormatInt(i, 10))
headers := strings.Split(uploadData.Get("requestHeader").ToString(), "&")
req, err := http.NewRequest("PUT", uploadData.Get("requestURL").ToString(), bytes.NewBuffer(byteData))
if err != nil {
return err
}
for _, header := range headers {
kv := strings.Split(header, "=")
req.Header.Set(kv[0], strings.Join(kv[1:], "="))
}
res, err := base.HttpClient.Do(req)
if err != nil {
return err
}
log.Debugf("%+v", res)
}
id := md5Sum.Sum(nil)
res, err = driver.UploadRequest("/person/commitMultiUploadFile", map[string]string{
"uploadFileId": uploadFileId,
"fileMd5": hex.EncodeToString(id),
"sliceMd5": utils.GetMD5Encode(strings.Join(md5s, "\n")),
"lazyCheck": "1",
}, account)
return err
} }
var _ base.Driver = (*Cloud189)(nil) var _ base.Driver = (*Cloud189)(nil)