Skip to content

refactor: centralize User-Agent header via shared httputil package - #79

Merged
steve-calvert-glean merged 1 commit into
mainfrom
rwjblue/refactor-centralize-useragent-httputil
Apr 6, 2026
Merged

refactor: centralize User-Agent header via shared httputil package#79
steve-calvert-glean merged 1 commit into
mainfrom
rwjblue/refactor-centralize-useragent-httputil

Conversation

@rwjblue-glean

Copy link
Copy Markdown
Member

Requests routed through the Glean Go SDK and the streaming chat endpoint were correctly sending User-Agent: glean-cli/<version>, but several other HTTP call sites were not — OAuth discovery, dynamic client registration, domain lookup, GitHub release checks, and the glean api command all used bare http.Client{} instances with no user-agent set.

This adds an internal/httputil package that centralizes both the CLI version string and User-Agent injection into a single place. All HTTP clients now go through httputil.NewHTTPClient(timeout) or compose on httputil.NewTransport(base), which guarantees every outbound request identifies itself.

As part of this, the cliTransport type in internal/client is eliminated — its only remaining job (injecting X-Glean-Auth-Type for OAuth tokens) is now handled by httputil.WithHeader, a general-purpose option on NewTransport.

Add internal/httputil package that owns the CLI version string and
provides NewHTTPClient/NewTransport to inject User-Agent on all
outbound HTTP requests. Previously only SDK and streaming chat
requests set the header; auth discovery, domain lookup, update
checks, and the api command did not.

- NewTransport wraps any RoundTripper with UA injection + optional
  extra headers via WithHeader option
- Eliminates cliTransport from internal/client (X-Glean-Auth-Type
  now handled via httputil.WithHeader)
- Removes duplicated SetVersion/Version from internal/client
- Migrates all 7 HTTP call sites to use the shared factory

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@rwjblue-glean
rwjblue-glean marked this pull request as ready for review April 6, 2026 20:19
@steve-calvert-glean
steve-calvert-glean merged commit c23e798 into main Apr 6, 2026
7 checks passed
@steve-calvert-glean
steve-calvert-glean deleted the rwjblue/refactor-centralize-useragent-httputil branch April 6, 2026 22:35
pavlo-v-chernykh added a commit to pavlo-v-chernykh/glean-cli that referenced this pull request Apr 9, 2026
…est helper

PR gleanwork#79 removed the package-level discoveryHTTPClient var from
discovery.go and inlined httputil.NewHTTPClient at each call site.
The device.go file (added in a parallel branch) still referenced the
deleted var, causing a build failure after rebase.

Inline the client at both device.go call sites to match the rest of
the auth package, and remove the now-unnecessary
overrideDiscoveryHTTPClient helper and all 16 calls across test files
(httptest.NewServer creates a real TCP server reachable by any client).
steve-calvert-glean pushed a commit that referenced this pull request Apr 10, 2026
…est helper

PR #79 removed the package-level discoveryHTTPClient var from
discovery.go and inlined httputil.NewHTTPClient at each call site.
The device.go file (added in a parallel branch) still referenced the
deleted var, causing a build failure after rebase.

Inline the client at both device.go call sites to match the rest of
the auth package, and remove the now-unnecessary
overrideDiscoveryHTTPClient helper and all 16 calls across test files
(httptest.NewServer creates a real TCP server reachable by any client).
steve-calvert-glean added a commit that referenced this pull request Apr 10, 2026
* feat: add Device Authorization Grant (RFC 8628) as login fallback

When DCR is unavailable (e.g. Okta SSO), auth login now falls back to
the OAuth 2.0 Device Authorization Grant. The user approves login on a
verification page instead of a local redirect.

* fix: narrow device flow fallback to DCR-unavailable errors only

The previous fallback triggered on any tryAuthCodeLogin failure, including
transient issues like network timeouts or the user closing their browser.
Now device flow only activates when dcrOrStaticClient returns
errNoOAuthClient (no registration endpoint + no static client), not when
DCR was attempted and failed.

Made-with: Cursor

* refactor: inline httputil.NewHTTPClient in device flow, remove dead test helper

PR #79 removed the package-level discoveryHTTPClient var from
discovery.go and inlined httputil.NewHTTPClient at each call site.
The device.go file (added in a parallel branch) still referenced the
deleted var, causing a build failure after rebase.

Inline the client at both device.go call sites to match the rest of
the auth package, and remove the now-unnecessary
overrideDiscoveryHTTPClient helper and all 16 calls across test files
(httptest.NewServer creates a real TCP server reachable by any client).

* refactor: add debug logging to device flow, improve auth UX and README

- Add auth:device debug namespace for tracing device flow login
- Improve fallback message: "Your SSO provider requires device-based
  login" instead of confusing OAuth jargon
- Rewrite README auth section with scannable table showing three
  login methods and when each is used
- Add "Credential resolution order" subsection
- Note that API tokens are scoped to individual user accounts

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Steve Calvert <steve.calvert@glean.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants