fix: P0-2 深度根因修复 — Worker端URL校验403 + endpoint HTTPS修复 #211
Reference in New Issue
Block a user
Delete Branch "fix/p02-deep-root-cause"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
根因分析
问题 1(P0 紧急):Worker 端上传后 URL 校验永远失败
现象:所有生成任务在 OSS 上传后失败,报 "OSS 上传后 URL 不可访问"。
根因:
_verify_url_accessible()用裸 URL 直接发起 HEAD 请求,私有 bucket 下永远返回 403,导致所有生成任务失败。修复:
get_signed_download_url()生成预签名 URLbucket.object_exists()确认上传成功(上传成功本身就是最可靠的凭证)问题 2:Worker 端 oss_bucket() endpoint 无 scheme
根因:
oss_helpers.py的oss_bucket()直接使用环境变量中的 endpoint(如oss-cn-hangzhou.aliyuncs.com),不传 scheme。oss2 SDK 在这种情况下 sign_url 会默认生成 HTTP URL。修复:endpoint 不带 scheme 时自动补
https://,与 API 端 storage.py 的修复保持一致。问题 3:API 端 results 接口返回裸 URL?
排查结论:API 端代码逻辑正确,不是后端 bug。
/api/v1/generation/tasks/{task_id}/results接口确实调用了storage_service.get_download_url(),预签名 URL 放在download_url字段返回。file_url字段保留原始 URL(设计如此)。如果前端拿不到预签名 URL,可能原因:
file_url而非download_url字段改动文件
apps/worker/video_processing/oss_helpers.pyapps/worker/worker_app/tasks/generation.pytests/unit/test_p02_worker_oss_fix.py测试
新增 10 个单元测试:
测试结果:10/10 passed
✅ PR #211 代码审计通过(P0-2 深度修复 — Worker 端)
评级:0P0 / 0P1 / 0P2 / 3P3
🔧 修复一:Worker 端 URL 校验方案
方案:预签名 URL 校验 + object_exists 降级兜底 ✅
修复前:私有 bucket 下
_verify_url_accessible(file_url)永远返回 403,导致所有生成任务全失败。修复后三级容错:
get_signed_download_url(file_url, expires_seconds=300),300s 有效期足够方案分析:
object_exists使用 SDK 认证 API,不受 bucket ACL 影响🔧 修复二:oss_bucket() endpoint HTTPS 前缀
与 API 端 storage.py 实现一致 ✅
startswith(("http://", "https://"))startswith(("http://", "https://"))f"https://{bucket_endpoint}"f"https://{endpoint}"两端实现完全一致,无差异风险。
🧪 测试验证(10/10 通过)
测试质量评价:良好
sign_url.assert_called_once_with("GET", "generated/test.mp4", 3600))_verify_url_accessible降级逻辑的集成测试(需要 mock 多层依赖,成本较高,可以接受)相关回归测试全部通过:67/67 ✅
🔍 漏网之鱼排查
全局排查了
apps/worker/下所有 HTTP 访问点:_verify_url_accessibledownload_assetupload_to_ossffmpeg_utils/ subprocess结论:无遗漏。 Worker 端所有 OSS 访问要么走 SDK 认证,要么已修复为预签名 URL。
💡 P3 建议(非阻塞)
P3-1:fallback 分支的 import 可以上移
from video_processing.oss_helpers import oss_bucket, normalize_storage_key放在 fallback 分支内oss_helpers顶部已经 import 了(get_signed_download_url就来自这里)get_signed_download_url同模块引用P3-2:upload_to_oss 文档与实际不符
P3-3:预签名失败时的额外 HTTP 请求冗余
get_signed_download_url返回 None 时,verify_url = file_url(裸 URL),然后_verify_url_accessible会发起一次必定失败的 HEAD 请求object_exists检查,省掉一次不必要的 HTTP 请求✅ 结论
P0-2 Worker 端深度修复正确,方案健壮,测试充分,无安全风险,可以合并。
与 PR #209(API 端 HTTPS 修复)+ PR #210(P0-3 fps/setpts)一起合并部署到 staging 后,即可启动第五轮端到端验证。
✅ PR #211 slash_safe 修复复审通过
复审范围:
481b4216commit — sign_url 添加 slash_safe=True🔧 修复验证
根因准确 ✅
slash_safe=False,key 中的/会被编码为%2Fslash_safe=True是标准修复方式两端均已修复 ✅
storage.py:202get_download_url()slash_safe=Trueoss_helpers.py:137get_signed_download_url()slash_safe=True全局排查
apps/下所有sign_url调用:仅上述 2 处,无遗漏。🧪 测试验证
两端各 1 个新增测试,共 2 个,全部通过 ✅
test_sign_url_uses_slash_safe_for_path_keys— 验证带路径 key 调用时slash_safe=Truetest_sign_url_uses_slash_safe_for_path_keys— 同上测试质量:直接验证
call_args.kwargs.get("slash_safe") is True,精准验证参数传递,而不是只测返回值。另外原有 2 个测试的
assert_called_once_with断言也同步更新了slash_safe=True,确保不回归。✅ 结论
slash_safe 修复正确,两端全覆盖,测试充分,复审通过。
PR #211 整体最终评级:0P0 / 0P1 / 0P2 / 3P3,可与 #209、#210 一起合并部署。