From 6bb3ad6f27a54170791071b1112b10005821dd47 Mon Sep 17 00:00:00 2001 From: Jesse <1430482733@qq.com> Date: Tue, 18 Oct 2022 20:21:56 +0800 Subject: [PATCH] fix: in for defer close (#2411) Resource leakage may occur. Call 'defer' in the 'for' loop. case: https://go.dev/doc/effective_go#defer --- contrib/log/fluent/fluent_test.go | 21 ++++++---- contrib/registry/eureka/client.go | 65 ++++++++++++++++++------------- 2 files changed, 51 insertions(+), 35 deletions(-) diff --git a/contrib/log/fluent/fluent_test.go b/contrib/log/fluent/fluent_test.go index 5b7b3e171..41f7080d3 100644 --- a/contrib/log/fluent/fluent_test.go +++ b/contrib/log/fluent/fluent_test.go @@ -11,18 +11,23 @@ import ( ) func TestMain(m *testing.M) { + listener := func(ln net.Listener) { + conn, err := ln.Accept() + if err != nil { + return + } + defer conn.Close() + _, err = io.ReadAll(conn) + if err != nil { + return + } + } + if ln, err := net.Listen("tcp", ":24224"); err == nil { defer ln.Close() go func() { for { - conn, err := ln.Accept() - if err != nil { - return - } - defer conn.Close() - if _, err = io.ReadAll(conn); err != nil { - continue - } + listener(ln) } }() } diff --git a/contrib/registry/eureka/client.go b/contrib/registry/eureka/client.go index 46b834167..020a9a904 100644 --- a/contrib/registry/eureka/client.go +++ b/contrib/registry/eureka/client.go @@ -307,39 +307,50 @@ func (e *Client) buildAPI(currentTimes int, params ...string) string { return strings.Join(params, "/") } -func (e *Client) do(ctx context.Context, method string, params []string, input io.Reader, output interface{}) error { - for i := 0; i < e.maxRetry; i++ { - request, err := http.NewRequest(method, e.buildAPI(i, params...), input) +func (e *Client) request(ctx context.Context, method string, params []string, input io.Reader, output interface{}, i int) (bool, error) { + request, err := http.NewRequestWithContext(ctx, method, e.buildAPI(i, params...), input) + if err != nil { + return false, err + } + request.Header.Add("User-Agent", "go-eureka-client") + request.Header.Add("Accept", "application/json;charset=UTF-8") + request.Header.Add("Content-Type", "application/json;charset=UTF-8") + resp, err := e.client.Do(request) + if err != nil { + return true, err + } + defer func() { + _, _ = io.Copy(io.Discard, resp.Body) + _ = resp.Body.Close() + }() + + if output != nil && resp.StatusCode/100 == 2 { + data, err := io.ReadAll(resp.Body) if err != nil { - return err + return false, err } - request = request.WithContext(ctx) - request.Header.Add("User-Agent", "go-eureka-client") - request.Header.Add("Accept", "application/json;charset=UTF-8") - request.Header.Add("Content-Type", "application/json;charset=UTF-8") - resp, err := e.client.Do(request) + err = json.Unmarshal(data, output) if err != nil { - continue - } - defer func() { - _, _ = io.Copy(io.Discard, resp.Body) - resp.Body.Close() - }() - - if output != nil && resp.StatusCode/100 == 2 { - data, err := io.ReadAll(resp.Body) - if err != nil { - return err - } - if err = json.Unmarshal(data, output); err != nil { - return err - } + return false, err } + } - if resp.StatusCode >= http.StatusBadRequest { - return fmt.Errorf("response Error %d", resp.StatusCode) - } + if resp.StatusCode >= http.StatusBadRequest { + return false, fmt.Errorf("response Error %d", resp.StatusCode) + } + return false, nil +} + +func (e *Client) do(ctx context.Context, method string, params []string, input io.Reader, output interface{}) error { + for i := 0; i < e.maxRetry; i++ { + retry, err := e.request(ctx, method, params, input, output, i) + if retry { + continue + } + if err != nil { + return err + } return nil } return fmt.Errorf("retry after %d times", e.maxRetry)