Files
EdgeCommon/pkg/serverconfigs/cache_policy.go

156 lines
4.2 KiB
Go
Raw Normal View History

2020-09-13 19:27:47 +08:00
package serverconfigs
import (
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/configutils"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
"github.com/iwind/TeaGo/Tea"
"github.com/iwind/TeaGo/files"
"github.com/iwind/TeaGo/lists"
"github.com/iwind/TeaGo/logs"
"strconv"
"strings"
"time"
)
var DefaultSkippedResponseCacheControlValues = []string{"private", "no-cache", "no-store"}
// 缓存策略配置
type CachePolicy struct {
Id int `yaml:"id" json:"id"`
IsOn bool `yaml:"isOn" json:"isOn"` // 是否开启 TODO
Name string `yaml:"name" json:"name"` // 名称
Key string `yaml:"key" json:"key"` // 每个缓存的Key规则里面可以有变量
Capacity shared.SizeCapacity `yaml:"capacity" json:"capacity"` // 最大内容容量
Life shared.TimeDuration `yaml:"life" json:"life"` // 时间
Status []int `yaml:"status" json:"status"` // 缓存的状态码列表
MaxSize shared.SizeCapacity `yaml:"maxSize" json:"maxSize"` // 能够请求的最大尺寸
SkipResponseCacheControlValues []string `yaml:"skipCacheControlValues" json:"skipCacheControlValues"` // 可以跳过的响应的Cache-Control值
SkipResponseSetCookie bool `yaml:"skipSetCookie" json:"skipSetCookie"` // 是否跳过响应的Set-Cookie Header
EnableRequestCachePragma bool `yaml:"enableRequestCachePragma" json:"enableRequestCachePragma"` // 是否支持客户端的Pragma: no-cache
Cond []*shared.RequestCond `yaml:"cond" json:"cond"`
life time.Duration
maxSize int64
capacity int64
uppercaseSkipCacheControlValues []string
Type string `yaml:"type" json:"type"` // 类型
Options map[string]interface{} `yaml:"options" json:"options"` // 选项
}
// 获取新对象
func NewCachePolicy() *CachePolicy {
return &CachePolicy{
SkipResponseCacheControlValues: DefaultSkippedResponseCacheControlValues,
SkipResponseSetCookie: true,
}
}
// 从文件中读取缓存策略
func NewCachePolicyFromFile(file string) *CachePolicy {
if len(file) == 0 {
return nil
}
reader, err := files.NewReader(Tea.ConfigFile(file))
if err != nil {
logs.Error(err)
return nil
}
defer func() {
_ = reader.Close()
}()
p := NewCachePolicy()
err = reader.ReadYAML(p)
if err != nil {
logs.Error(err)
return nil
}
return p
}
// 校验
func (this *CachePolicy) Validate() error {
var err error
this.maxSize = this.MaxSize.Bytes()
this.life = this.Life.Duration()
this.capacity = this.Capacity.Bytes()
this.uppercaseSkipCacheControlValues = []string{}
for _, value := range this.SkipResponseCacheControlValues {
this.uppercaseSkipCacheControlValues = append(this.uppercaseSkipCacheControlValues, strings.ToUpper(value))
}
// cond
if len(this.Cond) > 0 {
for _, cond := range this.Cond {
err := cond.Validate()
if err != nil {
return err
}
}
}
return err
}
// 最大数据尺寸
func (this *CachePolicy) MaxDataSize() int64 {
return this.maxSize
}
// 容量
func (this *CachePolicy) CapacitySize() int64 {
return this.capacity
}
// 生命周期
func (this *CachePolicy) LifeDuration() time.Duration {
return this.life
}
// 保存
func (this *CachePolicy) Save() error {
shared.Locker.Lock()
defer shared.Locker.Unlock()
filename := "cache.policy." + strconv.Itoa(this.Id) + ".conf"
writer, err := files.NewWriter(Tea.ConfigFile(filename))
if err != nil {
return err
}
defer func() {
_ = writer.Close()
}()
_, err = writer.WriteYAML(this)
return err
}
// 删除
func (this *CachePolicy) Delete() error {
filename := "cache.policy." + strconv.Itoa(this.Id) + ".conf"
return files.NewFile(Tea.ConfigFile(filename)).Delete()
}
// 是否包含某个Cache-Control值
func (this *CachePolicy) ContainsCacheControl(value string) bool {
return lists.ContainsString(this.uppercaseSkipCacheControlValues, strings.ToUpper(value))
}
// 检查是否匹配关键词
func (this *CachePolicy) MatchKeyword(keyword string) (matched bool, name string, tags []string) {
if configutils.MatchKeyword(this.Name, keyword) || configutils.MatchKeyword(this.Type, keyword) {
matched = true
name = this.Name
if len(this.Type) > 0 {
tags = []string{"类型:" + this.Type}
}
}
return
}