oauthex: build defaultDiscoveryTransport lazily instead of at import - #1278
Open
kilarusravankumar wants to merge 1 commit into
Open
kilarusravankumar wants to merge 1 commit into
kilarusravankumar wants to merge 1 commit into
Conversation
Comment on lines
+8
to
+15
| func TestImportDoesNotCacheProxyEnv(t *testing.T) { | ||
| t.Setenv("HTTPS_PROXY", "http://127.0.0.1:9") | ||
| req, _ := http.NewRequest(http.MethodGet, "https://example.com/", nil) | ||
| got, err := http.ProxyFromEnvironment(req) | ||
| if err != nil || got == nil { | ||
| t.Fatalf("proxy not detected: got=%v err=%v", got, err) | ||
| } | ||
| } |
Contributor
There was a problem hiding this comment.
this test fails when is not run in isolation
Author
There was a problem hiding this comment.
Yeah, that's it — another discovery test calls newDiscoveryClient which calls defaultDiscoveryTransport() before my test, so ProxyFromEnvironment is already cached by the time my t.Setenv runs. It only passed because I ran it alone.
I'll drop the test. Since that proxy env is read once per process, any test I write here is at the mercy of whatever runs first, so it's not reliable. The change itself is small and the fix is clear.
is that okay ?
Member
There was a problem hiding this comment.
let's drop the test, but leave a comment explaining why OnceValue is used, thanks for the fix!
kilarusravankumar
force-pushed
the
fix/1276-oauthex-proxy-init-cache
branch
from
September 17, 2026 20:11
c3f15f4 to
0206f96
Compare
defaultDiscoveryTransport was a package-level var, so it got built the moment the package was imported. Building it runs proxyConfigured, which calls http.DefaultTransport's proxy func (that's http.ProxyFromEnvironment). The problem is net/http only reads the proxy env vars once and caches the result forever. So the first call wins, and here that first call happens at import time, before main() has had a chance to set HTTPS_PROXY. By the time the app sets it, it's already too late and the setting gets ignored. You didn't hit this in v1.7.0 because this code didn't exist yet. Just importing .../mcp pulls in oauthex, which was enough to trigger it even if you never called anything in the SDK. Fixing it by wrapping the setup in sync.OnceValue so it runs on first use instead of at import. By then the app has set its proxy env. It's still only built once and reused, same as before. Fixes modelcontextprotocol#1276
kilarusravankumar
force-pushed
the
fix/1276-oauthex-proxy-init-cache
branch
from
September 17, 2026 20:18
0206f96 to
76675f5
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #1276
What's happening
oauthexbuildsdefaultDiscoveryTransportas a package-level var, so itruns at import time. That path calls
proxyConfigured, which invokeshttp.DefaultTransport's proxy func (http.ProxyFromEnvironment). net/httpreads the proxy env vars only once and caches the result, so this import-time
call freezes the proxy config before
main()can setHTTPS_PROXY.New in v1.8.0, which is why it's a regression — just importing
.../mcp(which pulls in
oauthex) triggers it, even with no use of the SDK.Fix
Wrap the setup in
sync.OnceValueso it runs on first use instead of atimport. Still built once and reused.
Testing (removed)
replace: printsproxy=http://127.0.0.1:9now,proxy=<nil>before.oauthex.go test ./...passes.