1
0
mirror of https://github.com/rancher/steve.git synced 2025-04-30 04:03:46 +00:00
steve/pkg/proxy/proxy.go

115 lines
2.7 KiB
Go
Raw Normal View History

2019-08-08 05:41:31 +00:00
package proxy
import (
2020-01-31 05:37:59 +00:00
"fmt"
2019-08-08 05:41:31 +00:00
"net/http"
"net/url"
"strings"
"github.com/rancher/wrangler/pkg/kubeconfig"
"k8s.io/apimachinery/pkg/util/proxy"
"k8s.io/client-go/rest"
"k8s.io/client-go/transport"
)
// Mostly copied from "kubectl proxy" code
func HandlerFromConfig(prefix, kubeConfig string) (http.Handler, error) {
loader := kubeconfig.GetInteractiveClientConfig(kubeConfig)
cfg, err := loader.ClientConfig()
if err != nil {
return nil, err
}
return Handler(prefix, cfg)
}
// Mostly copied from "kubectl proxy" code
func Handler(prefix string, cfg *rest.Config) (http.Handler, error) {
host := cfg.Host
if !strings.HasSuffix(host, "/") {
host = host + "/"
}
target, err := url.Parse(host)
if err != nil {
return nil, err
}
transport, err := rest.TransportFor(cfg)
if err != nil {
return nil, err
}
2020-01-31 05:37:59 +00:00
upgradeTransport, err := makeUpgradeTransport(cfg, transport)
2019-08-08 05:41:31 +00:00
if err != nil {
return nil, err
}
proxy := proxy.NewUpgradeAwareHandler(target, transport, false, false, er)
proxy.UpgradeTransport = upgradeTransport
proxy.UseRequestLocation = true
2020-01-31 05:37:59 +00:00
handler := http.Handler(proxy)
2019-08-13 23:36:03 +00:00
if len(target.Path) > 1 {
handler = prependPath(target.Path[:len(target.Path)-1], handler)
}
2019-08-08 05:41:31 +00:00
if len(prefix) > 2 {
2020-01-31 05:37:59 +00:00
handler = stripLeaveSlash(prefix, handler)
2019-08-08 05:41:31 +00:00
}
2020-01-31 05:37:59 +00:00
return authHeaders(handler), nil
2019-08-13 23:36:03 +00:00
}
2020-01-31 05:37:59 +00:00
func authHeaders(handler http.Handler) http.Handler {
return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
req.Header.Del("Authorization")
handler.ServeHTTP(rw, req)
})
}
func SetHost(host string, h http.Handler) http.Handler {
2019-08-13 23:36:03 +00:00
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
req.Host = host
h.ServeHTTP(w, req)
})
}
func prependPath(prefix string, h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
if len(req.URL.Path) > 1 {
req.URL.Path = prefix + req.URL.Path
} else {
req.URL.Path = prefix
}
h.ServeHTTP(w, req)
})
2019-08-08 05:41:31 +00:00
}
// like http.StripPrefix, but always leaves an initial slash. (so that our
// regexps will work.)
func stripLeaveSlash(prefix string, h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
p := strings.TrimPrefix(req.URL.Path, prefix)
if len(p) > 0 && p[:1] != "/" {
p = "/" + p
}
req.URL.Path = p
2020-01-31 05:37:59 +00:00
fmt.Println(req.Method, " ", req.URL.String())
2019-08-08 05:41:31 +00:00
h.ServeHTTP(w, req)
})
}
2020-01-31 05:37:59 +00:00
func makeUpgradeTransport(config *rest.Config, rt http.RoundTripper) (proxy.UpgradeRequestRoundTripper, error) {
2019-08-08 05:41:31 +00:00
transportConfig, err := config.TransportConfig()
if err != nil {
return nil, err
}
upgrader, err := transport.HTTPWrappersForConfig(transportConfig, proxy.MirrorRequest)
if err != nil {
return nil, err
}
return proxy.NewUpgradeRequestRoundTripper(rt, upgrader), nil
}