Skip to content

fix: stop login --ignore-ssl-errors panicking on a wrapped transport - #726

Merged
flin-8 merged 1 commit into
mainfrom
flin-8/fix-login-ignore-ssl-errors-panic
Sep 9, 2026
Merged

fix: stop login --ignore-ssl-errors panicking on a wrapped transport#726
flin-8 merged 1 commit into
mainfrom
flin-8/fix-login-ignore-ssl-errors-panic

Conversation

@flin-8

@flin-8 flin-8 commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Fixes #725.
Fixes SF-3525: Octopus CLI crash

login --ignore-ssl-errors type-asserted the client's transport to *http.Transport. Since #633 the client factory always installs the spinner round tripper (it was interactive-only before, so non-interactive runs had a nil transport and the assertion held), so that assertion panics for anyone with a server and API key already in config or environment — including every Octopus Jenkins plugin build with "Ignore SSL Errors" set.

skipTlsVerification walks past the spinner and applies the setting to the transport underneath. A transport it does not recognise returns an error, rather than quietly leaving verification on after the caller asked for the opposite. Everything else, including the existing nil-transport handling, is unchanged.

The login test panics without the fix — the mock factory's transport is not an *http.Transport either, so it now reports the unsupported transport instead. Internal tests cover the spinner path and the error.

Thanks to #727, which fixed the same bug independently; the error on unrecognised transports is taken from it.

🤖 Generated with Claude Code

@flin-8
flin-8 force-pushed the flin-8/fix-login-ignore-ssl-errors-panic branch 3 times, most recently from bbe12fb to 655cee0 Compare September 9, 2026 02:23
@flin-8
flin-8 requested a review from NickJosevski September 9, 2026 02:23
@flin-8 flin-8 self-assigned this Sep 9, 2026
@NickJosevski

NickJosevski commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

@flin-8 from the session I had with Claude from the start on this:

- NewSpinnerRoundTripper sets Next: http.DefaultTransport, the process-wide *http.Transport every client without its own uses.
- skipTlsVerification recurses past the spinner and assigns TLSClientConfig on that shared object, so unrelated clients stop verifying certificates.
- Measured: a plain &http.Client{}, never passed to the function, flips from rejecting a self-signed cert to accepting it; cloning instead leaves it rejecting.
- Replacing the whole config also clears NextProtos:[h2 http/1.1], the ALPN list that advertises HTTP/2.
- Not observable in the shipped CLI: client_factory.go:124 already sets InsecureSkipVerify on http.DefaultTransport for every command.

@NickJosevski NickJosevski reopened this Sep 9, 2026
@NickJosevski

Copy link
Copy Markdown
Contributor

I'm not sure how I hit the close button 😊

@NickJosevski NickJosevski left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'm ok for this to go, but just put in the comments I pulled from what I was doing with Claude in this space.

// The transport the client factory hands out is always spinner-wrapped, which is
// what the old type assertion tripped over.
func TestSkipTlsVerification_ThroughTheSpinner(t *testing.T) {
spinner := apiclient.NewSpinnerRoundTripper(nil)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@flin-8 with the session I had going with Claude that spun up context from when we first started to fix the original driver for the changes in this space, on this it brings up:

sets Next: http.DefaultTransport, the process-wide *http.Transport every client without its own uses.

Comment thread pkg/cmd/login/login.go Outdated

// The client factory wraps the transport in a spinner, so the setting has to be
// applied to the transport underneath rather than to the wrapper.
func skipTlsVerification(roundTripper http.RoundTripper) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

from my claude session:

skipTlsVerification recurses past the spinner and assigns TLSClientConfig on that shared object, so unrelated clients stop verifying certificates.

Comment thread pkg/cmd/login/login.go Outdated
}

httpClient.Transport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
skipTlsVerification(httpClient.Transport)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

from my claude session:, in general:

http.Client{}, never passed to the function, flips from rejecting a self-signed cert to accepting it; cloning instead leaves it rejecting.

@NickJosevski

Copy link
Copy Markdown
Contributor

I threw that Claude session at this also yesterday, and it proposed this PR:

#727

The client factory hands login a client whose transport is the spinner
round tripper, so type-asserting it to *http.Transport panics. Apply the
setting underneath any wrappers instead, leaving them in place.

Fixes #725

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@flin-8
flin-8 force-pushed the flin-8/fix-login-ignore-ssl-errors-panic branch from 655cee0 to 574ccda Compare September 9, 2026 04:01
@flin-8
flin-8 merged commit 3860c0c into main Sep 9, 2026
4 checks passed
@flin-8
flin-8 deleted the flin-8/fix-login-ignore-ssl-errors-panic branch September 9, 2026 04:32
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.

octopus login --ignore-ssl-errors panics: interface conversion on SpinnerRoundTripper

2 participants