github.com/saucelabs/saucectl@v0.175.1/internal/http/proxy.go (about)

     1  package http
     2  
     3  import (
     4  	"fmt"
     5  	"net/url"
     6  	"os"
     7  	"strings"
     8  
     9  	"github.com/fatih/color"
    10  	"github.com/rs/zerolog/log"
    11  )
    12  
    13  // Note: The verification logic is borrowed from golang.org/x/net/http/httpproxy.
    14  // Those useful functions are not exposed, but are required to allow us to warn
    15  // the user upfront.
    16  func getEnvAny(names ...string) string {
    17  	for _, n := range names {
    18  		if val := os.Getenv(n); val != "" {
    19  			return val
    20  		}
    21  	}
    22  	return ""
    23  }
    24  
    25  func parseProxy(proxy string) (*url.URL, error) {
    26  	if proxy == "" {
    27  		return nil, nil
    28  	}
    29  
    30  	proxyURL, err := url.Parse(proxy)
    31  	if err != nil ||
    32  		(proxyURL.Scheme != "http" &&
    33  			proxyURL.Scheme != "https" &&
    34  			proxyURL.Scheme != "socks5") {
    35  		// proxy was bogus. Try prepending "http://" to it and
    36  		// see if that parses correctly. If not, we fall
    37  		// through and complain about the original one.
    38  		if proxyURL, err := url.Parse("http://" + proxy); err == nil {
    39  			return proxyURL, nil
    40  		}
    41  	}
    42  	if err != nil {
    43  		return nil, fmt.Errorf("invalid proxy address %q: %v", proxy, err)
    44  	}
    45  	return proxyURL, nil
    46  }
    47  
    48  func doCheckProxy(scheme string) error {
    49  	proxyScheme := fmt.Sprintf("%s_proxy", scheme)
    50  	rawProxyURL := getEnvAny(strings.ToUpper(proxyScheme), strings.ToLower(proxyScheme))
    51  	proxyURL, err := parseProxy(rawProxyURL)
    52  
    53  	if err != nil {
    54  		color.Red("\nA proxy has been set, but its url is invalid !\n\n")
    55  		fmt.Printf("%s: %s", rawProxyURL, err)
    56  		return fmt.Errorf("invalid %s value", strings.ToUpper(proxyScheme))
    57  	}
    58  	if proxyURL == nil {
    59  		return nil
    60  	}
    61  
    62  	// Hide login/password
    63  	if proxyURL.User != nil {
    64  		pass, hasPass := proxyURL.User.Password()
    65  		if hasPass {
    66  			rawProxyURL = strings.Replace(rawProxyURL, pass, "****", -1)
    67  		}
    68  	}
    69  	log.Info().Msgf(fmt.Sprintf("Using %s proxy: %s", strings.ToUpper(scheme), rawProxyURL))
    70  	return nil
    71  }
    72  
    73  // CheckProxy checks that the HTTP_PROXY is valid if it exists.
    74  func CheckProxy() error {
    75  	var errs []error
    76  	if err := doCheckProxy("http"); err != nil {
    77  		errs = append(errs, err)
    78  	}
    79  	if err := doCheckProxy("https"); err != nil {
    80  		errs = append(errs, err)
    81  	}
    82  	if len(errs) != 0 {
    83  		return fmt.Errorf("proxy setup has %d error(s)", len(errs))
    84  	}
    85  	return nil
    86  }