Skip to content

建议支持配置 chunkedEncodingEnabled 以兼容 Cloudflare Tunnel 等反向代理 #201

@Cl0udTide

Description

@Cl0udTide

问题描述

在使用 Halo S3 插件连接通过 Cloudflare Tunnel 反向代理的 MinIO 服务时,对象存储验证及文件上传操作均失败,报错信息为 403 Forbidden (SignatureDoesNotMatch)

排查过程

  • 使用 aws-cli 在相同网络环境下(通过 Cloudflare Tunnel)使用相同的 Access Key 和 Endpoint 进行上传测试,操作成功,排除了网络连通性和 MinIO 权限配置错误的可能。

  • 初步推测是反向代理导致的 Host 头不匹配引起签名错误。在 Cloudflare Tunnel 的配置中强制指定正确的 Host 头,测试结果依旧为 403 错误。

  • 查阅插件源代码 src/main/java/run/halo/s3os/S3OsAttachmentHandler.java,发现在构建 S3 Client 时硬编码关闭了分块编码:

    // S3OsAttachmentHandler.java 第 227 行左右
    .serviceConfiguration(S3Configuration.builder()
        .chunkedEncodingEnabled(false) // 硬编码为 false
        .pathStyleAccessEnabled(properties.getEnablePathStyleAccess())
        .build())

    该配置强制 AWS SDK 在计算签名时包含 Content-Length 头。

  • Cloudflare Tunnel(以及常见的流式反向代理)默认会对 HTTP/1.1 回源请求启用 Transfer-Encoding: chunked 以优化传输,此过程会移除 Content-Length 头。如果客户端签名包含了 Content-Length,但服务端收到的请求中该头被代理移除并替换为 chunked 编码,则会导致服务端计算签名不匹配,因而返回403错误。后续在 Cloudflare Tunnel 设置中开启 "禁用分块编码",强制代理透传原始 Content-Length 头后,Halo S3 插件的对象存储验证与上传功能恢复正常。

建议

考虑到现代云原生架构中广泛使用 Cloudflare、Kubernetes Ingress 等反向代理中间件,且中间件修改传输编码属于常见行为,硬编码关闭分块编码限制了插件在复杂网络环境下的兼容性。

建议在 S3 插件的存储策略配置中增加一个 “启用分块传输编码” 的开关选项,默认值为关闭,当用户开启该选项时,将chunkedEncodingEnabled 设置为 true,允许 SDK 使用分块传输并调整签名策略,从而兼容 Cloudflare 等反向代理环境。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions