diff --git a/drivers/123_share/driver.go b/drivers/123_share/driver.go index b2fd4313..7fca7cc1 100644 --- a/drivers/123_share/driver.go +++ b/drivers/123_share/driver.go @@ -4,8 +4,11 @@ import ( "context" "encoding/base64" "fmt" + "golang.org/x/time/rate" "net/http" "net/url" + "sync" + "time" "github.com/alist-org/alist/v3/drivers/base" "github.com/alist-org/alist/v3/internal/driver" @@ -19,6 +22,7 @@ import ( type Pan123Share struct { model.Storage Addition + apiRateLimit sync.Map } func (d *Pan123Share) Config() driver.Config { @@ -146,4 +150,11 @@ func (d *Pan123Share) Put(ctx context.Context, dstDir model.Obj, stream model.Fi // return nil, errs.NotSupport //} +func (d *Pan123Share) APIRateLimit(api string) bool { + limiter, _ := d.apiRateLimit.LoadOrStore(api, + rate.NewLimiter(rate.Every(time.Millisecond*700), 1)) + ins := limiter.(*rate.Limiter) + return ins.Allow() +} + var _ driver.Driver = (*Pan123Share)(nil) diff --git a/drivers/123_share/meta.go b/drivers/123_share/meta.go index a4bb14a9..ce39b7ee 100644 --- a/drivers/123_share/meta.go +++ b/drivers/123_share/meta.go @@ -7,10 +7,11 @@ import ( type Addition struct { ShareKey string `json:"sharekey" required:"true"` - SharePwd string `json:"sharepassword" required:"true"` + SharePwd string `json:"sharepassword"` driver.RootID OrderBy string `json:"order_by" type:"select" options:"file_name,size,update_at" default:"file_name"` OrderDirection string `json:"order_direction" type:"select" options:"asc,desc" default:"asc"` + AccessToken string `json:"accesstoken" type:"text"` } var config = driver.Config{ diff --git a/drivers/123_share/util.go b/drivers/123_share/util.go index bfce54f3..b22b7cc4 100644 --- a/drivers/123_share/util.go +++ b/drivers/123_share/util.go @@ -2,8 +2,15 @@ package _123Share import ( "errors" + "fmt" + "hash/crc32" + "math" + "math/rand" "net/http" + "net/url" "strconv" + "strings" + "time" "github.com/alist-org/alist/v3/drivers/base" "github.com/alist-org/alist/v3/pkg/utils" @@ -15,20 +22,45 @@ const ( Api = "https://www.123pan.com/api" AApi = "https://www.123pan.com/a/api" BApi = "https://www.123pan.com/b/api" - MainApi = Api + MainApi = BApi FileList = MainApi + "/share/get" DownloadInfo = MainApi + "/share/download/info" //AuthKeySalt = "8-8D$sL8gPjom7bk#cY" ) +func signPath(path string, os string, version string) (k string, v string) { + table := []byte{'a', 'd', 'e', 'f', 'g', 'h', 'l', 'm', 'y', 'i', 'j', 'n', 'o', 'p', 'k', 'q', 'r', 's', 't', 'u', 'b', 'c', 'v', 'w', 's', 'z'} + random := fmt.Sprintf("%.f", math.Round(1e7*rand.Float64())) + now := time.Now().In(time.FixedZone("CST", 8*3600)) + timestamp := fmt.Sprint(now.Unix()) + nowStr := []byte(now.Format("200601021504")) + for i := 0; i < len(nowStr); i++ { + nowStr[i] = table[nowStr[i]-48] + } + timeSign := fmt.Sprint(crc32.ChecksumIEEE(nowStr)) + data := strings.Join([]string{timestamp, random, path, os, version, timeSign}, "|") + dataSign := fmt.Sprint(crc32.ChecksumIEEE([]byte(data))) + return timeSign, strings.Join([]string{timestamp, random, dataSign}, "-") +} + +func GetApi(rawUrl string) string { + u, _ := url.Parse(rawUrl) + query := u.Query() + query.Add(signPath(u.Path, "web", "3")) + u.RawQuery = query.Encode() + return u.String() +} + func (d *Pan123Share) request(url string, method string, callback base.ReqCallback, resp interface{}) ([]byte, error) { req := base.RestyClient.R() req.SetHeaders(map[string]string{ - "origin": "https://www.123pan.com", - "referer": "https://www.123pan.com/", - "user-agent": "Dart/2.19(dart:io)", - "platform": "android", - "app-version": "36", + "origin": "https://www.123pan.com", + "referer": "https://www.123pan.com/", + "authorization": "Bearer " + d.AccessToken, + "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) alist-client", + "platform": "web", + "app-version": "3", + //"user-agent": base.UserAgent, }) if callback != nil { callback(req) @@ -36,7 +68,7 @@ func (d *Pan123Share) request(url string, method string, callback base.ReqCallba if resp != nil { req.SetResult(resp) } - res, err := req.Execute(method, url) + res, err := req.Execute(method, GetApi(url)) if err != nil { return nil, err } @@ -52,6 +84,10 @@ func (d *Pan123Share) getFiles(parentId string) ([]File, error) { page := 1 res := make([]File, 0) for { + if !d.APIRateLimit(FileList) { + time.Sleep(time.Millisecond * 200) + continue + } var resp Files query := map[string]string{ "limit": "100",