spark-server/internal/pkg/media/check.go
2026-09-29 10:22:28 +08:00

84 lines
2.2 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package media
import "fmt"
// Kind classifies media for policy checks.
type Kind string
const (
KindImage Kind = "image"
KindVideo Kind = "video"
KindAvatar Kind = "avatar"
)
// Violation describes an oversize resource (dimensions and/or bytes).
type Violation struct {
Kind Kind
Reason string
Width int
Height int
MaxEdge int
Size int64
MaxSize int64
Duration int // ms; video only
}
func (v *Violation) Error() string {
if v == nil {
return ""
}
return fmt.Sprintf("media %s oversize: %s", v.Kind, v.Reason)
}
// Policy controls user-path detection (bots always compress via infrastructure/media).
type Policy struct {
Enabled bool // master switch for user checks
UserReject bool // when true, publish/upload returns ErrMediaOversized; else log-only
Limits Limits
}
// CheckImageMeta validates declared image width/height/size against Limits.
// Zero width/height skips dimension check (client omitted); size 0 skips byte check.
func (p Policy) CheckImageMeta(w, h int, size int64) *Violation {
return p.check(KindImage, w, h, size, 0)
}
// CheckVideoMeta validates declared video metadata.
func (p Policy) CheckVideoMeta(w, h int, size int64, durationMS int) *Violation {
return p.check(KindVideo, w, h, size, durationMS)
}
// CheckAvatarMeta validates avatar dimensions/size (≤200×200 by default).
func (p Policy) CheckAvatarMeta(w, h int, size int64) *Violation {
return p.check(KindAvatar, w, h, size, 0)
}
func (p Policy) check(kind Kind, w, h int, size int64, durationMS int) *Violation {
if !p.Enabled {
return nil
}
lim := p.Limits.Normalize()
maxEdge, maxSize := lim.ImageMaxEdge, lim.ImageMaxBytes
switch kind {
case KindVideo:
maxEdge, maxSize = lim.VideoMaxEdge, lim.VideoMaxBytes
case KindAvatar:
maxEdge, maxSize = lim.AvatarMaxEdge, lim.AvatarMaxBytes
}
if w > 0 && h > 0 && NeedsResize(w, h, maxEdge) {
return &Violation{
Kind: kind, Reason: "edge_exceeded",
Width: w, Height: h, MaxEdge: maxEdge,
Size: size, MaxSize: maxSize, Duration: durationMS,
}
}
if size > 0 && maxSize > 0 && size > maxSize {
return &Violation{
Kind: kind, Reason: "size_exceeded",
Width: w, Height: h, MaxEdge: maxEdge,
Size: size, MaxSize: maxSize, Duration: durationMS,
}
}
return nil
}