beta1
This commit is contained in:
@@ -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 == "" {
|
||||
|
||||
Reference in New Issue
Block a user