Skip to content

fix: set a clear User-Agent for all SonarQube API calls#482

Merged
okorach-sonar merged 2 commits into
release-1-1from
fix/issue-479
Jul 10, 2026
Merged

fix: set a clear User-Agent for all SonarQube API calls#482
okorach-sonar merged 2 commits into
release-1-1from
fix/issue-479

Conversation

@okorach-sonar

Copy link
Copy Markdown
Contributor

Summary

  • The migration tool previously sent the Go http.Client default User-Agent (Go-http-client/1.1), making SMT activity hard to distinguish in SonarQube Server/Cloud logs.
  • Added a userAgentTransport to the shared transport stack in lib/sq-api-go/client.go (same pattern as the existing authTransport), so every request now sends "User-Agent: sonar-migration-tool".
  • This is the only place *http.Client is constructed in the repo; all other request-building code paths reuse sqapi.Client.HTTPClient(), so the fix covers all API traffic.

Fixes #479

Test plan

  • go build ./... passes in both lib/sq-api-go and go modules
  • go test ./... passes in lib/sq-api-go
  • Added TestHTTPClientSetsUserAgent asserting the header is set on outgoing requests

🤖 Generated with Claude Code

Requests previously used the Go http.Client default User-Agent
(Go-http-client/1.1), making SMT activity hard to distinguish in SQC
logs. Add a userAgentTransport to the shared transport stack in
lib/sq-api-go so every request now sends "sonar-migration-tool".

Fixes #479

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@okorach-sonar
okorach-sonar requested a review from a team as a code owner July 9, 2026 15:38
…eaders

debugTransport wrapped authTransport/userAgentTransport from the outside,
but both inject their header by cloning the request and mutating the
clone, a clone debugTransport never saw since it held the original
request object. The debug log headers field was always empty as a
result.

Reorder buildTransport to: authTransport -> userAgentTransport ->
debugTransport (optional) -> retryTransport -> http.Transport, so header
injection happens before debug capture. debugTransport still sits outside
retryTransport, so it logs once per logical call, not once per retry
attempt.

Also document the fixed sonar-migration-tool User-Agent in
ADVANCED-CONFIG.md.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Comment thread lib/sq-api-go/client.go
Comment on lines +117 to +120
// authTransport and userAgentTransport sit outside debugTransport (rather
// than the other way around) because both inject their header by cloning
// the request and setting it on the clone — a clone debugTransport would
// never see if it wrapped them from the outside. Retry sits innermost so

@gitar-bot gitar-bot Bot Jul 10, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Quality: Garbled sentence in buildTransport ordering comment

The comment explaining the transport ordering reads: "because both inject their header by cloning the request and setting it on the clone — a clone debugTransport would never see if it wrapped them from the outside." This sentence is grammatically broken and hard to parse ("a clone debugTransport would never see if it wrapped them"). The intended meaning is that authTransport/userAgentTransport set their headers on a cloned request, so a debugTransport wrapping them from the outside would only ever see the caller's original request and miss the injected Authorization/User-Agent headers. Consider rewording for clarity, e.g. "...set it on the clone — a debugTransport wrapping them from the outside would only see the caller's original request and never the injected headers."

Reword the comment so the rationale reads clearly.:

// authTransport and userAgentTransport sit outside debugTransport (rather
// than the other way around) because both inject their header by cloning
// the request and setting it on the clone — a debugTransport wrapping them
// from the outside would only ever see the caller's original, unmodified
// request and never the injected headers. Retry sits innermost so
// debugTransport still logs exactly once per logical call, using the
// final response after any retries.

Was this helpful? React with 👍 / 👎

@sonarqubecloud

Copy link
Copy Markdown

@okorach-sonar
okorach-sonar merged commit e37b95f into release-1-1 Jul 10, 2026
9 checks passed
@gitar-bot

gitar-bot Bot commented Jul 10, 2026

Copy link
Copy Markdown
Code Review 👍 Approved with suggestions 0 resolved / 1 findings

Injects a specific 'sonar-migration-tool' User-Agent into all API requests to improve auditability in server logs. Consider clarifying the comment in buildTransport to improve readability.

💡 Quality: Garbled sentence in buildTransport ordering comment

📄 lib/sq-api-go/client.go:117-120

The comment explaining the transport ordering reads: "because both inject their header by cloning the request and setting it on the clone — a clone debugTransport would never see if it wrapped them from the outside." This sentence is grammatically broken and hard to parse ("a clone debugTransport would never see if it wrapped them"). The intended meaning is that authTransport/userAgentTransport set their headers on a cloned request, so a debugTransport wrapping them from the outside would only ever see the caller's original request and miss the injected Authorization/User-Agent headers. Consider rewording for clarity, e.g. "...set it on the clone — a debugTransport wrapping them from the outside would only see the caller's original request and never the injected headers."

Reword the comment so the rationale reads clearly.
// authTransport and userAgentTransport sit outside debugTransport (rather
// than the other way around) because both inject their header by cloning
// the request and setting it on the clone — a debugTransport wrapping them
// from the outside would only ever see the caller's original, unmodified
// request and never the injected headers. Retry sits innermost so
// debugTransport still logs exactly once per logical call, using the
// final response after any retries.
🤖 Prompt for agents
Code Review: Injects a specific 'sonar-migration-tool' User-Agent into all API requests to improve auditability in server logs. Consider clarifying the comment in buildTransport to improve readability.

1. 💡 Quality: Garbled sentence in buildTransport ordering comment
   Files: lib/sq-api-go/client.go:117-120

   The comment explaining the transport ordering reads: "because both inject their header by cloning the request and setting it on the clone — a clone debugTransport would never see if it wrapped them from the outside." This sentence is grammatically broken and hard to parse ("a clone debugTransport would never see if it wrapped them"). The intended meaning is that authTransport/userAgentTransport set their headers on a *cloned* request, so a debugTransport wrapping them from the outside would only ever see the caller's original request and miss the injected Authorization/User-Agent headers. Consider rewording for clarity, e.g. "...set it on the clone — a debugTransport wrapping them from the outside would only see the caller's original request and never the injected headers."

   Fix (Reword the comment so the rationale reads clearly.):
   // authTransport and userAgentTransport sit outside debugTransport (rather
   // than the other way around) because both inject their header by cloning
   // the request and setting it on the clone — a debugTransport wrapping them
   // from the outside would only ever see the caller's original, unmodified
   // request and never the injected headers. Retry sits innermost so
   // debugTransport still logs exactly once per logical call, using the
   // final response after any retries.

Options

Auto-apply is off → Gitar will not commit updates to this branch.
Display: compact → Showing less information.

Comment with these commands to change the behavior for this request:

Auto-apply Compact
gitar auto-apply:on         
gitar display:verbose         

Was this helpful? React with 👍 / 👎 | Gitar

@okorach-sonar
okorach-sonar deleted the fix/issue-479 branch July 10, 2026 12:50
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