Repository: go-resty/resty (go)

Issue:
DATA RACE: between go-resty/resty/v2.releaseBuffer()  and h2_bundle body 
I encountered a data race issue. Although the probability of it happening is very low, it still confuses me..

Operating environment is as follows.
```
golang version 1.18.10 

resty/v2 version 2.7.0

OS: win10
```

here is my test code:
```
var client = resty.New()

func main() {
	wg := sync.WaitGroup{}
	wg.Add(4000)
	for i := 0; i < 4000; i++ {
		index := i
		go func() {
			defer wg.Done()
			var data = make(map[string]interface{})
			data["index"] = index
			_, err := client.R().SetContext(context.TODO()).SetBody(data).Post("https://www.abc.com")
			if err != nil {
				return
			}
		}()
	}
	wg.Wait()
	fmt.Println("over")
}
```
here is DATA RACE warning:
1st:
```
==================
==================
WARNING: DATA RACE
Write at 0x00c0009a70f8 by goroutine 1418:
  bytes.(*Buffer).Reset()
      C:/Users/10188142.TREYANTAI/go/go1.18.10/src/bytes/buffer.go:99 +0x5a
  github.com/go-resty/resty/v2.releaseBuffer()
      D:/go/pkg/mod/github.com/go-resty/resty/v2@v2.7.0/util.go:287 +0x31
  github.com/go-resty/resty/v2.(*requestBodyReleaser).Close.func1()
      D:/go/pkg/mod/github.com/go-resty/resty/v2@v2.7.0/util.go:314 +0x44
  sync.(*Once).doSlow()
      C:/Users/10188142.TREYANTAI/go/go1.18.10/src/sync/once.go:68 +0x101
  sync.(*Once).Do()
      C:/Users/10188142.TREYANTAI/go/go1.18.10/src/sync/once.go:59 +0x46
  github.com/go-resty/resty/v2.(*requestBodyReleaser).Close()
      D:/go/pkg/mod/github.com/go-resty/resty/v2@v2.7.0/util.go:313 +0x7c
  net/http.(*readTrackingBody).Close()
      C:/Users/10188142.TREYANTAI/go/go1.18.10/src/net/http/transport.go:642 +0x56
  net/http.(*http2clientStream).abortStreamLocked()
      C:/Users/10188142.TREYANTAI/go/go1.18.10/src/net/http/h2_bundle.go:7097 +0xef
  net/http.(*http2clientStream).abortStream()
      C:/Users/10188142.TREYANTAI/go/go1.18.10/src/net/http/h2_bundle.go:7088 +0xc8
  net/http.(*http2clientConnReadLoop).processResetStream()
      C:/Users/10188142.TREYANTAI/go/go1.18.10/src/net/http/h2_bundle.go:9486 +0x28f
  net/http.(*http2clientConnReadLoop).run()
      C:/Users/10188142.TREYANTAI/go/go1.18.10/src/net/http/h2_bundle.go:8857 +0x5de
  net/http.(*http2ClientConn).readLoop()
      C:/Users/10188142.TREYANTAI/go/go1.18.10/src/net/http/h2_bundle.go:8715 +0x9e
  net/http.(*http2Transport).newClientConn.func1()
      C:/Users/10188142.TREYANTAI/go/go1.18.10/src/net/http/h2_bundle.go:7443 +0x39

Previous write at 0x00c0009a70f8 by goroutine 2930:
  bytes.(*Buffer).Read()
      C:/Users/10188142.TREYANTAI/go/go1.18.10/src/bytes/buffer.go:308 +0x1c4
  io.(*nopCloser).Read()
      <autogenerated>:1 +0x76
  github.com/go-resty/resty/v2.(*requestBodyReleaser).Read()
      <autogenerated>:1 +0x78
  net/http.(*readTrackingBody).Read()
      C:/Users/10188142.TREYANTAI/go/go1.18.10/src/net/http/transport.go:637 +0x77
  net/http.(*http2clientStream).writeRequestBody()
      C:/Users/10188142.TREYANTAI/go/go1.18.10/src/net/http/h2_bundle.go:8280 +0x532
  net/http.(*http2clientStream).writeRequest()
      C:/Users/10188142.TREYANTAI/go/go1.18.10/src/net/http/h2_bundle.go:8017 +0xb3a
  net/http.(*http2clientStream).doRequest()
      C:/Users/10188142.TREYANTAI/go/go1.18.10/src/net/http/h2_bundle.go:7903 +0x36
  net/http.(*http2ClientConn).RoundTrip.func3()
      C:/Users/10188142.TREYANTAI/go/go1.18.10/src/net/http/h2_bundle.go:7832 +0x47

Goroutine 1418 (running) created at:
  net/http.(*http2Transport).newClientConn()
      C:/Users/10188142.TREYANTAI/go/go1.18.10/src/net/http/h2_bundle.go:7443 +0x1468
  net/http.(*http2Transport).NewClientConn()
      C:/Users/10188142.TREYANTAI/go/go1.18.10/src/net/http/h2_bundle.go:7367 +0xa6
  net/http.(*http2addConnCall).run()
      C:/Users/10188142.TREYANTAI/go/go1.18.10/src/net/http/h2_bundle.go:918 +0x76
  net/http.(*http2clientConnPool).addConnIfNeeded.func1()
      C:/Users/10188142.TREYANTAI/go/go1.18.10/src/net/http/h2_bundle.go:899 +0x71

Goroutine 2930 (running) created at:
  net/http.(*http2ClientConn).RoundTrip()
      C:/Users/10188142.TREYANTAI/go/go1.18.10/src/net/http/h2_bundle.go:7832 +0x792
  net/http.(*http2Transport).RoundTripOpt()
      C:/Users/10188142.TREYANTAI/go/go1.18.10/src/net/http/h2_bundle.go:7217 +0x639
  net/http.(*http2Transport).RoundTrip()
      C:/Users/10188142.TREYANTAI/go/go1.18.10/src/net/http/h2_bundle.go:7178 +0x38
  net/http.(*Transport).roundTrip()
      C:/Users/10188142.TREYANTAI/go/go1.18.10/src/net/http/transport.go:592 +0xd2e
  net/http.(*Transport).RoundTrip()
      C:/Users/10188142.TREYANTAI/go/go1.18.10/src/net/http/roundtrip.go:17 +0x36
  net/http.send()
      C:/Users/10188142.TREYANTAI/go/go1.18.10/src/net/http/client.go:252 +0x93e
  net/http.(*Client).send()
      C:/Users/10188142.TREYANTAI/go/go1.18.10/src/net/http/client.go:176 +0x157
  net/http.(*Client).do()
      C:/Users/10188142.TREYANTAI/go/go1.18.10/src/net/http/client.go:725 +0x1064
  net/http.(*Client).Do()
      C:/Users/10188142.TREYANTAI/go/go1.18.10/src/net/http/client.go:593 +0x846
  github.com/go-resty/resty/v2.(*Client).execute()
      D:/go/pkg/mod/github.com/go-resty/resty/v2@v2.7.0/client.go:932 +0x7f3
  github.com/go-resty/resty/v2.(*Request).Execute()
      D:/go/pkg/mod/github.com/go-resty/resty/v2@v2.7.0/request.go:758 +0x3fb
  github.com/go-resty/resty/v2.(*Request).Post()
      D:/go/pkg/mod/github.com/go-resty/resty/v2@v2.7.0/request.go:699 +0x54a
  main.main.func1()
      D:/work/go/study/example/study-go/synconce/main.go:28 +0x125
==================
==================
```
---
2nd:
```
==================
==================
WARNING: DATA RACE
Write at 0x00c00032a5c0 by goroutine 1234:
  runtime.slicecopy()
      C:/Users/10188142.TREYANTAI/go/go1.18.10/src/runtime/slice.go:295 +0x0
  bytes.(*Buffer).Write()
      C:/Users/10188142.TREYANTAI/go/go1.18.10/src/bytes/buffer.go:174 +0x126
  github.com/go-resty/resty/v2.jsonMarshal()
      D:/go/pkg/mod/github.com/go-resty/resty/v2@v2.7.0/util.go:153 +0x164
  github.com/go-resty/resty/v2.handleRequestBody()
      D:/go/pkg/mod/github.com/go-resty/resty/v2@v2.7.0/middleware.go:459 +0x476
  github.com/go-resty/resty/v2.parseRequestBody()
      D:/go/pkg/mod/github.com/go-resty/resty/v2@v2.7.0/middleware.go:150 +0x3e6
  github.com/go-resty/resty/v2.(*Client).execute()
      D:/go/pkg/mod/github.com/go-resty/resty/v2@v2.7.0/client.go:909 +0x265
  github.com/go-resty/resty/v2.(*Request).Execute()
      D:/go/pkg/mod/github.com/go-resty/resty/v2@v2.7.0/request.go:758 +0x3fb
  github.com/go-resty/resty/v2.(*Request).Post()
      D:/go/pkg/mod/github.com/go-resty/resty/v2@v2.7.0/request.go:699 +0x54a
  main.main.func1()
      D:/work/go/study/example/study-go/synconce/main.go:28 +0x125

Previous read at 0x00c00032a5c0 by goroutine 2930:
  runtime.slicecopy()
      C:/Users/10188142.TREYANTAI/go/go1.18.10/src/runtime/slice.go:295 +0x0
  bytes.(*Buffer).Read()
      C:/Users/10188142.TREYANTAI/go/go1.18.10/src/bytes/buffer.go:307 +0x19d
  io.(*nopCloser).Read()
      <autogenerated>:1 +0x76
  github.com/go-resty/resty/v2.(*requestBodyReleaser).Read()
      <autogenerated>:1 +0x78
  net/http.(*readTrackingBody).Read()
      C:/Users/10188142.TREYANTAI/go/go1.18.10/src/net/http/transport.go:637 +0x77
  net/http.(*http2clientStream).writeRequestBody()
      C:/Users/10188142.TREYANTAI/go/go1.18.10/src/net/http/h2_bundle.go:8280 +0x532
  net/http.(*http2clientStream).writeRequest()
      C:/Users/10188142.TREYANTAI/go/go1.18.10/src/net/http/h2_bundle.go:8017 +0xb3a
  net/http.(*http2clientStream).doRequest()
      C:/Users/10188142.TREYANTAI/go/go1.18.10/src/net/http/h2_bundle.go:7903 +0x36
  net/http.(*http2ClientConn).RoundTrip.func3()
      C:/Users/10188142.TREYANTAI/go/go1.18.10/src/net/http/h2_bundle.go:7832 +0x47
```


