Skip to content

feat: add HTTP proxy strategy for caching absolute-form proxy requests#176

Merged
joshfriend merged 1 commit intoblock:mainfrom
joshfriend:feat/http-proxy-strategy
Mar 12, 2026
Merged

feat: add HTTP proxy strategy for caching absolute-form proxy requests#176
joshfriend merged 1 commit intoblock:mainfrom
joshfriend:feat/http-proxy-strategy

Conversation

@joshfriend
Copy link
Copy Markdown
Contributor

@joshfriend joshfriend commented Mar 11, 2026

Adds a new proxy {} strategy that acts as a caching HTTP proxy for clients that route downloads through a standard HTTP proxy via --proxy_host / --proxy_port flags. A common example is Android sdkmanager, which supports --no_https --proxy=http --proxy_host=<host> --proxy_port=<port> to route all package and repository manifest fetches through a proxy.

When a client sends an absolute-form proxy request (GET http://host/path HTTP/1.1), the strategy upgrades the upstream fetch to HTTPS, caches the response, and serves subsequent requests from the cache. Non-proxy requests (relative paths) are passed through as 404s so the handler does not interfere with other routes.

The strategy is registered under the proxy namespace in the cache, keeping it separate from the hermit strategy which handles hermit package manager downloads. It registers a "/" catch-all on the mux and detects proxy-form requests by inspecting r.RequestURI.

@joshfriend joshfriend marked this pull request as ready for review March 11, 2026 18:33
@joshfriend joshfriend requested a review from a team as a code owner March 11, 2026 18:33
@joshfriend joshfriend requested review from jrobotham-square and removed request for a team March 11, 2026 18:33
Copy link
Copy Markdown

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

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: c025b19cea

ℹ️ 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".

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

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread internal/strategy/proxy.go Outdated
logger := logging.FromContext(ctx)
p := &HTTPProxy{logger: logger}

mux.Handle("/", p.newHandler(c))
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Dispatch absolute-form proxy requests before mux routing

Registering the proxy as "/" lets more-specific handlers win first, and I verified this repo already registers GET /api/v1/... (internal/strategy/apiv1.go) plus /admin/... routes (cmd/cachewd/main.go). For absolute-form proxy traffic, ServeMux routing is still path-based, so a request like GET http://upstream/api/v1/object/ns/key is routed to cachew’s local API handler instead of being proxied upstream. That breaks proxied downloads for overlapping paths and can hit local control routes unexpectedly; absolute-form detection needs to happen before normal ServeMux path dispatch (or on a separate listener/host pattern).

Useful? React with 👍 / 👎.

if target == nil {
return r, nil
}
return http.NewRequestWithContext(r.Context(), http.MethodGet, target.String(), nil)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve original HTTP method for forwarded requests

The transform unconditionally rewrites upstream calls to GET, but this handler is mounted on "/" for all methods. Any absolute-form HEAD, POST, PUT, etc. request is therefore silently converted into a GET, which returns incorrect semantics and can cause clients to misbehave (for example, HEAD probes downloading content or POST never reaching upstream). Either constrain this strategy to GET/HEAD at routing time or forward method/body/headers as-is.

Useful? React with 👍 / 👎.

Adds a new `proxy {}` strategy that acts as a caching HTTP proxy for
clients that route traffic via --proxy_host / --proxy_port flags (e.g.
Android sdkmanager). When a client sends an absolute-form request
(GET http://host/path HTTP/1.1), the strategy upgrades the upstream
fetch to HTTPS, caches the response, and serves subsequent requests
from cache.

Registers a "/" catch-all handler that detects proxy-form requests by
inspecting r.RequestURI. Non-proxy requests (relative paths) fall
through to a 404. The strategy is namespaced in the cache under "proxy"
and is separate from the hermit strategy, which handles hermit package
manager downloads specifically.
@joshfriend joshfriend force-pushed the feat/http-proxy-strategy branch from c025b19 to a6c74eb Compare March 11, 2026 19:52
@joshfriend joshfriend merged commit ed051c2 into block:main Mar 12, 2026
5 checks passed
worstell pushed a commit that referenced this pull request Mar 12, 2026
#176)

Adds a new `proxy {}` strategy that acts as a caching HTTP proxy for
clients that route downloads through a standard HTTP proxy via
`--proxy_host` / `--proxy_port` flags. A common example is Android
`sdkmanager`, which supports `--no_https --proxy=http
--proxy_host=<host> --proxy_port=<port>` to route all package and
repository manifest fetches through a proxy.

When a client sends an absolute-form proxy request (`GET
http://host/path HTTP/1.1`), the strategy upgrades the upstream fetch to
HTTPS, caches the response, and serves subsequent requests from the
cache. Non-proxy requests (relative paths) are passed through as 404s so
the handler does not interfere with other routes.

The strategy is registered under the `proxy` namespace in the cache,
keeping it separate from the `hermit` strategy which handles hermit
package manager downloads. It registers a `"/"` catch-all on the mux and
detects proxy-form requests by inspecting `r.RequestURI`.
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.

2 participants