From 97187c431cf6db12100c49b68dab25bca79098c1 Mon Sep 17 00:00:00 2001 From: Andrew Krasichkov Date: Mon, 19 Feb 2024 04:25:10 +0300 Subject: [PATCH] Fixed JSONIndent request logging data race. (#775) --- client_test.go | 23 +++++++++++++++++++++++ request.go | 14 +++++++++----- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/client_test.go b/client_test.go index ad02f62f..1f291d12 100644 --- a/client_test.go +++ b/client_test.go @@ -766,6 +766,29 @@ func TestLogCallbacks(t *testing.T) { assertNotNil(t, resp) } +func TestDebugLogSimultaneously(t *testing.T) { + ts := createGetServer(t) + + c := New(). + SetDebug(true). + SetBaseURL(ts.URL). + outputLogTo(io.Discard) + + t.Cleanup(ts.Close) + for i := 0; i < 50; i++ { + t.Run(fmt.Sprint(i), func(t *testing.T) { + t.Parallel() + resp, err := c.R(). + SetBody([]int{1, 2, 3}). + SetHeader(hdrContentTypeKey, "application/json; charset=utf-8"). + Post("/") + + assertError(t, err) + assertEqual(t, http.StatusOK, resp.StatusCode()) + }) + } +} + func TestNewWithLocalAddr(t *testing.T) { ts := createGetServer(t) defer ts.Close() diff --git a/request.go b/request.go index fec09763..4e13ff09 100644 --- a/request.go +++ b/request.go @@ -1014,7 +1014,12 @@ func (r *Request) fmtBodyString(sl int64) (body string) { contentType := r.Header.Get(hdrContentTypeKey) kind := kindOf(r.Body) if canJSONMarshal(contentType, kind) { - prtBodyBytes, err = noescapeJSONMarshalIndent(&r.Body) + var bodyBuf *bytes.Buffer + bodyBuf, err = noescapeJSONMarshalIndent(&r.Body) + if err == nil { + prtBodyBytes = bodyBuf.Bytes() + defer releaseBuffer(bodyBuf) + } } else if IsXMLType(contentType) && (kind == reflect.Struct) { prtBodyBytes, err = xml.MarshalIndent(&r.Body, "", " ") } else if b, ok := r.Body.(string); ok { @@ -1077,17 +1082,16 @@ var noescapeJSONMarshal = func(v interface{}) (*bytes.Buffer, error) { return buf, nil } -var noescapeJSONMarshalIndent = func(v interface{}) ([]byte, error) { +var noescapeJSONMarshalIndent = func(v interface{}) (*bytes.Buffer, error) { buf := acquireBuffer() - defer releaseBuffer(buf) - encoder := json.NewEncoder(buf) encoder.SetEscapeHTML(false) encoder.SetIndent("", " ") if err := encoder.Encode(v); err != nil { + releaseBuffer(buf) return nil, err } - return buf.Bytes(), nil + return buf, nil }