Commit Graph

163 Commits (add-tests)

Author SHA1 Message Date
Julien Voisin 0476754858
reverseproxy: reduce allocation/CPU overhead in request hot paths (#7925)
Build the Via request and response headers with strconv-based
concatenation instead of fmt.Sprintf, avoiding fmt's reflection and
formatting overhead on every proxied request/response. Same single
allocation, ~40% faster for that construction in isolation.

                 | before (fmt) |            after (strconv)          |
                 |    sec/op    |    sec/op     vs base               |
PrepareRequest-8 | 6.136µ ± 11% | 4.491µ ± 33%  -26.80% (p=0.007 n=10)|

B/op:     1008 -> 1008   (unchanged)
allocs/op:  12 -> 12     (unchanged)

No behavior change. Adds BenchmarkPrepareRequest, as per policy, exercising the
request preparation path.
2026-08-10 15:49:55 +10:00
WeidiDeng 1830809afe
reverseproxy: save dial info in a context key instead of a variable key to avoid race conditions when forward_auth is used (#7859) 2026-07-10 09:37:07 -06:00
Saleh d2e0ad1e92
reverseproxy: log status 499 instead of 0 when client disconnects (#7827) 2026-06-18 13:31:02 +10:00
Dionis Ramadani 25b3eab6db
Merge commit from fork
* fix(reverseproxy): hop-by-hop header fix

* test(headers): Added unit tests for hop-by-hope header behavior
2026-06-12 12:39:01 -06:00
WeidiDeng ad912569b5
reverseproxy: wraps request body to prevent closing if not read (#7719)
Co-authored-by: Matt Holt <mholt@users.noreply.github.com>
2026-05-20 17:35:40 +00:00
James Hartig 77e9ce7404
reverseproxy: further prevent body closes from dial errors (#7715) 2026-05-12 12:05:50 -06:00
Matt Holt 4d6945769d
reverseproxy: Add ability to clear dynamic upstreams cache during retries (#7662)
* reverseproxy: Add ability to clear dynamic upstreams cache during retries

This is an optional interface for dynamic upstream modules to implement if they cache results.

TODO: More documentation; this is an experiment.

* Add some godoc

* Export interface; update godoc
2026-04-28 09:16:18 -06:00
Daniil Sivak aed1af5976
reverseproxy: add `lb_retry_match` condition on response status (#7569) 2026-04-21 14:59:31 -04:00
Zen Dodd ca0ca67fbd
reverseproxy: make stream copy buffer size configurable (#7627) 2026-04-10 14:49:32 -06:00
Tom Paulus a5e7c6e232
reverseproxy: prevent body close on dial-error retries (#7547) 2026-03-04 15:17:02 -05:00
Francis Lavoie db2986028f
reverseproxy: Track dynamic upstreams, enable passive healthchecking (#7539)
* reverseproxy: Track dynamic upstreams, enable passive healthchecking

* Add tests for dynamic upstream tracking, admin endpoint, health checks
2026-03-04 15:05:26 -05:00
Paulo Henrique 88616e86e6
api: Add all in-flight requests /reverse_proxy/upstreams (Fixes #7277) (#7517)
This refactors the initial approach in PR #7281, replacing the UsagePool
with a dedicated package-level sync.Map and atomic.Int64 to track
in-flight requests without global lock contention.

It also introduces a lookup map in the admin API to fix a potential
O(n^2) iteration over upstreams, ensuring that draining upstreams
are correctly exposed across config reloads without leaking memory.

Co-authored-by: Y.Horie <u5.horie@gmail.com>

reverseproxy: optimize in-flight tracking and admin API

- Replaced sync.RWMutex with sync.Map and atomic.Int64 to avoid lock contention under high RPS.
- Introduced a lookup map in the admin API to fix a potential O(n^2) iteration over upstreams.
2026-03-03 15:14:55 -07:00
WeidiDeng 2ab043b890
reverseproxy: query escape request urls when proxy protocol is enabled (#7537) 2026-03-02 02:04:06 -05:00
XYenon 03e6e439dd
reverseproxy: fix X-Forwarded-* headers for Unix socket requests (#7463)
When a request arrives via a Unix domain socket (RemoteAddr == "@"),
net.SplitHostPort fails, causing addForwardedHeaders to strip all
X-Forwarded-* headers even when the connection is trusted via
trusted_proxies_unix.

Handle Unix socket connections before parsing RemoteAddr: if untrusted,
strip headers for security; if trusted, let clientIP remain empty (no
peer IP for a Unix socket hop) and fall through to the shared header
logic, preserving the existing XFF chain without appending a spurious
entry.

Amp-Thread-ID: https://ampcode.com/threads/T-019c4225-a0ad-7283-ac56-e2c01eae1103

Co-authored-by: Amp <amp@ampcode.com>
2026-02-10 13:00:20 -07:00
Francis Lavoie 2ae0f7af69
reverseproxy: Set `Host` to `{upstream_hostport}` automatically if TLS (#7454) 2026-02-09 13:06:19 -07:00
Paulo Henrique 62134d65af
reverseproxy: fix error when remote address is not an IP (#7429) 2026-01-13 19:52:56 +00:00
Petr 67a9e0657e
reverseproxy: Fix retries for requests with bodies (#7360)
* capture the buffered body once, then reset clonedReq.Body before each retry

* no copy

* keep receiver name

* set the buf to nil after extraction and only return it to pool if not nil

---------

Co-authored-by: WeidiDeng <weidi_deng@icloud.com>
2025-11-24 12:03:18 -07:00
WeidiDeng a6da1acdc8
reverse_proxy: use interfaces to modify the behaviors of the transports (#7353) 2025-11-17 09:51:37 -07:00
WeidiDeng 8aca108d2c
reverseproxy: do not disable keepalive if proxy protocol is used (#7300) 2025-10-21 05:09:37 +00:00
Anthony Biondo 7fb39ec1e5
reverseproxy: Use http1.1 upgrade for websocket for extended connect of http2 and http3 (#7305)
Co-authored-by: WeidiDeng <weidi_deng@icloud.com>
2025-10-16 02:20:20 +00:00
WeidiDeng 2ec28bca43
reverse_proxy: use http1 for outbound tls requests with placeholder that are likely websockets (#7296) 2025-10-09 10:36:49 -06:00
joemicky 5125fbed41
use a more modern writing style to simplify code (#7182)
Signed-off-by: joemicky <joemickychang@outlook.com>
Co-authored-by: Matt Holt <mholt@users.noreply.github.com>
2025-08-20 11:41:21 -06:00
Mohammed Al Sahaf e039a5bb5c
chore: upgrade .golangci.yml and workflow to v2 (#6924)
* chore: upgrade .golangci.yml and workflow to v2

run `golangci-lint fmt`

Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>

* run `golangci-lint run --fix`

Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>

* more lint fixes

Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>

* bring back comments to .golangci.yml

Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>

* appease the linter some more

Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>

* oops

Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>

* use embedded structs

Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>

* use embedded structs where they were used before

Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>

* disable rule  `-QF1006`

Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>

* missed a spot

Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>

---------

Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>
2025-06-03 02:24:32 +03:00
Jesper Brix Rosenkilde 6c38ae7381
reverseproxy: Add valid Upstream to DialInfo in active health checks (#6949)
Currently if we extract the DialInfo from a Request Context during an active health check, then the Upstream in the DialInfo is nil.

This PR attempts to set the Upstream to a sensible value, based on wether or not the Upstream has been overriden in the active health check's config.
2025-04-15 08:44:53 -06:00
WeidiDeng 220cd1c2bc
reverseproxy: more comments about buffering and add new tests (#6778)
Co-authored-by: Matt Holt <mholt@users.noreply.github.com>
2025-03-07 11:22:43 -07:00
Mohammed Al Sahaf 904a0fa368
reverse_proxy: re-add healthy upstreams metric (#6806)
* reverse_proxy: re-add healthy upstreams metric

Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>

* lint

Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>

---------

Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>
2025-01-27 14:30:54 -07:00
Matthew Holt e7da3b267b
reverseproxy: Via header (#6275) 2025-01-17 06:49:01 -07:00
WeidiDeng 1bd567d7ad
reverseproxy: buffer requests for fastcgi by default (#6759)
* buffer requests for fastcgi by default

* fix import cycle

* fix the return value of bufferedBody

* more comments about fastcgi buffering

---------

Co-authored-by: Matt Holt <mholt@users.noreply.github.com>
2025-01-02 11:18:25 -07:00
WeidiDeng c864b82ae1
reverseproxy: Set Content-Length when body is fully buffered (#6638) 2024-12-17 23:36:13 +00:00
bt90 328fb614f0
reverseproxy: Only handle websocket protocol (#6740) 2024-12-11 11:17:05 -07:00
WeidiDeng 9c0c71e577
reverseproxy: Rewrite requests and responses for websocket over http2 (#6567)
* reverse proxy: rewrite requests and responses for websocket over http2

* delete protocol pseudo-header

* modify cloned requests

* set request variable to track if it's a h2 websocket

* use request bodu

* rewrite request body

* use WebSocket instead of Websocket in the headers

* use logger check for zap loggers

* fix lint
2024-12-06 13:23:27 -07:00
Francis Lavoie 315715e90f
core: Implement FastAbs to avoid repeated os.Getwd calls (#6687)
* core: Implement FastAbs to avoid repeated os.Getwd calls

* Lint

* Rename files
2024-11-13 03:55:51 -05:00
Matthew Holt 238f1108e6
reverseproxy: Revert #4952 - don't ignore context cancellation in stream mode
i.e. Revert commit f5dce84a70

Two years ago, the patch in #4952 was a seemingly necessary way to fix an issue (sort of an edge case), but it broke other more common use cases (see #6666).

Now, as of #6669, it seems like the original issue can no longer be replicated, so we are reverting that patch, because it was incorrect anyway.

If it turns out the original issue returns, a more proper patch may be in #6669 (even if used as a baseline for a future fix). A potential future fix could be an opt-in setting.
2024-11-12 13:43:34 -07:00
Francis Lavoie 09b2cbcf4d
caddyhttp: Add `MatchWithError` to replace SetVar hack (#6596)
* caddyhttp: Add `MatchWithError` to replace SetVar hack

* Error in IP matchers on TLS handshake not complete

* Use MatchWithError everywhere possible

* Move implementations to MatchWithError versions

* Looser interface checking to allow fallback

* CEL factories can return RequestMatcherWithError

* Clarifying comment since it's subtle that an err is returned

* Return 425 Too Early status in IP matchers

* Keep AnyMatch signature the same for now

* Apparently Deprecated can't be all-uppercase to get IDE linting

* Linter
2024-11-04 23:18:50 +00:00
Francis Lavoie fbf0f4c425
reverseproxy: Sync changes from stdlib for 1xx handling (#6656)
* reverseproxy: Sync changes from stdlib for 1xx handling

Sourced from 960654be0c

* Use clear()

3bc28402fa
2024-10-22 12:10:46 -06:00
WeidiDeng 48ce47f1d4
reverseproxy: Use correct cases for websocket related headers (#6621)
Co-authored-by: Francis Lavoie <lavofr@gmail.com>
2024-10-11 09:02:23 +00:00
Kévin Dunglas f4bf4e0097
perf: use zap's Check() to prevent useless allocs (#6560)
* perf: use zap's Check() to prevent useless allocs

* fix

* fix

* fix

* fix

* restore previous replacer behavior

* fix linter
2024-09-13 11:16:37 -06:00
Steffen Busch c050a37e1c
reverse_proxy: add placeholder http.reverse_proxy.retries (#6553)
* Add placeholder http.reverse_proxy.lb.retries

* Renamed placeholder to http.reverse_proxy.retries
2024-08-30 11:53:56 -06:00
Jens-Uwe Mager 2bb2ecc549
reverseproxy: Change errors writing the response to warning. (#6532)
Most of the errors that can be seen here are write errors due to clients
aborting the request from their side. Often seen ones include:

	* writing: ... write: broken pipe
	* writing: ... connection timed out
	* writing: http2: stream closed
	* writing: timeout...
	* writing: h3 error...

Most of these errors are beyond of the control of caddy on the client side,
probably nothing can be done on the server side. It still warrants
researching when these errors occur very often, so a change in level from
error to warn is better here to not polute the logs with errors in the
normal case.
2024-08-21 11:39:20 -06:00
Matt Holt c3fb5f4d3f
caddyhttp: Reject 0-RTT early data in IP matchers and set Early-Data header when proxying (#6427)
* caddyhttp: Reject 0-RTT early data in IP matchers and set Early-Data header when proxying

See RFC 8470: https://httpwg.org/specs/rfc8470.html

Thanks to Michael Wedl (@MWedl)  at the University of Applied Sciences St. Poelten for reporting this.

* Don't return value for {remote} placeholder in early data

* Add Caddyfile support
2024-07-05 10:46:20 -06:00
Matthew Holt 9f97df2275
reverseproxy: Remove long-deprecated buffering properties
They've been deprecated for over a year and we printed warnings during that time.
2024-04-22 15:34:14 -06:00
Matthew Holt d93e027e01
reverseproxy: Reuse buffered request body even if partially drained
Previous commit only works when the backends don't read any of the body first.
2024-04-22 15:22:50 -06:00
Matthew Holt 613d544a47 reverseproxy: Accept EOF when buffering
Before this change, a read of size (let's say) < 10, into a buffer of size 10, will return EOF because we're using CopyN to limit to the size of the buffer. That resulted in the body being read from later, which should only happen if it couldn't fit in the buffer.

With this change, the body is properly NOT set when it can all fit in the buffer.
2024-04-22 13:12:10 -06:00
WeidiDeng b40cacf5ce
reverseproxy: Wait for both ends of websocket to close (#6175) 2024-04-15 11:37:37 -06:00
WeidiDeng 53f7035299
reverseproxy: use context.WithoutCancel (#6116) 2024-02-19 20:25:02 -07:00
Yolan Romailler 2fe69a828f
chore: enabling a few more linters (#5961)
Co-authored-by: Francis Lavoie <lavofr@gmail.com>
2024-01-25 15:24:58 +00:00
Fred Cox d9ff7b1872
reverseproxy: Only change Content-Length when full request is buffered (#5830)
fixes: https://github.com/caddyserver/caddy/issues/5829

Signed-off-by: Fred Cox <mcfedr@gmail.com>
2024-01-09 12:59:30 -07:00
WeidiDeng 4de2c1c65e
panic when reading from backend failed to propagate stream error (#5952) 2023-11-23 03:18:18 -05:00
Matt Holt 3a3182fba3
reverseproxy: Add more debug logs (#5793)
* reverseproxy: Add more debug logs

This makes debug logging very noisy when reverse proxying, but I guess
that's the point.

This has shown to be useful in troubleshooting infrastructure issues.

* Update modules/caddyhttp/reverseproxy/streaming.go

Co-authored-by: Francis Lavoie <lavofr@gmail.com>

* Update modules/caddyhttp/reverseproxy/streaming.go

Co-authored-by: Francis Lavoie <lavofr@gmail.com>

* Add opt-in `trace_logs` option

* Rename to VerboseLogs

---------

Co-authored-by: Francis Lavoie <lavofr@gmail.com>
2023-10-11 13:36:20 -06:00
Francis Lavoie 2a6859a5e4
reverseproxy: Fix retries on "upstreams unavailable" error (#5841) 2023-10-10 22:07:20 +00:00