From a91aad71be936a5e5d8067f48c30cc1bb7c0431c Mon Sep 17 00:00:00 2001 From: Joseph Little Date: Tue, 9 Jul 2024 16:12:32 +0100 Subject: [PATCH] optimising the responsep package --- httpclient/request.go | 3 +++ response/success.go | 26 +++++++++++++++----------- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/httpclient/request.go b/httpclient/request.go index 16e3bdb..de81c45 100644 --- a/httpclient/request.go +++ b/httpclient/request.go @@ -130,6 +130,7 @@ func (c *Client) requestWithRetries(method, endpoint string, body, out interface c.Sugar.Warn("Redirect response received", zap.Int("status_code", resp.StatusCode), zap.String("location", resp.Header.Get("Location"))) } c.Sugar.Infof("%s request successful at %v", resp.Request.Method, resp.Request.URL) + return resp, response.HandleAPISuccessResponse(resp, out, c.Sugar) } @@ -142,6 +143,7 @@ func (c *Client) requestWithRetries(method, endpoint string, body, out interface // Non Retry if response.IsNonRetryableStatusCode(resp.StatusCode) { c.Sugar.Warn("Non-retryable error received", zap.Int("status_code", resp.StatusCode), zap.String("status_message", statusMessage)) + return resp, response.HandleAPIErrorResponse(resp, c.Sugar) } @@ -227,6 +229,7 @@ func (c *Client) requestNoRetries(method, endpoint string, body, out interface{} c.Sugar.Warn("Redirect response received", zap.Int("status_code", resp.StatusCode), zap.String("location", resp.Header.Get("Location"))) } c.Sugar.Infof("%s request successful at %v", resp.Request.Method, resp.Request.URL) + return resp, response.HandleAPISuccessResponse(resp, out, c.Sugar) } diff --git a/response/success.go b/response/success.go index 8ff60bb..b035c01 100644 --- a/response/success.go +++ b/response/success.go @@ -38,6 +38,7 @@ func HandleAPISuccessResponse(resp *http.Response, out interface{}, sugar *zap.S return err } + // TODO do we need to redact some auth headers here? I think so. sugar.Debug("HTTP Response Headers", zap.Any("Headers", resp.Header)) sugar.Debug("Raw HTTP Response", zap.String("Body", string(bodyBytes))) @@ -45,15 +46,23 @@ func HandleAPISuccessResponse(resp *http.Response, out interface{}, sugar *zap.S mimeType, _ := parseHeader(resp.Header.Get("Content-Type")) contentDisposition := resp.Header.Get("Content-Disposition") - if handler, ok := responseUnmarshallers[mimeType]; ok { + sugar.Debugf("MIMETYPE-%s", mimeType) + + var handler contentHandler + var ok bool + + if handler, ok = responseUnmarshallers[mimeType]; ok { return handler(bodyReader, out, sugar, mimeType) - } else if isBinaryData(mimeType, contentDisposition) { + } + + if isBinaryData(mimeType, contentDisposition) { return handleBinaryData(bodyReader, sugar, out, contentDisposition) - } else { - errMsg := fmt.Sprintf("unexpected MIME type: %s", mimeType) - sugar.Error("Unmarshal error", zap.String("content type", mimeType), zap.Error(errors.New(errMsg))) - return errors.New(errMsg) } + + errMsg := fmt.Sprintf("unexpected MIME type: %s", mimeType) + sugar.Error("Unmarshal error", zap.String("content type", mimeType), zap.Error(errors.New(errMsg))) + return errors.New(errMsg) + } // handleDeleteRequest handles the special case for DELETE requests, where a successful response might not contain a body. @@ -94,10 +103,8 @@ func isBinaryData(contentType, contentDisposition string) bool { // handleBinaryData reads binary data from an io.Reader and stores it in *[]byte or streams it to an io.Writer. func handleBinaryData(reader io.Reader, sugar *zap.SugaredLogger, out interface{}, contentDisposition string) error { - // Check if the output interface is either *[]byte or io.Writer switch out := out.(type) { case *[]byte: - // Read all data from reader and store it in *[]byte data, err := io.ReadAll(reader) if err != nil { sugar.Error("Failed to read binary data", zap.Error(err)) @@ -106,7 +113,6 @@ func handleBinaryData(reader io.Reader, sugar *zap.SugaredLogger, out interface{ *out = data case io.Writer: - // Stream data directly to the io.Writer _, err := io.Copy(out, reader) if err != nil { sugar.Error("Failed to stream binary data to io.Writer", zap.Error(err)) @@ -117,12 +123,10 @@ func handleBinaryData(reader io.Reader, sugar *zap.SugaredLogger, out interface{ return errors.New("output parameter is not suitable for binary data (*[]byte or io.Writer)") } - // Handle Content-Disposition if present if contentDisposition != "" { _, params := parseHeader(contentDisposition) if filename, ok := params["filename"]; ok { sugar.Debug("Extracted filename from Content-Disposition", zap.String("filename", filename)) - // Additional processing for the filename can be done here if needed } }