Skip to content

[Feature] 为 S3 direct-link 302 与 Web Proxy 增加显式兼容性契约 #2796

Open

Description

@nostalume

请确认以下事项

  • 我已确认阅读并同意 AGPL-3.0 第15条 。本程序不提供任何明示或暗示的担保,使用风险由您自行承担。
  • 我已确认阅读并同意 AGPL-3.0 第16条 。无论何种情况,版权持有人或其他分发者均不对使用本程序所造成的任何损失承担责任。
  • 我确认我的描述清晰,语法礼貌,能帮助开发者快速定位问题,并符合社区规则。
  • 我已确认阅读了 OpenList文档。
  • 我已确认没有重复的问题或讨论。
  • 我认为此问题必须由 OpenList 处理,而非第三方。
  • 我已确认此功能尚未被实现。
  • 我已确认此功能是合理的,且有普遍需求,并非我个人需要。
  • 我没有阅读这个清单,只是闭眼选中了所有的复选框,请关闭这个 Issue 。

需求描述

OpenList 的独立 S3 endpoint 在 storage 的 web_proxy=false 且没有其他强制代理条件时,已认证的普通对象 GET 如果获得可用的 provider URL-only 直链,可能返回 HTTP 302;并非所有 S3 GET 都会重定向。

在 server/s3/redirect.go 中,redirectHandler 会设置 Location 并返回 http.StatusFound。

对于某些严格的 S3 client(例如 restic),GetObject 收到跨 host 的云盘临时直链 302 后因不符合S3规范,无法读取对象。这个 redirect 不是典型的 S3 region/endpoint redirect,而是把 OpenList 的对象读取改道至 provider 的临时 URL。

将目标 storage 的 web_proxy=true 后,common.ShouldProxy() 会阻止 S3 redirect handler 返回 direct-link,OpenList 本机代理读取,可避开由该跨 host 302 引起的兼容性问题。

实现思路

  1. 在 S3 文档中明确:web_proxy=false 且满足直链条件时,S3 GET 可能返回 provider direct-link 302,部分 S3 client(包括 restic)可能不兼容。
  2. 考虑为 S3 endpoint 增加独立、显式的 s3_direct_redirect opt-in;默认以本地代理返回对象内容,或至少针对 repository/workload client 保持 S3 GET 语义稳定。
  3. 在 UI 中明确 storage 的 Web Proxy 对 S3 的影响。

附加信息

这不会移除 direct-link 优化;它会让管理员能明确选择吞吐优先还是 S3 客户端兼容性优先,并避免将 302 排查成 endpoint、bucket 或 credential 问题。

Activity

  1. xrgzs commented on Jul 16, 2026

    @xrgzs
    Member

    请严格按照issue模版填写信息

  2. huoxingdawang commented on Jul 19, 2026

    @huoxingdawang
    Contributor

    确实有这个问题
    如果配置中不设置 web_proxy=true,restic在使用s3后端的时候会一直报告 302 error

  3. changed the title [-][Enhancement] 明确并配置 S3 direct-link 302 与 Web Proxy 的兼容性行为[/-] [+][Feature] 为 S3 direct-link 302 与 Web Proxy 增加显式兼容性契约[/+] on Jul 23, 2026
  4. nostalume commented on Jul 23, 2026

    @nostalume
    ContributorAuthor

    @xrgzs 已依照规范修改

  5. reopened this on Jul 23, 2026
  6. added and removed
    invalidInvalid Content/Cannot Reproduce
    on Jul 23, 2026
  7. xrgzs commented on Jul 23, 2026

    @xrgzs
    Member

    目前审查发现S3 Server下载部分的文档和最新的实现对不上,需要更新文档。

  8. nostalume commented on Aug 26, 2026

    @nostalume
    ContributorAuthor

    目前 proxy 设置下使用rustic/restic备份时会将其 range-read 转发到 Aliyun Drive callback 下载。并发读取 pack 时,Aliyun Drive 返回:

    RequestDeniedByCallback / ExceedMaxConcurrency

    OpenList 最终向 S3 client 返回 HTTP 500。将 rustic 的连接数限制为 1 可以绕过问题,但这把后端限流责任交给了每一个客户端,并迫使 repository workload 串行。

    建议将 “S3 响应语义” 与 “后端传输策略” 分离:

    1. S3 endpoint 默认使用 proxy 模式,直接返回对象流并保持 Range / Content-Range 等 S3 GetObject 语义

    2. 为每个 storage 增加独立的代理下载并发上限,例如 s3_proxy_max_concurrency,而不是依赖全局 max_concurrency 或客户端自行限流。

    3. proxy 模式下,将客户端 Range 请求透传给后端 RangeReader,并流式转发响应,不缓存完整对象;用按 storage 的 semaphore/队列限制同时进行的 callback download。

    4. 队列饱和或 provider 明确限流时,返回可重试的 S3 错误(例如 SlowDown / 503,并可附 Retry-After),不要统一包装成无法诊断的 HTTP 500。

    5. 浏览器/普通下载可选择 direct 以获得直链吞吐;S3 repository client 选择 proxy 以获得稳定的协议语义。两者不应由 web_proxy 这个通用开关隐式混合。

  9. nostalume commented on Sep 18, 2026

    @nostalume
    ContributorAuthor

    进度更新(2026-09-18):S3 下载传输模式的文档更正已由 OpenListTeam/OpenList-Docs#368 合并;本 Issue 正文也已更正为“满足直链条件时可能返回 302”,并移除了误写的自引用。

    独立的 s3_direct_redirect 开关、默认策略和 UI 提示仍是待讨论的提议,尚未实现,因此本 Issue 保持开放。此前评论涉及的阿里云盘 callback 并发与 S3 SlowDown 已由 #2969 和审核中的 #3071 单独跟踪;#3071 使用按阿里云盘用户共享的上限,并未实现这里曾提议的每 storage 限制或 Retry-After。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions