s3: read chunks from HTTPS volume servers with the global HTTP client (#11800)

readChunkRange sent the volume lookup's http:// URL through a bare
http.Client, so with [https.client]/[https.volume] configured every read of
an SSE-KMS object larger than one chunk (and every ranged read through this
path) failed with "client sent an HTTP request to an HTTPS server" and the
GET returned 500. Normalise the URL's scheme and use util_http's global
client, which carries the [https.client] TLS configuration, as the other
volume reads already do. Drop the now-unused volumeServerHTTPClient.

Fixes #11799

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Nabil RagabandClaude Opus 5.5 authored and GitHub committed 2026-10-17 21:37:23 -07:00
1 parent e6a0534e3b
commit 6ab6926c94
1 file changed
+9 -14
+9 -14
View File
@@ -1486,16 +1486,6 @@ func (s3a *S3ApiServer) streamRangeToClient(w io.Writer, r *http.Request, reader
return cw.written, nil
}
// Shared HTTP client for volume server requests (connection pooling)
var volumeServerHTTPClient = &http.Client{
Timeout: 5 * time.Minute,
Transport: &http.Transport{
MaxIdleConns: 100,
MaxIdleConnsPerHost: 10,
IdleConnTimeout: 90 * time.Second,
},
}
// createLookupFileIdFunction creates a reusable lookup function for resolving volume URLs
// Uses FilerClient's vidMap cache to eliminate per-chunk gRPC overhead
func (s3a *S3ApiServer) createLookupFileIdFunction() func(context.Context, string) ([]string, error) {
@@ -2198,8 +2188,12 @@ func (s3a *S3ApiServer) readChunkRange(ctx context.Context, fileId string, offse
return nil, fmt.Errorf("failed to lookup chunk %s: %w", fileId, err)
}
// Use the first URL (already contains complete URL with fileId)
chunkUrl := urlStrings[0]
// Use the first URL (already contains complete URL with fileId). The lookup returns http:// URLs; when
// [https.client] is configured the volume servers only speak TLS, so take the global client's scheme.
chunkUrl, err := util_http.NormalizeUrl(urlStrings[0])
if err != nil {
return nil, fmt.Errorf("failed to normalize chunk URL %s: %w", fileId, err)
}
// Generate JWT for volume server authentication (uses config loaded once at startup)
jwt := filer.JwtForVolumeServer(fileId)
@@ -2220,8 +2214,9 @@ func (s3a *S3ApiServer) readChunkRange(ctx context.Context, fileId string, offse
req.Header.Set("Authorization", security.BearerPrefix+jwt)
}
// Use shared HTTP client with connection pooling
resp, err := volumeServerHTTPClient.Do(req)
// Use the global HTTP client: it carries the [https.client] TLS configuration (CA and client
// certificate) that HTTPS volume servers require; a bare http.Client cannot reach them.
resp, err := util_http.GetGlobalHttpClient().Do(req)
if err != nil {
return nil, fmt.Errorf("failed to fetch chunk: %w", err)
}