Files
EdgeNode/internal/stats/user_agent_parser.go

103 lines
2.3 KiB
Go
Raw Normal View History

2022-01-01 21:47:59 +08:00
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
package stats
import (
"github.com/TeaOSLab/EdgeNode/internal/utils"
"github.com/mssola/user_agent"
2022-01-06 17:05:04 +08:00
"sync"
2022-01-01 21:47:59 +08:00
)
2022-01-06 17:05:04 +08:00
var SharedUserAgentParser = NewUserAgentParser()
2022-01-01 21:47:59 +08:00
// UserAgentParser UserAgent解析器
type UserAgentParser struct {
parser *user_agent.UserAgent
cacheMap1 map[string]UserAgentParserResult
cacheMap2 map[string]UserAgentParserResult
maxCacheItems int
cacheCursor int
2022-01-06 17:05:04 +08:00
locker sync.RWMutex
2022-01-01 21:47:59 +08:00
}
func NewUserAgentParser() *UserAgentParser {
var parser = &UserAgentParser{
parser: &user_agent.UserAgent{},
cacheMap1: map[string]UserAgentParserResult{},
cacheMap2: map[string]UserAgentParserResult{},
cacheCursor: 0,
}
parser.init()
return parser
}
func (this *UserAgentParser) init() {
var maxCacheItems = 10_000
var systemMemory = utils.SystemMemoryGB()
if systemMemory >= 16 {
maxCacheItems = 40_000
} else if systemMemory >= 8 {
maxCacheItems = 30_000
} else if systemMemory >= 4 {
maxCacheItems = 20_000
}
this.maxCacheItems = maxCacheItems
}
func (this *UserAgentParser) Parse(userAgent string) (result UserAgentParserResult) {
// 限制长度
if len(userAgent) == 0 || len(userAgent) > 256 {
return
}
2022-01-06 17:05:04 +08:00
this.locker.RLock()
2022-01-01 21:47:59 +08:00
cacheResult, ok := this.cacheMap1[userAgent]
if ok {
2022-01-06 17:05:04 +08:00
this.locker.RUnlock()
2022-01-01 21:47:59 +08:00
return cacheResult
}
cacheResult, ok = this.cacheMap2[userAgent]
if ok {
2022-01-06 17:05:04 +08:00
this.locker.RUnlock()
2022-01-01 21:47:59 +08:00
return cacheResult
}
2022-01-06 17:05:04 +08:00
this.locker.RUnlock()
2022-01-01 21:47:59 +08:00
2022-01-06 17:05:04 +08:00
this.locker.Lock()
defer this.locker.Unlock()
2022-01-01 21:47:59 +08:00
this.parser.Parse(userAgent)
2022-01-06 17:05:04 +08:00
result.OS = this.parser.OSInfo()
result.BrowserName, result.BrowserVersion = this.parser.Browser()
result.IsMobile = this.parser.Mobile()
2022-01-01 21:47:59 +08:00
2022-11-13 10:32:12 +08:00
// 忽略特殊字符
if len(result.BrowserName) > 0 {
for _, r := range result.BrowserName {
if r == '$' || r == '"' || r == '\'' || r == '<' || r == '>' || r == ')' {
return
}
}
}
2022-01-01 21:47:59 +08:00
if this.cacheCursor == 0 {
this.cacheMap1[userAgent] = result
if len(this.cacheMap1) >= this.maxCacheItems {
this.cacheCursor = 1
this.cacheMap2 = map[string]UserAgentParserResult{}
}
} else {
this.cacheMap2[userAgent] = result
if len(this.cacheMap2) >= this.maxCacheItems {
this.cacheCursor = 0
this.cacheMap1 = map[string]UserAgentParserResult{}
}
}
return
}