diff --git a/pkg/http/client.go b/pkg/http/client.go index 36a8ec9..4fd9d37 100644 --- a/pkg/http/client.go +++ b/pkg/http/client.go @@ -29,7 +29,7 @@ type HTTPClient struct { } func NewHTTPClient(token string, maxRetries int, timeoutSecs int, cfg config.ConfigInterface, log *zap.SugaredLogger) *HTTPClient { - return &HTTPClient{ + client := HTTPClient{ bearerToken: token, client: &http.Client{ Timeout: time.Duration(timeoutSecs) * time.Second, @@ -63,6 +63,32 @@ func NewHTTPClient(token string, maxRetries int, timeoutSecs int, cfg config.Con ipv6: cmap.New[net.IP](), log: log, } + + if cfg.ShouldForceIPv6() { + dialer := &net.Dialer{} + + dialContext := func(ctx context.Context, network, address string) (net.Conn, error) { + ips, err := net.DefaultResolver.LookupIPAddr(ctx, address) + if err != nil { + return nil, err + } + + for _, ip := range ips { + if ip.IP.To4() == nil { // IPv6 address found + ipv6Address := "[" + ip.IP.String() + "]" + return dialer.DialContext(ctx, network, ipv6Address) + } + } + return nil, net.UnknownNetworkError("no IPv6 address found") + } + + transport := &http.Transport{ + DialContext: dialContext, + } + client.client.Transport = transport + } + + return &client } func (r *HTTPClient) Do(req *http.Request) (*http.Response, error) { @@ -77,40 +103,6 @@ func (r *HTTPClient) Do(req *http.Request) (*http.Response, error) { req.Header.Set("Authorization", "Bearer "+r.bearerToken) } - if r.cfg.ShouldForceIPv6() { - dialer := &net.Dialer{} - transport := r.client.Transport.(*http.Transport).Clone() - transport.DialContext = func(ctx context.Context, network, addr string) (net.Conn, error) { - host, port, err := net.SplitHostPort(addr) - if err != nil { - return nil, err - } - if ipv6, ok := r.ipv6.Get(host); !ok { - // Lookup IP address if not found in map - ips, err := net.LookupIP(host) - if err != nil { - return nil, err - } - for _, ip := range ips { - if ip.To4() == nil { // IPv6 - ipv6 = ip - r.ipv6.Set(host, ipv6) - break - } - } - if ipv6 == nil { // No IPv6 address found, fallback to default - addr = net.JoinHostPort(host, port) - } else { - addr = net.JoinHostPort(ipv6.String(), port) - } - } else if ipv6 != nil && host == req.URL.Hostname() { - addr = net.JoinHostPort(ipv6.String(), port) - } - return dialer.DialContext(ctx, network, addr) - } - r.client.Transport = transport - } - var resp *http.Response var err error attempt := 0