fix(onedrive): cannot list folder with more than 500 direct children (#2446)

pull/2224/merge
Aaron Liu 2025-06-05 16:51:48 +08:00
parent fe309b234c
commit 2a7b46437f
2 changed files with 48 additions and 27 deletions

View File

@ -4,16 +4,17 @@ import (
"context" "context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/cloudreve/Cloudreve/v4/pkg/filemanager/chunk"
"github.com/cloudreve/Cloudreve/v4/pkg/filemanager/chunk/backoff"
"github.com/cloudreve/Cloudreve/v4/pkg/filemanager/fs"
"github.com/cloudreve/Cloudreve/v4/pkg/request"
"io" "io"
"net/http" "net/http"
"net/url" "net/url"
"path" "path"
"strings" "strings"
"time" "time"
"github.com/cloudreve/Cloudreve/v4/pkg/filemanager/chunk"
"github.com/cloudreve/Cloudreve/v4/pkg/filemanager/chunk/backoff"
"github.com/cloudreve/Cloudreve/v4/pkg/filemanager/fs"
"github.com/cloudreve/Cloudreve/v4/pkg/request"
) )
const ( const (
@ -76,31 +77,50 @@ func (client *client) ListChildren(ctx context.Context, path string) ([]FileInfo
requestURL = client.getRequestURL("root:/" + dst + ":/children") requestURL = client.getRequestURL("root:/" + dst + ":/children")
} }
res, err := client.requestWithStr(ctx, "GET", requestURL+"?$top=999999999", "", 200) // Add pagination parameter
if err != nil { requestURL += "?$top=5000"
retried := 0
if v, ok := ctx.Value(RetryCtx{}).(int); ok { var allFiles []FileInfo
retried = v
for {
res, err := client.requestWithStr(ctx, "GET", requestURL, "", 200)
if err != nil {
retried := 0
if v, ok := ctx.Value(RetryCtx{}).(int); ok {
retried = v
}
if retried < ListRetry {
retried++
client.l.Debug("Failed to list path %q: %s, will retry in 5 seconds.", path, err)
time.Sleep(time.Duration(5) * time.Second)
return client.ListChildren(context.WithValue(ctx, RetryCtx{}, retried), path)
}
return nil, err
} }
if retried < ListRetry {
retried++ var (
client.l.Debug("Failed to list path %q: %s, will retry in 5 seconds.", path, err) decodeErr error
time.Sleep(time.Duration(5) * time.Second) fileInfo ListResponse
return client.ListChildren(context.WithValue(ctx, RetryCtx{}, retried), path) )
decodeErr = json.Unmarshal([]byte(res), &fileInfo)
if decodeErr != nil {
return nil, decodeErr
} }
return nil, err
// Append current page results
allFiles = append(allFiles, fileInfo.Value...)
// Check if there's a next page
if fileInfo.NextLink == "" {
break
}
// Use the next link for the next iteration
client.l.Debug("Load next page, next link: %s", fileInfo.NextLink)
requestURL = fileInfo.NextLink
} }
var ( return allFiles, nil
decodeErr error
fileInfo ListResponse
)
decodeErr = json.Unmarshal([]byte(res), &fileInfo)
if decodeErr != nil {
return nil, decodeErr
}
return fileInfo.Value, nil
} }
// Meta 根据资源ID或文件路径获取文件元信息 // Meta 根据资源ID或文件路径获取文件元信息

View File

@ -94,8 +94,9 @@ type ThumbResponse struct {
// ListResponse 列取子项目响应 // ListResponse 列取子项目响应
type ListResponse struct { type ListResponse struct {
Value []FileInfo `json:"value"` Value []FileInfo `json:"value"`
Context string `json:"@odata.context"` Context string `json:"@odata.context"`
NextLink string `json:"@odata.nextLink,omitempty"`
} }
// oauthEndpoint OAuth接口地址 // oauthEndpoint OAuth接口地址