Skip to content
Merged
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
36 changes: 32 additions & 4 deletions client_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,10 +119,23 @@ func buildHTTPRequest(
}

if log.V(logger.DebugLevel) {
log.Debug(
ctx,
fmt.Sprintf("request %s to %s with headers %v body %s", method, u.String(), hreq.Header, body),
)
if shouldLogBody(ct) {
log.Debug(
ctx,
fmt.Sprintf(
"micro.client http request: method=%s url=%s headers=%v body=%s",
method, u.String(), hreq.Header, body,
),
)
} else {
log.Debug(
ctx,
fmt.Sprintf(
"micro.client http request: method=%s url=%s headers=%v",
method, u.String(), hreq.Header,
),
)
}
}

return hreq, nil
Expand Down Expand Up @@ -259,3 +272,18 @@ func validateHeadersAndCookies(r *http.Request, parameters map[string]map[string

return nil
}

func shouldLogBody(contentType string) bool {
ct := strings.ToLower(strings.Split(contentType, ";")[0])
switch {
case strings.HasPrefix(ct, "text/"): // => text/html, text/plain, text/csv etc.
return true
case ct == "application/json",
ct == "application/xml",
ct == "application/x-www-form-urlencoded",
ct == "application/yaml":
return true
default:
return false
}
}
46 changes: 46 additions & 0 deletions client_helpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -399,3 +399,49 @@ func TestValidateHeadersAndCookies(t *testing.T) {
})
}
}

func TestShouldLogBody(t *testing.T) {
tests := []struct {
name string
contentType string
want bool
}{
// --- text/*
{"plain text", "text/plain", true},
{"html", "text/html", true},
{"csv", "text/csv", true},
{"yaml text", "text/yaml", true},

// --- application/*
{"json", "application/json", true},
{"xml", "application/xml", true},
{"form-urlencoded", "application/x-www-form-urlencoded", true},
{"yaml", "application/yaml", true},

// --- with parameters
{"json with charset", "application/json; charset=utf-8", true},
{"binary with charset", "application/octet-stream; charset=utf-8", false},

// --- binary
{"multipart form", "multipart/form-data", false},
{"binary stream", "application/octet-stream", false},
{"pdf", "application/pdf", false},
{"protobuf", "application/protobuf", false},
{"image", "image/png", false},

// --- edge cases
{"upper case type", "APPLICATION/JSON", true},
{"mixed case type", "Text/HTML", true},
{"unknown text prefix", "TEXT/FOO", true},
{"weird semicolon only", ";", false},
{"spaces only", " ", false},
{"empty content-type", "", false},
{"missing main type", "/plain", false},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
require.Equal(t, tt.want, shouldLogBody(tt.contentType))
})
}
}
28 changes: 22 additions & 6 deletions client_unary_call.go
Original file line number Diff line number Diff line change
Expand Up @@ -207,8 +207,6 @@ func (c *Client) parseRsp(ctx context.Context, hrsp *http.Response, rsp any, opt
default:
}

var buf []byte

if opts.ResponseMetadata != nil {
for k, v := range hrsp.Header {
opts.ResponseMetadata.Set(k, strings.Join(v, ","))
Expand All @@ -224,6 +222,8 @@ func (c *Client) parseRsp(ctx context.Context, hrsp *http.Response, rsp any, opt
ct = htype
}

var buf []byte

if hrsp.Body != nil {
var err error
buf, err = io.ReadAll(hrsp.Body)
Expand All @@ -232,15 +232,31 @@ func (c *Client) parseRsp(ctx context.Context, hrsp *http.Response, rsp any, opt
}
}

if log.V(logger.DebugLevel) {
if shouldLogBody(ct) {
log.Debug(
ctx,
fmt.Sprintf(
"micro.client http response: status=%s headers=%v body=%s",
hrsp.Status, hrsp.Header, buf,
),
)
} else {
log.Debug(
ctx,
fmt.Sprintf(
"micro.client http response: status=%s headers=%v",
hrsp.Status, hrsp.Header,
),
)
}
}

cf, err := c.newCodec(ct)
if err != nil {
return errors.InternalServerError("go.micro.client", "unknown content-type %s: %v", ct, err)
}

if log.V(logger.DebugLevel) {
log.Debug(ctx, fmt.Sprintf("response with headers: %v and body: %s", hrsp.Header, buf))
}

if hrsp.StatusCode < http.StatusBadRequest {
if err = cf.Unmarshal(buf, rsp); err != nil {
return errors.InternalServerError("go.micro.client", "unmarshal response: %v", err)
Expand Down
Loading