docs(comments): 注释中文化 · plugins/channels/weixin_ilink(20 文件,纯替换)
CI / Backend (build / vet / test / cross-compile) (push) Has been cancelled
CI / Frontend (tsc + vite build) (push) Has been cancelled

- 只翻注释/文档字符串:剥掉行尾注释后,每条「-」都有逐字节相同的「+」对应行(8 组,代码零改动)
- 保留协议/线上标识符原文:errcode、bot_token、context_token、getupdates、binded_redirect、PKCS#7、ECB 等
- 术语对齐既有译法:owner→主人、peer→对端、long poll→长轮询、backoff→退避、sentinel error→哨兵错误
- 已知既有欠债(未顺手修):login_reuse_test.go 在 HEAD 上就未 gofmt 干净;login_test.go 的 TestStartLogin_ScanStatusTransition 91 行 >80(HEAD 同为 91 行)
This commit is contained in:
AskaEth committed 2026-10-04 12:29:05 +08:00
1 parent 09fba77f87
commit 95f97f5df3
20 files changed
+488 -590

No files matched your search

+11 -15
View File
@@ -11,15 +11,12 @@ import (
"strings"
)
// ErrKeyTooShort is returned when the inbound derivation cannot yield an AES
// key of the required block size.
// ErrKeyTooShort 在入站密钥推导无法给出所需分组长度的 AES 密钥时返回。
var ErrKeyTooShort = errors.New("weixin_ilink: derived key shorter than a block")
// deriveInboundKey derives the AES-128 key for an inbound media payload. Per
// design/08 §3.3 the key is extracted from the bot_token: base64-decode the
// token and take the trailing 16 bytes. This is marked ⚠️ in the reference, so
// DownloadMediaWithKey lets callers supply an explicit key when the platform
// carries one per item instead.
// deriveInboundKey 为入站媒体负载推导 AES-128 密钥。按 design/08 §3.3,密钥从
// bot_token 中提取:先 base64 解码 token,再取末尾 16 字节。参考实现把这一步标记为
// ⚠️,因此 DownloadMediaWithKey 允许调用方在平台按每条媒体下发密钥时显式传入密钥。
func deriveInboundKey(botToken string) ([]byte, error) {
token := strings.TrimSpace(botToken)
if token == "" {
@@ -35,9 +32,8 @@ func deriveInboundKey(botToken string) ([]byte, error) {
return b[len(b)-aes.BlockSize:], nil
}
// DownloadMedia downloads an inbound CDN reference and returns the decrypted
// plaintext using the key derived from the configured bot_token. It fails with
// ErrMediaTooLarge when the ciphertext exceeds MaxMediaSize.
// DownloadMedia 下载一条入站 CDN 引用,并用从已配置 bot_token 推导出的密钥返回
// 明文。密文超过 MaxMediaSize 时以 ErrMediaTooLarge 失败。
func (a *Adapter) DownloadMedia(ctx context.Context, cdnURL string) ([]byte, error) {
key, err := deriveInboundKey(a.cfg.BotToken)
if err != nil {
@@ -46,8 +42,8 @@ func (a *Adapter) DownloadMedia(ctx context.Context, cdnURL string) ([]byte, err
return a.downloadWithKey(ctx, cdnURL, key)
}
// DownloadMediaWithKey is DownloadMedia with an explicit per-item AES key,
// used when the protocol delivers the key alongside the media reference.
// DownloadMediaWithKey 是 DownloadMedia 的显式按条 AES 密钥版本,用于协议把密钥
// 与媒体引用一并下发的场景。
func (a *Adapter) DownloadMediaWithKey(ctx context.Context, cdnURL string, key []byte) ([]byte, error) {
if len(key) != aes.BlockSize {
return nil, fmt.Errorf("weixin_ilink: key must be %d bytes: %w", aes.BlockSize, ErrKeyTooShort)
@@ -55,7 +51,7 @@ func (a *Adapter) DownloadMediaWithKey(ctx context.Context, cdnURL string, key [
return a.downloadWithKey(ctx, cdnURL, key)
}
// downloadWithKey fetches the CDN bytes and removes the AES-ECB layer.
// downloadWithKey 拉取 CDN 字节并剥掉 AES-ECB 层。
func (a *Adapter) downloadWithKey(ctx context.Context, cdnURL string, key []byte) ([]byte, error) {
ciphertext, err := a.fetchBody(ctx, a.cdnURL(cdnURL))
if err != nil {
@@ -68,8 +64,8 @@ func (a *Adapter) downloadWithKey(ctx context.Context, cdnURL string, key []byte
return plaintext, nil
}
// fetchBody GETs rawURL and returns the body, refusing anything over
// MaxMediaSize so a single huge file cannot exhaust memory.
// fetchBody 对 rawURL 发 GET 并返回响应体,超过 MaxMediaSize 的一律拒绝,避免单个
// 超大文件耗尽内存。
func (a *Adapter) fetchBody(ctx context.Context, rawURL string) ([]byte, error) {
req, err := http.NewRequestWithContext(ctx, http.MethodGet, rawURL, nil)
if err != nil {