Pull request:
fix sync pool data race: deep copy
fixes #630

Patch:
diff --git a/LICENSE b/LICENSE
index 27326a6..0c2d38a 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
 The MIT License (MIT)
 
-Copyright (c) 2015-2021 Jeevanandam M., https://myjeeva.com <jeeva@myjeeva.com>
+Copyright (c) 2015-2023 Jeevanandam M., https://myjeeva.com <jeeva@myjeeva.com>
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
diff --git a/README.md b/README.md
index bc3f924..d88c426 100644
--- a/README.md
+++ b/README.md
@@ -86,6 +86,8 @@
 
 #### Supported Go Versions
 
+Recommended to use `go1.16` and above.
+
 Initially Resty started supporting `go modules` since `v1.10.0` release.
 
 Starting Resty v2 and higher versions, it fully embraces [go modules](https://github.com/golang/go/wiki/Modules) package release. It requires a Go version capable of understanding `/vN` suffixed imports:
diff --git a/client.go b/client.go
index a7af66e..fb0f70a 100644
--- a/client.go
+++ b/client.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2015-2021 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
+// Copyright (c) 2015-2023 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
 // resty source code and usage is governed by a MIT style
 // license that can be found in the LICENSE file.
 
diff --git a/digest.go b/digest.go
index 0a7bb10..ba099ad 100644
--- a/digest.go
+++ b/digest.go
@@ -1,3 +1,9 @@
+// Copyright (c) 2015-2023 Jeevanandam M (jeeva@myjeeva.com)
+// 2023 Segev Dagan (https://github.com/segevda)
+// All rights reserved.
+// resty source code and usage is governed by a MIT style
+// license that can be found in the LICENSE file.
+
 package resty
 
 import (
@@ -121,6 +127,9 @@ func parseChallenge(input string) (*challenge, error) {
 	var r []string
 	for i := range sl {
 		r = strings.SplitN(sl[i], "=", 2)
+		if len(r) != 2 {
+			return nil, ErrDigestBadChallenge
+		}
 		switch r[0] {
 		case "realm":
 			c.realm = strings.Trim(r[1], qs)
diff --git a/middleware.go b/middleware.go
index 537a628..4ffb9db 100644
--- a/middleware.go
+++ b/middleware.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2015-2021 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
+// Copyright (c) 2015-2023 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
 // resty source code and usage is governed by a MIT style
 // license that can be found in the LICENSE file.
 
@@ -169,7 +169,9 @@ func createHTTPRequest(c *Client, r *Request) (err error) {
 			r.RawRequest, err = http.NewRequest(r.Method, r.URL, nil)
 		}
 	} else {
-		r.RawRequest, err = http.NewRequest(r.Method, r.URL, r.bodyBuf)
+		// fix data race: must deep copy.
+		bodyBuf := bytes.NewBuffer(append([]byte{}, r.bodyBuf.Bytes()...))
+		r.RawRequest, err = http.NewRequest(r.Method, r.URL, bodyBuf)
 	}
 
 	if err != nil {
diff --git a/redirect.go b/redirect.go
index dfc4f42..3b26eb2 100644
--- a/redirect.go
+++ b/redirect.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2015-2021 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
+// Copyright (c) 2015-2023 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
 // resty source code and usage is governed by a MIT style
 // license that can be found in the LICENSE file.
 
diff --git a/request.go b/request.go
index 49d9582..cd4e77c 100644
--- a/request.go
+++ b/request.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2015-2021 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
+// Copyright (c) 2015-2023 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
 // resty source code and usage is governed by a MIT style
 // license that can be found in the LICENSE file.
 
@@ -930,7 +930,7 @@ func (r *Request) fmtBodyString(sl int64) (body string) {
 	contentType := r.Header.Get(hdrContentTypeKey)
 	kind := kindOf(r.Body)
 	if canJSONMarshal(contentType, kind) {
-		prtBodyBytes, err = json.MarshalIndent(&r.Body, "", "   ")
+		prtBodyBytes, err = noescapeJSONMarshalIndent(&r.Body)
 	} else if IsXMLType(contentType) && (kind == reflect.Struct) {
 		prtBodyBytes, err = xml.MarshalIndent(&r.Body, "", "   ")
 	} else if b, ok := r.Body.(string); ok {
@@ -992,3 +992,18 @@ var noescapeJSONMarshal = func(v interface{}) (*bytes.Buffer, error) {
 
 	return buf, nil
 }
+
+var noescapeJSONMarshalIndent = func(v interface{}) ([]byte, error) {
+	buf := acquireBuffer()
+	defer releaseBuffer(buf)
+
+	encoder := json.NewEncoder(buf)
+	encoder.SetEscapeHTML(false)
+	encoder.SetIndent("", "   ")
+
+	if err := encoder.Encode(v); err != nil {
+		return nil, err
+	}
+
+	return buf.Bytes(), nil
+}
diff --git a/response.go b/response.go
index 0356c97..5501283 100644
--- a/response.go
+++ b/response.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2015-2021 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
+// Copyright (c) 2015-2023 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
 // resty source code and usage is governed by a MIT style
 // license that can be found in the LICENSE file.
 
diff --git a/resty.go b/resty.go
index 6f9c8b4..930a909 100644
--- a/resty.go
+++ b/resty.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2015-2021 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
+// Copyright (c) 2015-2023 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
 // resty source code and usage is governed by a MIT style
 // license that can be found in the LICENSE file.
 
diff --git a/retry.go b/retry.go
index e0b856a..c5eda26 100644
--- a/retry.go
+++ b/retry.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2015-2021 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
+// Copyright (c) 2015-2023 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
 // resty source code and usage is governed by a MIT style
 // license that can be found in the LICENSE file.
 
diff --git a/trace.go b/trace.go
index 23cf703..be7555c 100644
--- a/trace.go
+++ b/trace.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2015-2021 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
+// Copyright (c) 2015-2023 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
 // resty source code and usage is governed by a MIT style
 // license that can be found in the LICENSE file.
 
diff --git a/transport.go b/transport.go
index 3f4876c..63c273e 100644
--- a/transport.go
+++ b/transport.go
@@ -1,7 +1,7 @@
 //go:build go1.13
 // +build go1.13
 
-// Copyright (c) 2015-2021 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
+// Copyright (c) 2015-2023 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
 // resty source code and usage is governed by a MIT style
 // license that can be found in the LICENSE file.
 
diff --git a/transport112.go b/transport112.go
index 3468213..d4aa417 100644
--- a/transport112.go
+++ b/transport112.go
@@ -1,7 +1,7 @@
 //go:build !go1.13
 // +build !go1.13
 
-// Copyright (c) 2015-2021 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
+// Copyright (c) 2015-2023 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
 // resty source code and usage is governed by a MIT style
 // license that can be found in the LICENSE file.
 
diff --git a/util.go b/util.go
index 1d563be..99c203b 100644
--- a/util.go
+++ b/util.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2015-2021 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
+// Copyright (c) 2015-2023 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
 // resty source code and usage is governed by a MIT style
 // license that can be found in the LICENSE file.
 


Test patch:
diff --git a/client_test.go b/client_test.go
index 030abcc..90c2bee 100644
--- a/client_test.go
+++ b/client_test.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2015-2021 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
+// Copyright (c) 2015-2023 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
 // resty source code and usage is governed by a MIT style
 // license that can be found in the LICENSE file.
 
@@ -133,6 +133,7 @@ func TestClientDigestErrors(t *testing.T) {
 		{mutateConf: func(c *digestServerConfig) { c.charset = "utf-16" }, expect: ErrDigestCharset},
 		{mutateConf: func(c *digestServerConfig) { c.uri = "/bad" }, expect: ErrDigestBadChallenge},
 		{mutateConf: func(c *digestServerConfig) { c.uri = "/unknown_param" }, expect: ErrDigestBadChallenge},
+		{mutateConf: func(c *digestServerConfig) { c.uri = "/missing_value" }, expect: ErrDigestBadChallenge},
 		{mutateConf: func(c *digestServerConfig) { c.uri = "/no_challenge" }, expect: ErrDigestBadChallenge},
 		{mutateConf: func(c *digestServerConfig) { c.uri = "/status_500" }, expect: nil},
 	}
@@ -180,13 +181,13 @@ func TestClientRedirectPolicy(t *testing.T) {
 	c := dc().SetRedirectPolicy(FlexibleRedirectPolicy(20))
 	_, err := c.R().Get(ts.URL + "/redirect-1")
 
-	assertEqual(t, true, ("Get /redirect-21: stopped after 20 redirects" == err.Error() ||
-		"Get \"/redirect-21\": stopped after 20 redirects" == err.Error()))
+	assertEqual(t, true, (err.Error() == "Get /redirect-21: stopped after 20 redirects" ||
+		err.Error() == "Get \"/redirect-21\": stopped after 20 redirects"))
 
 	c.SetRedirectPolicy(NoRedirectPolicy())
 	_, err = c.R().Get(ts.URL + "/redirect-1")
-	assertEqual(t, true, ("Get /redirect-2: auto redirect is disabled" == err.Error() ||
-		"Get \"/redirect-2\": auto redirect is disabled" == err.Error()))
+	assertEqual(t, true, (err.Error() == "Get /redirect-2: auto redirect is disabled" ||
+		err.Error() == "Get \"/redirect-2\": auto redirect is disabled"))
 }
 
 func TestClientTimeout(t *testing.T) {
@@ -333,7 +334,9 @@ func TestClientSetHeaderVerbatim(t *testing.T) {
 		SetHeaderVerbatim("header-lowercase", "value_lowercase").
 		SetHeader("header-lowercase", "value_standard")
 
-	assertEqual(t, "value_lowercase", strings.Join(c.Header["header-lowercase"], "")) //nolint
+	//lint:ignore SA1008 valid one, so ignore this!
+	unConventionHdrValue := strings.Join(c.Header["header-lowercase"], "")
+	assertEqual(t, "value_lowercase", unConventionHdrValue)
 	assertEqual(t, "value_standard", c.Header.Get("Header-Lowercase"))
 }
 
diff --git a/context_test.go b/context_test.go
index 5da51fa..f3c5345 100644
--- a/context_test.go
+++ b/context_test.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2015-2021 Jeevanandam M (jeeva@myjeeva.com)
+// Copyright (c) 2015-2023 Jeevanandam M (jeeva@myjeeva.com)
 // 2016 Andrew Grigorev (https://github.com/ei-grad)
 // All rights reserved.
 // resty source code and usage is governed by a MIT style
diff --git a/example_test.go b/example_test.go
index 1a2aaeb..7608f1d 100644
--- a/example_test.go
+++ b/example_test.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2015-2021 Jeevanandam M. (jeeva@myjeeva.com), All rights reserved.
+// Copyright (c) 2015-2023 Jeevanandam M. (jeeva@myjeeva.com), All rights reserved.
 // resty source code and usage is governed by a MIT style
 // license that can be found in the LICENSE file.
 
diff --git a/request_test.go b/request_test.go
index 7f31484..ac4a9f1 100644
--- a/request_test.go
+++ b/request_test.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2015-2021 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
+// Copyright (c) 2015-2023 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
 // resty source code and usage is governed by a MIT style
 // license that can be found in the LICENSE file.
 
@@ -1122,8 +1122,8 @@ func TestHTTPAutoRedirectUpTo10(t *testing.T) {
 
 	_, err := dc().R().Get(ts.URL + "/redirect-1")
 
-	assertEqual(t, true, ("Get /redirect-11: stopped after 10 redirects" == err.Error() ||
-		"Get \"/redirect-11\": stopped after 10 redirects" == err.Error()))
+	assertEqual(t, true, (err.Error() == "Get /redirect-11: stopped after 10 redirects" ||
+		err.Error() == "Get \"/redirect-11\": stopped after 10 redirects"))
 }
 
 func TestHostCheckRedirectPolicy(t *testing.T) {
@@ -1464,7 +1464,8 @@ func TestSetHeaderVerbatim(t *testing.T) {
 		SetHeaderVerbatim("header-lowercase", "value_lowercase").
 		SetHeader("header-lowercase", "value_standard")
 
-	assertEqual(t, "value_lowercase", strings.Join(r.Header["header-lowercase"], "")) //nolint
+	//lint:ignore SA1008 valid one ignore this!
+	assertEqual(t, "value_lowercase", strings.Join(r.Header["header-lowercase"], ""))
 	assertEqual(t, "value_standard", r.Header.Get("Header-Lowercase"))
 }
 
diff --git a/resty_test.go b/resty_test.go
index 88e85ba..76d56fd 100644
--- a/resty_test.go
+++ b/resty_test.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2015-2021 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
+// Copyright (c) 2015-2023 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
 // resty source code and usage is governed by a MIT style
 // license that can be found in the LICENSE file.
 
@@ -645,22 +645,27 @@ func createDigestServer(t *testing.T, conf *digestServerConfig) *httptest.Server
 	if conf == nil {
 		conf = defaultDigestServerConf()
 	}
+
+	setWWWAuthHeader := func(w http.ResponseWriter, v string) {
+		w.Header().Set("WWW-Authenticate", v)
+		w.WriteHeader(http.StatusUnauthorized)
+	}
 	ts := createTestServer(func(w http.ResponseWriter, r *http.Request) {
 		t.Logf("Method: %v", r.Method)
 		t.Logf("Path: %v", r.URL.Path)
 
 		switch r.URL.Path {
 		case "/bad":
-			w.Header().Set("WWW-Authenticate", "Bad Challenge")
-			w.WriteHeader(http.StatusUnauthorized)
+			setWWWAuthHeader(w, "Bad Challenge")
 			return
 		case "/unknown_param":
-			w.Header().Set("WWW-Authenticate", "Digest unknown_param=true")
-			w.WriteHeader(http.StatusUnauthorized)
+			setWWWAuthHeader(w, "Digest unknown_param=true")
+			return
+		case "/missing_value":
+			setWWWAuthHeader(w, `Digest realm="hello", domain`)
 			return
 		case "/no_challenge":
-			w.Header().Set("WWW-Authenticate", "")
-			w.WriteHeader(http.StatusUnauthorized)
+			setWWWAuthHeader(w, "")
 			return
 		case "/status_500":
 			w.WriteHeader(http.StatusInternalServerError)
@@ -670,10 +675,9 @@ func createDigestServer(t *testing.T, conf *digestServerConfig) *httptest.Server
 		w.Header().Set(hdrContentTypeKey, "application/json; charset=utf-8")
 
 		if !authorizationHeaderValid(t, r, conf) {
-			w.Header().Set("WWW-Authenticate",
+			setWWWAuthHeader(w,
 				fmt.Sprintf(`Digest realm="%s", domain="%s", qop="%s", algorithm=%s, nonce="%s", opaque="%s", userhash=true, charset=%s, stale=FALSE`,
 					conf.realm, conf.uri, conf.qop, conf.algo, conf.nonce, conf.opaque, conf.charset))
-			w.WriteHeader(http.StatusUnauthorized)
 			_, _ = w.Write([]byte(`{ "id": "unauthorized", "message": "Invalid credentials" }`))
 		} else {
 			w.WriteHeader(http.StatusOK)
diff --git a/retry_test.go b/retry_test.go
index d04cae4..05a4baf 100644
--- a/retry_test.go
+++ b/retry_test.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2015-2021 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
+// Copyright (c) 2015-2023 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
 // resty source code and usage is governed by a MIT style
 // license that can be found in the LICENSE file.
 
@@ -751,7 +751,7 @@ func filler(*Response, error) bool {
 	return false
 }
 
-var seekFailure = fmt.Errorf("failing seek test")
+var errSeekFailure = fmt.Errorf("failing seek test")
 
 type failingSeeker struct {
 	reader *bytes.Reader
@@ -763,7 +763,7 @@ func (f failingSeeker) Read(b []byte) (n int, err error) {
 
 func (f failingSeeker) Seek(offset int64, whence int) (int64, error) {
 	if offset == 0 && whence == io.SeekStart {
-		return 0, seekFailure
+		return 0, errSeekFailure
 	}
 
 	return f.reader.Seek(offset, whence)
@@ -788,7 +788,7 @@ func TestResetMultipartReaderSeekStartError(t *testing.T) {
 		Post(ts.URL + "/set-reset-multipart-readers-test")
 
 	assertEqual(t, 500, resp.StatusCode())
-	assertEqual(t, err.Error(), seekFailure.Error())
+	assertEqual(t, err.Error(), errSeekFailure.Error())
 }
 
 func TestResetMultipartReaders(t *testing.T) {
diff --git a/util_test.go b/util_test.go
index ef2bb91..a78babf 100644
--- a/util_test.go
+++ b/util_test.go
@@ -1,4 +1,4 @@
-// Copyright (c) 2015-2021 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
+// Copyright (c) 2015-2023 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
 // resty source code and usage is governed by a MIT style
 // license that can be found in the LICENSE file.