This commit is contained in:
Alex Yang
2025-11-23 19:35:02 +08:00
parent d870f6bfcc
commit 5a1d44c3b3
10 changed files with 4783 additions and 17 deletions

View File

@@ -141,15 +141,65 @@ func (m *ShieldManager) loadRemoteRules() error {
return nil
}
// getCacheFilePath 根据URL生成缓存文件路径
func (m *ShieldManager) getCacheFilePath(url string) string {
// 使用URL的哈希值作为文件名避免文件名冲突
hash := fmt.Sprintf("%x", url)
// 简单处理,移除特殊字符,确保文件名合法
hash = strings.ReplaceAll(hash, "/", "_")
hash = strings.ReplaceAll(hash, "\\", "_")
return filepath.Join(m.config.RemoteRulesCacheDir, hash+".rules")
}
// shouldUpdateCache 检查缓存是否需要更新
func (m *ShieldManager) shouldUpdateCache(cacheFile string) bool {
// 检查文件是否存在
if _, err := os.Stat(cacheFile); os.IsNotExist(err) {
return true
}
// 检查文件修改时间
fileInfo, err := os.Stat(cacheFile)
if err != nil {
return true
}
// 如果缓存文件超过更新间隔时间,则需要更新
return time.Since(fileInfo.ModTime()) > time.Duration(m.config.UpdateInterval)*time.Second
}
// fetchRemoteRules 从远程URL获取规则
func (m *ShieldManager) fetchRemoteRules(url string) error {
// 获取缓存文件路径
cacheFile := m.getCacheFilePath(url)
// 尝试从缓存加载
hasLoadedFromCache := false
if !m.shouldUpdateCache(cacheFile) {
if err := m.loadCachedRules(cacheFile); err == nil {
logger.Info("从缓存加载远程规则", "url", url)
hasLoadedFromCache = true
}
}
// 从远程获取规则
resp, err := http.Get(url)
if err != nil {
// 如果从远程获取失败但已经从缓存加载成功则返回nil
if hasLoadedFromCache {
logger.Warn("远程规则更新失败,使用缓存版本", "url", url, "error", err)
return nil
}
return err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
// 如果状态码不正确但已经从缓存加载成功则返回nil
if hasLoadedFromCache {
logger.Warn("远程规则更新失败,使用缓存版本", "url", url, "statusCode", resp.StatusCode)
return nil
}
return fmt.Errorf("远程服务器返回错误状态码: %d", resp.StatusCode)
}
@@ -158,6 +208,38 @@ func (m *ShieldManager) fetchRemoteRules(url string) error {
return err
}
// 保存规则到缓存
if err := m.saveRemoteRulesToCache(cacheFile, body); err != nil {
logger.Warn("保存远程规则缓存失败", "url", url, "error", err)
// 继续处理,不返回错误
}
// 解析并加载规则
lines := strings.Split(string(body), "\n")
for _, line := range lines {
line = strings.TrimSpace(line)
if line == "" || strings.HasPrefix(line, "#") {
continue
}
m.parseRule(line)
}
return nil
}
// loadCachedRules 从缓存文件加载规则
func (m *ShieldManager) loadCachedRules(filePath string) error {
file, err := os.Open(filePath)
if err != nil {
return err
}
defer file.Close()
body, err := ioutil.ReadAll(file)
if err != nil {
return err
}
lines := strings.Split(string(body), "\n")
for _, line := range lines {
line = strings.TrimSpace(line)
@@ -170,6 +252,17 @@ func (m *ShieldManager) fetchRemoteRules(url string) error {
return nil
}
// saveRemoteRulesToCache 保存远程规则到缓存文件
func (m *ShieldManager) saveRemoteRulesToCache(filePath string, data []byte) error {
// 确保缓存目录存在
if err := os.MkdirAll(m.config.RemoteRulesCacheDir, 0755); err != nil {
return err
}
// 写入文件
return ioutil.WriteFile(filePath, data, 0644)
}
// loadHosts 加载hosts文件
func (m *ShieldManager) loadHosts() error {
if m.config.HostsFile == "" {