HTTP Header:实现请求方法、域名、状态码等限制,实现内容替换功能

This commit is contained in:
刘祥超
2021-12-14 21:26:43 +08:00
parent 12985e1bd9
commit 9171242c37
6 changed files with 280 additions and 103 deletions

View File

@@ -2,27 +2,81 @@ package shared
import (
"github.com/TeaOSLab/EdgeCommon/pkg/configutils"
"regexp"
"strings"
)
// 头部信息定义
// HTTPHeaderReplaceValue 值替换定义
type HTTPHeaderReplaceValue struct {
Pattern string `yaml:"pattern" json:"pattern"`
Replacement string `yaml:"replacement" json:"replacement"`
IsCaseInsensitive bool `yaml:"isCaseInsensitive" json:"isCaseInsensitive"` // TODO
IsRegexp bool `yaml:"isRegexp" json:"isRegexp"` // TODO
patternReg *regexp.Regexp
}
func (this *HTTPHeaderReplaceValue) Init() error {
if this.IsRegexp {
var pattern = this.Pattern
if this.IsCaseInsensitive && !strings.HasPrefix(pattern, "(?i)") {
pattern = "(?i)" + pattern
}
reg, err := regexp.Compile(pattern)
if err != nil {
return err
}
// TODO 支持匹配名(${name})和反向引用${1}。。。
this.patternReg = reg
} else {
if this.IsCaseInsensitive {
var pattern = "(?i)" + regexp.QuoteMeta(this.Pattern)
reg, err := regexp.Compile(pattern)
if err != nil {
return err
}
this.patternReg = reg
}
}
return nil
}
func (this *HTTPHeaderReplaceValue) Replace(value string) string {
if this.patternReg != nil {
return this.patternReg.ReplaceAllString(value, this.Replacement)
} else {
return strings.ReplaceAll(value, this.Pattern, this.Replacement)
}
}
// HTTPHeaderConfig 头部信息定义
type HTTPHeaderConfig struct {
Id int64 `yaml:"id" json:"id"` // ID
IsOn bool `yaml:"isOn" json:"isOn"` // 是否开启
Name string `yaml:"name" json:"name"` // Name
Value string `yaml:"value" json:"value"` // Value
Status *HTTPStatusConfig `yaml:"status" json:"status"` // 支持的状态码 TODO
Id int64 `yaml:"id" json:"id"` // ID
IsOn bool `yaml:"isOn" json:"isOn"` // 是否开启
Name string `yaml:"name" json:"name"` // Name
Value string `yaml:"value" json:"value"` // Value
Status *HTTPStatusConfig `yaml:"status" json:"status"` // 支持的状态码
DisableRedirect bool `yaml:"disableRedirect" json:"disableRedirect"` // 在跳转时不调用
ShouldAppend bool `yaml:"shouldAppend" json:"shouldAppend"` // 是否为附加
ShouldReplace bool `yaml:"shouldReplace" json:"shouldReplace"` // 是否替换值
ReplaceValues []*HTTPHeaderReplaceValue `yaml:"replaceValues" json:"replaceValues"` // 替换值
Methods []string `yaml:"methods" json:"methods"` // 请求方法
Domains []string `yaml:"domains" json:"domains"` // 专属域名
hasVariables bool
}
// 获取新Header对象
// NewHeaderConfig 获取新Header对象
func NewHeaderConfig() *HTTPHeaderConfig {
return &HTTPHeaderConfig{
IsOn: true,
}
}
// 校验
// Init 校验
func (this *HTTPHeaderConfig) Init() error {
this.hasVariables = configutils.HasVariables(this.Value)
@@ -33,23 +87,19 @@ func (this *HTTPHeaderConfig) Init() error {
}
}
if this.ShouldReplace {
for _, v := range this.ReplaceValues {
err := v.Init()
if err != nil {
return err
}
}
}
return nil
}
// 判断是否匹配状态码
func (this *HTTPHeaderConfig) Match(statusCode int) bool {
if !this.IsOn {
return false
}
if this.Status == nil {
return false
}
return this.Status.Match(statusCode)
}
// 是否有变量
// HasVariables 是否有变量
func (this *HTTPHeaderConfig) HasVariables() bool {
return this.hasVariables
}

