From fc7dfe1625c7c570638d97bf421f9e63e1cfd6b7 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Thu, 1 Oct 2026 12:32:13 +0200 Subject: [PATCH] pkg/httputil: configure HTTP transport timeouts Configure a timeout for connecting to the RootlessKit API socket, and set an idle connection timeout on the HTTP transport. Previously, idle connections had no expiration because IdleConnTimeout was left at its zero value. This could leave connections open indefinitely for callers that create short-lived clients without explicitly closing idle connections. Use the same dial and idle connection timeouts as http.DefaultTransport. Signed-off-by: Sebastiaan van Stijn --- pkg/httputil/httputil.go | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/pkg/httputil/httputil.go b/pkg/httputil/httputil.go index e2f4d1a5..f0c4bc6f 100644 --- a/pkg/httputil/httputil.go +++ b/pkg/httputil/httputil.go @@ -9,6 +9,7 @@ import ( "net" "net/http" "os" + "time" ) // ErrorJSON is returned with "application/json" content type and non-2XX status code @@ -70,20 +71,34 @@ func Successful(resp *http.Response) error { return nil } +// NewHTTPClient returns an HTTP client configured to communicate with the +// RootlessKit API over the Unix socket at socketPath. func NewHTTPClient(socketPath string) (*http.Client, error) { if _, err := os.Stat(socketPath); err != nil { return nil, err } return &http.Client{ + // Use the dial and idle connection timeouts from http.DefaultTransport. + // + // Other defaults are either TCP/TLS-specific or unnecessary for the + // local Unix socket connection. + // See https://github.com/golang/go/blob/go1.27.2/src/net/http/transport.go#L42-L58 Transport: &http.Transport{ - DialContext: func(ctx context.Context, _, _ string) (net.Conn, error) { - var d net.Dialer - return d.DialContext(ctx, "unix", socketPath) - }, + DialContext: unixDialContext(socketPath, &net.Dialer{ + Timeout: 30 * time.Second, + }), + IdleConnTimeout: 90 * time.Second, }, }, nil } +// unixDialContext returns a dial function that connects to socketPath using dialer. +func unixDialContext(socketPath string, dialer *net.Dialer) func(context.Context, string, string) (net.Conn, error) { + return func(ctx context.Context, _, _ string) (net.Conn, error) { + return dialer.DialContext(ctx, "unix", socketPath) + } +} + // WriteError writes an error. // WriteError sould not be used if an error may contain sensitive information and the client is not reliable. func WriteError(w http.ResponseWriter, r *http.Request, err error, ec int) {