// dial dials the host specified by req, using TLS if appropriate. func (s *SpdyRoundTripper) dial(req *http.Request) (net.Conn, error) { dialAddr := netutil.CanonicalAddr(req.URL) if req.URL.Scheme == "http" { if s.Dialer == nil { return net.Dial("tcp", dialAddr) } else { return s.Dialer.Dial("tcp", dialAddr) } } // TODO validate the TLSClientConfig is set up? var conn *tls.Conn var err error if s.Dialer == nil { conn, err = tls.Dial("tcp", dialAddr, s.tlsConfig) } else { conn, err = tls.DialWithDialer(s.Dialer, "tcp", dialAddr, s.tlsConfig) } if err != nil { return nil, err } host, _, err := net.SplitHostPort(dialAddr) if err != nil { return nil, err } err = conn.VerifyHostname(host) if err != nil { return nil, err } return conn, nil }
func dialURL(url *url.URL, transport http.RoundTripper) (net.Conn, error) { dialAddr := netutil.CanonicalAddr(url) switch url.Scheme { case "http": return net.Dial("tcp", dialAddr) case "https": // Get the tls config from the transport if we recognize it var tlsConfig *tls.Config if transport != nil { httpTransport, ok := transport.(*http.Transport) if ok { tlsConfig = httpTransport.TLSClientConfig } } // Dial tlsConn, err := tls.Dial("tcp", dialAddr, tlsConfig) if err != nil { return nil, err } // Verify host, _, _ := net.SplitHostPort(dialAddr) if err := tlsConn.VerifyHostname(host); err != nil { tlsConn.Close() return nil, err } return tlsConn, nil default: return nil, fmt.Errorf("Unknown scheme: %s", url.Scheme) } }
func (p *UpgradeAwareSingleHostReverseProxy) dialBackend(req *http.Request) (net.Conn, error) { dialAddr := netutil.CanonicalAddr(req.URL) switch p.backendAddr.Scheme { case "http": return net.Dial("tcp", dialAddr) case "https": tlsConfig, err := kclient.TLSConfigFor(p.clientConfig) if err != nil { return nil, err } tlsConn, err := tls.Dial("tcp", dialAddr, tlsConfig) if err != nil { return nil, err } hostToVerify, _, err := net.SplitHostPort(dialAddr) if err != nil { return nil, err } err = tlsConn.VerifyHostname(hostToVerify) return tlsConn, err default: return nil, fmt.Errorf("unknown scheme: %s", p.backendAddr.Scheme) } }
// 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) { proxyURL, err := http.ProxyFromEnvironment(req) if err != nil { return nil, err } if proxyURL == nil { return s.dialWithoutProxy(req.URL) } // ensure we use a canonical host with proxyReq targetHost := netutil.CanonicalAddr(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: targetHost, } 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 }
// GetClusterNicknameFromURL returns host:port of the apiServerLocation, with .'s replaced by -'s func GetClusterNicknameFromURL(apiServerLocation string) (string, error) { u, err := url.Parse(apiServerLocation) if err != nil { return "", err } hostPort := netutil.CanonicalAddr(u) // we need a character other than "." to avoid conflicts with. replace with '-' return strings.Replace(hostPort, ".", "-", -1), 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 { return s.Dialer.Dial("tcp", dialAddr) } } // TODO validate the TLSClientConfig is set up? var conn *tls.Conn var err error if s.Dialer == nil { conn, err = tls.Dial("tcp", dialAddr, s.tlsConfig) } else { conn, err = tls.DialWithDialer(s.Dialer, "tcp", dialAddr, s.tlsConfig) } if err != nil { return nil, err } // Return if we were configured to skip validation if s.tlsConfig != nil && s.tlsConfig.InsecureSkipVerify { return conn, nil } host, _, err := net.SplitHostPort(dialAddr) if err != nil { return nil, err } err = conn.VerifyHostname(host) if err != nil { return nil, err } return conn, nil }
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 } } else { // Dial tlsConn, err = tls.Dial("tcp", dialAddr, tlsConfig) if err != nil { return nil, err } } // Return if we were configured to skip validation if tlsConfig != nil && tlsConfig.InsecureSkipVerify { return tlsConn, nil } // Verify host, _, _ := net.SplitHostPort(dialAddr) if err := tlsConn.VerifyHostname(host); err != nil { tlsConn.Close() return nil, err } return tlsConn, nil default: return nil, fmt.Errorf("unknown scheme: %s", h.Location.Scheme) } }
func DialURL(url *url.URL, transport http.RoundTripper) (net.Conn, error) { dialAddr := netutil.CanonicalAddr(url) dialer, _ := util.Dialer(transport) switch url.Scheme { case "http": if dialer != nil { return dialer("tcp", dialAddr) } return net.Dial("tcp", dialAddr) case "https": // Get the tls config from the transport if we recognize it var tlsConfig *tls.Config var tlsConn *tls.Conn var err error tlsConfig, _ = util.TLSClientConfig(transport) 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 } if tlsConfig == nil { // tls.Client requires non-nil config glog.Warningf("using custom dialer with no TLSClientConfig. Defaulting to InsecureSkipVerify") // tls.Handshake() requires ServerName or InsecureSkipVerify tlsConfig = &tls.Config{ InsecureSkipVerify: true, } } else if len(tlsConfig.ServerName) == 0 && !tlsConfig.InsecureSkipVerify { // tls.Handshake() requires ServerName or InsecureSkipVerify // infer the ServerName from the hostname we're connecting to. inferredHost := dialAddr if host, _, err := net.SplitHostPort(dialAddr); err == nil { inferredHost = host } // Make a copy to avoid polluting the provided config tlsConfigCopy := *tlsConfig tlsConfigCopy.ServerName = inferredHost tlsConfig = &tlsConfigCopy } tlsConn = tls.Client(netConn, tlsConfig) if err := tlsConn.Handshake(); err != nil { netConn.Close() return nil, err } } else { // Dial tlsConn, err = tls.Dial("tcp", dialAddr, tlsConfig) if err != nil { return nil, err } } // Return if we were configured to skip validation if tlsConfig != nil && tlsConfig.InsecureSkipVerify { return tlsConn, nil } // Verify host, _, _ := net.SplitHostPort(dialAddr) if err := tlsConn.VerifyHostname(host); err != nil { tlsConn.Close() return nil, err } return tlsConn, nil default: return nil, fmt.Errorf("Unknown scheme: %s", url.Scheme) } }