diff --git a/drivers/s3/driver.go b/drivers/s3/driver.go index ef17fb98..390ca08a 100644 --- a/drivers/s3/driver.go +++ b/drivers/s3/driver.go @@ -79,6 +79,18 @@ func (driver S3) Items() []base.Item { Type: base.TypeString, Description: "default empty string", }, + { + Name: "bool_1", + Label: "S3ForcePathStyle", + Type: base.TypeBool, + }, + { + Name: "internal_type", + Label: "ListObject Version", + Type: base.TypeSelect, + Values: "v1,v2", + Default: "v1", + }, } } @@ -132,7 +144,11 @@ func (driver S3) Files(path string, account *model.Account) ([]model.File, error if err == nil { files, _ = cache.([]model.File) } else { - files, err = driver.List(path, account) + if account.InternalType == "v2" { + files, err = driver.ListV2(path, account) + } else { + files, err = driver.List(path, account) + } if err == nil && len(files) > 0 { _ = base.SetCache(path, files, account) } diff --git a/drivers/s3/s3.go b/drivers/s3/s3.go index 883ed3fb..98459218 100644 --- a/drivers/s3/s3.go +++ b/drivers/s3/s3.go @@ -1,6 +1,7 @@ package s3 import ( + "errors" "fmt" "github.com/Xhofe/alist/conf" "github.com/Xhofe/alist/drivers/base" @@ -22,9 +23,10 @@ var sessionsMap map[string]*session.Session func (driver S3) NewSession(account *model.Account) (*session.Session, error) { cfg := &aws.Config{ - Credentials: credentials.NewStaticCredentials(account.AccessKey, account.AccessSecret, ""), - Region: &account.Region, - Endpoint: &account.Endpoint, + Credentials: credentials.NewStaticCredentials(account.AccessKey, account.AccessSecret, ""), + Region: &account.Region, + Endpoint: &account.Endpoint, + S3ForcePathStyle: aws.Bool(account.Bool1), } return session.NewSession(cfg) } @@ -99,6 +101,9 @@ func (driver S3) List(prefix string, account *model.Account) ([]model.File, erro } files = append(files, file) } + if listObjectsResult.IsTruncated == nil { + return nil, errors.New("IsTruncated nil") + } if *listObjectsResult.IsTruncated { marker = *listObjectsResult.NextMarker } else { @@ -108,6 +113,73 @@ func (driver S3) List(prefix string, account *model.Account) ([]model.File, erro return files, nil } +func (driver S3) ListV2(prefix string, account *model.Account) ([]model.File, error) { + prefix = driver.GetKey(prefix, account, true) + //if prefix == "" { + // prefix = "/" + //} + log.Debugf("list: %s", prefix) + client, err := driver.GetClient(account, false) + if err != nil { + return nil, err + } + files := make([]model.File, 0) + var continuationToken, startAfter *string + for { + input := &s3.ListObjectsV2Input{ + Bucket: &account.Bucket, + ContinuationToken: continuationToken, + Prefix: &prefix, + Delimiter: aws.String("/"), + StartAfter: startAfter, + } + listObjectsResult, err := client.ListObjectsV2(input) + if err != nil { + return nil, err + } + log.Debugf("resp: %+v", listObjectsResult) + for _, object := range listObjectsResult.CommonPrefixes { + name := utils.Base(strings.Trim(*object.Prefix, "/")) + file := model.File{ + //Id: *object.Key, + Name: name, + Driver: driver.Config().Name, + UpdatedAt: account.UpdatedAt, + TimeStr: "-", + Type: conf.FOLDER, + } + files = append(files, file) + } + for _, object := range listObjectsResult.Contents { + name := utils.Base(*object.Key) + if name == account.Zone { + continue + } + file := model.File{ + //Id: *object.Key, + Name: name, + Size: *object.Size, + Driver: driver.Config().Name, + UpdatedAt: object.LastModified, + Type: utils.GetFileType(path.Ext(*object.Key)), + } + files = append(files, file) + } + if !aws.BoolValue(listObjectsResult.IsTruncated) { + break + } + if listObjectsResult.NextContinuationToken != nil { + continuationToken = listObjectsResult.NextContinuationToken + continue + } + if len(listObjectsResult.Contents) == 0 { + break + } + startAfter = listObjectsResult.Contents[len(listObjectsResult.Contents)-1].Key + } + return files, nil +} + func (driver S3) GetKey(path string, account *model.Account, dir bool) string { path = utils.Join(account.RootFolder, path) path = strings.TrimPrefix(path, "/") diff --git a/model/account.go b/model/account.go index 9bb04f6b..f1086578 100644 --- a/model/account.go +++ b/model/account.go @@ -47,6 +47,7 @@ type Account struct { AccessSecret string `json:"access_secret"` CustomHost string `json:"custom_host"` ExtractFolder string `json:"extract_folder"` + Bool1 bool `json:"bool_1"` } var accountsMap = make(map[string]Account)