mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-19 08:40:42 +00:00
Add http proxy support for exec/port-forward
Add http proxy support for exec/port-forward in SpdyRoundTripper
This commit is contained in:
parent
26c51881ca
commit
e73652411e
@ -23,6 +23,8 @@ import (
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
@ -53,21 +55,82 @@ type SpdyRoundTripper struct {
|
||||
Dialer *net.Dialer
|
||||
}
|
||||
|
||||
// NewSpdyRoundTripper creates a new SpdyRoundTripper that will use
|
||||
// NewRoundTripper creates a new SpdyRoundTripper that will use
|
||||
// the specified tlsConfig.
|
||||
func NewRoundTripper(tlsConfig *tls.Config) httpstream.UpgradeRoundTripper {
|
||||
return NewSpdyRoundTripper(tlsConfig)
|
||||
}
|
||||
|
||||
// NewSpdyRoundTripper creates a new SpdyRoundTripper that will use
|
||||
// the specified tlsConfig. This function is mostly meant for unit tests.
|
||||
func NewSpdyRoundTripper(tlsConfig *tls.Config) *SpdyRoundTripper {
|
||||
return &SpdyRoundTripper{tlsConfig: tlsConfig}
|
||||
}
|
||||
|
||||
// dial dials the host specified by req, using TLS if appropriate.
|
||||
// dial dials the host specified by req, using TLS if appropriate, optionally
|
||||
// using a proxy server if one is configured via environment variables.
|
||||
func (s *SpdyRoundTripper) dial(req *http.Request) (net.Conn, error) {
|
||||
dialAddr := netutil.CanonicalAddr(req.URL)
|
||||
proxyURL, err := http.ProxyFromEnvironment(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if req.URL.Scheme == "http" {
|
||||
if proxyURL == nil {
|
||||
return s.dialWithoutProxy(req.URL)
|
||||
}
|
||||
|
||||
// proxying logic adapted from http://blog.h6t.eu/post/74098062923/golang-websocket-with-http-proxy-support
|
||||
proxyReq := http.Request{
|
||||
Method: "CONNECT",
|
||||
URL: &url.URL{},
|
||||
Host: req.URL.Host,
|
||||
}
|
||||
|
||||
proxyDialConn, err := s.dialWithoutProxy(proxyURL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
proxyClientConn := httputil.NewProxyClientConn(proxyDialConn, nil)
|
||||
_, err = proxyClientConn.Do(&proxyReq)
|
||||
if err != nil && err != httputil.ErrPersistEOF {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rwc, _ := proxyClientConn.Hijack()
|
||||
|
||||
if req.URL.Scheme != "https" {
|
||||
return rwc, nil
|
||||
}
|
||||
|
||||
host, _, err := net.SplitHostPort(req.URL.Host)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(s.tlsConfig.ServerName) == 0 {
|
||||
s.tlsConfig.ServerName = host
|
||||
}
|
||||
|
||||
tlsConn := tls.Client(rwc, s.tlsConfig)
|
||||
|
||||
// need to manually call Handshake() so we can call VerifyHostname() below
|
||||
if err := tlsConn.Handshake(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := tlsConn.VerifyHostname(host); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return tlsConn, nil
|
||||
}
|
||||
|
||||
// dialWithoutProxy dials the host specified by url, using TLS if appropriate.
|
||||
func (s *SpdyRoundTripper) dialWithoutProxy(url *url.URL) (net.Conn, error) {
|
||||
dialAddr := netutil.CanonicalAddr(url)
|
||||
|
||||
if url.Scheme == "http" {
|
||||
if s.Dialer == nil {
|
||||
return net.Dial("tcp", dialAddr)
|
||||
} else {
|
||||
|
Loading…
Reference in New Issue
Block a user