From 270587723579f717d6da0c3e5b7131d72f919b1a Mon Sep 17 00:00:00 2001 From: lany Date: Tue, 2 Jul 2024 15:30:00 +0800 Subject: [PATCH] fix(iLanZou): resolve resource access issue (#6673) * fix(drivers/iLanZou): resolve resource access issue on iLanZou driver mount The driver failed to mount due to incorrect URL parameter ordering which the backend did not accept This commit reorders the parameters to meet the backend's expectations and ensures successful mounting of the iLanZou driver. Closes #6271, Closes #6415 * fix(drivers/iLanZou): Fixed the error ID number returned when creating a folder Closes #6610, Closes #6333 --------- Co-authored-by: maye174 <96584640+maye174@users.noreply.github.com> --- drivers/ilanzou/driver.go | 72 +++++++++++++++++++-------------------- drivers/ilanzou/util.go | 49 +++++++++++++++----------- 2 files changed, 64 insertions(+), 57 deletions(-) diff --git a/drivers/ilanzou/driver.go b/drivers/ilanzou/driver.go index 63d86363962..ab5ebe7ee5d 100644 --- a/drivers/ilanzou/driver.go +++ b/drivers/ilanzou/driver.go @@ -66,18 +66,18 @@ func (d *ILanZou) Drop(ctx context.Context) error { } func (d *ILanZou) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error) { - offset := 1 - limit := 60 var res []ListItem for { var resp ListResp _, err := d.proved("/record/file/list", http.MethodGet, func(req *resty.Request) { - req.SetQueryParams(map[string]string{ - "type": "0", - "folderId": dir.GetID(), - "offset": strconv.Itoa(offset), - "limit": strconv.Itoa(limit), - }).SetResult(&resp) + params := []string{ + "offset=1", + "limit=60", + "folderId=" + dir.GetID(), + "type=0", + } + queryString := strings.Join(params, "&") + req.SetQueryString(queryString).SetResult(&resp) }) if err != nil { return nil, err @@ -86,7 +86,6 @@ func (d *ILanZou) List(ctx context.Context, dir model.Obj, args model.ListArgs) if resp.TotalPage <= resp.Offset { break } - offset++ } return utils.SliceConvert(res, func(f ListItem) (model.Obj, error) { updTime, err := time.ParseInLocation("2006-01-02 15:04:05", f.UpdTime, time.Local) @@ -118,31 +117,33 @@ func (d *ILanZou) Link(ctx context.Context, file model.Obj, args model.LinkArgs) if err != nil { return nil, err } - query := u.Query() - query.Set("uuid", d.UUID) - query.Set("devType", "6") - query.Set("devCode", d.UUID) - query.Set("devModel", "chrome") - query.Set("devVersion", d.conf.devVersion) - query.Set("appVersion", "") - ts, err := getTimestamp(d.conf.secret) - if err != nil { - return nil, err + ts, ts_str, err := getTimestamp(d.conf.secret) + + params := []string{ + "uuid=" + url.QueryEscape(d.UUID), + "devType=6", + "devCode=" + url.QueryEscape(d.UUID), + "devModel=chrome", + "devVersion=" + url.QueryEscape(d.conf.devVersion), + "appVersion=", + "timestamp=" + ts_str, + "appToken=" + url.QueryEscape(d.Token), + "enable=0", } - query.Set("timestamp", ts) - query.Set("appToken", d.Token) - query.Set("enable", "1") + downloadId, err := mopan.AesEncrypt([]byte(fmt.Sprintf("%s|%s", file.GetID(), d.userID)), d.conf.secret) if err != nil { return nil, err } - query.Set("downloadId", hex.EncodeToString(downloadId)) - auth, err := mopan.AesEncrypt([]byte(fmt.Sprintf("%s|%d", file.GetID(), time.Now().UnixMilli())), d.conf.secret) + params = append(params, "downloadId="+url.QueryEscape(hex.EncodeToString(downloadId))) + + auth, err := mopan.AesEncrypt([]byte(fmt.Sprintf("%s|%d", file.GetID(), ts)), d.conf.secret) if err != nil { return nil, err } - query.Set("auth", hex.EncodeToString(auth)) - u.RawQuery = query.Encode() + params = append(params, "auth="+url.QueryEscape(hex.EncodeToString(auth))) + + u.RawQuery = strings.Join(params, "&") realURL := u.String() // get the url after redirect res, err := base.NoRedirectClient.R().SetHeaders(map[string]string{ @@ -156,12 +157,7 @@ func (d *ILanZou) Link(ctx context.Context, file model.Obj, args model.LinkArgs) if res.StatusCode() == 302 { realURL = res.Header().Get("location") } else { - contentLengthStr := res.Header().Get("Content-Length") - contentLength, err := strconv.Atoi(contentLengthStr) - if err != nil || contentLength == 0 || contentLength > 1024*10 { - return nil, fmt.Errorf("redirect failed, status: %d", res.StatusCode()) - } - return nil, fmt.Errorf("redirect failed, content: %s", res.String()) + return nil, fmt.Errorf("redirect failed, status: %d, msg: %s", res.StatusCode(), utils.Json.Get(res.Body(), "msg").ToString()) } link := model.Link{URL: realURL} return &link, nil @@ -179,7 +175,7 @@ func (d *ILanZou) MakeDir(ctx context.Context, parentDir model.Obj, dirName stri return nil, err } return &model.Object{ - ID: utils.Json.Get(res, "list", "0", "id").ToString(), + ID: utils.Json.Get(res, "list", 0, "id").ToString(), //Path: "", Name: dirName, Size: 0, @@ -348,10 +344,12 @@ func (d *ILanZou) Put(ctx context.Context, dstDir model.Obj, stream model.FileSt var resp UploadResultResp for i := 0; i < 10; i++ { _, err = d.unproved("/7n/results", http.MethodPost, func(req *resty.Request) { - req.SetQueryParams(map[string]string{ - "tokenList": token, - "tokenTime": time.Now().Format("Mon Jan 02 2006 15:04:05 GMT-0700 (MST)"), - }).SetResult(&resp) + params := []string{ + "tokenList=" + token, + "tokenTime=" + time.Now().Format("Mon Jan 02 2006 15:04:05 GMT-0700 (MST)"), + } + queryString := strings.Join(params, "&") + req.SetQueryString(queryString).SetResult(&resp) }) if err != nil { return nil, err diff --git a/drivers/ilanzou/util.go b/drivers/ilanzou/util.go index c9a30765b7f..a57e2a4a6be 100644 --- a/drivers/ilanzou/util.go +++ b/drivers/ilanzou/util.go @@ -4,7 +4,9 @@ import ( "encoding/hex" "fmt" "net/http" + "net/url" "strconv" + "strings" "time" "github.com/alist-org/alist/v3/drivers/base" @@ -31,45 +33,52 @@ func (d *ILanZou) login() error { return nil } -func getTimestamp(secret []byte) (string, error) { +func getTimestamp(secret []byte) (int64, string, error) { ts := time.Now().UnixMilli() tsStr := strconv.FormatInt(ts, 10) res, err := mopan.AesEncrypt([]byte(tsStr), secret) if err != nil { - return "", err + return 0, "", err } - return hex.EncodeToString(res), nil + return ts, hex.EncodeToString(res), nil } func (d *ILanZou) request(pathname, method string, callback base.ReqCallback, proved bool, retry ...bool) ([]byte, error) { - req := base.RestyClient.R() - ts, err := getTimestamp(d.conf.secret) + _, ts_str, err := getTimestamp(d.conf.secret) if err != nil { return nil, err } - req.SetQueryParams(map[string]string{ - "uuid": d.UUID, - "devType": "6", - "devCode": d.UUID, - "devModel": "chrome", - "devVersion": d.conf.devVersion, - "appVersion": "", - "timestamp": ts, - //"appToken": d.Token, - "extra": "2", - }) + + params := []string{ + "uuid=" + url.QueryEscape(d.UUID), + "devType=6", + "devCode=" + url.QueryEscape(d.UUID), + "devModel=chrome", + "devVersion=" + url.QueryEscape(d.conf.devVersion), + "appVersion=", + "timestamp=" + ts_str, + } + + if proved { + params = append(params, "appToken="+url.QueryEscape(d.Token)) + } + + params = append(params, "extra=2") + + queryString := strings.Join(params, "&") + + req := base.RestyClient.R() req.SetHeaders(map[string]string{ "Origin": d.conf.site, "Referer": d.conf.site + "/", "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36 Edg/125.0.0.0", }) - if proved { - req.SetQueryParam("appToken", d.Token) - } + if callback != nil { callback(req) } - res, err := req.Execute(method, d.conf.base+pathname) + + res, err := req.Execute(method, d.conf.base+pathname+"?"+queryString) if err != nil { if res != nil { log.Errorf("[iLanZou] request error: %s", res.String())