Skip to content

Commit d121ec3

Browse files
aUsernameWoWclaude
andcommitted
Surface ACL-denied status on the forwarding path (502 -> 403)
Not from the ultrareview — found while verifying the review fixes. On the non-CONNECT proxy-forwarding path, the ACL check runs inside httpTransport's DialContext, so a denial (e.g. caddyhttp.Error(403, ...)) comes back from RoundTrip wrapped in a transport error rather than as a bare HandlerError. The error check used a non-unwrapping type assertion (err.(caddyhttp.HandlerError)), which failed on the wrapped error and fell through to a blanket 502 — so an operator's ACL block surfaced to the client as "502 Bad Gateway" instead of "403 Forbidden". The request was still blocked (no leak); only the status code was wrong. Use errors.As to unwrap so the underlying HandlerError's status reaches the client. The CONNECT path was already correct (it returns the ACL error directly). Fixes TestWhitelistBlocking, TestLocalNetworksDefault- Forbidden, and TestBlacklistBlocking (the last requires an environment without an HTTP_PROXY env var, since http.ProxyFromEnvironment otherwise routes the forwarded request through the proxy and the per-IP ACL never sees the target IP). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent dacac91 commit d121ec3

1 file changed

Lines changed: 7 additions & 2 deletions

File tree

forwardproxy.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -502,8 +502,13 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyht
502502
defer response.Body.Close()
503503
}
504504
if err != nil {
505-
if _, ok := err.(caddyhttp.HandlerError); ok {
506-
return err
505+
// The ACL check runs inside httpTransport's DialContext, so a denial
506+
// (e.g. 403) comes back wrapped in a transport error rather than as a
507+
// bare HandlerError. Unwrap with errors.As so the operator's status
508+
// reaches the client instead of a blanket 502.
509+
var handlerErr caddyhttp.HandlerError
510+
if errors.As(err, &handlerErr) {
511+
return handlerErr
507512
}
508513
return caddyhttp.Error(http.StatusBadGateway,
509514
fmt.Errorf("failed to read response: %v", err))

0 commit comments

Comments
 (0)