Skip to content

client: do not modify user-provided HTTP client#51817

Merged
thaJeztah merged 1 commit intomoby:masterfrom
corhere:client/clone-http-client
Jan 7, 2026
Merged

client: do not modify user-provided HTTP client#51817
thaJeztah merged 1 commit intomoby:masterfrom
corhere:client/clone-http-client

Conversation

@corhere
Copy link
Copy Markdown
Contributor

@corhere corhere commented Jan 6, 2026

- What I did
Fixed constructing two Engine API clients from the same http.Client so that the second behaves the same as the first.

- How I did it
The http.Client passed into client.WithHTTPClient() is modified by the constructor in-place: the value of its Transport field is mutated and wrapped in an OpenTelemetry decorator. This can lead to very surprising behaviour when a second client is constructed reusing the same http.Client value. If the http.Client is configured for TLS, the second client will fail to detect that and will incorrectly dial the Engine API socket as cleartext HTTP. Copy the provided http.Client so our modifications don't leak out to unexpected places.

- How to verify it
New unit test.

- Human readable description for the release notes

- The http.Client value passed to client.WithHTTPClient() is now copied rather than mutated in-place.

- A picture of a cute animal (not mandatory but encouraged)

@corhere corhere requested a review from thaJeztah January 6, 2026 21:20
@corhere corhere added the impact/go-sdk Noteworthy (compatibility changes) in the Go SDK label Jan 6, 2026
@corhere corhere added the kind/bugfix PR's that fix bugs label Jan 6, 2026
@thaJeztah thaJeztah added this to the 29.2.0 milestone Jan 6, 2026
@thaJeztah
Copy link
Copy Markdown
Member

Heh. Nice find! Looks like it has been like this since .. forever.

Validate is failing; looks like you need to run hack/vendor.sh @corhere

@corhere corhere force-pushed the client/clone-http-client branch from 197b591 to a6334d2 Compare January 6, 2026 21:50
@corhere corhere added the area/cli Client label Jan 6, 2026
@thaJeztah
Copy link
Copy Markdown
Member

🙈 sigh.. GOSEC linting failure now (sorry!) 🫶

client/client_options_test.go:382:54: G402: TLS InsecureSkipVerify set true. (gosec)
				TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
				                                                 ^
client/client_options_test.go:390:46: G402: TLS MinVersion too low. (gosec)
		cmpopts.IgnoreUnexported(http.Transport{}, tls.Config{}),
		                                           ^

The http.Client passed into client.WithHTTPClient() is modified by the
constructor in-place: the value of its Transport field is mutated and
wrapped in an OpenTelemetry decorator. This can lead to very surprising
behaviour when a second client is constructed reusing the same
http.Client value. If the http.Client is configured for TLS, the second
client will fail to detect that and will incorrectly dial the Engine API
socket as cleartext HTTP. Copy the provided http.Client so our
modifications don't leak out to unexpected places.

Signed-off-by: Cory Snider <csnider@mirantis.com>
@corhere corhere force-pushed the client/clone-http-client branch from a6334d2 to 9ebbf65 Compare January 6, 2026 23:14
Copy link
Copy Markdown
Member

@thaJeztah thaJeztah left a comment

Choose a reason for hiding this comment

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

LGTM, thanks!

@thaJeztah thaJeztah merged commit 8f1457a into moby:master Jan 7, 2026
209 of 211 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/cli Client impact/changelog impact/go-sdk Noteworthy (compatibility changes) in the Go SDK kind/bugfix PR's that fix bugs module/client

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants