caddy/modules/caddyhttp
SillyZir e096ca9503
Some checks failed
Tests / test (./cmd/caddy/caddy, ~1.26.0, macos-14, 0, 1.26, mac) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy, ~1.26.0, ubuntu-latest, 0, 1.26, linux) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy.exe, ~1.26.0, windows-latest, True, 1.26, windows) (push) Has been cancelled
Tests / test (s390x on IBM Z) (push) Has been cancelled
Tests / goreleaser-check (push) Has been cancelled
Cross-Build / build (~1.26.0, 1.26, aix) (push) Has been cancelled
Cross-Build / build (~1.26.0, 1.26, darwin) (push) Has been cancelled
Cross-Build / build (~1.26.0, 1.26, dragonfly) (push) Has been cancelled
Cross-Build / build (~1.26.0, 1.26, freebsd) (push) Has been cancelled
Cross-Build / build (~1.26.0, 1.26, illumos) (push) Has been cancelled
Cross-Build / build (~1.26.0, 1.26, linux) (push) Has been cancelled
Cross-Build / build (~1.26.0, 1.26, netbsd) (push) Has been cancelled
Cross-Build / build (~1.26.0, 1.26, openbsd) (push) Has been cancelled
Cross-Build / build (~1.26.0, 1.26, solaris) (push) Has been cancelled
Cross-Build / build (~1.26.0, 1.26, windows) (push) Has been cancelled
Lint / lint (push) Has been cancelled
Lint / lint-1 (push) Has been cancelled
Lint / lint-2 (push) Has been cancelled
Lint / govulncheck (push) Has been cancelled
Lint / dependency-review (push) Has been cancelled
OpenSSF Scorecard supply-chain security / Scorecard analysis (push) Has been cancelled
caddyauth: isolate provider responses to prevent cross-provider clobbering (#7904)
* caddyauth: isolate provider responses to prevent cross-provider clobbering

When multiple authentication providers are configured, each was handed the
real ResponseWriter, so a failing provider that wrote to the response (a
401 challenge or a login redirect) could clobber the response of another
provider or of the successful handler chain. Because provider map iteration
order is randomized, which provider's side effects won was nondeterministic.

A single provider now receives the real ResponseWriter unchanged — no
buffering, and Flusher/Hijacker/Pusher/ReaderFrom preserved exactly as
before. Only with multiple providers does each get its own buffered writer;
those writers embed caddyhttp.ResponseWriterWrapper so the underlying
capabilities remain type-assertable via http.ResponseController (Flush is
suppressed while buffering so a provider cannot prematurely commit the
response), and the buffered body is size-capped to avoid unbounded memory.

On success the winning provider's headers (e.g. a Set-Cookie) are copied to
the real writer and the chain proceeds. On total failure one provider's
challenge headers are applied (a redirect is sent as a full response),
otherwise the auth error is returned so handle_errors runs and a
header-only challenge (like basic auth) still returns 401.

Fixes #5190

* caddyauth: return total consumed bytes and drain error from ReadFrom

ReadFrom drained a source that exceeded the buffer cap but reported only
the bytes retained in the buffer and dropped any error from the drain,
violating the io.ReaderFrom contract: a caller such as io.Copy would see
fewer bytes than were actually consumed from the source, and a read
failure during the drain was silently swallowed. Return the
retained-plus-drained total and propagate the drain error.

* caddyauth: preserve Flusher and Hijacker on the buffered writer

The buffered writer used for multi-provider isolation embeds
caddyhttp.ResponseWriterWrapper, which promotes only Header, Write and
WriteHeader from the wrapped ResponseWriter and adds Push, ReadFrom and
Unwrap. Flush and Hijack were therefore reachable only through
http.ResponseController; a provider doing a plain w.(http.Flusher) or
w.(http.Hijacker) assertion silently lost them once a second provider was
configured.

Declare both on bufferedResponseWriter. Flush is a no-op so a provider
cannot prematurely commit a buffered response, and FlushError keeps the
same suppression for ResponseController, which prefers it over Flush.
Hijack delegates through the embedded wrapper, mirroring
responseRecorder.Hijack in the caddyhttp package.

The existing capability test only probed via http.ResponseController,
which is why this went unnoticed. It now asserts each capability both by
direct type assertion and through the controller, and uses two
non-authenticating providers so the probe is guaranteed to run — map
iteration order previously allowed a succeeding provider to break out of
the loop before the probe executed.

Also replace two header copy loops with maps.Copy, fixing the mapsloop
lint failures.
2026-08-01 12:19:27 +10:00
..
caddyauth caddyauth: isolate provider responses to prevent cross-provider clobbering (#7904) 2026-08-01 12:19:27 +10:00
encode encode: flush headers immediately for server-sent events responses (#7905) 2026-08-01 00:27:28 +10:00
fileserver fileserver: speed up directory browsing for large directories (#7903) 2026-08-01 00:38:04 +10:00
headers chore: Enable modernize linter (#7519) 2026-02-26 14:01:35 -07:00
intercept intercept: fix misleading handle_response error for extra matcher args (#7871) 2026-07-12 09:16:34 +10:00
logging logging: log_append Early option, Supports {http.response.body} (#7368) 2025-12-16 23:42:42 -05:00
map chore: Use slices package where possible (#6585) 2024-09-25 14:30:56 -06:00
proxyprotocol docs: expand proxy protocol docs (#6620) 2024-10-10 16:21:26 -04:00
push chore: Dumb prealloc lint fix (#7430) 2026-01-13 14:13:43 -05:00
requestbody chore: ugh, lint fix... (#7275) 2025-09-26 03:14:48 -04:00
reverseproxy fileserver: speed up directory browsing for large directories (#7903) 2026-08-01 00:38:04 +10:00
rewrite rewrite: preserve non-canonical path encoding after uri replace (#7907) 2026-07-26 08:49:44 +10:00
standard caddyhttp: New experimental handler for intercepting responses (#6232) 2024-05-13 17:38:18 +00:00
templates fileserver: speed up directory browsing for large directories (#7903) 2026-08-01 00:38:04 +10:00
tracing tracing: fix BatchSpanProcessor goroutine leak on config reload (#7826) 2026-06-18 11:42:58 -06:00
app.go caddyhttp: Document dropping underscore headers 2026-06-20 13:45:10 -06:00
autohttps.go tls: add alpn to managed HTTPS records (#7653) 2026-05-10 13:10:29 +10:00
autohttps_test.go tls: add alpn to managed HTTPS records (#7653) 2026-05-10 13:10:29 +10:00
caddyhttp.go caddyhttp: Add MatchWithError to replace SetVar hack (#6596) 2024-11-04 23:18:50 +00:00
caddyhttp_test.go caddyhttp: Add test cases to corpus (#6374) 2024-06-04 14:23:55 -06:00
celmatcher.go build(deps): bump cel-go from v0.28.1 to v0.29.2 (#7872) 2026-07-12 09:17:08 +10:00
celmatcher_test.go caddyhttp: add URL pattern request matcher (#7787) 2026-06-22 10:25:43 -06:00
errors.go use math/rand/v2 instead of math/rand (#7413) 2026-02-11 09:15:51 -07:00
http2listener.go chore: clean up wording and typo fixes (#7745) 2026-05-20 16:36:30 +10:00
httpredirectlistener.go chore: clean up wording and typo fixes (#7745) 2026-05-20 16:36:30 +10:00
invoke.go caddyhttp: Implement named routes, invoke directive (#5107) 2023-05-16 15:27:52 +00:00
ip_matchers.go caddyhttp: refactor to use reflect.TypeFor (#7187) 2025-08-18 17:08:46 -06:00
ip_range.go Move PrivateRangesCIDR() back: add a pass-through function (#6514) 2024-08-12 05:47:05 -04:00
logging.go core: custom slog handlers for modules (log contextual data) (#7346) 2025-11-12 13:29:47 -07:00
marshalers.go admin: Redact sensitive request headers in API logs (#7578) 2026-04-17 14:56:42 -06:00
matchers.go caddyhttp: use canonical header key casing to avoid re-canonicalization (#7911) 2026-07-30 20:40:35 +10:00
matchers_test.go caddyhttp: fix path_regexp (MatchPathRE) Windows backslash bypass (#7858) 2026-07-11 08:37:44 +10:00
metrics.go metrics: Implement pushing via OLTP (#7664) 2026-04-25 06:52:08 -04:00
metrics_test.go metrics: Implement pushing via OLTP (#7664) 2026-04-25 06:52:08 -04:00
replacer.go caddyhttp: add {http.request.proto_name} placeholder for spec-compliant protocol names (#7782) 2026-06-04 11:03:19 -04:00
replacer_test.go caddyhttp: add {http.request.proto_name} placeholder for spec-compliant protocol names (#7782) 2026-06-04 11:03:19 -04:00
responsematchers.go caddyhttp: Allow matching Transfer-Encoding, add to access logs (#6629) 2024-12-20 11:16:34 -07:00
responsematchers_test.go reverseproxy: Add handle_response blocks to reverse_proxy (#3710) (#4021) 2021-05-02 12:39:06 -06:00
responsewriter.go caddyhttp: ResponseRecorder sets stream regardless of 1xx 2025-01-27 08:18:37 -07:00
responsewriter_test.go caddyhttp: Address some Go 1.20 features (#6252) 2024-04-24 00:05:57 +00:00
routes.go chore: Fix golangci-lint 2.12.1 findings (#7690) 2026-05-07 03:40:26 -04:00
server.go Set the QUIC InitialPacketSize to 1200 bytes (#7886) 2026-07-26 08:48:25 +10:00
server_test.go caddyhttp: New expected_underscore_headers server option (#7809) 2026-06-11 22:26:21 -06:00
staticerror.go caddyhttp: run error (msg) through replacer (#6536) 2024-08-22 11:32:44 -06:00
staticresp.go chore: fix sabotage spelling in nolint comments (#7892) 2026-07-18 08:14:38 +00:00
staticresp_test.go Move from deprecated ioutil to os and io packages (#4364) 2021-09-29 11:17:48 -06:00
subroute.go reverseproxy: Enable changing only the status code (close #2920) 2020-06-04 12:06:38 -06:00
urlpatternmatcher.go caddyhttp: add URL pattern request matcher (#7787) 2026-06-22 10:25:43 -06:00
urlpatternmatcher_test.go caddyhttp: add URL pattern request matcher (#7787) 2026-06-22 10:25:43 -06:00
vars.go caddyhttp: Clean up variable scope in vars matcher 2026-06-20 13:45:10 -06:00
vars_test.go vars: Add matcher placeholder handling tests (#7640) 2026-04-10 16:27:52 -06:00