Skip to content

Commit

Permalink
Merge branch 'release/v1.0.32'
Browse files Browse the repository at this point in the history
  • Loading branch information
SheltonZhu committed Dec 8, 2024
2 parents 4f7a713 + 59ad257 commit 68d9ca8
Show file tree
Hide file tree
Showing 11 changed files with 120 additions and 51 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ func main() {
UID: "xxx",
CID: "xxx",
SEID: "xxx",
KID: "xxx",
}
// or err := cr.FromCookie(cookieStr)

Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ go 1.20

require (
github.com/aead/ecdh v0.2.0
github.com/aliyun/aliyun-oss-go-sdk v2.2.5+incompatible
github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible
github.com/andreburgaud/crypt2go v1.1.0
github.com/go-resty/resty/v2 v2.7.0
github.com/pierrec/lz4/v4 v4.1.17
Expand All @@ -20,7 +20,7 @@ require (
github.com/rogpeppe/go-internal v1.8.0 // indirect
golang.org/x/crypto v0.0.0-20221005025214-4161e89ecf1b // indirect
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 // indirect
golang.org/x/time v0.0.0-20220922220347-f3bd1da661af // indirect
golang.org/x/time v0.8.0 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
github.com/aead/ecdh v0.2.0 h1:pYop54xVaq/CEREFEcukHRZfTdjiWvYIsZDXXrBapQQ=
github.com/aead/ecdh v0.2.0/go.mod h1:a9HHtXuSo8J1Js1MwLQx2mBhkXMT6YwUmVVEY4tTB8U=
github.com/aliyun/aliyun-oss-go-sdk v2.2.5+incompatible h1:QoRMR0TCctLDqBCMyOu1eXdZyMw3F7uGA9qPn2J4+R8=
github.com/aliyun/aliyun-oss-go-sdk v2.2.5+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8=
github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible h1:8psS8a+wKfiLt1iVDX79F7Y6wUM49Lcha2FMXt4UM8g=
github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8=
github.com/andreburgaud/crypt2go v1.1.0 h1:eitZxTPY1krUsxinsng3Qvt/Ud7q/aQmmYRh8p4hyPw=
github.com/andreburgaud/crypt2go v1.1.0/go.mod h1:4qhZPzarj1dCIRmCkpdgCklwp+hBq9yEt0zPe9Ayuhc=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
Expand Down Expand Up @@ -47,8 +47,8 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/time v0.0.0-20220922220347-f3bd1da661af h1:Yx9k8YCG3dvF87UAn2tu2HQLf2dt/eR1bXxpLMWeH+Y=
golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.8.0 h1:9i3RxcPv3PZnitoVGMPDKZSq1xW1gK1Xy3ArNOGZfEg=
golang.org/x/time v0.8.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
Expand Down
16 changes: 8 additions & 8 deletions pkg/driver/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,19 @@ package driver

const (
ApiGetVersion = "https://appversion.115.com/1/web/1.0/api/chrome"

// login
ApiLoginCheck = "https://passportapi.115.com/app/1.0/web/1.0/check/sso"
ApiUserInfo = "https://my.115.com/?ct=ajax&ac=nav"

// login
ApiLoginCheck = "https://passportapi.115.com/app/1.0/web/1.0/check/sso"
ApiUserInfo = "https://my.115.com/?ct=ajax&ac=nav"
ApiStatusCheck = "https://my.115.com/?ct=guide&ac=status"
// dir
ApiDirAdd = "https://webapi.115.com/files/add"

// file
ApiFileDelete = "https://webapi.115.com/rb/delete"
ApiFileMove = "https://webapi.115.com/files/move"
ApiFileCopy = "https://webapi.115.com/files/copy"
ApiFileRename = "https://webapi.115.com/files/batch_rename"
ApiFileDelete = "https://webapi.115.com/rb/delete"
ApiFileMove = "https://webapi.115.com/files/move"
ApiFileCopy = "https://webapi.115.com/files/copy"
ApiFileRename = "https://webapi.115.com/files/batch_rename"
ApiFileIndexInfo = "https://webapi.115.com/files/index_info"

ApiFileList = "https://webapi.115.com/files"
Expand Down
20 changes: 15 additions & 5 deletions pkg/driver/driver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,26 @@ func TestMain(m *testing.M) {

func TestImportFromCookie(t *testing.T) {
cr := &Credential{}
assert.Nil(t, cr.FromCookie("UID=1;CID=2;SEID=3;other=4"))
assert.Nil(t, cr.FromCookie("UID=1;CID=2;SEID=3;KID=12;other=4"))
assert.Error(t, ErrBadCookie, cr.FromCookie(""))
assert.Error(t, ErrBadCookie, cr.FromCookie("k=a;;"))
assert.Error(t, ErrBadCookie, cr.FromCookie("1=2;2=3;3=4"))
assert.Error(t, ErrBadCookie, cr.FromCookie("1=2;2=3;3=4"))
}

func TestLogin(t *testing.T) {
func TestLoginErr(t *testing.T) {
assert.Error(t, New().ImportCredential(&Credential{}).LoginCheck())
}

func TestBadCookie(t *testing.T) {
assert.Error(t, New().ImportCredential(&Credential{}).CookieCheck())
}

func teardown(t *testing.T) func(t *testing.T) {
cr := &Credential{}
assert.Nil(t, cr.FromCookie(cookieStr))
client = New(UA(UA115Browser), WithDebug(), WithTrace()).ImportCredential(cr)
assert.Nil(t, client.LoginCheck())
assert.Nil(t, client.CookieCheck())
return func(t *testing.T) {}
}

Expand Down Expand Up @@ -249,8 +253,14 @@ func TestUploadMultipart(t *testing.T) {
assert.Nil(t, err)

randStr := NowMilli().String()
_, err = f.WriteString(randStr)
assert.Nil(t, err)
targetSize := 2048 // 目标文件大小,单位字节,这里设置为2KB
currentSize := 0
for currentSize < targetSize {
// 获取当前时间的毫秒时间戳字符串作为随机内容的一部分
n, err := f.WriteString(randStr)
assert.Nil(t, err)
currentSize += n
}

_, err = f.Seek(0, io.SeekStart)
assert.Nil(t, err)
Expand Down
2 changes: 1 addition & 1 deletion pkg/driver/example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (

func ExamplePan115Client_ImportCredential() {
cr := &Credential{}
if err := cr.FromCookie("UID=xxx;CID=xxxx;SEID=xxx;other=xxxx"); err != nil {
if err := cr.FromCookie("UID=xxx;CID=xxxx;SEID=xxx;KID=xxx;other=xxxx"); err != nil {
log.Fatalf("Import credentail error: %s", err)
}
client := Defalut().ImportCredential(cr)
Expand Down
20 changes: 18 additions & 2 deletions pkg/driver/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,22 @@ import (
"github.com/pkg/errors"
)

// LoginCheck check login status
// CookieCheck checks the cookie status and will not logout of other devices.
func (c *Pan115Client) CookieCheck() error {
result := struct {
State bool `json:"state"`
}{}
req := c.NewRequest().
SetQueryParam("_", NowMilli().String()).
SetResult(&result)

if _, _ = req.Get(ApiStatusCheck); !result.State {
return ErrBadCookie
}
return nil
}

// LoginCheck checks the login status and will logout of other devices.
func (c *Pan115Client) LoginCheck() error {
result := LoginResp{}
req := c.NewRequest().
Expand Down Expand Up @@ -95,7 +110,8 @@ func (cr *Credential) FromCookie(cookie string) error {
cr.CID = cookieMap["CID"]
cr.SEID = cookieMap["SEID"]
cr.KID = cookieMap["KID"]
if cr.CID == "" || cr.UID == "" || cr.SEID == "" || cr.KID == "" {
// No need to verify the KID for those old cookies that are still available.
if cr.CID == "" || cr.UID == "" || cr.SEID == "" {
return errors.Wrap(ErrBadCookie, "bad cookie, miss UID, CID or SEID")
}
return nil
Expand Down
4 changes: 3 additions & 1 deletion pkg/driver/offline.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,11 @@ func (c *Pan115Client) AddOfflineTaskURIs(uris []string, saveDirID string) (hash
}

if c.UserID < 0 {
if err := c.LoginCheck(); err != nil {
userInfo, err := c.GetUser()
if err != nil {
return nil, err
}
c.UserID = userInfo.UserID
}

key := crypto.GenerateKey()
Expand Down
6 changes: 3 additions & 3 deletions pkg/driver/option.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
package driver

import (
"crypto/tls"
"net/http"
"strconv"
"time"

"crypto/tls"

"github.com/go-resty/resty/v2"
)

Expand Down Expand Up @@ -153,7 +152,8 @@ type UploadMultipartOptions struct {

func DefalutUploadMultipartOptions() *UploadMultipartOptions {
return &UploadMultipartOptions{
ThreadsNum: 10,
// oss 启用Sequential必须按顺序上传
ThreadsNum: 1,
Timeout: time.Hour * 24,
TokenRefreshTime: time.Minute * 50,
}
Expand Down
50 changes: 36 additions & 14 deletions pkg/driver/response.go
Original file line number Diff line number Diff line change
Expand Up @@ -235,20 +235,27 @@ type UserInfoResp struct {
UserInfo UserInfo `json:"data"`
}
type UserInfo struct {
Device int `json:"device"`
Rank int `json:"rank"`
Liang int `json:"liang"`
Mark int `json:"mark"`
Mark1 int `json:"mark1"`
Vip int `json:"vip"`
Expire int `json:"expire"`
Global int `json:"global"`
Forever int `json:"forever"`
IsPrivilege bool `json:"is_privilege"`
Privilege []interface{} `json:"privilege"`
UserName string `json:"user_name"`
Face string `json:"face"`
UserID int64 `json:"user_id"`
Device int `json:"device"`
Rank int `json:"rank"`
Liang int `json:"liang"`
Mark int `json:"mark"`
Mark1 int `json:"mark1"`
Vip int `json:"vip"`
Expire int `json:"expire"`
Global int `json:"global"`
Forever int `json:"forever"`
IsPrivilege bool `json:"is_privilege"`
Privilege Privilege `json:"privilege"`
UserName string `json:"user_name"`
Face string `json:"face"`
UserID int64 `json:"user_id"`
}

type Privilege struct {
Start int `json:"start"`
Expire int `json:"expire"`
State bool `json:"state"`
Mark int `json:"mark"`
}

type FileStatResponse struct {
Expand Down Expand Up @@ -388,3 +395,18 @@ type ShareFile struct {
// E string `json:"e"`
// U string `json:"u"`
}

type UploadResult struct {
BasicResp
Data struct {
PickCode string `json:"pick_code"`
FileSize int `json:"file_size"`
FileID string `json:"file_id"`
ThumbURL string `json:"thumb_url"`
Sha1 string `json:"sha1"`
Aid int `json:"aid"`
FileName string `json:"file_name"`
Cid string `json:"cid"`
IsVideo int `json:"is_video"`
} `json:"data"`
}
40 changes: 29 additions & 11 deletions pkg/driver/upload.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (
"io"
"net/url"
"os"
"path/filepath"
"strconv"
"strings"
"sync"
Expand Down Expand Up @@ -369,6 +368,7 @@ func (c *Pan115Client) UploadByMultipart(params *UploadOSSParams, fileSize int64
ossClient *oss.Client
bucket *oss.Bucket
ossToken *UploadOSSTokenResp
bodyBytes []byte
err error
)

Expand All @@ -379,11 +379,18 @@ func (c *Pan115Client) UploadByMultipart(params *UploadOSSParams, fileSize int64
}
}

options.ThreadsNum = 1
if ossToken, err = c.GetOSSToken(); err != nil {
return err
}

if ossClient, err = oss.New(c.getOSSEndpoint(c.UseInternalUpload), ossToken.AccessKeyID, ossToken.AccessKeySecret); err != nil {
if ossClient, err = oss.New(
c.getOSSEndpoint(c.UseInternalUpload),
ossToken.AccessKeyID,
ossToken.AccessKeySecret,
oss.EnableMD5(true),
oss.EnableCRC(true),
); err != nil {
return err
}

Expand All @@ -404,6 +411,8 @@ func (c *Pan115Client) UploadByMultipart(params *UploadOSSParams, fileSize int64
if imur, err = bucket.InitiateMultipartUpload(params.Object,
oss.SetHeader(OssSecurityTokenHeaderName, ossToken.SecurityToken),
oss.UserAgentHeader(OSSUserAgent),
oss.EnableSha1(),
oss.Sequential(), // oss 启用Sequential必须按顺序上传, options.ThreadsNum = 1
); err != nil {
return err
}
Expand Down Expand Up @@ -447,8 +456,12 @@ func (c *Pan115Client) UploadByMultipart(params *UploadOSSParams, fileSize int64
continue
}

b := bytes.NewBuffer(buf)
if part, err = bucket.UploadPart(imur, b, chunk.Size, chunk.Number, OssOption(params, ossToken)...); err == nil {
if part, err = bucket.UploadPart(
imur,
bytes.NewBuffer(buf),
chunk.Size,
chunk.Number,
OssOption(params, ossToken)...); err == nil {
break
}
}
Expand Down Expand Up @@ -483,14 +496,19 @@ LOOP:
}
}

// EOF错误是xml的Unmarshal导致的,响应其实是json格式,所以实际上上传是成功的
if _, err = bucket.CompleteMultipartUpload(imur, parts, OssOption(params, ossToken)...); err != nil && !errors.Is(err, io.EOF) {
// 当文件名含有 &< 这两个字符之一时响应的xml解析会出现错误,实际上上传是成功的
if filename := filepath.Base(f.Name()); !strings.ContainsAny(filename, "&<") {
return err
}
if _, err := bucket.CompleteMultipartUpload(imur, parts,
append(
OssOption(params, ossToken),
oss.CallbackResult(&bodyBytes),
)...); err != nil {
return err
}
return c.checkUploadStatus(dirID, params.SHA1)

var uploadResult UploadResult
if err = json.Unmarshal(bodyBytes, &uploadResult); err != nil {
return err
}
return uploadResult.Err(string(bodyBytes))
}

func chunksProducer(ch chan oss.FileChunk, chunks []oss.FileChunk) {
Expand Down

0 comments on commit 68d9ca8

Please sign in to comment.