From d702df200c2e421d0ae36a711d8b12f1297b456a Mon Sep 17 00:00:00 2001 From: Sergey Vilgelm Date: Thu, 28 Sep 2023 17:11:08 -0700 Subject: [PATCH] improve parseRequesBody and add additional benchmarks Final benchmarks: ```shell % go test -benchmem -bench=. -run=^Benchmark goos: darwin goarch: amd64 pkg: github.com/go-resty/resty/v2 cpu: Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz Benchmark_parseRequestBody_string-16 7623501 155.3 ns/op 16 B/op 1 allocs/op Benchmark_parseRequestBody_byte-16 8421992 141.6 ns/op 16 B/op 1 allocs/op Benchmark_parseRequestBody_reader_with_SetContentLength-16 17632350 67.37 ns/op 16 B/op 1 allocs/op Benchmark_parseRequestBody_reader_without_SetContentLength-16 26575016 45.34 ns/op 0 B/op 0 allocs/op Benchmark_parseRequestBody_struct-16 1243986 953.8 ns/op 40 B/op 2 allocs/op Benchmark_parseRequestBody_struct_xml-16 495250 2458 ns/op 4647 B/op 10 allocs/op Benchmark_parseRequestBody_map-16 694786 1761 ns/op 454 B/op 12 allocs/op Benchmark_parseRequestBody_slice-16 1304724 913.1 ns/op 32 B/op 2 allocs/op Benchmark_parseRequestBody_FormData-16 1000000 1128 ns/op 272 B/op 9 allocs/op Benchmark_parseRequestBody_MultiPart-16 93248 12583 ns/op 8738 B/op 130 allocs/op ``` --- middleware.go | 66 +++++++++++++++++++-------------------------------- 1 file changed, 24 insertions(+), 42 deletions(-) diff --git a/middleware.go b/middleware.go index b01d869a..94ce31e4 100644 --- a/middleware.go +++ b/middleware.go @@ -15,6 +15,7 @@ import ( "os" "path/filepath" "reflect" + "strconv" "strings" "time" ) @@ -134,45 +135,34 @@ func parseRequestHeader(c *Client, r *Request) error { return nil } -func parseRequestBody(c *Client, r *Request) (err error) { +func parseRequestBody(c *Client, r *Request) error { if isPayloadSupported(r.Method, c.AllowGetMethodPayload) { - // Handling Multipart - if r.isMultiPart { - if err = handleMultipart(c, r); err != nil { - return + switch { + case r.isMultiPart: // Handling Multipart + if err := handleMultipart(c, r); err != nil { + return err } - - goto CL - } - - // Handling Form Data - if len(c.FormData) > 0 || len(r.FormData) > 0 { + case len(c.FormData) > 0 || len(r.FormData) > 0: // Handling Form Data handleFormData(c, r) - - goto CL - } - - // Handling Request body - if r.Body != nil { + case r.Body != nil: // Handling Request body handleContentType(c, r) - if err = handleRequestBody(c, r); err != nil { - return + if err := handleRequestBody(c, r); err != nil { + return err } } } -CL: // by default resty won't set content length, you can if you want to :) if c.setContentLength || r.setContentLength { if r.bodyBuf == nil { r.Header.Set(hdrContentLengthKey, "0") } else { - r.Header.Set(hdrContentLengthKey, fmt.Sprintf("%d", r.bodyBuf.Len())) + r.Header.Set(hdrContentLengthKey, strconv.Itoa(r.bodyBuf.Len())) } } - return + return nil } func createHTTPRequest(c *Client, r *Request) (err error) { @@ -370,13 +360,13 @@ func parseResponseBody(c *Client, res *Response) (err error) { return } -func handleMultipart(c *Client, r *Request) (err error) { +func handleMultipart(c *Client, r *Request) error { r.bodyBuf = acquireBuffer() w := multipart.NewWriter(r.bodyBuf) for k, v := range c.FormData { for _, iv := range v { - if err = w.WriteField(k, iv); err != nil { + if err := w.WriteField(k, iv); err != nil { return err } } @@ -385,12 +375,11 @@ func handleMultipart(c *Client, r *Request) (err error) { for k, v := range r.FormData { for _, iv := range v { if strings.HasPrefix(k, "@") { // file - err = addFile(w, k[1:], iv) - if err != nil { - return + if err := addFile(w, k[1:], iv); err != nil { + return err } } else { // form value - if err = w.WriteField(k, iv); err != nil { + if err := w.WriteField(k, iv); err != nil { return err } } @@ -398,28 +387,21 @@ func handleMultipart(c *Client, r *Request) (err error) { } // #21 - adding io.Reader support - if len(r.multipartFiles) > 0 { - for _, f := range r.multipartFiles { - err = addFileReader(w, f) - if err != nil { - return - } + for _, f := range r.multipartFiles { + if err := addFileReader(w, f); err != nil { + return err } } // GitHub #130 adding multipart field support with content type - if len(r.multipartFields) > 0 { - for _, mf := range r.multipartFields { - if err = addMultipartFormField(w, mf); err != nil { - return - } + for _, mf := range r.multipartFields { + if err := addMultipartFormField(w, mf); err != nil { + return err } } r.Header.Set(hdrContentTypeKey, w.FormDataContentType()) - err = w.Close() - - return + return w.Close() } func handleFormData(c *Client, r *Request) {