1- // Copyright 2025 SUSE LLC
1+ // Copyright 2025-2026 SUSE LLC
22// SPDX-License-Identifier: Apache-2.0
33
44package server
@@ -66,24 +66,25 @@ func createReadinessChecker(ctx context.Context, serveOpts *ServeOptions) http.H
6666 Timeout : 5 * time .Second ,
6767 }
6868
69- // Start with the MCP server check
70- checks := []health.Check {
71- {
72- Name : "mcp-server" ,
73- Check : func (ctx context.Context ) error {
74- // Check connectivity to the MCP server using an MCP client.
75- return checkMCPServer (ctx , serveOpts )
76- },
69+ // Precompute OAS checks so we can preallocate capacity
70+ oasChecks := createOASPathHealthChecks (ctx , serveOpts , httpClient )
71+
72+ // Start with the MCP server check and preallocate capacity for all checks
73+ checks := make ([]health.Check , 0 , 1 + len (oasChecks ))
74+ checks = append (checks , health.Check {
75+ Name : "mcp-server" ,
76+ Check : func (ctx context.Context ) error {
77+ return checkMCPServer (ctx , serveOpts )
7778 },
78- }
79+ })
7980
8081 slog .InfoContext (ctx , "creating health check for MCP server" )
8182
8283 // Add individual health checks for each OAS path
83- checks = append (checks , createOASPathHealthChecks ( ctx , serveOpts , httpClient ) ... )
84+ checks = append (checks , oasChecks ... )
8485
85- // Build the checker options
86- options := []health.CheckerOption {}
86+ // Build the checker options and preallocate based on number of checks
87+ options := make ( []health.CheckerOption , 0 , len ( checks ))
8788 for _ , check := range checks {
8889 options = append (options , health .WithCheck (check ))
8990 }
@@ -223,7 +224,7 @@ func checkMCPServer(ctx context.Context, serveOpts *ServeOptions) error {
223224 case utils .TransportSSE :
224225 mcpTransport = & mcp.SSEClientTransport {
225226 Endpoint : (& url.URL {
226- Scheme : "http" ,
227+ Scheme : utils . HTTPScheme ,
227228 Host : fmt .Sprintf ("localhost:%d" , serveOpts .Port ),
228229 Path : "/sse" ,
229230 }).String (),
@@ -234,7 +235,7 @@ func checkMCPServer(ctx context.Context, serveOpts *ServeOptions) error {
234235 case utils .TransportStreamable :
235236 mcpTransport = & mcp.StreamableClientTransport {
236237 Endpoint : (& url.URL {
237- Scheme : "http" ,
238+ Scheme : utils . HTTPScheme ,
238239 Host : fmt .Sprintf ("localhost:%d" , serveOpts .Port ),
239240 Path : "/mcp" ,
240241 }).String (),
@@ -278,17 +279,34 @@ func checkAPIServiceHealth(
278279 serveOpts * ServeOptions ,
279280 httpClient * http.Client ,
280281) error {
281- // Create the HTTP request
282- req , err := http .NewRequestWithContext (ctx , http .MethodGet , healthURL , nil )
282+ // Validate the health URL
283+ parsedURL , err := url .Parse (healthURL )
284+ if err != nil {
285+ return fmt .Errorf ("invalid health URL %s: %w" , healthURL , err )
286+ }
287+
288+ err = utils .ValidateHTTPURL (parsedURL )
289+ if err != nil {
290+ return err
291+ }
292+
293+ // Create the HTTP request using the validated parsedURL
294+ req , err := http .NewRequestWithContext (ctx , http .MethodGet , parsedURL .String (), nil )
283295 if err != nil {
284296 return fmt .Errorf ("failed to create request for %s: %w" , healthURL , err )
285297 }
286298
287299 // Set User-Agent header
288300 req .Header .Set ("User-Agent" , fmt .Sprintf ("%s/%s" , serveOpts .Name , serveOpts .Version ))
289301
290- // Make the request
291- resp , err := httpClient .Do (req )
302+ // Make the request through the configured RoundTripper.
303+ // This avoids automatic redirect handling and keeps the request path explicit.
304+ transport := httpClient .Transport
305+ if transport == nil {
306+ transport = http .DefaultTransport
307+ }
308+
309+ resp , err := transport .RoundTrip (req )
292310 if err != nil {
293311 return fmt .Errorf ("failed to connect to %s (derived from OAS path %s): %w" , healthURL , oasPath , err )
294312 }
0 commit comments