diff --git a/pkg/registry/cluster/storage/aggregate.go b/pkg/registry/cluster/storage/aggregate.go index 7cec60f84346..e1d8c798b473 100644 --- a/pkg/registry/cluster/storage/aggregate.go +++ b/pkg/registry/cluster/storage/aggregate.go @@ -31,7 +31,6 @@ import ( "k8s.io/apiserver/pkg/authentication/user" "k8s.io/apiserver/pkg/endpoints/handlers/responsewriters" "k8s.io/apiserver/pkg/endpoints/request" - apirequest "k8s.io/apiserver/pkg/endpoints/request" "k8s.io/apiserver/pkg/registry/rest" restclient "k8s.io/client-go/rest" "k8s.io/klog/v2" @@ -147,7 +146,7 @@ func requestWithResourceNameHandlerFunc( klog.Errorf("failed to get impersonateToken for cluster %s: %v", cluster.Name, err) return } - statusCode, err := doClusterRequest(req.Method, requestURLStr(location.String(), proxyRequestInfo), transport, requester, impersonateToken) + statusCode, err := doClusterRequest(req.Method, requestURLStr(location, proxyRequestInfo), transport, requester, impersonateToken) if err != nil { klog.Errorf("failed to do request for cluster %s: %v", cluster.Name, err) return @@ -356,7 +355,7 @@ func doClusterRequest( } // requestURLStr returns the request resource url string. -func requestURLStr(urlStr string, requestInfo *apirequest.RequestInfo) string { +func requestURLStr(location *url.URL, requestInfo *request.RequestInfo) string { parts := []string{requestInfo.APIPrefix} if requestInfo.APIGroup != "" { parts = append(parts, requestInfo.APIGroup) @@ -375,7 +374,7 @@ func requestURLStr(urlStr string, requestInfo *apirequest.RequestInfo) string { requestInfo.Subresource != "exec" && requestInfo.Subresource != "log" { parts = append(parts, requestInfo.Subresource) } - return fmt.Sprintf("%s/%s", urlStr, strings.Join(parts, "/")) + return location.ResolveReference(&url.URL{Path: strings.Join(parts, "/")}).String() } func setRequestHeader(req *http.Request, userInfo user.Info, impersonateToken string) { diff --git a/pkg/registry/cluster/storage/aggregate_test.go b/pkg/registry/cluster/storage/aggregate_test.go new file mode 100644 index 000000000000..7f13375ffcaf --- /dev/null +++ b/pkg/registry/cluster/storage/aggregate_test.go @@ -0,0 +1,68 @@ +/* +Copyright 2022 The Karmada Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package storage + +import ( + "net/http" + "net/url" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/karmada-io/karmada/pkg/util/lifted" +) + +func TestRequestURL(t *testing.T) { + tests := []struct { + name string + urlString string + request http.Request + want string + }{ + { + name: "without slash in the end", + urlString: "https://0.0.0.0:6443", + request: http.Request{ + Method: "GET", + URL: &url.URL{ + Path: "/api/v1/namespaces/test/pods/", + }, + }, + want: "https://0.0.0.0:6443/api/v1/namespaces/test/pods", + }, + { + name: "with slash in the end", + urlString: "https://0.0.0.0:6443/", + request: http.Request{ + Method: "GET", + URL: &url.URL{ + Path: "/api/v1/namespaces/test/pods/", + }, + }, + want: "https://0.0.0.0:6443/api/v1/namespaces/test/pods", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + request := tt.request + proxyRequestInfo := lifted.NewRequestInfo(&request) + location, _ := url.Parse(tt.urlString) + requestURL := requestURLStr(location, proxyRequestInfo) + require.Equal(t, tt.want, requestURL) + }) + } +}