2020-09-20 16:27:59 +08:00
|
|
|
|
package serverconfigs
|
|
|
|
|
|
|
2020-10-04 20:38:03 +08:00
|
|
|
|
import (
|
|
|
|
|
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
|
|
|
|
|
|
"github.com/iwind/TeaGo/lists"
|
2021-12-07 10:43:34 +08:00
|
|
|
|
"net/http"
|
2020-10-04 20:38:03 +08:00
|
|
|
|
"strings"
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
var DefaultSkippedResponseCacheControlValues = []string{"private", "no-cache", "no-store"}
|
|
|
|
|
|
|
2020-09-20 16:27:59 +08:00
|
|
|
|
type HTTPCacheRef struct {
|
2020-10-04 20:38:03 +08:00
|
|
|
|
IsOn bool `yaml:"isOn" json:"isOn"`
|
|
|
|
|
|
CachePolicyId int64 `yaml:"cachePolicyId" json:"cachePolicyId"`
|
|
|
|
|
|
|
2021-12-08 17:40:27 +08:00
|
|
|
|
Key string `yaml:"key" json:"key"` // 每个缓存的Key规则,里面可以有变量
|
|
|
|
|
|
Life *shared.TimeDuration `yaml:"life" json:"life"` // 时间
|
|
|
|
|
|
ExpiresTime *HTTPExpiresTimeConfig `yaml:"expiresTime" json:"expiresTime"` // 客户端过期时间
|
|
|
|
|
|
Status []int `yaml:"status" json:"status"` // 缓存的状态码列表
|
|
|
|
|
|
MinSize *shared.SizeCapacity `yaml:"minSize" json:"minSize"` // 能够缓存的最小尺寸
|
|
|
|
|
|
MaxSize *shared.SizeCapacity `yaml:"maxSize" json:"maxSize"` // 能够缓存的最大尺寸
|
|
|
|
|
|
Methods []string `yaml:"methods" json:"methods"` // 支持的请求方法
|
2020-10-04 20:38:03 +08:00
|
|
|
|
|
|
|
|
|
|
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
|
2021-04-18 22:16:56 +08:00
|
|
|
|
AllowChunkedEncoding bool `yaml:"allowChunkedEncoding" json:"allowChunkedEncoding"` // 是否允许分片内容
|
2022-03-03 19:36:58 +08:00
|
|
|
|
AllowPartialContent bool `yaml:"allowPartialContent" json:"allowPartialContent"` // 支持分段内容缓存
|
2023-06-15 15:14:25 +08:00
|
|
|
|
ForcePartialContent bool `yaml:"forcePartialContent" json:"forcePartialContent"` // 强制分段内容优先
|
2022-08-07 16:37:03 +08:00
|
|
|
|
EnableIfNoneMatch bool `yaml:"enableIfNoneMatch" json:"enableIfNoneMatch"`
|
|
|
|
|
|
EnableIfModifiedSince bool `yaml:"enableIfModifiedSince" json:"enableIfModifiedSince"`
|
2020-10-04 20:38:03 +08:00
|
|
|
|
|
2022-09-03 18:15:56 +08:00
|
|
|
|
Conds *shared.HTTPRequestCondsConfig `yaml:"conds" json:"conds"` // 复杂请求条件组合
|
|
|
|
|
|
SimpleCond *shared.HTTPRequestCond `yaml:"simpleCond" json:"simpleCond"` // 简单条件
|
2020-10-04 20:38:03 +08:00
|
|
|
|
|
|
|
|
|
|
CachePolicy *HTTPCachePolicy `yaml:"cachePolicy" json:"cachePolicy"`
|
|
|
|
|
|
|
2021-06-09 17:15:12 +08:00
|
|
|
|
IsReverse bool `yaml:"isReverse" json:"isReverse"` // 是否为反向条件,反向条件的不缓存
|
|
|
|
|
|
|
2020-10-05 16:54:21 +08:00
|
|
|
|
lifeSeconds int64
|
2021-09-26 15:02:03 +08:00
|
|
|
|
minSize int64
|
2020-10-04 20:38:03 +08:00
|
|
|
|
maxSize int64
|
|
|
|
|
|
uppercaseSkipCacheControlValues []string
|
2021-12-07 10:43:34 +08:00
|
|
|
|
|
2022-03-04 17:00:37 +08:00
|
|
|
|
methodMap map[string]bool
|
|
|
|
|
|
statusList []int
|
2020-09-20 16:27:59 +08:00
|
|
|
|
}
|
2020-09-26 08:07:24 +08:00
|
|
|
|
|
|
|
|
|
|
func (this *HTTPCacheRef) Init() error {
|
2021-09-26 15:02:03 +08:00
|
|
|
|
if this.MinSize != nil {
|
|
|
|
|
|
this.minSize = this.MinSize.Bytes()
|
|
|
|
|
|
}
|
2020-10-04 20:38:03 +08:00
|
|
|
|
if this.MaxSize != nil {
|
|
|
|
|
|
this.maxSize = this.MaxSize.Bytes()
|
|
|
|
|
|
}
|
|
|
|
|
|
if this.Life != nil {
|
2020-10-05 16:54:21 +08:00
|
|
|
|
this.lifeSeconds = int64(this.Life.Duration().Seconds())
|
2020-10-04 20:38:03 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// control-values
|
|
|
|
|
|
this.uppercaseSkipCacheControlValues = []string{}
|
|
|
|
|
|
for _, value := range this.SkipResponseCacheControlValues {
|
|
|
|
|
|
this.uppercaseSkipCacheControlValues = append(this.uppercaseSkipCacheControlValues, strings.ToUpper(value))
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// conds
|
|
|
|
|
|
if this.Conds != nil {
|
|
|
|
|
|
err := this.Conds.Init()
|
2020-10-02 17:22:46 +08:00
|
|
|
|
if err != nil {
|
|
|
|
|
|
return err
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2020-10-04 20:38:03 +08:00
|
|
|
|
|
2022-09-03 18:15:56 +08:00
|
|
|
|
if this.SimpleCond != nil {
|
|
|
|
|
|
err := this.SimpleCond.Init()
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return err
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-10-04 20:38:03 +08:00
|
|
|
|
// policy
|
|
|
|
|
|
if this.CachePolicy != nil {
|
|
|
|
|
|
err := this.CachePolicy.Init()
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return err
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2021-12-07 10:43:34 +08:00
|
|
|
|
// methods
|
|
|
|
|
|
this.methodMap = map[string]bool{}
|
|
|
|
|
|
if len(this.Methods) > 0 {
|
|
|
|
|
|
for _, method := range this.Methods {
|
|
|
|
|
|
this.methodMap[strings.ToUpper(method)] = true
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-03-04 17:00:37 +08:00
|
|
|
|
// status
|
|
|
|
|
|
this.statusList = this.Status
|
|
|
|
|
|
if this.AllowPartialContent {
|
|
|
|
|
|
if !lists.ContainsInt(this.statusList, http.StatusPartialContent) {
|
|
|
|
|
|
this.statusList = append(this.statusList, http.StatusPartialContent)
|
|
|
|
|
|
}
|
|
|
|
|
|
} else if lists.ContainsInt(this.statusList, http.StatusPartialContent) {
|
|
|
|
|
|
this.AllowPartialContent = true
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-09-26 08:07:24 +08:00
|
|
|
|
return nil
|
|
|
|
|
|
}
|
2020-10-04 20:38:03 +08:00
|
|
|
|
|
2021-09-26 15:02:03 +08:00
|
|
|
|
// MaxSizeBytes 最大数据尺寸
|
2020-10-05 16:54:21 +08:00
|
|
|
|
func (this *HTTPCacheRef) MaxSizeBytes() int64 {
|
2020-10-04 20:38:03 +08:00
|
|
|
|
return this.maxSize
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2021-09-26 15:02:03 +08:00
|
|
|
|
// MinSizeBytes 最小数据尺寸
|
|
|
|
|
|
func (this *HTTPCacheRef) MinSizeBytes() int64 {
|
|
|
|
|
|
return this.minSize
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// LifeSeconds 生命周期
|
2020-10-05 16:54:21 +08:00
|
|
|
|
func (this *HTTPCacheRef) LifeSeconds() int64 {
|
|
|
|
|
|
return this.lifeSeconds
|
2020-10-04 20:38:03 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2021-09-26 15:02:03 +08:00
|
|
|
|
// ContainsCacheControl 是否包含某个Cache-Control值
|
2020-10-04 20:38:03 +08:00
|
|
|
|
func (this *HTTPCacheRef) ContainsCacheControl(value string) bool {
|
|
|
|
|
|
return lists.ContainsString(this.uppercaseSkipCacheControlValues, strings.ToUpper(value))
|
|
|
|
|
|
}
|
2021-12-07 10:43:34 +08:00
|
|
|
|
|
|
|
|
|
|
// MatchRequest 匹配请求
|
|
|
|
|
|
func (this *HTTPCacheRef) MatchRequest(req *http.Request) bool {
|
|
|
|
|
|
// 请求方法
|
|
|
|
|
|
if len(this.methodMap) > 0 {
|
|
|
|
|
|
_, ok := this.methodMap[req.Method]
|
|
|
|
|
|
if !ok {
|
|
|
|
|
|
return false
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return true
|
|
|
|
|
|
}
|
2022-03-04 17:00:37 +08:00
|
|
|
|
|
|
|
|
|
|
// MatchStatus 检查是否包含某个状态码
|
|
|
|
|
|
func (this *HTTPCacheRef) MatchStatus(statusCode int) bool {
|
|
|
|
|
|
if len(this.statusList) == 0 {
|
|
|
|
|
|
return true
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for _, status := range this.statusList {
|
|
|
|
|
|
if status == statusCode {
|
|
|
|
|
|
return true
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return false
|
|
|
|
|
|
}
|