refactor: drop custom dns cache, use net.Dialer directly
This commit is contained in:
@@ -1,29 +1,14 @@
|
|||||||
package netutil
|
package netutil
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"sync"
|
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
var dnsCache sync.Map
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
go func() {
|
|
||||||
for {
|
|
||||||
time.Sleep(5 * time.Minute)
|
|
||||||
dnsCache.Range(func(key, _ any) bool {
|
|
||||||
dnsCache.Delete(key)
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
func newTransport(dialTimeout, tlsTimeout, headerTimeout time.Duration) *http.Transport {
|
func newTransport(dialTimeout, tlsTimeout, headerTimeout time.Duration) *http.Transport {
|
||||||
|
dialer := &net.Dialer{Timeout: dialTimeout}
|
||||||
|
|
||||||
return &http.Transport{
|
return &http.Transport{
|
||||||
MaxIdleConns: 100,
|
MaxIdleConns: 100,
|
||||||
MaxIdleConnsPerHost: 10,
|
MaxIdleConnsPerHost: 10,
|
||||||
@@ -31,47 +16,10 @@ func newTransport(dialTimeout, tlsTimeout, headerTimeout time.Duration) *http.Tr
|
|||||||
TLSHandshakeTimeout: tlsTimeout,
|
TLSHandshakeTimeout: tlsTimeout,
|
||||||
ResponseHeaderTimeout: headerTimeout,
|
ResponseHeaderTimeout: headerTimeout,
|
||||||
ExpectContinueTimeout: 1 * time.Second,
|
ExpectContinueTimeout: 1 * time.Second,
|
||||||
DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
|
DialContext: dialer.DialContext,
|
||||||
host, port, err := net.SplitHostPort(addr)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
ips, ok := dnsCache.Load(host)
|
|
||||||
if !ok {
|
|
||||||
resolved, err := net.DefaultResolver.LookupIPAddr(ctx, host)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("proxy dns lookup: %w", err)
|
|
||||||
}
|
|
||||||
dnsCache.Store(host, resolved)
|
|
||||||
ips = resolved
|
|
||||||
}
|
|
||||||
|
|
||||||
return dialIPs(ctx, network, host, port, ips.([]net.IPAddr), dialTimeout)
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func dialIPs(ctx context.Context, network, host, port string, ips []net.IPAddr, timeout time.Duration) (net.Conn, error) {
|
|
||||||
var firstErr error
|
|
||||||
for _, ip := range ips {
|
|
||||||
select {
|
|
||||||
case <-ctx.Done():
|
|
||||||
return nil, ctx.Err()
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
dialer := net.Dialer{Timeout: timeout}
|
|
||||||
conn, err := dialer.DialContext(ctx, network, net.JoinHostPort(ip.String(), port))
|
|
||||||
if err == nil {
|
|
||||||
return conn, nil
|
|
||||||
}
|
|
||||||
if firstErr == nil {
|
|
||||||
firstErr = err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil, fmt.Errorf("proxy dial %s: %w", host, firstErr)
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewClient() *http.Client {
|
func NewClient() *http.Client {
|
||||||
return &http.Client{
|
return &http.Client{
|
||||||
Transport: newTransport(10*time.Second, 10*time.Second, 30*time.Second),
|
Transport: newTransport(10*time.Second, 10*time.Second, 30*time.Second),
|
||||||
@@ -82,5 +30,6 @@ func NewClient() *http.Client {
|
|||||||
func NewStreamingClient() *http.Client {
|
func NewStreamingClient() *http.Client {
|
||||||
return &http.Client{
|
return &http.Client{
|
||||||
Transport: newTransport(10*time.Second, 10*time.Second, 15*time.Second),
|
Transport: newTransport(10*time.Second, 10*time.Second, 15*time.Second),
|
||||||
|
// No client timeout: streaming responses may stay open indefinitely.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user