Skip to content

feat(client): send a stackctl User-Agent header - #171

Merged
omattsson merged 3 commits into
mainfrom
feat/170-user-agent
Oct 23, 2026
Merged

omattsson merged 3 commits into
mainfrom
feat/170-user-agent

Conversation

@omattsson

@omattsson omattsson commented Oct 23, 2026 •

Copy link
Copy Markdown
Owner

Closes #170

Summary

  • Every request sends User-Agent: stackctl/<version> (<os>/<arch>), for example stackctl/1.4.0 (linux/amd64). This covers API requests (send()), the session requests (sendSession() in auth.go) and the WebSocket upgrade, including the ?token= fallback dial. The fallback still sends no Authorization or X-API-Key header.
  • cmd.SetVersionInfo calls the new client.SetVersion, so the header shows the same version as stackctl version. A build without ldflags sends stackctl/dev.
  • Any character outside the RFC 9110 token set becomes _, so a malformed version cannot break the header.
  • The header is set where each request is built, not in a RoundTripper, because cmd/stack.go replaces HTTPClient.
  • README and CLAUDE.md now describe the header.

Tests

  • New httptest tests check the header on an API request, a session request (Logout), the WebSocket upgrade with a JWT and with an API key, and the 401 fallback on both dials. They also cover the dev default and the character replacement. SetVersionInfo has a test that checks it sets the header version.
  • go vet ./... is clean and go test ./... -race -count=1 passes.

Follow-ups (not in this PR)

  • Export STACKCTL_VERSION to plugins so they can send <plugin>/<version> stackctl/<version>.
  • Print the User-Agent in the --debug output.

Also in this PR

  • cli/go.mod: Go 1.26.9 to 1.26.10 for GO-2026-6809 (crypto/x509), which failed the govulncheck job. Main has the same problem.
  • Review fixes (fe2e446): SetVersion builds the header once, both WebSocket dials share baseWSHeader(), the version tests restore their globals, and the docs name Go 1.26.10.

🤖 Generated with Claude Code

Every request from cli/pkg/client, the session requests in auth.go and
both WebSocket dials (also the ?token= fallback) now send
"User-Agent: stackctl/<version> (<os>/<arch>)". cmd.SetVersionInfo
passes the build version to client.SetVersion, so the header matches
`stackctl version`; a build without ldflags sends "stackctl/dev".
Characters outside the RFC 9110 token set become "_".

The header is set where each request is built, not in a transport,
because cmd/stack.go replaces HTTPClient.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

omattsson and others added 2 commits October 23, 2026 18:24
Go 1.26.9 is affected by GO-2026-6809 (crypto/x509 trusts compromised
intermediate certificates). govulncheck reaches it through the TLS
WebSocket dial in client.dialWS. CI reads the Go version from
cli/go.mod.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… header

Review fixes for #171:
- SetVersion builds the header value once (atomic.Pointer[string]);
  UserAgent() only loads it.
- Both WebSocket dials take their headers from baseWSHeader(), so the
  ?token= fallback cannot miss a header that the first dial sends.
- All version tests restore the build globals, so TestVersionCmd_JSON no
  longer leaks "2.0.0" into the client User-Agent of later cmd tests.
- The test server handlers report failures on their subtest.
- CLAUDE.md documents the t.Parallel exception for tests that change
  package-global state; the docs name Go 1.26.10.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@omattsson
omattsson merged commit 165d1b8 into main Oct 23, 2026
8 checks passed
@omattsson
omattsson deleted the feat/170-user-agent branch October 23, 2026 18:07
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.

Send a User-Agent header that names stackctl and its version

1 participant