Skip to content
Snippets Groups Projects
httpclient.go 1.47 KiB
Newer Older
  • Learn to ignore specific revisions
  • package httpclient
    
    import (
    	"crypto/tls"
    	"crypto/x509"
    
    	"fmt"
    	"net"
    	"net/http"
    	"os"
    	"time"
    )
    
    
    func extractCAs(input []string) [][]byte {
    	result := make([][]byte, 0, len(input))
    	for _, ca := range input {
    		if ca == "" {
    			continue
    		}
    
    		pemData, err := os.ReadFile(ca)
    		if err != nil {
    			pemData, err = base64.StdEncoding.DecodeString(ca)
    			if err != nil {
    				pemData = []byte(ca)
    			}
    		}
    
    		result = append(result, pemData)
    	}
    	return result
    }
    
    
    func NewHTTPClient(rootCAs []string, insecureSkipVerify bool) (*http.Client, error) {
    	pool, err := x509.SystemCertPool()
    	if err != nil {
    		return nil, err
    	}
    
    	tlsConfig := tls.Config{RootCAs: pool, InsecureSkipVerify: insecureSkipVerify}
    
    	for index, rootCABytes := range extractCAs(rootCAs) {
    
    		if !tlsConfig.RootCAs.AppendCertsFromPEM(rootCABytes) {
    
    			return nil, fmt.Errorf("rootCAs.%d is not in PEM format, certificate must be "+
    				"a PEM encoded string, a base64 encoded bytes that contain PEM encoded string, "+
    				"or a path to a PEM encoded certificate", index)
    
    		}
    	}
    
    	return &http.Client{
    		Transport: &http.Transport{
    			TLSClientConfig: &tlsConfig,
    			Proxy:           http.ProxyFromEnvironment,
    			DialContext: (&net.Dialer{
    				Timeout:   30 * time.Second,
    				KeepAlive: 30 * time.Second,
    				DualStack: true,
    			}).DialContext,
    			MaxIdleConns:          100,
    			IdleConnTimeout:       90 * time.Second,
    			TLSHandshakeTimeout:   10 * time.Second,
    			ExpectContinueTimeout: 1 * time.Second,
    		},
    	}, nil
    }