From b795f606724513dae05db9c497d2b7741bd7dfcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E7=A5=A5=E8=B6=85?= Date: Wed, 26 Oct 2022 16:07:32 +0800 Subject: [PATCH] =?UTF-8?q?URL=E8=B7=B3=E8=BD=AC=E4=B8=AD=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E5=9F=9F=E5=90=8D=E8=B7=B3=E8=BD=AC=E3=80=81=E7=AB=AF?= =?UTF-8?q?=E5=8F=A3=E8=B7=B3=E8=BD=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../http_host_redirect_config.go | 99 +++++++++++++++---- 1 file changed, 82 insertions(+), 17 deletions(-) diff --git a/pkg/serverconfigs/http_host_redirect_config.go b/pkg/serverconfigs/http_host_redirect_config.go index a6fa8b5..c375d23 100644 --- a/pkg/serverconfigs/http_host_redirect_config.go +++ b/pkg/serverconfigs/http_host_redirect_config.go @@ -2,8 +2,18 @@ package serverconfigs import ( "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared" + "github.com/iwind/TeaGo/types" "net/url" "regexp" + "strings" +) + +type HTTPHostRedirectType = string + +const ( + HTTPHostRedirectTypeURL HTTPHostRedirectType = "url" + HTTPHostRedirectTypeDomain HTTPHostRedirectType = "domain" + HTTPHostRedirectTypePort HTTPHostRedirectType = "port" ) // HTTPHostRedirectConfig 主机名跳转设置 @@ -11,39 +21,84 @@ type HTTPHostRedirectConfig struct { IsOn bool `yaml:"isOn" json:"isOn"` // 是否开启 Status int `yaml:"status" json:"status"` // 跳转用的状态码 - Mode string `yaml:"mode" json:"mode"` // 模式 + Type string `yaml:"type" json:"type"` // 类型 + Mode HTTPHostRedirectType `yaml:"mode" json:"mode"` // 模式 + // URL跳转 BeforeURL string `yaml:"beforeURL" json:"beforeURL"` // 跳转前的地址 AfterURL string `yaml:"afterURL" json:"afterURL"` // 跳转后的地址 - MatchPrefix bool `yaml:"matchPrefix" json:"matchPrefix"` // 只匹配前缀部分 - MatchRegexp bool `yaml:"matchRegexp" json:"matchRegexp"` // 匹配正则表达式 + MatchPrefix bool `yaml:"matchPrefix" json:"matchPrefix"` // 只匹配前缀部分 + MatchRegexp bool `yaml:"matchRegexp" json:"matchRegexp"` // 匹配正则表达式 + KeepRequestURI bool `yaml:"keepRequestURI" json:"keepRequestURI"` // 保留请求URI KeepArgs bool `yaml:"keepArgs" json:"keepArgs"` // 保留参数 Conds *shared.HTTPRequestCondsConfig `yaml:"conds" json:"conds"` // 匹配条件 realBeforeURL string beforeURLRegexp *regexp.Regexp + + // 域名跳转 + DomainsAll bool `yaml:"domainAll" json:"domainsAll"` // 所有域名都跳转 + DomainsBefore []string `yaml:"domainsBefore" json:"domainsBefore"` // 指定跳转之前的域名 + DomainAfter string `yaml:"domainAfter" json:"domainAfter"` // 跳转之后的域名 + DomainAfterScheme string `yaml:"domainAfterScheme" json:"domainAfterScheme"` // 跳转之后的协议 + //DomainRegexp bool `yaml:"domainRegexp" json:"domainRegexp"` // 使用正则匹配域名 TODO 暂时不实现 + //DomainKeepPort bool `yaml:"domainKeepPort" json:"domainKeepPort"` // 是否保持端口 TODO 暂时不实现 + //DomainNewPort int `yaml:"domainNewPort" json:"domainNewPort"` // 是否使用新端口 TODO 暂时不实现 + + // 端口跳转 + PortsAll bool `yaml:"portsAll" json:"portsAll"` // 所有端口 + PortsBefore []string `yaml:"portsBefore" json:"portsBefore"` // 跳转之前的端口:8080, 8080-8090 + PortAfter int `yaml:"port" json:"portAfter"` // 跳转之后的端口 + PortAfterScheme string `yaml:"portAfterScheme" json:"portAfterScheme"` // 跳转之后的协议 + + beforePortRanges [][2]int // [[from, to], {from2, to2}, ...] } // Init 初始化 func (this *HTTPHostRedirectConfig) Init() error { - if !this.MatchRegexp { - u, err := url.Parse(this.BeforeURL) - if err != nil { - return err + if len(this.Type) == 0 { + this.Type = HTTPHostRedirectTypeURL + } + + if this.Type == HTTPHostRedirectTypeURL { + if !this.MatchRegexp { + u, err := url.Parse(this.BeforeURL) + if err != nil { + return err + } + if len(u.Path) == 0 { + this.realBeforeURL = this.BeforeURL + "/" + } else { + this.realBeforeURL = this.BeforeURL + } + } else if this.MatchRegexp { + reg, err := regexp.Compile(this.BeforeURL) + if err != nil { + return err + } + this.beforeURLRegexp = reg } - if len(u.Path) == 0 { - this.realBeforeURL = this.BeforeURL + "/" - } else { - this.realBeforeURL = this.BeforeURL + } else if this.Type == HTTPHostRedirectTypePort { + this.beforePortRanges = [][2]int{} + var portReg = regexp.MustCompile(`^\d+$`) + var portRangeReg = regexp.MustCompile(`^\d+-\d+$`) + for _, port := range this.PortsBefore { + if portReg.MatchString(port) { + this.beforePortRanges = append(this.beforePortRanges, [2]int{types.Int(port), types.Int(port)}) + } else if portRangeReg.MatchString(port) { + var pieces = strings.Split(port, "-") + if len(pieces) == 2 { + var portFrom = types.Int(pieces[0]) + var portTo = types.Int(pieces[1]) + if portFrom > portTo { + portFrom, portTo = portTo, portFrom + } + this.beforePortRanges = append(this.beforePortRanges, [2]int{portFrom, portTo}) + } + } } - } else if this.MatchRegexp { - reg, err := regexp.Compile(this.BeforeURL) - if err != nil { - return err - } - this.beforeURLRegexp = reg } if this.Conds != nil { @@ -73,3 +128,13 @@ func (this *HTTPHostRedirectConfig) MatchRequest(formatter func(source string) s } return this.Conds.MatchRequest(formatter) } + +// ContainsPort 是否包含端口 +func (this *HTTPHostRedirectConfig) ContainsPort(reqPort int) bool { + for _, port := range this.beforePortRanges { + if port[0] <= reqPort && port[1] >= reqPort { + return true + } + } + return false +}