[Bug][im] 经 Latin-1 敏感代理下载非 ASCII 文件名附件时报 HTTP 502
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 17.3k
- Forks
- 1.4k
- Avg merge
- 2d 4h
- Merged PRs (30d)
- 105
Description
沙箱/代理环境下,im +messages-resources-download 下载**文件名含非 ASCII 字符(中文)**的群消息附件时失败,CLI 报 HTTP 502: Bad Gateway。同一命令、同一账号、同一文件在无代理环境(本机直连)下一次成功。
环境
- 触发环境:AI agent 沙箱(出口流量经其内置的 tls-terminate 正向代理,Node 实现),沙箱内 lark-cli
1.0.74 - 对照环境(成功):本机直连(无代理),lark-cli
1.0.63,同一 user 身份 - 触发条件:附件文件名含非 ASCII 字符 且 出口经过会对非 Latin-1 响应头敏感的代理;二者缺一不可
复现命令
(沙箱内执行)
lark-cli im +messages-resources-download \
--as user \
--message-id <om_xxx> \
--file-key <file_v3_xxx> \
--type file \
--output ./中文文件名.docx \
--format json
实际行为
{
"ok": false,
"identity": "user",
"error": {
"type": "network",
"subtype": "server_error",
"code": 502,
"message": "HTTP 502: Bad Gateway"
}
}
跨约 1.5 小时间隔多次重试(4 次),结果一致。
根因分析(已在代理侧定位到错误栈)
502 并非来自飞书服务端,而是本地代理转发上游响应时崩溃产生:
TypeError [ERR_INVALID_CHAR]: Invalid character in header content ["content-disposition"]
at storeHeader (node:_http_outgoing:628:5)
...
at ServerResponse.writeHead (node:_http_server:439:8)
at .../sandbox-runtime/dist/sandbox/tls-terminate-proxy.js:419:13
完整链路:
- lark-cli 按文档约定,下载请求带
Content-Type: application/json(im/v1/message-resource/get的请求头要求;同时官方文档写明「If you need the Content-Disposition header, you need to set the
Content-Type in the header to application/json when initiating the request」); - 飞书正常返回文件字节 +
Content-Disposition: attachment; filename="中文文件名.docx"(裸 UTF-8 头值——RFC 7230 obs-text 文法内合法,但非 RFC 5987 推荐形态); - Node 实现的 MITM 代理把该头
writeHead写回沙箱内客户端时,Node 拒绝非 Latin-1 头值(ERR_INVALID_CHAR),本次转发作废 → CLI 收到 502。
对照组证据(同账号、同一 message/file、同一中文文件名):
| 环境 | lark-cli | 结果 |
|---|---|---|
| 沙箱内(经代理) | 1.0.74 | ❌ 502 ×4 |
| 本机直连(无代理) | 1.0.63 | ✅ 一次成功,完整字节数下载,文件名正常 |
即:CLI 客户端解析与服务端下载本身均正常,唯一断点是「带非 ASCII Content-Disposition 的响应经过 Latin-1 敏感代理」这一组合。该场景下任意服务端发非 ASCII 头都会踩中,飞书只是常见来源之一。
期望行为与建议
--output 已显式指定时,CLI 并不需要服务端原始文件名(按 Content-Disposition 保留原名的特性仅在省略 --output 时有意义)。建议任一:
--output显式时,下载请求省略触发 Content-Disposition 的Content-Type(需验证:不带该头时飞书侧是否仍允许下载——文档只写了正向条件,未说明不带时的行为);- 或提供
--no-content-disposition类开关; - 或至少在 lark-im 的下载参考文档中标注已知限制:在会对非 Latin-1 响应头敏感的代理/沙箱环境下,非 ASCII 文件名的附件下载会失败,workaround 为改用不经该代理的网络出口。
相关
- 下载参考文档:
Preserves the server's original filename via Content-Disposition (supports RFC 5987 UTF-8 encoding)——解析侧已支持 RFC 5987,但服务端实际发送为裸 UTF-8 头值 - 飞书开放平台
im/v1/message-resource/get文档:请求头Content-Type必填application/json; charset=utf-8 - 代理侧(Anthropic sandbox-runtime)的对应 bug 已在该仓库报 issue:anthropics/sandbox-runtime#490(non-latin1 response header 导致 ERR_INVALID_CHAR),尚未修复;本 issue 关注 CLI 侧可独立采取的缓解
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at the im +messages-resources-download command and its handling of --output, then inspect how the im/v1/message-resource/get request sets Content-Type. Verify the explicit-output path through a Latin-1-sensitive proxy and add regression coverage showing that a non-ASCII attachment downloads successfully without requiring Content-Disposition.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- cli, networking
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100