Skip to content
Open
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
2 changes: 1 addition & 1 deletion internal/pkg/generic-client/generic_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func ConfigureClientGeneric[T any](p *print.Printer, cliVersion, customEndpoint

if p.IsVerbosityDebug() {
cfgOptions = append(cfgOptions,
sdkConfig.WithMiddleware(print.RequestResponseCapturer(p, nil)),
sdkConfig.WithMiddleware(print.RequestResponseCapturer(p)),
)
}

Expand Down
44 changes: 16 additions & 28 deletions internal/pkg/print/debug.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,23 +89,14 @@ func BuildDebugStrFromSlice(inputSlice []string) string {

// buildHeaderMap converts a map to a user-friendly string representation.
// This function also filters the headers based on the includeHeaders parameter.
// If includeHeaders is empty, the default header filters are used.
// If includeHeaders is empty, all headers will be printed.
func buildHeaderMap(headers http.Header, includeHeaders []string) map[string]any {
headersMap := make(map[string]any)
for key, values := range headers {
headersMap[key] = strings.Join(values, ", ")
}

headersToInclude := defaultHTTPHeaders
if len(includeHeaders) != 0 {
headersToInclude = includeHeaders
}
for key := range headersMap {
if !slices.Contains(headersToInclude, key) {
delete(headersMap, key)
if len(includeHeaders) == 0 || slices.Contains(includeHeaders, key) {
headersMap[key] = strings.Join(values, ", ")
}
}

return headersMap
}

Expand All @@ -132,9 +123,9 @@ func drainBody(b io.ReadCloser) (r1, r2 io.ReadCloser, err error) {
}

// BuildDebugStrFromHTTPRequest converts an HTTP request to a user-friendly string representation.
// This function also receives a list of headers to include in the output, if empty, the default headers are used.
// Only the headers specified in defaultHTTPHeaders will be printed.
// The return value is a list of strings that should be printed separately.
func BuildDebugStrFromHTTPRequest(req *http.Request, includeHeaders []string) ([]string, error) {
func BuildDebugStrFromHTTPRequest(req *http.Request) ([]string, error) {
if req == nil {
return nil, fmt.Errorf("request is nil")
}
Expand All @@ -150,7 +141,7 @@ func BuildDebugStrFromHTTPRequest(req *http.Request, includeHeaders []string) ([

status := fmt.Sprintf("request to %s: %s %s", unescapedURL, req.Method, req.Proto)

headersMap := buildHeaderMap(req.Header, includeHeaders)
headersMap := buildHeaderMap(req.Header, defaultHTTPHeaders)
headers := fmt.Sprintf("request headers: %v", BuildDebugStrFromMap(headersMap))

var save io.ReadCloser
Expand Down Expand Up @@ -179,9 +170,9 @@ func BuildDebugStrFromHTTPRequest(req *http.Request, includeHeaders []string) ([
}

// BuildDebugStrFromHTTPResponse converts an HTTP response to a user-friendly string representation.
// This function also receives a list of headers to include in the output, if empty, the default headers are used.
// All headers will be printed.
// The return value is a list of strings that should be printed separately.
func BuildDebugStrFromHTTPResponse(resp *http.Response, includeHeaders []string) ([]string, error) {
func BuildDebugStrFromHTTPResponse(resp *http.Response) ([]string, error) {
if resp == nil {
return nil, fmt.Errorf("response is nil")
}
Expand All @@ -199,7 +190,7 @@ func BuildDebugStrFromHTTPResponse(resp *http.Response, includeHeaders []string)

status := fmt.Sprintf("response from %s: %s %s", unescapedURL, resp.Proto, resp.Status)

headersMap := buildHeaderMap(resp.Header, includeHeaders)
headersMap := buildHeaderMap(resp.Header, nil)
headers := fmt.Sprintf("response headers: %v", BuildDebugStrFromMap(headersMap))

var save io.ReadCloser
Expand Down Expand Up @@ -228,23 +219,20 @@ func BuildDebugStrFromHTTPResponse(resp *http.Response, includeHeaders []string)
}

// RequestResponseCapturer is a middleware that captures the request and response of an HTTP request.
// Receives a printer and a list of headers to include in the output
// If the list of headers is empty, the default headers are used.
// The printer is used to print the captured data.
func RequestResponseCapturer(p *Printer, includeHeaders []string) config.Middleware {
// Receives a printer used to print the captured data.
func RequestResponseCapturer(p *Printer) config.Middleware {
return func(rt http.RoundTripper) http.RoundTripper {
return &roundTripperWithCapture{rt, p, includeHeaders}
return &roundTripperWithCapture{rt, p}
}
}

type roundTripperWithCapture struct {
transport http.RoundTripper
p *Printer
debugHttpHeaders []string
transport http.RoundTripper
p *Printer
}

func (rt roundTripperWithCapture) RoundTrip(req *http.Request) (*http.Response, error) {
reqStr, err := BuildDebugStrFromHTTPRequest(req, rt.debugHttpHeaders)
reqStr, err := BuildDebugStrFromHTTPRequest(req)
if err != nil {
rt.p.Debug(ErrorLevel, "printing request to debug logs: %v", err)
}
Expand All @@ -254,7 +242,7 @@ func (rt roundTripperWithCapture) RoundTrip(req *http.Request) (*http.Response,
resp, err := rt.transport.RoundTrip(req)
defer func() {
if err == nil {
respStrSlice, tempErr := BuildDebugStrFromHTTPResponse(resp, rt.debugHttpHeaders)
respStrSlice, tempErr := BuildDebugStrFromHTTPResponse(resp)
if tempErr != nil {
rt.p.Debug(ErrorLevel, "printing HTTP response to debug logs: %v", tempErr)
}
Expand Down
34 changes: 17 additions & 17 deletions internal/pkg/print/debug_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ func TestBuildHeaderMap(t *testing.T) {
},
},
{
description: "no include headers",
description: "non default HTTP headers",
inputHeader: http.Header{
"Accept": []string{"value1"},
"key2": []string{"value2"},
Expand All @@ -332,6 +332,7 @@ func TestBuildHeaderMap(t *testing.T) {
expected: map[string]any{
"Accept": "value1",
"Date": "value3",
"key2": "value2",
},
},
{
Expand Down Expand Up @@ -364,11 +365,10 @@ func TestBuildHeaderMap(t *testing.T) {

func TestBuildDebugStrFromHTTPRequest(t *testing.T) {
tests := []struct {
description string
inputReq *http.Request
inputIncludeHeaders []string
expected []string
isValid bool
description string
inputReq *http.Request
expected []string
isValid bool
}{
{
description: "base",
Expand All @@ -381,12 +381,13 @@ func TestBuildDebugStrFromHTTPRequest(t *testing.T) {
isValid: true,
},
{
description: "include headers",
inputReq: fixtureHTTPRequest(),
inputIncludeHeaders: []string{"Content-Type", "Accept"},
description: "includes only default headers",
inputReq: fixtureHTTPRequest(func(req *http.Request) {
req.Header["Authorization"] = []string{"Bearer: ey"}
}),
expected: []string{
"request to http://example.com: GET HTTP/1.1",
"request headers: [Accept: application/json, Content-Type: application/json]",
"request headers: [Accept: application/json, Content-Length: 15, Content-Type: application/json]",
"request body: [key: value]",
},
isValid: true,
Expand Down Expand Up @@ -438,7 +439,7 @@ func TestBuildDebugStrFromHTTPRequest(t *testing.T) {

for _, tt := range tests {
t.Run(tt.description, func(t *testing.T) {
actual, err := BuildDebugStrFromHTTPRequest(tt.inputReq, tt.inputIncludeHeaders)
actual, err := BuildDebugStrFromHTTPRequest(tt.inputReq)
if err != nil {
if !tt.isValid {
return
Expand All @@ -458,11 +459,10 @@ func TestBuildDebugStrFromHTTPRequest(t *testing.T) {

func TestBuildDebugStrFromHTTPResponse(t *testing.T) {
tests := []struct {
description string
inputResp *http.Response
inputIncludeHeaders []string
expected []string
isValid bool
description string
inputResp *http.Response
expected []string
isValid bool
}{
{
description: "base",
Expand Down Expand Up @@ -517,7 +517,7 @@ func TestBuildDebugStrFromHTTPResponse(t *testing.T) {
err = tt.inputResp.Body.Close()
}()
}
actual, err := BuildDebugStrFromHTTPResponse(tt.inputResp, tt.inputIncludeHeaders)
actual, err := BuildDebugStrFromHTTPResponse(tt.inputResp)
if err != nil {
if !tt.isValid {
return
Expand Down
Loading