fix: 认证失败不泄漏连接表并脱敏 mochi 整包日志

This commit is contained in:
Nixevol
2026-09-30 16:21:05 +08:00
parent deb2398e27
commit 0b9ce0359a
5 changed files with 442 additions and 14 deletions
+88
View File
@@ -0,0 +1,88 @@
package broker
import (
"context"
"log/slog"
"github.com/mochi-mqtt/server/v2/packets"
)
type redactHandler struct {
inner slog.Handler
}
func newRedactHandler(inner slog.Handler) slog.Handler {
if inner == nil {
inner = slog.Default().Handler()
}
return &redactHandler{inner: inner}
}
func (h *redactHandler) Enabled(ctx context.Context, level slog.Level) bool {
return h.inner.Enabled(ctx, level)
}
func (h *redactHandler) Handle(ctx context.Context, r slog.Record) error {
rec := slog.NewRecord(r.Time, r.Level, r.Message, r.PC)
r.Attrs(func(a slog.Attr) bool {
rec.AddAttrs(redactSlogAttr(a))
return true
})
return h.inner.Handle(ctx, rec)
}
func (h *redactHandler) WithAttrs(attrs []slog.Attr) slog.Handler {
out := make([]slog.Attr, len(attrs))
for i, a := range attrs {
out[i] = redactSlogAttr(a)
}
return &redactHandler{inner: h.inner.WithAttrs(out)}
}
func (h *redactHandler) WithGroup(name string) slog.Handler {
return &redactHandler{inner: h.inner.WithGroup(name)}
}
func redactSlogAttr(a slog.Attr) slog.Attr {
a.Value = a.Value.Resolve()
switch v := a.Value.Any().(type) {
case packets.Packet:
return slog.Any(a.Key, summarizePacket(v))
case *packets.Packet:
if v == nil {
return a
}
return slog.Any(a.Key, summarizePacket(*v))
}
if a.Value.Kind() == slog.KindGroup {
group := a.Value.Group()
out := make([]slog.Attr, len(group))
for i, g := range group {
out[i] = redactSlogAttr(g)
}
return slog.Attr{Key: a.Key, Value: slog.GroupValue(out...)}
}
return a
}
type mqttPacketLog struct {
Type string `json:"type"`
QoS byte `json:"qos"`
PacketID uint16 `json:"packet_id"`
Topic string `json:"topic,omitempty"`
PayloadLen int `json:"payload_len"`
}
func summarizePacket(pk packets.Packet) mqttPacketLog {
name := packets.PacketNames[pk.FixedHeader.Type]
if name == "" {
name = "unknown"
}
return mqttPacketLog{
Type: name,
QoS: pk.FixedHeader.Qos,
PacketID: pk.PacketID,
Topic: pk.TopicName,
PayloadLen: len(pk.Payload),
}
}