Ver código fonte

Fix resource leak in OTC API pagination by moving resp.Body.Close() (#3668)

Signed-off-by: Claude <claude@anthropic.com>
Signed-off-by: peatey <warwick.peatey@ibm.com>
Co-authored-by: Claude <noreply@anthropic.com>
Warwick 1 mês atrás
pai
commit
44016ce86a
2 arquivos alterados com 16 adições e 2 exclusões
  1. 4 0
      CLAUDE.md
  2. 12 2
      pkg/cloud/otc/pricingapi.go

+ 4 - 0
CLAUDE.md

@@ -2,6 +2,10 @@
 
 This document provides guidance for AI assistants working with the OpenCost codebase.
 
+## AI Assistant Behaviour
+
+- Never include claude.ai session links or URLs in commit messages or pull request bodies.
+
 ## Project Overview
 
 OpenCost is an open source Kubernetes cost monitoring tool maintained by the Cloud Native Computing Foundation (CNCF). It provides real-time cost allocation, asset tracking, and cloud cost monitoring for Kubernetes clusters across multiple cloud providers.

+ 12 - 2
pkg/cloud/otc/pricingapi.go

@@ -9,6 +9,8 @@ import (
 	"github.com/opencost/opencost/core/pkg/log"
 )
 
+var otcHTTPClient = http.DefaultClient
+
 // Fetches and flattens all product entries across multiple services with pagination
 func (otc *OTC) fetchPaginatedProducts(serviceNames []string) ([]Product, error) {
 	const baseURL = "https://calculator.otc-service.com/de/open-telekom-price-api/"
@@ -20,14 +22,22 @@ func (otc *OTC) fetchPaginatedProducts(serviceNames []string) ([]Product, error)
 	for {
 		url := fmt.Sprintf("%s?%s&columns%%5B0%%5D=productIdParameter&columns%%5B1%%5D=opiFlavour&columns%%5B2%%5D=osUnit&columns%%5B3%%5D=vCpu&columns%%5B4%%5D=ram&columns%%5B5%%5D=priceAmount&limitFrom=%d", baseURL, query, limitFrom)
 
-		resp, err := http.Get(url)
+		resp, err := otcHTTPClient.Get(url)
 		if err != nil {
+			if resp != nil {
+				resp.Body.Close()
+			}
 			log.Errorf("Error fetching products from OTC API: %v", err)
 			return nil, err
 		}
-		defer resp.Body.Close()
+		if resp.StatusCode != http.StatusOK {
+			io.Copy(io.Discard, resp.Body)
+			resp.Body.Close()
+			return nil, fmt.Errorf("OTC API returned unexpected status %d", resp.StatusCode)
+		}
 
 		pageData, stats, err := otc.loadPaginatedResponse(resp)
+		resp.Body.Close()
 		if err != nil {
 			log.Errorf("Error loading paginated response: %v", err)
 			return nil, err