Skip to content

Conversation

@zly2006
Copy link
Contributor

@zly2006 zly2006 commented Nov 18, 2025

Subsystem
Client (plugins)

Motivation
The user agent plugins is used to provide default value, not to send both values to the server, this may cause server mistakes trying to identifying the client.

Solution
This PR simply do not append to the user agent header if its value is already set. This makes the headers passed by the user to have the highest priority.

This behavior is generally applicable. python's requests library follows the same (requests.Session .headers).

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 18, 2025

Walkthrough

A guard condition was added to the UserAgent plugin to prevent overwriting an existing User-Agent header. The header is now only added if HttpHeaders.UserAgent is not already present in the request, with trace and assignment logic moved inside the conditional.

Changes

Cohort / File(s) Summary
User-Agent header guard
ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/UserAgent.kt
Added conditional check to skip User-Agent header assignment if one already exists in the request

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~5–10 minutes

  • Focus areas:
    • Verify the conditional logic correctly identifies existing User-Agent headers
    • Confirm the guard condition aligns with HTTP specification expectations for header precedence
    • Check that trace logging behavior remains appropriate within the new conditional scope

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: preventing User-Agent header overwriting when already specified by the user.
Description check ✅ Passed The description follows the template with all required sections (Subsystem, Motivation, Solution) properly filled and provides clear context and justification.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link
Contributor

@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)
ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/UserAgent.kt (1)

20-27: Consider clarifying documentation to reflect conditional behavior.

The documentation states the plugin "adds a User-Agent header to all requests," but with this change, it only adds the header when not already present. Consider updating the documentation to reflect this behavior:

 /**
- * A plugin that adds a `User-Agent` header to all requests.
+ * A plugin that adds a `User-Agent` header to requests that don't already have one.
+ * Headers set by the user take precedence over the plugin's default value.
  *
  *
  * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.client.plugins.UserAgent)
  *
  * @property agent a `User-Agent` header value.
  */
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4f405a4 and 2d58343.

📒 Files selected for processing (1)
  • ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/UserAgent.kt (1 hunks)
🔇 Additional comments (1)
ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/UserAgent.kt (1)

33-36: Guard condition is correctly implemented and will properly prevent overriding user-specified User-Agent headers.

Verification confirms that user-set headers are accessible during the onRequest phase. The RequestHook intercepts at HttpRequestPipeline.State, which runs after DefaultRequest at HttpRequestPipeline.Before. This means user-specified headers are populated before the UserAgent plugin's guard condition evaluates, so request.headers.contains(HttpHeaders.UserAgent) will correctly detect and preserve custom User-Agent headers.

@e5l e5l self-requested a review November 20, 2025 16:48
Copy link
Member

@e5l e5l left a comment

Choose a reason for hiding this comment

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

Hey @zly2006, thank you for the PR. LGTM

@e5l e5l enabled auto-merge (squash) November 20, 2025 16:48
@e5l e5l self-assigned this Nov 20, 2025
@e5l e5l merged commit 45e7955 into ktorio:main Nov 21, 2025
17 of 19 checks passed
@zly2006 zly2006 deleted the user-agent branch November 21, 2025 06:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants