Skip to content

Commit 22d29ef

Browse files
committed
test: add unit test for UseLocationHost fix in HandlerWithErrorResponder
1 parent b3a3a73 commit 22d29ef

1 file changed

Lines changed: 53 additions & 0 deletions

File tree

pkg/server/handler/handler_test.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package handler
2+
3+
import (
4+
"net/http"
5+
"net/http/httptest"
6+
"testing"
7+
8+
"gotest.tools/assert"
9+
"k8s.io/client-go/rest"
10+
)
11+
12+
// fakeResponder satisfies the ErrorResponder interface for tests.
13+
type fakeResponder struct{}
14+
15+
func (f *fakeResponder) Error(w http.ResponseWriter, _ *http.Request, err error) {
16+
http.Error(w, err.Error(), http.StatusInternalServerError)
17+
}
18+
19+
// TestHandlerWithErrorResponder_UseLocationHost verifies that UseLocationHost=true causes
20+
// the UpgradeAwareHandler to send the backend hostname as the Host header, not the
21+
// original client Host header.
22+
//
23+
// On clusters where the API server is fronted by an Istio proxy (e.g. Gardener shoots),
24+
// Istio enforces virtual host routing and returns 404 for any Host value it does not
25+
// recognise. Without this fix, kubectl logs/exec/port-forward fail because the handler
26+
// forwards the vcluster LB hostname instead of the actual API server hostname.
27+
func TestHandlerWithErrorResponder_UseLocationHost(t *testing.T) {
28+
var receivedHost string
29+
backend := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
30+
receivedHost = r.Host
31+
w.WriteHeader(http.StatusOK)
32+
}))
33+
defer backend.Close()
34+
35+
cfg := &rest.Config{
36+
Host: backend.URL,
37+
TLSClientConfig: rest.TLSClientConfig{Insecure: true},
38+
}
39+
40+
h, err := HandlerWithErrorResponder("", cfg, nil, &fakeResponder{})
41+
assert.NilError(t, err)
42+
43+
// Simulate a client request with a vcluster LB hostname as Host —
44+
// this is what the UpgradeAwareHandler used to forward before the fix.
45+
req := httptest.NewRequest(http.MethodGet, "/api/v1/namespaces/default/pods/test/log", nil)
46+
req.Host = "vcluster-lb.us-west-2.elb.amazonaws.com"
47+
48+
h.ServeHTTP(httptest.NewRecorder(), req)
49+
50+
// The backend must receive its own hostname, not the client's LB address.
51+
assert.Equal(t, receivedHost, backend.Listener.Addr().String(),
52+
"UpgradeAwareHandler must send Host: <backend hostname> (UseLocationHost=true), not the original client Host header")
53+
}

0 commit comments

Comments
 (0)