feat: apikey 账号支持请求头覆写(Anthropic/OpenAI)

- 账号 credentials 新增 header_override_enabled / header_overrides,
  仅对 anthropic/openai 平台的 api_key 账号生效
- 转发前对同名请求头做大小写不敏感覆盖(EqualFold 全量删除后按
  wire casing 写入单值),值为空的条目视为占位不参与覆盖
- 覆盖全部出站路径:/v1/messages(标准+透传)、count_tokens、
  /v1/responses、chat completions、embeddings、images、全部 WS 模式、
  账号测试/探测、上游模型列表
- 创建/编辑/批量更新统一校验:RFC 7230 名称格式、去重、长度/条目上限、
  24 个禁止覆写头(认证/连接控制/accept-encoding/sec-websocket-*/
  会话隔离头),应用时二次防御过滤
- 前端三个账号弹窗新增开关+键值行编辑器+模板按钮(Claude Code CLI /
  Codex CLI 标准头,值为空),本地校验与后端规则对齐,i18n 中英文
This commit is contained in:
shaw
2026-07-06 19:11:08 +08:00
parent 6cea1c35bb
commit ec7b20649e
21 changed files with 1526 additions and 3 deletions
+16
View File
@@ -3674,6 +3674,22 @@ export default {
interceptWarmupRequests: 'Intercept Warmup Requests',
interceptWarmupRequestsDesc:
'When enabled, warmup requests like title generation will return mock responses without consuming upstream tokens',
headerOverride: {
title: 'Header Override',
hint: 'Override same-named request headers on forwarding (case-insensitive)',
info: 'Applies to outbound requests of this account only: configured headers override client/gateway-generated headers of the same name before forwarding. Auth headers (authorization, x-api-key) and connection-control headers cannot be overridden.',
namePlaceholder: 'Header name (e.g. user-agent)',
valuePlaceholder: 'Override value (leave empty to skip)',
addRow: 'Add Header',
fillTemplate: 'Fill Template',
emptyValueHint: 'Rows with an empty value are placeholders and do not override anything.',
bulkDisableHint: 'Saving will disable header override and clear existing configuration on the selected accounts.',
invalidName: 'Invalid header name (only letters, digits and !#$%&\'*+-.^_`|~ are allowed)',
blockedName: 'This header cannot be overridden (auth and connection-control headers are managed by the system)',
duplicateName: 'Duplicate header name (matching is case-insensitive)',
invalidValue: 'Invalid header value (control characters are not allowed; max length 8192)',
tooManyEntries: 'Too many header override entries (max 64)'
},
autoPauseOnExpired: 'Auto Pause On Expired',
autoPauseOnExpiredDesc: 'When enabled, the account will auto pause scheduling after it expires',
autoPause5hThreshold: '5h Usage Threshold (%)',
+16
View File
@@ -3842,6 +3842,22 @@ export default {
errorCodeExists: '该错误码已被选中',
interceptWarmupRequests: '拦截预热请求',
interceptWarmupRequestsDesc: '启用后,标题生成等预热请求将返回 mock 响应,不消耗上游 token',
headerOverride: {
title: '请求头覆写',
hint: '转发时用配置值覆盖同名请求头(不区分大小写)',
info: '仅对本账号的出站请求生效:配置的请求头会在转发前覆盖客户端/网关生成的同名头。认证头(authorization、x-api-key)与连接控制头不允许覆写。',
namePlaceholder: '请求头名称(如 user-agent)',
valuePlaceholder: '覆写值(留空表示不覆写)',
addRow: '添加请求头',
fillTemplate: '填入模板',
emptyValueHint: '值留空的行不会参与覆盖,仅作为待填写的占位。',
bulkDisableHint: '保存后将关闭所选账号的请求头覆写并清空已有配置。',
invalidName: '请求头名称格式不正确(仅允许字母、数字和 !#$%&\'*+-.^_`|~ 字符)',
blockedName: '该请求头不允许覆写(认证头与连接控制头由系统管理)',
duplicateName: '存在重复的请求头名称(匹配不区分大小写)',
invalidValue: '请求头值不合法(不允许控制字符,长度不超过 8192)',
tooManyEntries: '请求头覆写条目过多(最多 64 条)'
},
autoPauseOnExpired: '过期自动暂停调度',
autoPauseOnExpiredDesc: '启用后,账号过期将自动暂停调度',
autoPause5hThreshold: '5h 用量阈值(%)',