Skip to content

Dev #57

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Merged
merged 2 commits into from
Feb 20, 2024
Merged

Dev #57

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 59 additions & 1 deletion apihandlers/jamfpro/jamfpro_api_response.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,65 @@ import (
)

// Functions
func (j *JamfAPIHandler) HandleAPISuccessResponse(resp *http.Response, out interface{}, log logger.Logger) error {
// Special handling for DELETE requests
if resp.Request.Method == "DELETE" {
return j.handleDeleteRequest(resp)
}

// Read the response body
bodyBytes, err := j.readResponseBody(resp)
if err != nil {
return err
}

// Log the raw response details for debugging
j.logResponseDetails(resp, bodyBytes)

// Unmarshal the response based on content type
contentType := resp.Header.Get("Content-Type")

// Check for binary data handling
contentDisposition := resp.Header.Get("Content-Disposition")
if err := j.handleBinaryData(contentType, contentDisposition, bodyBytes, out); err != nil {
return err
}

return j.unmarshalResponse(contentType, bodyBytes, out)
}

func (j *JamfAPIHandler) HandleAPIErrorResponse(resp *http.Response, out interface{}, log logger.Logger) error {
// Read the response body
bodyBytes, err := j.readResponseBody(resp)
if err != nil {
return err
}

// Convert bodyBytes to a string to represent the raw response body
rawResponse := string(bodyBytes)

// Log the raw response details for debugging
j.logResponseDetails(resp, bodyBytes)

// Get the content type from the response headers
contentType := resp.Header.Get("Content-Type")

// Handle known error content types (e.g., JSON, HTML)
if strings.Contains(contentType, "application/json") {
return j.handleErrorJSONResponse(bodyBytes, resp.StatusCode, rawResponse)
} else if strings.Contains(contentType, "text/html") {
return j.handleErrorHTMLResponse(bodyBytes, resp.StatusCode)
}

// Generic error handling for unknown content types
j.Logger.Error("Received non-success status code without detailed error response",
zap.Int("status_code", resp.StatusCode),
zap.String("raw_response", rawResponse),
)
Comment on lines +68 to +71

Check warning

Code scanning / gosec

Errors unhandled.

Errors unhandled.
return fmt.Errorf("received non-success status code: %d, raw response: %s", resp.StatusCode, rawResponse)
}

/*
// HandleResponse processes an HTTP response for a Jamf API request. It handles different response types and errors accordingly.
func (j *JamfAPIHandler) HandleResponse(resp *http.Response, out interface{}, log logger.Logger) error {
// Special handling for DELETE requests
Expand Down Expand Up @@ -62,7 +120,7 @@ func (j *JamfAPIHandler) HandleResponse(resp *http.Response, out interface{}, lo
// Unmarshal the response based on content type
return j.unmarshalResponse(contentType, bodyBytes, out)
}

*/
// handleDeleteRequest handles the special case for DELETE requests, where a successful response might not contain a body.
func (j *JamfAPIHandler) handleDeleteRequest(resp *http.Response) error {
if resp.StatusCode >= 200 && resp.StatusCode < 300 {
Expand Down
4 changes: 3 additions & 1 deletion httpclient/httpclient_api_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ type APIHandler interface {
ConstructAPIAuthEndpoint(instanceName string, endpointPath string, log logger.Logger) string
MarshalRequest(body interface{}, method string, endpoint string, log logger.Logger) ([]byte, error)
MarshalMultipartRequest(fields map[string]string, files map[string]string, log logger.Logger) ([]byte, string, error)
HandleResponse(resp *http.Response, out interface{}, log logger.Logger) error
//HandleResponse(resp *http.Response, out interface{}, log logger.Logger) error
HandleAPISuccessResponse(resp *http.Response, out interface{}, log logger.Logger) error
HandleAPIErrorResponse(resp *http.Response, out interface{}, log logger.Logger) error
GetContentTypeHeader(method string, log logger.Logger) string
GetAcceptHeader() string
GetDefaultBaseDomain() string
Expand Down
18 changes: 2 additions & 16 deletions httpclient/httpclient_request.go
Original file line number Diff line number Diff line change
Expand Up @@ -350,22 +350,8 @@ func (c *Client) executeHTTPRequest(req *http.Request, log logger.Logger, method
//
// Returns:
// - An error object parsed from the HTTP response, indicating the nature of the failure.
func (c *Client) handleErrorResponseV1(resp *http.Response, log logger.Logger, errorMessage, method, endpoint string) error {
apiErr := errors.HandleAPIError(resp, log)

// Log the provided error message along with method, endpoint, and status code.
log.Error(errorMessage,
zap.String("method", method),
zap.String("endpoint", endpoint),
zap.Int("status_code", resp.StatusCode),
zap.String("error", apiErr.Error()),
)

return apiErr
}

func (c *Client) handleErrorResponse(resp *http.Response, out interface{}, log logger.Logger, method, endpoint string) error {
if err := c.APIHandler.HandleResponse(resp, out, log); err != nil {
if err := c.APIHandler.HandleAPIErrorResponse(resp, out, log); err != nil {
log.Error("Failed to unmarshal HTTP response",
zap.String("method", method),
zap.String("endpoint", endpoint),
Expand Down Expand Up @@ -395,7 +381,7 @@ func (c *Client) handleErrorResponse(resp *http.Response, out interface{}, log l
// Returns:
// - nil if the response was successfully unmarshalled into the 'out' parameter, or an error if unmarshalling failed.
func (c *Client) handleSuccessResponse(resp *http.Response, out interface{}, log logger.Logger, method, endpoint string) error {
if err := c.APIHandler.HandleResponse(resp, out, log); err != nil {
if err := c.APIHandler.HandleAPISuccessResponse(resp, out, log); err != nil {
log.Error("Failed to unmarshal HTTP response",
zap.String("method", method),
zap.String("endpoint", endpoint),
Expand Down