Skip to content

fix(proxy): preserve User-Agent for gemini providers (fix #515)#520

Merged
ding113 merged 1 commit intodevfrom
fix/515-gemini-user-agent
Jan 3, 2026
Merged

fix(proxy): preserve User-Agent for gemini providers (fix #515)#520
ding113 merged 1 commit intodevfrom
fix/515-gemini-user-agent

Conversation

@ding113
Copy link
Owner

@ding113 ding113 commented Jan 3, 2026

Summary

Fixes User-Agent header loss in Gemini provider forwarding, which caused Cloudflare to block requests. This PR implements header passthrough for Gemini providers similar to the approach used in PR #465 for Codex.

修复 Gemini 供应商转发时 User-Agent 请求头丢失的问题,该问题导致 Cloudflare 拦截请求。此 PR 为 Gemini 供应商实现了类似 PR #465 中 Codex 的请求头透传机制。

Problem

Related Issues:

Root Cause:

In the Gemini/Gemini-CLI forwarding branch, the code used new Headers() to rebuild request headers from scratch, which caused:

  1. User-Agent loss: Original user-agent header was not preserved, causing Cloudflare to block requests
  2. Filter bypass: Request filter and provider filter modifications to headers were not applied
  3. Inconsistent behavior: Different from other provider types (Claude, OpenAI, Codex)

Gemini/Gemini-CLI 转发分支使用 new Headers() 重建请求头,导致:

  1. User-Agent 丢失,被 Cloudflare 拦截
  2. 请求过滤器/供应商过滤器对 header 的修改不生效
  3. 与其他供应商类型(Claude、OpenAI、Codex)行为不一致

Solution

Changed Gemini branch to use header passthrough based on session.headers with unified filtering/override via HeaderProcessor:

  1. New buildGeminiHeaders() method: Centralized header processing for Gemini providers
  2. Header passthrough: Base headers on session.headers (includes filter modifications)
  3. Security: Explicit blacklist to remove proxy authentication headers (authorization, x-api-key, x-goog-api-key) to prevent leaking proxy user keys to upstream
  4. User-Agent priority:
    • First: Filter-modified session.headers["user-agent"]
    • Fallback: Original session.userAgent
    • Last resort: "claude-code-hub"
  5. Upstream authentication override: Set x-goog-api-key (API key mode) or Authorization: Bearer (OAuth mode) for upstream

修改 Gemini 分支改为基于 session.headers 进行透传,使用 HeaderProcessor 统一过滤/覆盖:

  1. 新增 buildGeminiHeaders() 方法统一处理 Gemini 供应商请求头
  2. 请求头透传:基于 session.headers(包含过滤器修改)
  3. 安全性:显式黑名单移除代理认证头避免泄露
  4. User-Agent 优先级:过滤器 → 原始 → 兜底
  5. 上游鉴权覆盖:根据模式设置正确的认证头

Changes

Core Changes (src/app/v1/_lib/proxy/forwarder.ts)

  • Removed hardcoded new Headers() logic in Gemini forwarding branch (lines 851-872)
  • Added buildGeminiHeaders() private method (+51 lines):
    • Implements header passthrough with HeaderProcessor
    • Explicit authentication header blacklist for security
    • User-agent resolution with 3-tier fallback
    • Support for preserveClientIp (X-Forwarded-For, X-Real-IP)
    • Gemini-CLI specific headers (x-goog-api-client)

Test Coverage (tests/unit/proxy/proxy-forwarder.test.ts)

Added 5 comprehensive test cases for buildGeminiHeaders() (+163 lines):

  1. ✅ User-agent passthrough with upstream authentication override (API key mode)
  2. ✅ Request filter modifications to user-agent are respected
  3. ✅ Fallback to original userAgent when filter deletes user-agent
  4. ✅ OAuth mode uses Authorization: Bearer and removes x-goog-api-key
  5. ✅ Gemini-CLI injects x-goog-api-client header

Breaking Changes

None. This is a bug fix that aligns Gemini provider behavior with other provider types.

Testing

Automated Tests

  • ✅ Unit tests added (5 new tests for header passthrough)
  • ✅ bun run test
  • ✅ bun run typecheck
  • ✅ bun run lint
  • ✅ bun run build

Manual Testing Needed

To verify the fix for #515:

  1. Configure a Gemini provider with a custom request filter that sets user-agent
  2. Send a request through the proxy
  3. Verify Cloudflare does not block the request
  4. Check session details to confirm user-agent is present and matches filter settings

Architecture Note

This PR applies the same header modification tracking pattern introduced in #465 (for Codex) to Gemini providers, ensuring consistent header handling across all provider types:

Checklist

  • Code follows project conventions
  • Self-review completed
  • Tests pass locally (5 new unit tests)
  • No documentation changes needed (internal fix)
  • Security: Proxy authentication headers properly blacklisted

🤖 Description enhanced by Claude AI

@coderabbitai
Copy link

coderabbitai bot commented Jan 3, 2026

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

📝 Walkthrough

概览

在 ProxyForwarder 中引入新的私有静态辅助方法 buildGeminiHeaders,用于集中处理 Gemini 和 Gemini-cli 相关的请求头构建,包括认证、主机、内容类型等头部信息,替代之前分散的头部处理逻辑。

变更清单

类别 / 文件 变更摘要
核心代理逻辑
src/app/v1/_lib/proxy/forwarder.ts
新增 buildGeminiHeaders 私有静态方法,统一处理 Gemini 请求头构建(包括授权、API 密钥、User-Agent、主机、内容类型等);将原有分散的头部构建逻辑集中到该方法中;确保通过 HeaderProcessor 进行默认头部处理
测试覆盖
tests/unit/proxy/proxy-forwarder.test.ts
新增 createGeminiProvider 测试辅助函数;新增测试套件 "ProxyForwarder - buildGeminiHeaders headers passthrough" 验证 API 密钥模式、OAuth 模式、User-Agent 过滤、Gemini-cli 客户端头等多个场景的正确性

预估代码审查工作量

🎯 3 (中等) | ⏱️ ~20 分钟

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed 标题准确总结了主要改动:为gemini供应商保留User-Agent,并关联了修复的问题#515
Linked Issues check ✅ Passed 代码变更成功实现了问题#515的核心需求:通过保留User-Agent和正确处理认证头来避免Cloudflare拦截。
Out of Scope Changes check ✅ Passed 所有代码变更都在问题#515的范围内,专注于修复Gemini头部转发和认证处理的问题。
Description check ✅ Passed PR 描述清晰完整地说明了问题(User-Agent 丢失导致 Cloudflare 拦截)、解决方案(引入 buildGeminiHeaders 方法实现请求头透传)及其原理,与代码变更高度相关。
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/515-gemini-user-agent

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @ding113, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

此拉取请求旨在解决Gemini代理服务中请求头处理不当的问题,特别是User-Agent丢失和请求过滤器失效。通过重构请求头构建逻辑,现在能够更安全、更灵活地处理Gemini提供商的请求头,确保User-Agent的正确传递,并防止代理认证信息泄露,同时增强了代码的可维护性和测试覆盖率。

Highlights

  • Gemini代理请求头处理优化: 修复了此前使用new Headers()重建请求头导致User-Agent丢失以及请求过滤器对头部修改失效的问题。
  • 统一的请求头构建逻辑: 引入了buildGeminiHeaders私有静态方法,该方法基于session.headers进行透传,并利用HeaderProcessor实现统一的过滤、覆盖和上游鉴权处理。
  • 增强安全性: 显式地将代理侧的认证头(如authorizationx-api-keyx-goog-api-key)列入黑名单并移除,以防止代理用户的敏感密钥意外泄露给上游服务。
  • User-Agent优先级处理: 确保User-Agent头按照明确的优先级顺序设置:优先使用过滤器修改后的session.headers中的user-agent,其次回退到session.userAgent,最后使用默认值claude-code-hub
  • 新增单元测试: 为Gemini请求头的透传、鉴权覆盖、敏感头移除以及gemini-cli特定头的注入等新逻辑添加了全面的单元测试,提高了代码的健壮性。
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

本次 PR 修复了 Gemini 供应商请求头(特别是 User-Agent)未能正确透传的 Bug,做得很好。通过重构 Gemini 的请求头构建逻辑,统一使用 HeaderProcessor,显著提升了代码的一致性和可维护性。新的实现正确地处理了会话中的请求头透传、过滤器修改以及上游鉴权的覆盖,并通过黑名单机制安全地移除了代理侧的用户凭证,防止了密钥泄露风险。此外,新增的单元测试覆盖了各种场景,包括 API Key 和 OAuth 模式、User-Agent 的回退逻辑等,确保了修复的可靠性。我有一个关于代码明确性的小建议,除此之外,这是一个高质量的修复。

}

const headerProcessor = HeaderProcessor.createForProxy({
blacklist: ["content-length", "connection", "x-api-key", GEMINI_PROTOCOL.HEADERS.API_KEY],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

为了提高代码的明确性和可维护性,建议在黑名单中显式添加 authorization。虽然 HeaderProcessor.createForProxy 默认会因 preserveAuthorization: false 而隐式地将其加入黑名单,但显式声明可以使意图更加清晰,并减少对 HeaderProcessor 内部实现的依赖。这也与 PR 描述中提到的“显式黑名单移除 proxy 侧认证头(authorization/x-api-key/x-goog-api-key)”保持一致。

Suggested change
blacklist: ["content-length", "connection", "x-api-key", GEMINI_PROTOCOL.HEADERS.API_KEY],
blacklist: ["content-length", "connection", "authorization", "x-api-key", GEMINI_PROTOCOL.HEADERS.API_KEY],

@github-actions github-actions bot added the size/M Medium PR (< 500 lines) label Jan 3, 2026
@github-actions
Copy link
Contributor

github-actions bot commented Jan 3, 2026

🧪 测试结果

测试类型 状态
代码质量
单元测试
集成测试
API 测试

总体结果: ✅ 所有测试通过

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
src/app/v1/_lib/proxy/forwarder.ts (1)

1815-1815: 可选优化:User-Agent 解析逻辑与 Codex 分支略有不同。

当前 Gemini 实现使用简单的 nullish coalescing:

session.headers.get("user-agent") ?? session.userAgent ?? "claude-code-hub"

而 Codex 分支(第 1721-1738 行)使用 isHeaderModified 检测来决定是否使用过滤后的值。

两种实现在实际场景中结果相同,但如果未来需要统一行为,可以考虑提取为共享辅助函数。

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to Reviews > Disable Cache setting

📥 Commits

Reviewing files that changed from the base of the PR and between e488505 and 6f3520a.

📒 Files selected for processing (2)
  • src/app/v1/_lib/proxy/forwarder.ts
  • tests/unit/proxy/proxy-forwarder.test.ts
🧰 Additional context used
📓 Path-based instructions (10)
**/*.{ts,tsx,js,jsx,json}

📄 CodeRabbit inference engine (CLAUDE.md)

Use 2-space indentation in all code files

Files:

  • tests/unit/proxy/proxy-forwarder.test.ts
  • src/app/v1/_lib/proxy/forwarder.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx,js,jsx}: Use double quotes for strings instead of single quotes
Use trailing commas in multi-line structures
Enforce maximum line length of 100 characters
Use path alias @/* to reference files from ./src/* directory

**/*.{ts,tsx,js,jsx}: Use Biome for linting and formatting with 2-space indent, double quotes, trailing commas, and 100 character max line length
Use path alias @/* to reference files in ./src/* directory

Files:

  • tests/unit/proxy/proxy-forwarder.test.ts
  • src/app/v1/_lib/proxy/forwarder.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Use TypeScript strict mode for type safety
Use readonly or const assertions for immutable data structures

Files:

  • tests/unit/proxy/proxy-forwarder.test.ts
  • src/app/v1/_lib/proxy/forwarder.ts
**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use Vitest for unit testing with Node environment, coverage thresholds: 50% lines/functions, 40% branches

Files:

  • tests/unit/proxy/proxy-forwarder.test.ts
**/*.test.ts

📄 CodeRabbit inference engine (AGENTS.md)

Ensure test database names contain 'test' keyword for safety validation

Files:

  • tests/unit/proxy/proxy-forwarder.test.ts
src/app/v1/_lib/**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Guard pipeline must execute in order: ProxyAuthenticator, SensitiveWordGuard, VersionGuard, ProxySessionGuard, ProxyRateLimitGuard, ProxyProviderResolver

Files:

  • src/app/v1/_lib/proxy/forwarder.ts
src/app/v1/_lib/proxy/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

src/app/v1/_lib/proxy/**/*.ts: Implement guard pipeline pattern for cross-cutting concerns in request processing (auth, rate limiting, session)
Use undici library for HTTP requests instead of node-fetch for better performance

Files:

  • src/app/v1/_lib/proxy/forwarder.ts
src/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

src/**/*.ts: Hash API keys using SHA-256 before storing in database, never store plaintext keys
Mask API keys and sensitive data in application logs
Validate required environment variables at startup with clear error messages

Files:

  • src/app/v1/_lib/proxy/forwarder.ts
src/app/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Implement Content-Security-Policy headers for XSS prevention

Files:

  • src/app/v1/_lib/proxy/forwarder.ts
src/app/v1/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Use Hono router for ultrafast, lightweight routing in proxy endpoints

Files:

  • src/app/v1/_lib/proxy/forwarder.ts
🧠 Learnings (6)
📚 Learning: 2026-01-03T09:08:20.573Z
Learnt from: CR
Repo: ding113/claude-code-hub PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-03T09:08:20.573Z
Learning: Applies to src/app/v1/_lib/proxy-handler.ts : Structure request flow in proxy handler through: ProxySession.fromContext() -> detectFormat() -> GuardPipelineBuilder.run() -> ProxyForwarder.send() -> ProxyResponseHandler.dispatch()

Applied to files:

  • tests/unit/proxy/proxy-forwarder.test.ts
  • src/app/v1/_lib/proxy/forwarder.ts
📚 Learning: 2026-01-03T09:10:02.182Z
Learnt from: NieiR
Repo: ding113/claude-code-hub PR: 517
File: src/app/v1/_lib/proxy/auth-guard.ts:205-232
Timestamp: 2026-01-03T09:10:02.182Z
Learning: In `src/app/v1/_lib/proxy/auth-guard.ts`, the `extractApiKeyFromHeaders` function is intentionally a standalone simplified version for non-Guard flows. It deliberately does not check for multi-source conflicts (unlike `ProxyAuthenticator.validate`), and the code duplication is intentional to avoid coupling between Guard and non-Guard authentication flows.

Applied to files:

  • tests/unit/proxy/proxy-forwarder.test.ts
  • src/app/v1/_lib/proxy/forwarder.ts
📚 Learning: 2026-01-03T09:08:49.019Z
Learnt from: CR
Repo: ding113/claude-code-hub PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-03T09:08:49.019Z
Learning: Applies to src/app/v1/_lib/proxy/**/*.ts : Implement guard pipeline pattern for cross-cutting concerns in request processing (auth, rate limiting, session)

Applied to files:

  • src/app/v1/_lib/proxy/forwarder.ts
📚 Learning: 2026-01-03T09:08:49.019Z
Learnt from: CR
Repo: ding113/claude-code-hub PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-03T09:08:49.019Z
Learning: Applies to src/app/v1/_lib/proxy/**/*.ts : Use undici library for HTTP requests instead of node-fetch for better performance

Applied to files:

  • src/app/v1/_lib/proxy/forwarder.ts
📚 Learning: 2026-01-03T09:08:20.573Z
Learnt from: CR
Repo: ding113/claude-code-hub PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-03T09:08:20.573Z
Learning: Applies to src/app/v1/_lib/**/*.ts : Guard pipeline must execute in order: ProxyAuthenticator, SensitiveWordGuard, VersionGuard, ProxySessionGuard, ProxyRateLimitGuard, ProxyProviderResolver

Applied to files:

  • src/app/v1/_lib/proxy/forwarder.ts
📚 Learning: 2026-01-03T09:08:49.019Z
Learnt from: CR
Repo: ding113/claude-code-hub PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-03T09:08:49.019Z
Learning: Applies to src/app/v1/_lib/proxy/*handler*.ts : Stream responses with proper backpressure handling and chunked transfer encoding

Applied to files:

  • src/app/v1/_lib/proxy/forwarder.ts
🧬 Code graph analysis (1)
src/app/v1/_lib/proxy/forwarder.ts (4)
src/app/v1/_lib/gemini/auth.ts (1)
  • isApiKey (79-82)
src/app/v1/_lib/proxy/session.ts (1)
  • ProxySession (48-671)
src/app/v1/_lib/headers.ts (1)
  • HeaderProcessor (20-143)
src/app/v1/_lib/gemini/protocol.ts (1)
  • GEMINI_PROTOCOL (1-20)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
  • GitHub Check: Greptile Review
  • GitHub Check: 🌐 API Tests
  • GitHub Check: Docker Build Test
  • GitHub Check: pr-description
  • GitHub Check: pr-label
  • GitHub Check: pr-review
  • GitHub Check: check-codex-status
  • GitHub Check: dev-build-deploy
🔇 Additional comments (6)
tests/unit/proxy/proxy-forwarder.test.ts (4)

62-69: LGTM!测试辅助函数结构清晰。

createGeminiProvider 辅助函数与现有的 createCodexProvider 模式一致,正确地支持 "gemini""gemini-cli" 两种类型。


160-197: LGTM!API key 模式测试覆盖全面。

测试正确验证了关键的安全行为:

  • 代理侧认证头(x-api-keyauthorizationx-goog-api-key)被移除,防止泄露
  • 上游 x-goog-api-key 使用正确的上游密钥
  • user-agent 被正确透传

199-253: LGTM!User-Agent 过滤和回退逻辑测试完整。

两个测试用例正确覆盖了:

  1. 过滤器修改 user-agent 的场景(应使用过滤后的值)
  2. 过滤器删除 user-agent 的场景(应回退到原始 userAgent

255-311: LGTM!OAuth 模式和 gemini-cli 测试覆盖到位。

  • OAuth 模式测试验证了 Authorization: Bearer 正确设置且 x-goog-api-key 被移除
  • gemini-cli 测试验证了 x-goog-api-client: GeminiCLI/1.0 头的注入

这些测试与 Issue #515 的修复目标一致,确保请求不会被 CF 拦截。

src/app/v1/_lib/proxy/forwarder.ts (2)

859-868: LGTM!Gemini 分支现在使用统一的头部处理逻辑。

将 Gemini 头部构建委托给 buildGeminiHeaders 方法,解决了之前使用 new Headers() 导致 User-Agent 丢失和过滤器失效的问题。注释清晰说明了改动原因。


1801-1844: 头部处理逻辑正确,安全性得到保障。

实现正确处理了以下关键点:

  1. 认证头安全:通过黑名单移除客户端的 x-api-keyx-goog-api-keyauthorizationcreateForProxy 默认设置 preserveAuthorization: false 自动加入黑名单,然后通过 overrides 设置上游认证。

  2. User-Agent 解析链session.headers.get("user-agent") ?? session.userAgent ?? "claude-code-hub" 正确实现了优先级顺序。

  3. gemini-cli 特殊处理:正确注入 x-goog-api-client 头。

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Summary

No significant issues identified in this PR.

PR Size: M

  • Lines changed: 239
  • Files changed: 2

Review Coverage

  • Logic and correctness - Clean
  • Security (OWASP Top 10) - Clean
  • Error handling - Clean
  • Type safety - Clean
  • Documentation accuracy - Clean
  • Test coverage - Adequate
  • Code clarity - Good

Automated review by Codex AI

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Applied PR size label size/M to #520 (239 lines changed across 2 files) and submitted a review via gh pr review.

No diff-scoped issues met the reporting threshold, so no inline review comments were posted.

@ding113 ding113 merged commit a479718 into dev Jan 3, 2026
20 checks passed
@github-project-automation github-project-automation bot moved this from Backlog to Done in Claude Code Hub Roadmap Jan 3, 2026
Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Summary

This PR successfully fixes the User-Agent header loss issue in Gemini provider forwarding by implementing header passthrough similar to the Codex provider approach. The implementation is clean, well-tested, and follows established patterns in the codebase.

PR Size: M

  • Lines changed: 239 (218 additions, 21 deletions)
  • Files changed: 2

Issues Found

Category Critical High Medium Low
Logic/Bugs 0 0 0 0
Security 0 0 0 0
Error Handling 0 0 0 0
Types 0 0 0 0
Comments/Docs 0 0 0 0
Tests 0 0 0 0
Simplification 0 0 0 0

Code Quality Assessment

Strengths:

  • ✅ Comprehensive test coverage (5 new test cases covering all scenarios)
  • ✅ Proper security: Proxy authentication headers correctly blacklisted
  • ✅ Consistent with existing codebase patterns (follows Codex provider approach)
  • ✅ Error handling properly delegated to existing retry/circuit breaker logic
  • ✅ Type-safe implementation with no any usage
  • ✅ All automated checks pass (tests, typecheck, lint, build)

Implementation Details Verified:

  • User-Agent resolution uses 3-tier fallback: filter-modified → original → default
  • Authorization headers properly sanitized (proxy credentials removed, upstream credentials added)
  • Header passthrough via HeaderProcessor with appropriate blacklist
  • OAuth vs API key authentication modes both handled correctly
  • Gemini-CLI specific headers (x-goog-api-client) properly injected

Architecture Alignment:
This PR completes the header passthrough standardization across all provider types:

  • Claude/OpenAI: Uses buildHeaders() with HeaderProcessor
  • Codex: Uses buildHeaders() with modification tracking (#465)
  • Gemini: Now uses buildGeminiHeaders() with same HeaderProcessor pattern ✓

Review Coverage

  • Logic and correctness - Clean
  • Security (OWASP Top 10) - Clean
  • Error handling - Clean
  • Type safety - Clean
  • Documentation accuracy - Clean
  • Test coverage - Comprehensive
  • Code clarity - Good

Recommendation: Approve and merge


Automated review by Claude AI

@github-actions github-actions bot mentioned this pull request Jan 3, 2026
@ding113 ding113 deleted the fix/515-gemini-user-agent branch January 27, 2026 09:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:Google Gemini area:provider bug Something isn't working size/M Medium PR (< 500 lines)

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant

Comments