Last active
July 1, 2023 18:31
-
-
Save nielskrijger/e680db57580d9939f2adf0fcd9eb35c6 to your computer and use it in GitHub Desktop.
httpmock LogResponder
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
func joinLines(lines []string, suffix, separator string) string { | |
var result string | |
for i, line := range lines { | |
result += fmt.Sprintf("%s%s", suffix, line) | |
if i < len(lines)-1 { | |
result += separator | |
} | |
} | |
return result | |
} | |
// formatRequest generates representation of the request | |
func formatRequest(req *http.Request) string { | |
var lines []string | |
lines = append(lines, fmt.Sprintf("%v %v %v", req.Method, req.URL, req.Proto)) | |
lines = append(lines, fmt.Sprintf("Host: %v", req.Host)) | |
// Loop through headers | |
for name, headers := range req.Header { | |
for _, h := range headers { | |
lines = append(lines, fmt.Sprintf("%v: %v", name, h)) | |
} | |
} | |
result := joinLines(lines, "> ", "\n") | |
result += "\n\n" | |
// If this is a POST, add post data | |
if req.Method == "POST" { | |
req.ParseForm() | |
result += req.Form.Encode() + "\n\n" | |
} | |
return result | |
} | |
func formatResponse(res *http.Response) string { | |
var lines []string | |
lines = append(lines, fmt.Sprintf("%v %v %v", res.Proto, res.StatusCode, res.Status)) | |
// Loop through headers | |
for name, headers := range res.Header { | |
for _, h := range headers { | |
lines = append(lines, fmt.Sprintf("%v: %v", name, h)) | |
} | |
} | |
result := joinLines(lines, "< ", "\n") | |
result += "\n\n" | |
// If this response has a body add it | |
if res.Body != nil { | |
body, err := io.ReadAll(res.Body) | |
if err != nil { | |
result += fmt.Sprintf("reading request body: %v", err) | |
} else { | |
result += string(body) | |
res.Body = io.NopCloser(bytes.NewReader(body)) // Allow body to be read for a second time | |
} | |
result += "\n\n" | |
} | |
return result | |
} | |
// LogResponder logs the request and response for an outgoing request. | |
func LogResponder(req *http.Request) (*http.Response, error) { | |
httpmock.Deactivate() | |
defer httpmock.Activate() | |
res, err := http.DefaultClient.Do(req) | |
if err != nil { | |
return nil, err | |
} | |
defer res.Body.Close() | |
fmt.Print(formatRequest(req)) | |
fmt.Print(formatResponse(res)) | |
if res.Body != nil { | |
body, err := io.ReadAll(res.Body) | |
if err != nil { | |
return nil, err | |
} | |
res.Body = io.NopCloser(bytes.NewReader(body)) // Allow body to be read a second time by the app | |
} | |
return res, nil | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment