-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
feat(s3): implement Getter interface #1790
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
| // If HeadObject fails with 404, check if it's a directory | ||
| prefix := getKey(path, true) | ||
| var contents []*s3.Object | ||
| var commonPrefixes []*s3.CommonPrefix | ||
| switch d.ListObjectVersion { | ||
| case "v1": | ||
| listInput := &s3.ListObjectsInput{ | ||
| Bucket: &d.Bucket, | ||
| Prefix: &prefix, | ||
| MaxKeys: aws.Int64(1), // Only need to check if at least one object exists | ||
| } | ||
| listResult, err := d.client.ListObjectsWithContext(ctx, listInput) | ||
| if err != nil { | ||
| return nil, errors.WithMessage(err, "failed to list objects with prefix") | ||
| } | ||
| contents = listResult.Contents | ||
| commonPrefixes = listResult.CommonPrefixes | ||
| case "v2": | ||
| listInput := &s3.ListObjectsV2Input{ | ||
| Bucket: &d.Bucket, | ||
| Prefix: &prefix, | ||
| MaxKeys: aws.Int64(1), | ||
| } | ||
| listResult, err := d.client.ListObjectsV2WithContext(ctx, listInput) | ||
| if err != nil { | ||
| return nil, errors.WithMessage(err, "failed to list objects v2 with prefix") | ||
| } | ||
| contents = listResult.Contents | ||
| commonPrefixes = listResult.CommonPrefixes | ||
| default: | ||
| return nil, fmt.Errorf("unsupported ListObjectVersion: %s", d.ListObjectVersion) | ||
| } | ||
| if len(contents) > 0 || len(commonPrefixes) > 0 { | ||
| dirName := stdpath.Base(path + "/") | ||
| return &model.Object{ | ||
| Name: dirName, | ||
| Modified: d.Modified, | ||
| IsFolder: true, | ||
| Path: path, | ||
| }, nil | ||
| } | ||
| return nil, errs.ObjectNotFound |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| // If HeadObject fails with 404, check if it's a directory | |
| prefix := getKey(path, true) | |
| var contents []*s3.Object | |
| var commonPrefixes []*s3.CommonPrefix | |
| switch d.ListObjectVersion { | |
| case "v1": | |
| listInput := &s3.ListObjectsInput{ | |
| Bucket: &d.Bucket, | |
| Prefix: &prefix, | |
| MaxKeys: aws.Int64(1), // Only need to check if at least one object exists | |
| } | |
| listResult, err := d.client.ListObjectsWithContext(ctx, listInput) | |
| if err != nil { | |
| return nil, errors.WithMessage(err, "failed to list objects with prefix") | |
| } | |
| contents = listResult.Contents | |
| commonPrefixes = listResult.CommonPrefixes | |
| case "v2": | |
| listInput := &s3.ListObjectsV2Input{ | |
| Bucket: &d.Bucket, | |
| Prefix: &prefix, | |
| MaxKeys: aws.Int64(1), | |
| } | |
| listResult, err := d.client.ListObjectsV2WithContext(ctx, listInput) | |
| if err != nil { | |
| return nil, errors.WithMessage(err, "failed to list objects v2 with prefix") | |
| } | |
| contents = listResult.Contents | |
| commonPrefixes = listResult.CommonPrefixes | |
| default: | |
| return nil, fmt.Errorf("unsupported ListObjectVersion: %s", d.ListObjectVersion) | |
| } | |
| if len(contents) > 0 || len(commonPrefixes) > 0 { | |
| dirName := stdpath.Base(path + "/") | |
| return &model.Object{ | |
| Name: dirName, | |
| Modified: d.Modified, | |
| IsFolder: true, | |
| Path: path, | |
| }, nil | |
| } | |
| return nil, errs.ObjectNotFound | |
| return nil, errs.NotSupport |
既然调用一次列表,这里就直接返回errs.NotSupport让op.Get去op.List寻找,op.List有缓存
| } | ||
|
|
||
| // try to get object as a file using HeadObject | ||
| key := getKey(path, false) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| key := getKey(path, false) | |
| key := getKey(stdpath.Join(d.GetRootPath(), path), false) |
| if utils.PathEqual(path, "/") { | ||
| return &model.Object{ | ||
| Name: "Root", | ||
| IsFolder: true, | ||
| Path: "/", | ||
| }, nil | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| if utils.PathEqual(path, "/") { | |
| return &model.Object{ | |
| Name: "Root", | |
| IsFolder: true, | |
| Path: "/", | |
| }, nil | |
| } |
已经不用Get获取根目录对象了
Description / 描述
The S3 driver has been updated to implement the Getter interface. This addition introduces the Get method, which allows the retrieval of both files and directories from S3. The method works by first attempting to fetch the object as a file using HeadObject. If the object is not found (HTTP 404), it checks if the path corresponds to a directory by listing objects with the given prefix. The Get method handles two different object listing strategies, “v1” and “v2”, based on the configuration of the ListObjectVersion.
Motivation and Context / 背景
How Has This Been Tested? / 测试
I added logging inside the newly implemented Get method, then created an S3 storage instance to verify that:
This confirmed that the new logic behaves as expected.
Checklist / 检查清单
我已阅读 CONTRIBUTING 文档。
go fmtor prettier.我已使用
go fmt或 prettier 格式化提交的代码。我已为此 PR 添加了适当的标签(如无权限或需要的标签不存在,请在描述中说明,管理员将后续处理)。
我已在适当情况下使用"Request review"功能请求相关代码作者进行审查。
我已相应更新了相关仓库(若适用)。