MCPcopy
hub / github.com/caddyserver/caddy / testProxyProtocolMatrix

Function testProxyProtocolMatrix

caddytest/integration/proxyprotocol_test.go:475–533  ·  view source on GitHub ↗

testProxyProtocolMatrix is the shared implementation for the proxy protocol tests. It: 1. Starts a go-proxyproto-wrapped backend. 2. Configures Caddy as a reverse proxy with the given PROXY protocol version and transport versions. 3. Sends numRequests GET requests through Caddy and asserts 200 OK e

(t *testing.T, ppVersion string, transportVersions []string, numRequests int)

Source from the content-addressed store, hash-verified

473// 4. Asserts the backend recorded at least one PROXY header whose source host
474// is 127.0.0.1 (the loopback address used by the test client).
475func testProxyProtocolMatrix(t *testing.T, ppVersion string, transportVersions []string, numRequests int) {
476 t.Helper()
477
478 backend := newProxyProtoBackend(t)
479 listenPort := freePort(t)
480
481 tester := caddytest.NewTester(t)
482 tester.WithDefaultOverrides(caddytest.Config{
483 AdminPort: 2999,
484 })
485 cfg := proxyProtoConfig(listenPort, backend.addr(), ppVersion, transportVersions)
486 tester.InitServer(cfg, "json")
487
488 // If the test is h2c-only (no "1.1" in versions), reconfigure the test
489 // client transport to use unencrypted HTTP/2 so we actually exercise the
490 // h2c code path through Caddy.
491 if slices.Contains(transportVersions, "h2c") && !slices.Contains(transportVersions, "1.1") {
492 tr, ok := tester.Client.Transport.(*http.Transport)
493 if ok {
494 tr.Protocols = new(http.Protocols)
495 tr.Protocols.SetHTTP1(false)
496 tr.Protocols.SetUnencryptedHTTP2(true)
497 }
498 }
499
500 proxyURL := fmt.Sprintf("http://127.0.0.1:%d/", listenPort)
501
502 for i := 0; i < numRequests; i++ {
503 resp, err := tester.Client.Get(proxyURL)
504 if err != nil {
505 t.Fatalf("request %d/%d: GET %s: %v", i+1, numRequests, proxyURL, err)
506 }
507 resp.Body.Close()
508 if resp.StatusCode != http.StatusOK {
509 t.Errorf("request %d/%d: expected status 200, got %d", i+1, numRequests, resp.StatusCode)
510 }
511 }
512
513 // The backend must have seen at least one PROXY header. For h1, there is
514 // one per request; for h2c, requests share the same connection so only one
515 // header is written at connection establishment.
516 addrs := backend.recordedAddrs()
517 if len(addrs) == 0 {
518 t.Fatalf("backend recorded no PROXY protocol addresses (expected at least 1)")
519 }
520
521 // Every PROXY-decoded source address must be the loopback address since
522 // the test client always connects from 127.0.0.1.
523 for i, addr := range addrs {
524 host, _, err := net.SplitHostPort(addr)
525 if err != nil {
526 t.Errorf("addr[%d] %q: SplitHostPort: %v", i, addr, err)
527 continue
528 }
529 if host != "127.0.0.1" {
530 t.Errorf("addr[%d]: expected source 127.0.0.1, got %q", i, host)
531 }
532 }

Calls 10

WithDefaultOverridesMethod · 0.95
InitServerMethod · 0.95
NewTesterFunction · 0.92
newProxyProtoBackendFunction · 0.85
freePortFunction · 0.85
proxyProtoConfigFunction · 0.85
GetMethod · 0.65
addrMethod · 0.45
CloseMethod · 0.45
recordedAddrsMethod · 0.45

Tested by

no test coverage detected