Skip to content

Commit 2a72f13

Browse files
autoBojunChai
authored andcommitted
internal: add tests for LoggableHTTPHeader redaction
1 parent 4430756 commit 2a72f13

1 file changed

Lines changed: 90 additions & 0 deletions

File tree

internal/logmarshalers_test.go

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
package internal
2+
3+
import (
4+
"net/http"
5+
"testing"
6+
7+
"go.uber.org/zap/zapcore"
8+
)
9+
10+
func TestLoggableHTTPHeaderRedactsSensitive(t *testing.T) {
11+
h := http.Header{
12+
"Authorization": []string{"Bearer secret-token"},
13+
"Proxy-Authorization": []string{"Basic dXNlcjpwYXNz"},
14+
"Cookie": []string{"session=abc"},
15+
"Set-Cookie": []string{"session=abc; Path=/"},
16+
"X-Custom": []string{"keep-me"},
17+
}
18+
19+
enc := zapcore.NewMapObjectEncoder()
20+
if err := (LoggableHTTPHeader{Header: h}).MarshalLogObject(enc); err != nil {
21+
t.Fatalf("MarshalLogObject: %v", err)
22+
}
23+
24+
for _, key := range []string{"Authorization", "Proxy-Authorization", "Cookie", "Set-Cookie"} {
25+
if got := singleStringField(t, enc, key); got != "REDACTED" {
26+
t.Errorf("%s: expected REDACTED, got %q", key, got)
27+
}
28+
}
29+
30+
if got := singleStringField(t, enc, "X-Custom"); got != "keep-me" {
31+
t.Errorf("X-Custom: expected keep-me, got %q", got)
32+
}
33+
}
34+
35+
func singleStringField(t *testing.T, enc *zapcore.MapObjectEncoder, key string) string {
36+
t.Helper()
37+
raw, ok := enc.Fields[key]
38+
if !ok {
39+
t.Fatalf("%s: field missing", key)
40+
}
41+
arr, ok := raw.([]any)
42+
if !ok {
43+
t.Fatalf("%s: expected []any, got %T", key, raw)
44+
}
45+
if len(arr) != 1 {
46+
t.Fatalf("%s: expected 1 element, got %d", key, len(arr))
47+
}
48+
s, ok := arr[0].(string)
49+
if !ok {
50+
t.Fatalf("%s: expected string, got %T", key, arr[0])
51+
}
52+
return s
53+
}
54+
55+
func TestLoggableHTTPHeaderLogsCredentialsWhenEnabled(t *testing.T) {
56+
h := http.Header{"Authorization": []string{"Bearer secret-token"}}
57+
58+
enc := zapcore.NewMapObjectEncoder()
59+
err := LoggableHTTPHeader{Header: h, ShouldLogCredentials: true}.MarshalLogObject(enc)
60+
if err != nil {
61+
t.Fatalf("MarshalLogObject: %v", err)
62+
}
63+
64+
if got := singleStringField(t, enc, "Authorization"); got != "Bearer secret-token" {
65+
t.Errorf("expected credentials to be logged verbatim, got %q", got)
66+
}
67+
}
68+
69+
func TestLoggableHTTPHeaderNilHeaderIsNoOp(t *testing.T) {
70+
enc := zapcore.NewMapObjectEncoder()
71+
if err := (LoggableHTTPHeader{}).MarshalLogObject(enc); err != nil {
72+
t.Fatalf("MarshalLogObject: %v", err)
73+
}
74+
if len(enc.Fields) != 0 {
75+
t.Errorf("expected no fields, got %v", enc.Fields)
76+
}
77+
}
78+
79+
func TestLoggableHTTPHeaderRedactsIsCaseInsensitive(t *testing.T) {
80+
h := http.Header{"authorization": []string{"Bearer secret"}}
81+
82+
enc := zapcore.NewMapObjectEncoder()
83+
if err := (LoggableHTTPHeader{Header: h}).MarshalLogObject(enc); err != nil {
84+
t.Fatalf("MarshalLogObject: %v", err)
85+
}
86+
87+
if got := singleStringField(t, enc, "authorization"); got != "REDACTED" {
88+
t.Errorf("expected lowercase authorization to be redacted, got %q", got)
89+
}
90+
}

0 commit comments

Comments
 (0)