Skip to content

[BUG] S3 HeadObject/GetObject 返回空 ETag(Hash 字段未填充) #2773

Description

@ChasLui

环境

  • OpenList 版本: v4.2.3-aio(Docker 镜像 openlistteam/openlist:v4.2.3-aio
  • S3 endpoint: http://127.0.0.1:5246
  • Bucket: tianyi(后端为天翼云盘)

复现步骤

# PUT
aws --endpoint-url http://127.0.0.1:5246 s3api put-object \
  --bucket tianyi --key test.txt --body /tmp/test.txt

# HEAD
aws --endpoint-url http://127.0.0.1:5246 s3api head-object \
  --bucket tianyi --key test.txt

实际行为

PUT  ETag: "6ad255986677cad6b8fdc86e8f0800f4"   ← 有值
HEAD ETag: ""                                      ← 空字符串

HEAD 响应头:

Etag: ""
Content-Length: 10
Last-Modified: Thu, 09 Jul 2026 10:43:28 GMT

期望行为

HEAD 和 GET 应该返回与 PUT 一致的 ETag。

根因分析

server/s3/backend.goHeadObject()GetObject() 返回的 gofakes3.ObjectHash 字段未被填充:

HeadObject (~L112):

// hash := getFileHashByte(fobj)   // ← 计算 hash 的代码被注释

HeadObject 返回值 (~L125):

return &gofakes3.Object{
    Name: objectName,
    // Hash:     hash,              // ← ETag 从未被填充
    Metadata: meta,
    Size:     size,
    Contents: noOpReadCloser{},
}, nil

GetObject 返回值 (~L200): 同样 // Hash: "",

PUT 能返回 ETag 是因为 gofakes3 库在上传过程中自行计算并写入响应;但 HEAD/GET 完全依赖后端返回的 Object.Hash 字段——该字段当前始终为零值。

影响

  • 任何依赖 If-Match / If-None-Match 条件请求的 S3 客户端都会受影响
  • rclone S3 remote 的文件变更检测(modtime + size + hash 比对)依赖 ETag

参考

Metadata

Metadata

Assignees

No one assigned

    Labels

    invalidInvalid Content/Cannot Reproduce

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions