Skip to content

Commit e6b5a4f

Browse files
fix(httpclient): clone DefaultTransport + only set RootCAs with custom CA (OD-30)
Address PR #205 review: - Clone http.DefaultTransport to preserve connection pooling, idle/handshake timeouts, and HTTP/2 instead of building a bare Transport. - Only set tls.Config.RootCAs when SSL_CERT_FILE is configured; leave nil otherwise so Go uses default system verification. Prevents an empty pool (when SystemCertPool fails) from rejecting all TLS handshakes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent a66ee27 commit e6b5a4f

2 files changed

Lines changed: 14 additions & 10 deletions

File tree

utils/httpclient/client.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,11 @@ func New(opts ...Option) (*http.Client, error) {
2020
return nil, err
2121
}
2222

23-
transport := &http.Transport{
24-
Proxy: http.ProxyFromEnvironment,
25-
TLSClientConfig: tlsCfg,
26-
}
23+
// Clone DefaultTransport to preserve Go's tuned defaults (connection pooling,
24+
// idle/handshake timeouts, HTTP/2) and only override proxy + TLS.
25+
transport := http.DefaultTransport.(*http.Transport).Clone()
26+
transport.Proxy = http.ProxyFromEnvironment
27+
transport.TLSClientConfig = tlsCfg
2728

2829
return &http.Client{
2930
Timeout: o.Timeout,

utils/httpclient/tls.go

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,22 +22,25 @@ func buildTLSConfig() (*tls.Config, error) {
2222
return cfg, nil
2323
}
2424

25-
pool, err := x509.SystemCertPool()
26-
if err != nil || pool == nil {
27-
pool = x509.NewCertPool()
28-
}
29-
25+
// Only override RootCAs when a custom CA bundle is configured. Otherwise leave
26+
// it nil so Go falls back to default system verification — building an explicit
27+
// pool unconditionally is wasteful and, if SystemCertPool fails, would leave an
28+
// empty pool that rejects every TLS handshake.
3029
if path := caBundlePath(); path != "" {
30+
pool, err := x509.SystemCertPool()
31+
if err != nil || pool == nil {
32+
pool = x509.NewCertPool()
33+
}
3134
pemBytes, err := os.ReadFile(path)
3235
if err != nil {
3336
return nil, fmt.Errorf("failed to read CA bundle from %s (%s): %w", EnvCABundle, path, err)
3437
}
3538
if !pool.AppendCertsFromPEM(pemBytes) {
3639
return nil, fmt.Errorf("no valid certificates found in CA bundle %s (%s)", EnvCABundle, path)
3740
}
41+
cfg.RootCAs = pool
3842
}
3943

40-
cfg.RootCAs = pool
4144
return cfg, nil
4245
}
4346

0 commit comments

Comments
 (0)