fix websocket lost query string bug (#2705)
Signed-off-by: Jeff <zw0948@gmail.com>
This commit is contained in:
@@ -20,6 +20,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
"k8s.io/apimachinery/pkg/api/errors"
|
"k8s.io/apimachinery/pkg/api/errors"
|
||||||
|
"k8s.io/apimachinery/pkg/util/httpstream"
|
||||||
"k8s.io/apimachinery/pkg/util/net"
|
"k8s.io/apimachinery/pkg/util/net"
|
||||||
"k8s.io/apimachinery/pkg/util/proxy"
|
"k8s.io/apimachinery/pkg/util/proxy"
|
||||||
"k8s.io/apiserver/pkg/endpoints/handlers/responsewriters"
|
"k8s.io/apiserver/pkg/endpoints/handlers/responsewriters"
|
||||||
@@ -159,6 +160,14 @@ func (c *clusterDispatch) Dispatch(w http.ResponseWriter, req *http.Request, han
|
|||||||
if len(u.Query()["dryRun"]) != 0 {
|
if len(u.Query()["dryRun"]) != 0 {
|
||||||
req.URL.RawQuery = strings.Replace(req.URL.RawQuery, "dryRun", "dryrun", 1)
|
req.URL.RawQuery = strings.Replace(req.URL.RawQuery, "dryRun", "dryrun", 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// kube-apiserver lost query string when proxy websocket requests, there are several issues opened
|
||||||
|
// tracking this, like https://github.com/kubernetes/kubernetes/issues/89360. Also there is a promising
|
||||||
|
// PR aim to fix this, but it's unlikely it will get merged soon. So here we are again. Put raw query
|
||||||
|
// string in Header and extract it on member cluster.
|
||||||
|
if httpstream.IsUpgradeRequest(req) && len(req.URL.RawQuery) != 0 {
|
||||||
|
req.Header.Set("X-KubeSphere-Rawquery", req.URL.RawQuery)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// everything else goes to ks-apiserver, since our ks-apiserver has the ability to proxy kube-apiserver requests
|
// everything else goes to ks-apiserver, since our ks-apiserver has the ability to proxy kube-apiserver requests
|
||||||
|
|
||||||
|
|||||||
@@ -26,13 +26,6 @@ import (
|
|||||||
|
|
||||||
func WithRequestInfo(handler http.Handler, resolver request.RequestInfoResolver) http.Handler {
|
func WithRequestInfo(handler http.Handler, resolver request.RequestInfoResolver) http.Handler {
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||||
ctx := req.Context()
|
|
||||||
info, err := resolver.NewRequestInfo(req)
|
|
||||||
if err != nil {
|
|
||||||
responsewriters.InternalError(w, req, fmt.Errorf("failed to crate RequestInfo: %v", err))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// KubeSphere supports kube-apiserver proxy requests in multicluster mode. But kube-apiserver
|
// KubeSphere supports kube-apiserver proxy requests in multicluster mode. But kube-apiserver
|
||||||
// stripped all authorization headers. Use custom header to carry token to avoid losing authentication token.
|
// stripped all authorization headers. Use custom header to carry token to avoid losing authentication token.
|
||||||
// We may need a better way. See issue below.
|
// We may need a better way. See issue below.
|
||||||
@@ -54,6 +47,22 @@ func WithRequestInfo(handler http.Handler, resolver request.RequestInfoResolver)
|
|||||||
req.URL.RawQuery = strings.Replace(req.URL.RawQuery, "dryrun", "dryRun", 1)
|
req.URL.RawQuery = strings.Replace(req.URL.RawQuery, "dryrun", "dryRun", 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// kube-apiserver lost query string when proxy websocket requests, there are several issues opened
|
||||||
|
// tracking this, like https://github.com/kubernetes/kubernetes/issues/89360. Also there is a promising
|
||||||
|
// PR aim to fix this, but it's unlikely it will get merged soon. So here we are again. Put raw query
|
||||||
|
// string in Header and extract it on member cluster.
|
||||||
|
if rawQuery := req.Header.Get("X-KubeSphere-Rawquery"); len(rawQuery) != 0 && len(req.URL.RawQuery) == 0 {
|
||||||
|
req.URL.RawQuery = rawQuery
|
||||||
|
req.Header.Del("X-KubeSphere-Rawquery")
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := req.Context()
|
||||||
|
info, err := resolver.NewRequestInfo(req)
|
||||||
|
if err != nil {
|
||||||
|
responsewriters.InternalError(w, req, fmt.Errorf("failed to crate RequestInfo: %v", err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
req = req.WithContext(request.WithRequestInfo(ctx, info))
|
req = req.WithContext(request.WithRequestInfo(ctx, info))
|
||||||
handler.ServeHTTP(w, req)
|
handler.ServeHTTP(w, req)
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user