View File

@@ -9,41 +9,18 @@ type HTTPHeaderPolicy struct {
IsOn bool `yaml:"isOn" json:"isOn"` // 是否启用 TODO
Description string `yaml:"description" json:"description"` // 描述 TODO
AddHeaderRefs []*HTTPHeaderRef `yaml:"addHeaderRefs" json:"addHeaderRefs"`
AddHeaders []*HTTPHeaderConfig `yaml:"addHeaders" json:"addHeaders"`
AddTrailerRefs []*HTTPHeaderRef `yaml:"addTrailerRefs" json:"addTrailerRefs"`
AddTrailers []*HTTPHeaderConfig `yaml:"addTrailers" json:"addTrailers"` // TODO
SetHeaderRefs []*HTTPHeaderRef `yaml:"setHeaderRefs" json:"setHeaderRefs"`
SetHeaders []*HTTPHeaderConfig `yaml:"setHeaders" json:"setHeaders"`
ReplaceHeaderRefs []*HTTPHeaderRef `yaml:"replaceHeaderRefs" json:"replaceHeaderRefs"`
ReplaceHeaders []*HTTPHeaderConfig `yaml:"replaceHeaders" json:"replaceHeaders"` // 替换Header内容 TODO
DeleteHeaders []string `yaml:"deleteHeaders" json:"deleteHeaders"` // 删除的Header
SetHeaderRefs []*HTTPHeaderRef `yaml:"setHeaderRefs" json:"setHeaderRefs"`
SetHeaders []*HTTPHeaderConfig `yaml:"setHeaders" json:"setHeaders"`
DeleteHeaders []string `yaml:"deleteHeaders" json:"deleteHeaders"` // 删除的Header
Expires *HTTPExpireHeaderConfig `yaml:"expires" json:"expires"` // TODO
addHeaderNames []string
setHeaderNames []string
deleteHeaderMap map[string]bool // header => bool
}
// Init 校验
func (this *HTTPHeaderPolicy) Init() error {
this.addHeaderNames = []string{}
for _, h := range this.AddHeaders {
err := h.Init()
if err != nil {
return err
}
this.addHeaderNames = append(this.addHeaderNames, strings.ToUpper(h.Name))
}
for _, h := range this.AddTrailers {
err := h.Init()
if err != nil {
return err
}
}
this.setHeaderNames = []string{}
for _, h := range this.SetHeaders {
err := h.Init()
@@ -53,13 +30,6 @@ func (this *HTTPHeaderPolicy) Init() error {
this.setHeaderNames = append(this.setHeaderNames, strings.ToUpper(h.Name))
}
for _, h := range this.ReplaceHeaders {
err := h.Init()
if err != nil {
return err
}
}
// delete
this.deleteHeaderMap = map[string]bool{}
for _, header := range this.DeleteHeaders {
@@ -71,18 +41,13 @@ func (this *HTTPHeaderPolicy) Init() error {
// IsEmpty 判断是否为空
func (this *HTTPHeaderPolicy) IsEmpty() bool {
return len(this.AddHeaders) == 0 && len(this.AddTrailers) == 0 && len(this.SetHeaders) == 0 && len(this.ReplaceHeaders) == 0 && this.Expires == nil && len(this.DeleteHeaders) == 0
return len(this.SetHeaders) == 0 && this.Expires == nil && len(this.DeleteHeaders) == 0
}
// ContainsHeader 判断Add和Set中是否包含某个Header
func (this *HTTPHeaderPolicy) ContainsHeader(name string) bool {
name = strings.ToUpper(name)
for _, n := range this.addHeaderNames {
if n == name {
return true
}
}
for _, n := range this.setHeaderNames {
if n == name {
return true

View File

@@ -1,6 +1,6 @@
package shared
// 状态
// HTTPStatusConfig 状态
type HTTPStatusConfig struct {
Always bool `yaml:"always" json:"always"`
Codes []int `yaml:"codes" json:"codes"`