Skip to content

fix: keep http.DefaultTransport a *http.Transport for OPA http.send - #449

Open
dgilman-perplexity wants to merge 1 commit into
block:mainfrom
dgilman-perplexity:fix/opa-http-send-default-transport
Open

dgilman-perplexity wants to merge 1 commit into
block:mainfrom
dgilman-perplexity:fix/opa-http-send-default-transport

Conversation

@dgilman-perplexity

@dgilman-perplexity dgilman-perplexity commented Nov 13, 2026 •

Copy link
Copy Markdown

Problem

configureProcess reassigns the global http.DefaultTransport to the BackoffTransport/OriginTransport wrapper (since #430) so every strategy shares 429 cooldowns and origin metrics. OPA's http.send builtin does http.DefaultTransport.(*http.Transport).Clone() whenever a policy passes a TLS option (tls_ca_cert_file, tls_ca_cert, tls_client_cert*, tls_server_name, or a Host header), see v1/topdown/http.go. With the wrapper installed, every evaluation that reaches http.send panics:

interface conversion: http.RoundTripper is *httputil.BackoffTransport, not *http.Transport

net/http recovers the panic per connection, so the daemon stays healthy and passes readiness checks while every admitted request on such a policy fails. Setting upstream-backoff doesn't help; any wrapper on the global trips the assertion.

Fix

  • http.DefaultTransport is left as a *http.Transport. The cooldown/metrics wrapper is installed through a new httputil.SetUpstreamTransport, and clients that previously relied on the default transport or http.DefaultClient (GitHub App tokens and API client, Hermit, Git reverse proxy, github-releases, host and its fallbacks, artifactory, proxy, OCI, Go module proxy and its sumdb client) now get it explicitly via httputil.UpstreamTransport() / httputil.UpstreamClient(), so cooldown and origin-metric coverage is unchanged for them.
  • Until a transport is installed, UpstreamTransport() forwards to the live http.DefaultTransport at request time, so the existing tests that swap the global to intercept upstream traffic keep working unchanged.
  • One behavioural difference: OPA's own http.send requests without TLS options previously went through the cooldown wrapper (via the global) and now use the plain default transport, matching what its TLS path always did.

Tests

  • cmd/cachewd/opa_transport_test.go runs a real http.send with tls_ca_cert_file against an httptest TLS server after configureProcess, in a child process. On main it fails with the panic above; with this change it passes.
  • internal/httputil/upstream_test.go covers the fallback-to-global and installed-transport paths.
  • go build ./..., go vet, and go test on cmd/cachewd, internal/httputil, internal/githubapp, internal/strategy, internal/strategy/gomod, internal/opa pass locally. Failures in internal/strategy/git and internal/strategy/handler are pre-existing in my environment (need Docker, pzstd, and git-lfs ≥ 3.8.1) and reproduce identically on main.

Created with Perplexity

@dgilman-perplexity
dgilman-perplexity requested a review from a team as a code owner November 13, 2026 13:53
@dgilman-perplexity
dgilman-perplexity requested review from worstell and removed request for a team November 13, 2026 13:53
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 13, 2026 •

Copy link
Copy Markdown
Codex Review Summary: ✅ Completed

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-13T14:19:44.074685Z c5d94a3 New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@dgilman-perplexity
dgilman-perplexity force-pushed the fix/opa-http-send-default-transport branch from 3936689 to 0bcfece Compare November 13, 2026 13:54

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3936689486

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread cmd/cachewd/opa_transport_test.go Resolved
Comment thread cmd/cachewd/main.go Resolved
@dgilman-perplexity
dgilman-perplexity force-pushed the fix/opa-http-send-default-transport branch from 0bcfece to 3df166c Compare November 13, 2026 14:09
@dgilman-perplexity

dgilman-perplexity commented Nov 13, 2026 •

Copy link
Copy Markdown
Author

Addressed the two review findings in c5d94a3: removed the doc comment on the top-level test, and wired the Go module proxy's GoFetcher and Goproxy (sumdb client) to httputil.UpstreamTransport() so module fetches keep the shared cooldowns and origin metrics. Also moved the new httputil test to an external test package to satisfy tsk.

configureProcess replaced the global http.DefaultTransport with the
BackoffTransport/OriginTransport wrapper so every strategy shared 429
cooldowns and origin metrics. OPA's http.send asserts
http.DefaultTransport.(*http.Transport) whenever a policy sets a TLS
option such as tls_ca_cert_file, so every policy evaluation that reached
http.send panicked with "interface conversion: http.RoundTripper is
*httputil.BackoffTransport, not *http.Transport" and net/http dropped
the client connection.

Install the wrapper through httputil.SetUpstreamTransport instead, and
give every client that relied on the default transport or
http.DefaultClient the shared transport explicitly via
httputil.UpstreamTransport / httputil.UpstreamClient. Until a transport
is installed the accessor forwards to the live http.DefaultTransport, so
tests that swap the global to intercept upstream traffic keep working.

The regression test runs a real http.send with tls_ca_cert_file after
configureProcess in a child process; it fails with the panic above on
the previous code.

Co-authored-by: Perplexity <noreply@perplexity.ai>
Signed-off-by: dgilman-perplexity <293900578+dgilman-perplexity@users.noreply.github.com>
@dgilman-perplexity
dgilman-perplexity force-pushed the fix/opa-http-send-default-transport branch from 3df166c to c5d94a3 Compare November 13, 2026 14:15
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.

1 participant