Files
EdgeCommon/pkg/serverconfigs/http_location_config.go

212 lines
5.8 KiB
Go
Raw Normal View History

2020-09-21 11:37:09 +08:00
package serverconfigs
2020-09-22 11:36:40 +08:00
import (
"regexp"
"strings"
)
2020-09-21 11:37:09 +08:00
type HTTPLocationConfig struct {
2020-09-21 19:52:10 +08:00
Id int64 `yaml:"id" json:"id"` // ID
IsOn bool `yaml:"isOn" json:"isOn"` // 是否启用
Pattern string `yaml:"pattern" json:"pattern"` // 匹配规则 TODO 未来支持更多样的匹配规则
Name string `yaml:"name" json:"name"` // 名称
Web *HTTPWebConfig `yaml:"web" json:"web"` // Web配置
URLPrefix string `yaml:"urlPrefix" json:"urlPrefix"` // 实际的URL前缀TODO 未来支持变量
Description string `yaml:"description" json:"description"` // 描述
ReverseProxyRef *ReverseProxyRef `yaml:"reverseProxyRef" json:"reverseProxyRef"` // 反向代理引用
ReverseProxy *ReverseProxyConfig `yaml:"reverseProxy" json:"reverseProxy"` // 反向代理设置
IsBreak bool `yaml:"isBreak" json:"isBreak"` // 终止向下解析
Children []*HTTPLocationConfig `yaml:"children" json:"children"` // 子规则
2020-09-22 11:36:40 +08:00
patternType HTTPLocationPatternType // 规则类型LocationPattern*
prefix string // 前缀
path string // 精确的路径
reg *regexp.Regexp // 匹配规则
caseInsensitive bool // 大小写不敏感
reverse bool // 是否翻转规则,比如非前缀,非路径
2020-09-21 11:37:09 +08:00
}
func (this *HTTPLocationConfig) Init() error {
2020-09-22 11:36:40 +08:00
err := this.parsePattern()
if err != nil {
return err
}
2020-09-21 11:37:09 +08:00
if this.Web != nil {
err := this.Web.Init()
if err != nil {
return err
}
}
if this.ReverseProxy != nil {
err := this.Web.Init()
if err != nil {
return err
}
}
2020-09-22 11:36:40 +08:00
// Children
for _, child := range this.Children {
err := child.Init()
if err != nil {
return err
}
}
2020-09-21 11:37:09 +08:00
return nil
}
2020-09-21 19:52:10 +08:00
// 组合参数为一个字符串
func (this *HTTPLocationConfig) SetPattern(pattern string, patternType int, caseInsensitive bool, reverse bool) {
op := ""
if patternType == HTTPLocationPatternTypePrefix {
if caseInsensitive {
op = "*"
if reverse {
op = "!*"
}
} else {
if reverse {
op = "!"
}
}
} else if patternType == HTTPLocationPatternTypeExact {
op = "="
if caseInsensitive {
op += "*"
}
if reverse {
op = "!" + op
}
} else if patternType == HTTPLocationPatternTypeRegexp {
op = "~"
if caseInsensitive {
op += "*"
}
if reverse {
op = "!" + op
}
}
if len(op) > 0 {
pattern = op + " " + pattern
}
this.Pattern = pattern
}
2020-09-22 11:36:40 +08:00
// 模式类型
func (this *HTTPLocationConfig) PatternType() int {
return this.patternType
}
// 模式字符串
// 去掉了模式字符
func (this *HTTPLocationConfig) PatternString() string {
if this.patternType == HTTPLocationPatternTypePrefix {
return this.prefix
}
return this.path
}
// 是否翻转
func (this *HTTPLocationConfig) IsReverse() bool {
return this.reverse
}
// 是否大小写非敏感
func (this *HTTPLocationConfig) IsCaseInsensitive() bool {
return this.caseInsensitive
}
// 分析匹配条件
func (this *HTTPLocationConfig) parsePattern() error {
// 分析pattern
this.reverse = false
this.caseInsensitive = false
if len(this.Pattern) > 0 {
spaceIndex := strings.Index(this.Pattern, " ")
if spaceIndex < 0 {
this.patternType = HTTPLocationPatternTypePrefix
this.prefix = this.Pattern
} else {
cmd := this.Pattern[:spaceIndex]
pattern := strings.TrimSpace(this.Pattern[spaceIndex+1:])
if cmd == "*" { // 大小写非敏感
this.patternType = HTTPLocationPatternTypePrefix
this.prefix = pattern
this.caseInsensitive = true
} else if cmd == "!*" { // 大小写非敏感,翻转
this.patternType = HTTPLocationPatternTypePrefix
this.prefix = pattern
this.caseInsensitive = true
this.reverse = true
} else if cmd == "!" {
this.patternType = HTTPLocationPatternTypePrefix
this.prefix = pattern
this.reverse = true
} else if cmd == "=" {
this.patternType = HTTPLocationPatternTypeExact
this.path = pattern
} else if cmd == "=*" {
this.patternType = HTTPLocationPatternTypeExact
this.path = pattern
this.caseInsensitive = true
} else if cmd == "!=" {
this.patternType = HTTPLocationPatternTypeExact
this.path = pattern
this.reverse = true
} else if cmd == "!=*" {
this.patternType = HTTPLocationPatternTypeExact
this.path = pattern
this.reverse = true
this.caseInsensitive = true
} else if cmd == "~" { // 正则
this.patternType = HTTPLocationPatternTypeRegexp
reg, err := regexp.Compile(pattern)
if err != nil {
return err
}
this.reg = reg
this.path = pattern
} else if cmd == "!~" {
this.patternType = HTTPLocationPatternTypeRegexp
reg, err := regexp.Compile(pattern)
if err != nil {
return err
}
this.reg = reg
this.reverse = true
this.path = pattern
} else if cmd == "~*" { // 大小写非敏感小写
this.patternType = HTTPLocationPatternTypeRegexp
reg, err := regexp.Compile("(?i)" + pattern)
if err != nil {
return err
}
this.reg = reg
this.caseInsensitive = true
this.path = pattern
} else if cmd == "!~*" {
this.patternType = HTTPLocationPatternTypeRegexp
reg, err := regexp.Compile("(?i)" + pattern)
if err != nil {
return err
}
this.reg = reg
this.reverse = true
this.caseInsensitive = true
this.path = pattern
} else {
this.patternType = HTTPLocationPatternTypePrefix
this.prefix = pattern
}
}
} else {
this.patternType = HTTPLocationPatternTypePrefix
this.prefix = this.Pattern
}
return nil
}