package guard import ( "net" "net/http" "net/netip" "syscall" "time" ) func (policy *Policy) NewHTTPClient() *http.Client { dialer := &net.Dialer{ Timeout: 15 * time.Second, KeepAlive: 30 * time.Second, Control: policy.controlConnection, } transport := &http.Transport{ Proxy: nil, DialContext: dialer.DialContext, ForceAttemptHTTP2: true, TLSHandshakeTimeout: 15 * time.Second, ResponseHeaderTimeout: 30 * time.Second, ExpectContinueTimeout: time.Second, MaxIdleConns: 10, IdleConnTimeout: 90 * time.Second, } return &http.Client{ Transport: transport, CheckRedirect: policy.checkRedirect, } } func (policy *Policy) controlConnection(_ string, address string, _ syscall.RawConn) error { addressPort, err := netip.ParseAddrPort(address) if err != nil { return ErrBlockedAddress } if !IsPublicAddress(addressPort.Addr()) { return ErrBlockedAddress } if !policy.portAllowed(addressPort.Port()) { return ErrBlockedPort } return nil } func (policy *Policy) checkRedirect(request *http.Request, previous []*http.Request) error { if len(previous) >= maxRedirects { return ErrTooManyRedirects } _, err := policy.ValidateURL(request.URL.String()) return err }