// RunStartBuildWebHook tries to trigger the provided webhook. It will attempt to utilize the current client // configuration if the webhook has the same URL. func (o *StartBuildOptions) RunStartBuildWebHook() error { repo := o.Git hook, err := url.Parse(o.FromWebhook) if err != nil { return err } event, err := hookEventFromPostReceive(repo, o.GitRepository, o.GitPostReceive) if err != nil { return err } // TODO: should be a versioned struct var data []byte if event != nil { data, err = json.Marshal(event) if err != nil { return err } } httpClient := http.DefaultClient // when using HTTPS, try to reuse the local config transport if possible to get a client cert // TODO: search all configs if hook.Scheme == "https" { config, err := o.ClientConfig.ClientConfig() if err == nil { if url, _, err := restclient.DefaultServerURL(config.Host, "", unversioned.GroupVersion{}, true); err == nil { if netutil.CanonicalAddr(url) == netutil.CanonicalAddr(hook) && url.Scheme == hook.Scheme { if rt, err := restclient.TransportFor(config); err == nil { httpClient = &http.Client{Transport: rt} } } } } } glog.V(4).Infof("Triggering hook %s\n%s", hook, string(data)) resp, err := httpClient.Post(hook.String(), "application/json", bytes.NewBuffer(data)) if err != nil { return err } defer resp.Body.Close() switch { case resp.StatusCode == 301 || resp.StatusCode == 302: // TODO: follow redirect and display output case resp.StatusCode < 200 || resp.StatusCode >= 300: body, _ := ioutil.ReadAll(resp.Body) return fmt.Errorf("server rejected our request %d\nremote: %s", resp.StatusCode, string(body)) } return nil }
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 := restclient.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) } }
// 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 DialURL(url *url.URL, transport http.RoundTripper) (net.Conn, error) { dialAddr := netutil.CanonicalAddr(url) dialer, _ := utilnet.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, _ = utilnet.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) } }
// 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) { proxier := s.proxier if proxier == nil { proxier = http.ProxyFromEnvironment } proxyURL, err := proxier(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, } if pa := s.proxyAuth(proxyURL); pa != "" { proxyReq.Header = http.Header{} proxyReq.Header.Set("Proxy-Authorization", pa) } 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(targetHost) if err != nil { return nil, err } if s.tlsConfig == nil { s.tlsConfig = &tls.Config{} } 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 } // Return if we were configured to skip validation if s.tlsConfig != nil && s.tlsConfig.InsecureSkipVerify { return tlsConn, nil } if err := tlsConn.VerifyHostname(host); err != nil { return nil, err } return tlsConn, nil }