mirror of
https://github.com/caddyserver/caddy.git
synced 2026-04-19 23:48:46 -04:00
Some checks failed
Tests / test (s390x on IBM Z) (push) Has been skipped
Tests / goreleaser-check (push) Has been skipped
Tests / test (./cmd/caddy/caddy, ~1.26.0, ubuntu-latest, 0, 1.26, linux) (push) Failing after 1m28s
Cross-Build / build (~1.26.0, 1.26, darwin) (push) Successful in 1m38s
Cross-Build / build (~1.26.0, 1.26, dragonfly) (push) Successful in 1m39s
Cross-Build / build (~1.26.0, 1.26, aix) (push) Successful in 1m50s
Cross-Build / build (~1.26.0, 1.26, freebsd) (push) Successful in 1m25s
Cross-Build / build (~1.26.0, 1.26, illumos) (push) Successful in 1m32s
Cross-Build / build (~1.26.0, 1.26, linux) (push) Successful in 1m31s
Cross-Build / build (~1.26.0, 1.26, netbsd) (push) Successful in 1m41s
Cross-Build / build (~1.26.0, 1.26, openbsd) (push) Successful in 1m23s
Cross-Build / build (~1.26.0, 1.26, solaris) (push) Successful in 1m36s
Cross-Build / build (~1.26.0, 1.26, windows) (push) Successful in 1m34s
Lint / dependency-review (push) Failing after 23s
OpenSSF Scorecard supply-chain security / Scorecard analysis (push) Failing after 27s
Lint / lint (ubuntu-latest, linux) (push) Successful in 2m5s
Lint / govulncheck (push) Successful in 1m25s
Tests / test (./cmd/caddy/caddy, ~1.26.0, macos-14, 0, 1.26, mac) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy.exe, ~1.26.0, windows-latest, True, 1.26, windows) (push) Has been cancelled
Lint / lint (macos-14, mac) (push) Has been cancelled
Lint / lint (windows-latest, windows) (push) Has been cancelled
Signed-off-by: tsinglua <tsinglua@outlook.com>
128 lines
3.9 KiB
Go
128 lines
3.9 KiB
Go
package reverseproxy
|
|
|
|
import (
|
|
"context"
|
|
"net/http/httptest"
|
|
"testing"
|
|
|
|
"github.com/caddyserver/caddy/v2/modules/caddyhttp"
|
|
)
|
|
|
|
func TestAddForwardedHeadersNonIP(t *testing.T) {
|
|
h := Handler{}
|
|
|
|
// Simulate a request with a non-IP remote address (e.g. SCION, abstract socket, or hostname)
|
|
req := httptest.NewRequest("GET", "/", nil)
|
|
req.RemoteAddr = "my-weird-network:12345"
|
|
|
|
// Mock the context variables required by Caddy.
|
|
// We need to inject the variable map manually since we aren't running the full server.
|
|
vars := map[string]any{
|
|
caddyhttp.TrustedProxyVarKey: false,
|
|
}
|
|
ctx := context.WithValue(req.Context(), caddyhttp.VarsCtxKey, vars)
|
|
req = req.WithContext(ctx)
|
|
|
|
// Execute the unexported function
|
|
err := h.addForwardedHeaders(req)
|
|
|
|
// Expectation: No error should be returned for non-IP addresses.
|
|
// The function should simply skip the trusted proxy check.
|
|
if err != nil {
|
|
t.Errorf("expected no error for non-IP address, got: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestAddForwardedHeaders_UnixSocketTrusted(t *testing.T) {
|
|
h := Handler{}
|
|
|
|
req := httptest.NewRequest("GET", "http://example.com/", nil)
|
|
req.RemoteAddr = "@"
|
|
req.Header.Set("X-Forwarded-For", "1.2.3.4, 10.0.0.1")
|
|
req.Header.Set("X-Forwarded-Proto", "https")
|
|
req.Header.Set("X-Forwarded-Host", "original.example.com")
|
|
|
|
vars := map[string]any{
|
|
caddyhttp.TrustedProxyVarKey: true,
|
|
caddyhttp.ClientIPVarKey: "1.2.3.4",
|
|
}
|
|
ctx := context.WithValue(req.Context(), caddyhttp.VarsCtxKey, vars)
|
|
req = req.WithContext(ctx)
|
|
|
|
err := h.addForwardedHeaders(req)
|
|
if err != nil {
|
|
t.Fatalf("expected no error, got: %v", err)
|
|
}
|
|
|
|
if got := req.Header.Get("X-Forwarded-For"); got != "1.2.3.4, 10.0.0.1" {
|
|
t.Errorf("X-Forwarded-For = %q, want %q", got, "1.2.3.4, 10.0.0.1")
|
|
}
|
|
if got := req.Header.Get("X-Forwarded-Proto"); got != "https" {
|
|
t.Errorf("X-Forwarded-Proto = %q, want %q", got, "https")
|
|
}
|
|
if got := req.Header.Get("X-Forwarded-Host"); got != "original.example.com" {
|
|
t.Errorf("X-Forwarded-Host = %q, want %q", got, "original.example.com")
|
|
}
|
|
}
|
|
|
|
func TestAddForwardedHeaders_UnixSocketUntrusted(t *testing.T) {
|
|
h := Handler{}
|
|
|
|
req := httptest.NewRequest("GET", "http://example.com/", nil)
|
|
req.RemoteAddr = "@"
|
|
req.Header.Set("X-Forwarded-For", "1.2.3.4")
|
|
req.Header.Set("X-Forwarded-Proto", "https")
|
|
req.Header.Set("X-Forwarded-Host", "spoofed.example.com")
|
|
|
|
vars := map[string]any{
|
|
caddyhttp.TrustedProxyVarKey: false,
|
|
caddyhttp.ClientIPVarKey: "",
|
|
}
|
|
ctx := context.WithValue(req.Context(), caddyhttp.VarsCtxKey, vars)
|
|
req = req.WithContext(ctx)
|
|
|
|
err := h.addForwardedHeaders(req)
|
|
if err != nil {
|
|
t.Fatalf("expected no error, got: %v", err)
|
|
}
|
|
|
|
if got := req.Header.Get("X-Forwarded-For"); got != "" {
|
|
t.Errorf("X-Forwarded-For should be deleted, got %q", got)
|
|
}
|
|
if got := req.Header.Get("X-Forwarded-Proto"); got != "" {
|
|
t.Errorf("X-Forwarded-Proto should be deleted, got %q", got)
|
|
}
|
|
if got := req.Header.Get("X-Forwarded-Host"); got != "" {
|
|
t.Errorf("X-Forwarded-Host should be deleted, got %q", got)
|
|
}
|
|
}
|
|
|
|
func TestAddForwardedHeaders_UnixSocketTrustedNoExistingHeaders(t *testing.T) {
|
|
h := Handler{}
|
|
|
|
req := httptest.NewRequest("GET", "http://example.com/", nil)
|
|
req.RemoteAddr = "@"
|
|
|
|
vars := map[string]any{
|
|
caddyhttp.TrustedProxyVarKey: true,
|
|
caddyhttp.ClientIPVarKey: "5.6.7.8",
|
|
}
|
|
ctx := context.WithValue(req.Context(), caddyhttp.VarsCtxKey, vars)
|
|
req = req.WithContext(ctx)
|
|
|
|
err := h.addForwardedHeaders(req)
|
|
if err != nil {
|
|
t.Fatalf("expected no error, got: %v", err)
|
|
}
|
|
|
|
if got := req.Header.Get("X-Forwarded-For"); got != "" {
|
|
t.Errorf("X-Forwarded-For should be empty when no prior XFF exists, got %q", got)
|
|
}
|
|
if got := req.Header.Get("X-Forwarded-Proto"); got != "http" {
|
|
t.Errorf("X-Forwarded-Proto = %q, want %q", got, "http")
|
|
}
|
|
if got := req.Header.Get("X-Forwarded-Host"); got != "example.com" {
|
|
t.Errorf("X-Forwarded-Host = %q, want %q", got, "example.com")
|
|
}
|
|
}
|