mirror of
https://github.com/yusing/godoxy.git
synced 2026-04-21 16:01:22 +02:00
feature: accesslogger
This commit is contained in:
103
internal/net/http/accesslog/fields.go
Normal file
103
internal/net/http/accesslog/fields.go
Normal file
@@ -0,0 +1,103 @@
|
||||
package accesslog
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
type (
|
||||
FieldConfig struct {
|
||||
DefaultMode FieldMode `validate:"oneof=keep drop redact"`
|
||||
Config map[string]FieldMode `validate:"dive,oneof=keep drop redact"`
|
||||
}
|
||||
FieldMode string
|
||||
)
|
||||
|
||||
const (
|
||||
FieldModeKeep FieldMode = "keep"
|
||||
FieldModeDrop FieldMode = "drop"
|
||||
FieldModeRedact FieldMode = "redact"
|
||||
|
||||
RedactedValue = "REDACTED"
|
||||
)
|
||||
|
||||
func processMap[V any](cfg *FieldConfig, m map[string]V, redactedV V) map[string]V {
|
||||
if len(cfg.Config) == 0 {
|
||||
switch cfg.DefaultMode {
|
||||
case FieldModeKeep:
|
||||
return m
|
||||
case FieldModeDrop:
|
||||
return nil
|
||||
case FieldModeRedact:
|
||||
redacted := make(map[string]V)
|
||||
for k := range m {
|
||||
redacted[k] = redactedV
|
||||
}
|
||||
return redacted
|
||||
}
|
||||
}
|
||||
|
||||
if len(m) == 0 {
|
||||
return m
|
||||
}
|
||||
|
||||
newMap := make(map[string]V)
|
||||
for k := range m {
|
||||
var mode FieldMode
|
||||
var ok bool
|
||||
if mode, ok = cfg.Config[k]; !ok {
|
||||
mode = cfg.DefaultMode
|
||||
}
|
||||
switch mode {
|
||||
case FieldModeKeep:
|
||||
newMap[k] = m[k]
|
||||
case FieldModeRedact:
|
||||
newMap[k] = redactedV
|
||||
}
|
||||
}
|
||||
return newMap
|
||||
}
|
||||
|
||||
func processSlice[V any, VReturn any](cfg *FieldConfig, s []V, getKey func(V) string, convert func(V) VReturn, redact func(V) VReturn) map[string]VReturn {
|
||||
if len(s) == 0 ||
|
||||
len(cfg.Config) == 0 && cfg.DefaultMode == FieldModeDrop {
|
||||
return nil
|
||||
}
|
||||
newMap := make(map[string]VReturn, len(s))
|
||||
for _, v := range s {
|
||||
var mode FieldMode
|
||||
var ok bool
|
||||
k := getKey(v)
|
||||
if mode, ok = cfg.Config[k]; !ok {
|
||||
mode = cfg.DefaultMode
|
||||
}
|
||||
switch mode {
|
||||
case FieldModeKeep:
|
||||
newMap[k] = convert(v)
|
||||
case FieldModeRedact:
|
||||
newMap[k] = redact(v)
|
||||
}
|
||||
}
|
||||
return newMap
|
||||
}
|
||||
|
||||
func (cfg *FieldConfig) ProcessHeaders(headers http.Header) http.Header {
|
||||
return processMap(cfg, headers, []string{RedactedValue})
|
||||
}
|
||||
|
||||
func (cfg *FieldConfig) ProcessQuery(q url.Values) url.Values {
|
||||
return processMap(cfg, q, []string{RedactedValue})
|
||||
}
|
||||
|
||||
func (cfg *FieldConfig) ProcessCookies(cookies []*http.Cookie) map[string]string {
|
||||
return processSlice(cfg, cookies,
|
||||
func(c *http.Cookie) string {
|
||||
return c.Name
|
||||
},
|
||||
func(c *http.Cookie) string {
|
||||
return c.Value
|
||||
},
|
||||
func(c *http.Cookie) string {
|
||||
return RedactedValue
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user