feat(s3): implement Getter interface#1790
Open
ZRHann wants to merge 3 commits intoOpenListTeam:mainfrom
Open
Conversation
7 tasks
jyxjjj
previously approved these changes
Dec 15, 2025
j2rong4cn
reviewed
Dec 15, 2025
Comment on lines
+281
to
+322
| // 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 |
Member
There was a problem hiding this comment.
Suggested change
| // 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有缓存
Author
There was a problem hiding this comment.
- 这里list的目录不一样?我们是对a/b/进行ListObjects,返回NotSupport的话,op.List是去list a/,又回到递归了。由于目录的上一级也是目录,这里的get完全回退到了递归的list。
- 上面设置了max key=1(只返回一个文件或目录),开销不大。用op.List的话,如果文件多而且刚好没缓存,可能有大量开销。(虽然根据1. ,这里list的目录也不一样)
j2rong4cn
reviewed
Dec 15, 2025
drivers/s3/driver.go
Outdated
| } | ||
|
|
||
| // try to get object as a file using HeadObject | ||
| key := getKey(path, false) |
Member
There was a problem hiding this comment.
Suggested change
| key := getKey(path, false) | |
| key := getKey(stdpath.Join(d.GetRootPath(), path), false) |
j2rong4cn
reviewed
Dec 15, 2025
drivers/s3/driver.go
Outdated
Comment on lines
251
to
257
| if utils.PathEqual(path, "/") { | ||
| return &model.Object{ | ||
| Name: "Root", | ||
| IsFolder: true, | ||
| Path: "/", | ||
| }, nil | ||
| } |
Member
There was a problem hiding this comment.
Suggested change
| if utils.PathEqual(path, "/") { | |
| return &model.Object{ | |
| Name: "Root", | |
| IsFolder: true, | |
| Path: "/", | |
| }, nil | |
| } |
已经不用Get获取根目录对象了
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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"功能请求相关代码作者进行审查。
我已相应更新了相关仓库(若适用)。