diff --git a/pkg/registry/generic/rest/proxy.go b/pkg/registry/generic/rest/proxy.go index bd4f3946a21..5339c596f46 100644 --- a/pkg/registry/generic/rest/proxy.go +++ b/pkg/registry/generic/rest/proxy.go @@ -174,23 +174,56 @@ func (h *UpgradeAwareProxyHandler) tryUpgrade(w http.ResponseWriter, req *http.R func (h *UpgradeAwareProxyHandler) dialURL() (net.Conn, error) { dialAddr := netutil.CanonicalAddr(h.Location) + var dialer func(network, addr string) (net.Conn, error) + if httpTransport, ok := h.Transport.(*http.Transport); ok && httpTransport.Dial != nil { + dialer = httpTransport.Dial + } + switch h.Location.Scheme { case "http": + if dialer != nil { + return dialer("tcp", dialAddr) + } return net.Dial("tcp", dialAddr) case "https": + // TODO: this TLS logic can probably be cleaned up; it's messy in an attempt + // to preserve behavior that we don't know for sure is exercised. + // Get the tls config from the transport if we recognize it var tlsConfig *tls.Config + var tlsConn *tls.Conn + var err error if h.Transport != nil { httpTransport, ok := h.Transport.(*http.Transport) if ok { tlsConfig = httpTransport.TLSClientConfig } } + if dialer != nil { + // We have a dialer; use it to open the connection, then + // create a tls client using the connection. + netConn, err := dialer("tcp", dialAddr) + if err != nil { + return nil, err + } + // tls.Client requires non-nil config + if tlsConfig == nil { + glog.Warningf("using custom dialer with no TLSClientConfig. Defaulting to InsecureSkipVerify") + tlsConfig = &tls.Config{ + InsecureSkipVerify: true, + } + } + tlsConn = tls.Client(netConn, tlsConfig) + if err := tlsConn.Handshake(); err != nil { + return nil, err + } - // Dial - tlsConn, err := tls.Dial("tcp", dialAddr, tlsConfig) - if err != nil { - return nil, err + } else { + // Dial + tlsConn, err = tls.Dial("tcp", dialAddr, tlsConfig) + if err != nil { + return nil, err + } } // Verify @@ -202,7 +235,7 @@ func (h *UpgradeAwareProxyHandler) dialURL() (net.Conn, error) { return tlsConn, nil default: - return nil, fmt.Errorf("Unknown scheme: %s", h.Location.Scheme) + return nil, fmt.Errorf("unknown scheme: %s", h.Location.Scheme) } }