logging: query filter for array of strings (#5779)

Co-authored-by: Matt Holt <mholt@users.noreply.github.com>
Co-authored-by: Francis Lavoie <lavofr@gmail.com>
This commit is contained in:
Paul Jeannot 2023-08-30 00:59:43 +02:00 committed by GitHub
parent c46ec3b500
commit 1b73e3862d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 52 additions and 6 deletions

View file

@ -373,11 +373,25 @@ func (m *QueryFilter) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
// Filter filters the input field. // Filter filters the input field.
func (m QueryFilter) Filter(in zapcore.Field) zapcore.Field { func (m QueryFilter) Filter(in zapcore.Field) zapcore.Field {
u, err := url.Parse(in.String) if array, ok := in.Interface.(caddyhttp.LoggableStringArray); ok {
if err != nil { newArray := make(caddyhttp.LoggableStringArray, len(array))
for i, s := range array {
newArray[i] = m.processQueryString(s)
}
in.Interface = newArray
} else {
in.String = m.processQueryString(in.String)
}
return in return in
} }
func (m QueryFilter) processQueryString(s string) string {
u, err := url.Parse(s)
if err != nil {
return s
}
q := u.Query() q := u.Query()
for _, a := range m.Actions { for _, a := range m.Actions {
switch a.Type { switch a.Type {
@ -397,9 +411,7 @@ func (m QueryFilter) Filter(in zapcore.Field) zapcore.Field {
} }
u.RawQuery = q.Encode() u.RawQuery = q.Encode()
in.String = u.String() return u.String()
return in
} }
type cookieFilterAction struct { type cookieFilterAction struct {

View file

@ -83,7 +83,7 @@ func TestIPMaskMultiValue(t *testing.T) {
} }
} }
func TestQueryFilter(t *testing.T) { func TestQueryFilterSingleValue(t *testing.T) {
f := QueryFilter{[]queryFilterAction{ f := QueryFilter{[]queryFilterAction{
{replaceAction, "foo", "REDACTED"}, {replaceAction, "foo", "REDACTED"},
{replaceAction, "notexist", "REDACTED"}, {replaceAction, "notexist", "REDACTED"},
@ -102,6 +102,40 @@ func TestQueryFilter(t *testing.T) {
} }
} }
func TestQueryFilterMultiValue(t *testing.T) {
f := QueryFilter{
Actions: []queryFilterAction{
{Type: replaceAction, Parameter: "foo", Value: "REDACTED"},
{Type: replaceAction, Parameter: "notexist", Value: "REDACTED"},
{Type: deleteAction, Parameter: "bar"},
{Type: deleteAction, Parameter: "notexist"},
{Type: hashAction, Parameter: "hash"},
},
}
if f.Validate() != nil {
t.Fatalf("the filter must be valid")
}
out := f.Filter(zapcore.Field{Interface: caddyhttp.LoggableStringArray{
"/path1?foo=a&foo=b&bar=c&bar=d&baz=e&hash=hashed",
"/path2?foo=c&foo=d&bar=e&bar=f&baz=g&hash=hashed",
}})
arr, ok := out.Interface.(caddyhttp.LoggableStringArray)
if !ok {
t.Fatalf("field is wrong type: %T", out.Interface)
}
expected1 := "/path1?baz=e&foo=REDACTED&foo=REDACTED&hash=e3b0c442"
expected2 := "/path2?baz=g&foo=REDACTED&foo=REDACTED&hash=e3b0c442"
if arr[0] != expected1 {
t.Fatalf("query parameters in entry 0 have not been filtered correctly: got %s, expected %s", arr[0], expected1)
}
if arr[1] != expected2 {
t.Fatalf("query parameters in entry 1 have not been filtered correctly: got %s, expected %s", arr[1], expected2)
}
}
func TestValidateQueryFilter(t *testing.T) { func TestValidateQueryFilter(t *testing.T) {
f := QueryFilter{[]queryFilterAction{ f := QueryFilter{[]queryFilterAction{
{}, {},