k8s.io/apiserver@v0.31.1/pkg/util/proxy/translatinghandler_test.go (about) 1 /* 2 Copyright 2023 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package proxy 18 19 import ( 20 "net/http" 21 "testing" 22 23 "github.com/stretchr/testify/require" 24 "k8s.io/apimachinery/pkg/util/httpstream/wsstream" 25 ) 26 27 // fakeHandler implements http.Handler interface 28 type fakeHandler struct { 29 served bool 30 } 31 32 // ServeHTTP stores the fact that this fake handler was called. 33 func (fh *fakeHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { 34 fh.served = true 35 } 36 37 func TestTranslatingHandler(t *testing.T) { 38 tests := map[string]struct { 39 upgrade string 40 version string 41 expectTranslator bool 42 }{ 43 "websocket/v5 upgrade, serves translator": { 44 upgrade: "websocket", 45 version: "v5.channel.k8s.io", 46 expectTranslator: true, 47 }, 48 "websocket/v5 upgrade with multiple other versions, serves translator": { 49 upgrade: "websocket", 50 version: "v5.channel.k8s.io, v4.channel.k8s.io, v3.channel.k8s.io", 51 expectTranslator: true, 52 }, 53 "websocket/v5 upgrade with multiple other versions out of order, serves translator": { 54 upgrade: "websocket", 55 version: "v4.channel.k8s.io, v3.channel.k8s.io, v5.channel.k8s.io", 56 expectTranslator: true, 57 }, 58 "no upgrade, serves delegate": { 59 upgrade: "", 60 version: "", 61 expectTranslator: false, 62 }, 63 "no upgrade with v5, serves delegate": { 64 upgrade: "", 65 version: "v5.channel.k8s.io", 66 expectTranslator: false, 67 }, 68 "websocket/v5 wrong case upgrade, serves delegage": { 69 upgrade: "websocket", 70 version: "v5.CHANNEL.k8s.io", 71 expectTranslator: false, 72 }, 73 "spdy/v5 upgrade, serves delegate": { 74 upgrade: "spdy", 75 version: "v5.channel.k8s.io", 76 expectTranslator: false, 77 }, 78 "spdy/v4 upgrade, serves delegate": { 79 upgrade: "spdy", 80 version: "v4.channel.k8s.io", 81 expectTranslator: false, 82 }, 83 "websocket/v4 upgrade, serves delegate": { 84 upgrade: "websocket", 85 version: "v4.channel.k8s.io", 86 expectTranslator: false, 87 }, 88 "websocket without version upgrade, serves delegate": { 89 upgrade: "websocket", 90 version: "", 91 expectTranslator: false, 92 }, 93 } 94 for name, test := range tests { 95 req, err := http.NewRequest("GET", "http://www.example.com/", nil) 96 require.NoError(t, err) 97 if test.upgrade != "" { 98 req.Header.Add("Connection", "Upgrade") 99 req.Header.Add("Upgrade", test.upgrade) 100 } 101 if len(test.version) > 0 { 102 req.Header.Add(wsstream.WebSocketProtocolHeader, test.version) 103 } 104 delegate := fakeHandler{} 105 translator := fakeHandler{} 106 translatingHandler := NewTranslatingHandler(&delegate, &translator, 107 wsstream.IsWebSocketRequestWithStreamCloseProtocol) 108 translatingHandler.ServeHTTP(nil, req) 109 if !delegate.served && !translator.served { 110 t.Errorf("unexpected neither translator nor delegate served") 111 continue 112 } 113 if test.expectTranslator { 114 if !translator.served { 115 t.Errorf("%s: expected translator served, got delegate served", name) 116 } 117 } else if !delegate.served { 118 t.Errorf("%s: expected delegate served, got translator served", name) 119 } 120 } 121 }