From f7cf0b9b19f3fbe36cc9cb60782e21fe82fe54b5 Mon Sep 17 00:00:00 2001
From: maye174 <96584640+maye174@users.noreply.github.com>
Date: Sun, 30 Jun 2024 18:48:47 +0800
Subject: [PATCH 1/2] 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
---
 drivers/ilanzou/driver.go | 43 +++++++++++++++++------------------
 drivers/ilanzou/util.go   | 47 ++++++++++++++++++++++-----------------
 2 files changed, 47 insertions(+), 43 deletions(-)

diff --git a/drivers/ilanzou/driver.go b/drivers/ilanzou/driver.go
index 63d86363962..7c86390dc36 100644
--- a/drivers/ilanzou/driver.go
+++ b/drivers/ilanzou/driver.go
@@ -118,31 +118,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 +158,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
diff --git a/drivers/ilanzou/util.go b/drivers/ilanzou/util.go
index c9a30765b7f..592a9bf859b 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,50 @@ 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))
+	}
+
+	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())

From 50fd4acadde2eaaf537c7af186bfbd67bfa918a9 Mon Sep 17 00:00:00 2001
From: maye174 <96584640+maye174@users.noreply.github.com>
Date: Mon, 1 Jul 2024 19:10:18 +0800
Subject: [PATCH 2/2] fix(drivers/iLanZou): Fixed the error ID number returned
 when creating a folder

Closes #6610, Closes #6333
---
 drivers/ilanzou/driver.go | 29 +++++++++++++++--------------
 drivers/ilanzou/util.go   |  2 ++
 2 files changed, 17 insertions(+), 14 deletions(-)

diff --git a/drivers/ilanzou/driver.go b/drivers/ilanzou/driver.go
index 7c86390dc36..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)
@@ -176,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,
@@ -345,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 592a9bf859b..a57e2a4a6be 100644
--- a/drivers/ilanzou/util.go
+++ b/drivers/ilanzou/util.go
@@ -63,6 +63,8 @@ func (d *ILanZou) request(pathname, method string, callback base.ReqCallback, pr
 		params = append(params, "appToken="+url.QueryEscape(d.Token))
 	}
 
+	params = append(params, "extra=2")
+
 	queryString := strings.Join(params, "&")
 
 	req := base.RestyClient.R()