fix(baidu_netdisk): hash and `error 2` (#5356)

* fix(baidu):hash and error:2

* fix:invalid memory address
pull/4118/head
foxxorcat 2023-10-10 18:08:27 +08:00 committed by GitHub
parent 35d672217d
commit 8ef89ad0a4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 92 additions and 41 deletions

View File

@ -5,7 +5,6 @@ import (
"crypto/md5" "crypto/md5"
"encoding/hex" "encoding/hex"
"errors" "errors"
"fmt"
"io" "io"
"math" "math"
"net/url" "net/url"
@ -153,20 +152,13 @@ func (d *BaiduNetdisk) PutRapid(ctx context.Context, dstDir model.Obj, stream mo
} }
streamSize := stream.GetSize() streamSize := stream.GetSize()
rawPath := stdpath.Join(dstDir.GetPath(), stream.GetName()) path := stdpath.Join(dstDir.GetPath(), stream.GetName())
path := encodeURIComponent(rawPath)
mtime := stream.ModTime().Unix() mtime := stream.ModTime().Unix()
ctime := stream.CreateTime().Unix() ctime := stream.CreateTime().Unix()
blockList, _ := utils.Json.MarshalToString([]string{contentMd5}) blockList, _ := utils.Json.MarshalToString([]string{contentMd5})
data := fmt.Sprintf("path=%s&size=%d&isdir=0&rtype=3&block_list=%s&local_mtime=%d&local_ctime=%d",
path, streamSize, blockList, mtime, ctime)
params := map[string]string{
"method": "create",
}
log.Debugf("[baidu_netdisk] precreate data: %s", data)
var newFile File var newFile File
_, err := d.post("/xpan/file", params, data, &newFile) _, err := d.create(path, streamSize, 0, "", blockList, &newFile, mtime, ctime)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -218,9 +210,7 @@ func (d *BaiduNetdisk) Put(ctx context.Context, dstDir model.Obj, stream model.F
contentMd5 := hex.EncodeToString(fileMd5H.Sum(nil)) contentMd5 := hex.EncodeToString(fileMd5H.Sum(nil))
sliceMd5 := hex.EncodeToString(sliceMd5H2.Sum(nil)) sliceMd5 := hex.EncodeToString(sliceMd5H2.Sum(nil))
blockListStr, _ := utils.Json.MarshalToString(blockList) blockListStr, _ := utils.Json.MarshalToString(blockList)
path := stdpath.Join(dstDir.GetPath(), stream.GetName())
rawPath := stdpath.Join(dstDir.GetPath(), stream.GetName())
path := encodeURIComponent(rawPath)
mtime := stream.ModTime().Unix() mtime := stream.ModTime().Unix()
ctime := stream.CreateTime().Unix() ctime := stream.CreateTime().Unix()
@ -228,13 +218,23 @@ func (d *BaiduNetdisk) Put(ctx context.Context, dstDir model.Obj, stream model.F
// 尝试获取之前的进度 // 尝试获取之前的进度
precreateResp, ok := base.GetUploadProgress[*PrecreateResp](d, d.AccessToken, contentMd5) precreateResp, ok := base.GetUploadProgress[*PrecreateResp](d, d.AccessToken, contentMd5)
if !ok { if !ok {
data := fmt.Sprintf("path=%s&size=%d&isdir=0&autoinit=1&rtype=3&block_list=%s&content-md5=%s&slice-md5=%s&local_mtime=%d&local_ctime=%d",
path, streamSize, blockListStr, contentMd5, sliceMd5, mtime, ctime)
params := map[string]string{ params := map[string]string{
"method": "precreate", "method": "precreate",
} }
log.Debugf("[baidu_netdisk] precreate data: %s", data) form := map[string]string{
_, err = d.post("/xpan/file", params, data, &precreateResp) "path": path,
"size": strconv.FormatInt(streamSize, 10),
"isdir": "0",
"autoinit": "1",
"rtype": "3",
"block_list": blockListStr,
"content-md5": contentMd5,
"slice-md5": sliceMd5,
}
joinTime(form, ctime, mtime)
log.Debugf("[baidu_netdisk] precreate data: %s", form)
_, err = d.postForm("/xpan/file", params, form, &precreateResp)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -290,7 +290,7 @@ func (d *BaiduNetdisk) Put(ctx context.Context, dstDir model.Obj, stream model.F
// step.3 创建文件 // step.3 创建文件
var newFile File var newFile File
_, err = d.create(rawPath, streamSize, 0, precreateResp.Uploadid, blockListStr, &newFile, mtime, ctime) _, err = d.create(path, streamSize, 0, precreateResp.Uploadid, blockListStr, &newFile, mtime, ctime)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -1,7 +1,6 @@
package baidu_netdisk package baidu_netdisk
import ( import (
"github.com/alist-org/alist/v3/pkg/utils"
"path" "path"
"strconv" "strconv"
"time" "time"
@ -71,7 +70,9 @@ func fileToObj(f File) *model.ObjThumb {
Modified: time.Unix(f.LocalMtime, 0), Modified: time.Unix(f.LocalMtime, 0),
Ctime: time.Unix(f.LocalCtime, 0), Ctime: time.Unix(f.LocalCtime, 0),
IsFolder: f.Isdir == 1, IsFolder: f.Isdir == 1,
HashInfo: utils.NewHashInfo(utils.MD5, f.Md5),
// 直接获取的MD5是错误的
// HashInfo: utils.NewHashInfo(utils.MD5, f.Md5),
}, },
Thumbnail: model.Thumbnail{Thumbnail: f.Thumbs.Url3}, Thumbnail: model.Thumbnail{Thumbnail: f.Thumbs.Url3},
} }

View File

@ -4,9 +4,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"net/http" "net/http"
"net/url"
"strconv" "strconv"
"strings"
"time" "time"
"github.com/alist-org/alist/v3/drivers/base" "github.com/alist-org/alist/v3/drivers/base"
@ -96,10 +94,10 @@ func (d *BaiduNetdisk) get(pathname string, params map[string]string, resp inter
}, resp) }, resp)
} }
func (d *BaiduNetdisk) post(pathname string, params map[string]string, data interface{}, resp interface{}) ([]byte, error) { func (d *BaiduNetdisk) postForm(pathname string, params map[string]string, form map[string]string, resp interface{}) ([]byte, error) {
return d.request("https://pan.baidu.com/rest/2.0"+pathname, http.MethodPost, func(req *resty.Request) { return d.request("https://pan.baidu.com/rest/2.0"+pathname, http.MethodPost, func(req *resty.Request) {
req.SetQueryParams(params) req.SetQueryParams(params)
req.SetBody(data) req.SetFormData(form)
}, resp) }, resp)
} }
@ -154,6 +152,9 @@ func (d *BaiduNetdisk) linkOfficial(file model.Obj, args model.LinkArgs) (*model
//if res.StatusCode() == 302 { //if res.StatusCode() == 302 {
u = res.Header().Get("location") u = res.Header().Get("location")
//} //}
updateObjMd5(file, "pan.baidu.com", u)
return &model.Link{ return &model.Link{
URL: u, URL: u,
Header: http.Header{ Header: http.Header{
@ -176,6 +177,9 @@ func (d *BaiduNetdisk) linkCrack(file model.Obj, args model.LinkArgs) (*model.Li
if err != nil { if err != nil {
return nil, err return nil, err
} }
updateObjMd5(file, d.CustomCrackUA, resp.Info[0].Dlink)
return &model.Link{ return &model.Link{
URL: resp.Info[0].Dlink, URL: resp.Info[0].Dlink,
Header: http.Header{ Header: http.Header{
@ -190,29 +194,56 @@ func (d *BaiduNetdisk) manage(opera string, filelist any) ([]byte, error) {
"opera": opera, "opera": opera,
} }
marshal, _ := utils.Json.MarshalToString(filelist) marshal, _ := utils.Json.MarshalToString(filelist)
data := fmt.Sprintf("async=0&filelist=%s&ondup=fail", marshal) return d.postForm("/xpan/file", params, map[string]string{
return d.post("/xpan/file", params, data, nil) "async": "0",
"filelist": marshal,
"ondup": "fail",
}, nil)
} }
func (d *BaiduNetdisk) create(path string, size int64, isdir int, uploadid, block_list string, resp any, mtime, ctime int64) ([]byte, error) { func (d *BaiduNetdisk) create(path string, size int64, isdir int, uploadid, block_list string, resp any, mtime, ctime int64) ([]byte, error) {
params := map[string]string{ params := map[string]string{
"method": "create", "method": "create",
} }
data := "" form := map[string]string{
if mtime == 0 || ctime == 0 { "path": path,
data = fmt.Sprintf("path=%s&size=%d&isdir=%d&rtype=3", encodeURIComponent(path), size, isdir) "size": strconv.FormatInt(size, 10),
} else { "isdir": strconv.Itoa(isdir),
data = fmt.Sprintf("path=%s&size=%d&isdir=%d&rtype=3&local_mtime=%d&local_ctime=%d", encodeURIComponent(path), size, isdir, mtime, ctime) "rtype": "3",
}
if mtime != 0 && ctime != 0 {
joinTime(form, ctime, mtime)
} }
if uploadid != "" { if uploadid != "" {
data += fmt.Sprintf("&uploadid=%s&block_list=%s", uploadid, block_list) form["uploadid"] = uploadid
} }
return d.post("/xpan/file", params, data, resp) if block_list != "" {
form["block_list"] = block_list
}
return d.postForm("/xpan/file", params, form, resp)
} }
func encodeURIComponent(str string) string { func joinTime(form map[string]string, ctime, mtime int64) {
r := url.QueryEscape(str) form["local_mtime"] = strconv.FormatInt(mtime, 10)
r = strings.ReplaceAll(r, "+", "%20") form["local_ctime"] = strconv.FormatInt(ctime, 10)
return r
} }
func updateObjMd5(obj model.Obj, userAgent, u string) {
object := model.GetRawObject(obj)
if object != nil {
req, _ := http.NewRequest(http.MethodHead, u, nil)
req.Header.Add("User-Agent", userAgent)
resp, _ := base.HttpClient.Do(req)
if resp != nil {
contentMd5 := resp.Header.Get("Content-Md5")
object.HashInfo = utils.NewHashInfo(utils.MD5, contentMd5)
}
}
}
// func encodeURIComponent(str string) string {
// r := url.QueryEscape(str)
// r = strings.ReplaceAll(r, "+", "%20")
// return r
// }

View File

@ -1,14 +1,15 @@
package model package model
import ( import (
"github.com/alist-org/alist/v3/pkg/http_range"
"github.com/alist-org/alist/v3/pkg/utils"
"io" "io"
"regexp" "regexp"
"sort" "sort"
"strings" "strings"
"time" "time"
"github.com/alist-org/alist/v3/pkg/http_range"
"github.com/alist-org/alist/v3/pkg/utils"
mapset "github.com/deckarep/golang-set/v2" mapset "github.com/deckarep/golang-set/v2"
"github.com/maruel/natural" "github.com/maruel/natural"
@ -146,6 +147,20 @@ func GetUrl(obj Obj) (url string, ok bool) {
return url, false return url, false
} }
func GetRawObject(obj Obj) *Object {
switch v := obj.(type) {
case *ObjThumbURL:
return &v.Object
case *ObjThumb:
return &v.Object
case *ObjectURL:
return &v.Object
case *Object:
return v
}
return nil
}
// Merge // Merge
func NewObjMerge() *ObjMerge { func NewObjMerge() *ObjMerge {
return &ObjMerge{ return &ObjMerge{

View File

@ -3,13 +3,14 @@ package stream
import ( import (
"context" "context"
"fmt" "fmt"
"io"
"net/http"
"github.com/alist-org/alist/v3/internal/errs" "github.com/alist-org/alist/v3/internal/errs"
"github.com/alist-org/alist/v3/internal/model" "github.com/alist-org/alist/v3/internal/model"
"github.com/alist-org/alist/v3/internal/net" "github.com/alist-org/alist/v3/internal/net"
"github.com/alist-org/alist/v3/pkg/http_range" "github.com/alist-org/alist/v3/pkg/http_range"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"io"
"net/http"
) )
func GetRangeReadCloserFromLink(size int64, link *model.Link) (model.RangeReadCloserIF, error) { func GetRangeReadCloserFromLink(size int64, link *model.Link) (model.RangeReadCloserIF, error) {
@ -40,6 +41,9 @@ func GetRangeReadCloserFromLink(size int64, link *model.Link) (model.RangeReadCl
if len(link.URL) > 0 { if len(link.URL) > 0 {
response, err := RequestRangedHttp(ctx, link, r.Start, r.Length) response, err := RequestRangedHttp(ctx, link, r.Start, r.Length)
if err != nil { if err != nil {
if response == nil {
return nil, fmt.Errorf("http request failure, err:%s", err)
}
return nil, fmt.Errorf("http request failure,status: %d err:%s", response.StatusCode, err) return nil, fmt.Errorf("http request failure,status: %d err:%s", response.StatusCode, err)
} }
if r.Start == 0 && (r.Length == -1 || r.Length == size) || response.StatusCode == http.StatusPartialContent || if r.Start == 0 && (r.Length == -1 || r.Length == size) || response.StatusCode == http.StatusPartialContent ||