79 lines
1.5 KiB
Go
79 lines
1.5 KiB
Go
package ipstat
|
|
|
|
import (
|
|
"net"
|
|
"time"
|
|
"videoweb/pub/common/enum/redisconst"
|
|
"videoweb/pub/common/ipaddr"
|
|
"videoweb/pub/common/log"
|
|
"videoweb/pub/common/utils"
|
|
"videoweb/pub/pubdef"
|
|
"videoweb/pub/redis"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
func IpStatMiddleware(ctx *gin.Context) {
|
|
ctx.Next()
|
|
|
|
normalized := normalizeIP(ipaddr.ResolveClientIP(ctx))
|
|
if normalized == "" {
|
|
return
|
|
}
|
|
|
|
date := time.Now().In(utils.LocBJ).Format("20060102")
|
|
key := redisconst.IpStatKey(pubdef.AppId, date)
|
|
|
|
added, err := redis.SAddCount(key, normalized)
|
|
if err != nil {
|
|
log.Warn("IpStatMiddleware SAdd failed", log.Any("key", key), log.E(err))
|
|
return
|
|
}
|
|
if added > 0 {
|
|
if err := redis.Expire(key, redisconst.IpStatExpire); err != nil {
|
|
log.Warn("IpStatMiddleware Expire failed", log.Any("key", key), log.E(err))
|
|
}
|
|
}
|
|
}
|
|
|
|
func normalizeIP(raw string) string {
|
|
ip := net.ParseIP(raw)
|
|
if ip == nil {
|
|
return ""
|
|
}
|
|
if v4 := ip.To4(); v4 != nil {
|
|
ip = v4
|
|
}
|
|
if isPrivateIP(ip) {
|
|
return ""
|
|
}
|
|
return ip.String()
|
|
}
|
|
|
|
var privateRanges = []net.IPNet{
|
|
parseCIDR("10.0.0.0/8"),
|
|
parseCIDR("172.16.0.0/12"),
|
|
parseCIDR("192.168.0.0/16"),
|
|
parseCIDR("127.0.0.0/8"),
|
|
parseCIDR("::1/128"),
|
|
parseCIDR("fe80::/10"),
|
|
parseCIDR("fc00::/7"),
|
|
}
|
|
|
|
func parseCIDR(s string) net.IPNet {
|
|
_, network, err := net.ParseCIDR(s)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return *network
|
|
}
|
|
|
|
func isPrivateIP(ip net.IP) bool {
|
|
for _, r := range privateRanges {
|
|
if r.Contains(ip) {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|