From 7a2bb597d83e453ec32dadac5fd1545536b26af9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Bigaj?= Date: Wed, 22 Feb 2023 19:05:15 +0100 Subject: [PATCH 1/2] fix: BaseService.Request invoked without result does not close http.Response MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The method BaseService.Request invoked without result (nil) does not close http.Response and prevents connection to be put back into idle state. We observed significant memory usage or quick MaxConnsPerHost limit exhaustion, when BaseService.Request is called with nil result. Issue: https://github.com/IBM/go-sdk-core/issues/175 Signed-off-by: RafaƂ Bigaj --- v5/core/base_service.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/v5/core/base_service.go b/v5/core/base_service.go index 3d55fa51..7e3e1c9e 100644 --- a/v5/core/base_service.go +++ b/v5/core/base_service.go @@ -533,6 +533,8 @@ func (service *BaseService) Request(req *http.Request, result interface{}) (deta return } } + } else { + _ = httpResponse.Body.Close() } return From fa4c899c99278f9316cbab46000747f97e92af23 Mon Sep 17 00:00:00 2001 From: Phil Adams Date: Thu, 23 Feb 2023 10:20:31 -0600 Subject: [PATCH 2/2] fix: additional tweaks Signed-off-by: Phil Adams --- v5/core/base_service.go | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/v5/core/base_service.go b/v5/core/base_service.go index 7e3e1c9e..defeef2e 100644 --- a/v5/core/base_service.go +++ b/v5/core/base_service.go @@ -387,7 +387,7 @@ func (service *BaseService) Request(req *http.Request, result interface{}) (deta // If debug is enabled, then dump the request. if GetLogger().IsLogLevelEnabled(LevelDebug) { - buf, dumpErr := httputil.DumpRequestOut(req, req.Body != nil) + buf, dumpErr := httputil.DumpRequestOut(req, !IsNil(req.Body)) if dumpErr == nil { GetLogger().Debug("Request:\n%s\n", RedactSecrets(string(buf))) } else { @@ -407,7 +407,7 @@ func (service *BaseService) Request(req *http.Request, result interface{}) (deta // If debug is enabled, then dump the response. if GetLogger().IsLogLevelEnabled(LevelDebug) { - buf, dumpErr := httputil.DumpResponse(httpResponse, httpResponse.Body != nil) + buf, dumpErr := httputil.DumpResponse(httpResponse, !IsNil(httpResponse.Body)) if err == nil { GetLogger().Debug("Response:\n%s\n", RedactSecrets(string(buf))) } else { @@ -430,7 +430,7 @@ func (service *BaseService) Request(req *http.Request, result interface{}) (deta var responseBody []byte // First, read the response body into a byte array. - if httpResponse.Body != nil { + if !IsNil(httpResponse.Body) { var readErr error defer httpResponse.Body.Close() // #nosec G307 @@ -533,7 +533,9 @@ func (service *BaseService) Request(req *http.Request, result interface{}) (deta return } } - } else { + } else if !IsNil(httpResponse.Body) { + // We weren't expecting a response, but we have a reponse body, + // so we need to close it now since we're not going to consume it. _ = httpResponse.Body.Close() }