2020-09-13 19:27:47 +08:00
|
|
|
|
package serverconfigs
|
|
|
|
|
|
|
|
|
|
|
|
import (
|
2020-09-27 10:03:24 +08:00
|
|
|
|
"github.com/TeaOSLab/EdgeCommon/pkg/configutils"
|
2020-09-15 14:44:38 +08:00
|
|
|
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/schedulingconfigs"
|
2020-09-13 19:27:47 +08:00
|
|
|
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
|
2021-01-26 20:28:46 +08:00
|
|
|
|
"github.com/iwind/TeaGo/lists"
|
2020-09-13 19:27:47 +08:00
|
|
|
|
"sync"
|
|
|
|
|
|
)
|
|
|
|
|
|
|
2020-11-30 22:28:08 +08:00
|
|
|
|
type RequestHostType = int8
|
|
|
|
|
|
|
|
|
|
|
|
const (
|
|
|
|
|
|
RequestHostTypeProxyServer RequestHostType = 0
|
|
|
|
|
|
RequestHostTypeOrigin RequestHostType = 1
|
|
|
|
|
|
RequestHostTypeCustomized RequestHostType = 2
|
|
|
|
|
|
)
|
|
|
|
|
|
|
2020-09-13 19:27:47 +08:00
|
|
|
|
// 反向代理设置
|
|
|
|
|
|
type ReverseProxyConfig struct {
|
2020-09-21 20:21:20 +08:00
|
|
|
|
Id int64 `yaml:"id" json:"id"` // ID
|
|
|
|
|
|
IsOn bool `yaml:"isOn" json:"isOn"` // 是否启用
|
|
|
|
|
|
PrimaryOrigins []*OriginConfig `yaml:"primaryOrigins" json:"primaryOrigins"` // 主要源站列表
|
|
|
|
|
|
PrimaryOriginRefs []*OriginRef `yaml:"primaryOriginRefs" json:"primaryOriginRefs"` // 主要源站引用
|
|
|
|
|
|
BackupOrigins []*OriginConfig `yaml:"backupOrigins" json:"backupOrigins"` // 备用源站列表
|
|
|
|
|
|
BackupOriginRefs []*OriginRef `yaml:"backupOriginRefs" json:"backupOriginRefs"` // 备用源站引用
|
|
|
|
|
|
Scheduling *SchedulingConfig `yaml:"scheduling" json:"scheduling"` // 调度算法选项
|
2020-09-13 19:27:47 +08:00
|
|
|
|
|
2020-11-30 22:28:08 +08:00
|
|
|
|
StripPrefix string `yaml:"stripPrefix" json:"stripPrefix"` // 去除URL前缀
|
|
|
|
|
|
RequestHostType RequestHostType `yaml:"requestHostType" json:"requestHostType"` // 请求Host类型
|
|
|
|
|
|
RequestHost string `yaml:"requestHost" json:"requestHost"` // 请求Host,支持变量
|
|
|
|
|
|
RequestURI string `yaml:"requestURI" json:"requestURI"` // 请求URI,支持变量,如果同时定义了StripPrefix,则先执行StripPrefix
|
2020-09-27 10:03:24 +08:00
|
|
|
|
|
2021-01-26 20:28:46 +08:00
|
|
|
|
AddHeaders []string `yaml:"addHeaders" json:"addHeaders"` // 自动添加的Header
|
|
|
|
|
|
|
2020-09-27 18:41:21 +08:00
|
|
|
|
AutoFlush bool `yaml:"autoFlush" json:"autoFlush"` // 是否自动刷新缓冲区,在比如SSE(server-sent events)场景下很有用
|
|
|
|
|
|
|
2020-09-27 10:03:24 +08:00
|
|
|
|
requestHostHasVariables bool
|
|
|
|
|
|
requestURIHasVariables bool
|
2020-09-26 19:54:20 +08:00
|
|
|
|
|
2020-09-15 14:44:38 +08:00
|
|
|
|
hasPrimaryOrigins bool
|
|
|
|
|
|
hasBackupOrigins bool
|
2020-09-13 19:27:47 +08:00
|
|
|
|
schedulingIsBackup bool
|
2020-09-15 14:44:38 +08:00
|
|
|
|
schedulingObject schedulingconfigs.SchedulingInterface
|
2020-09-13 19:27:47 +08:00
|
|
|
|
schedulingLocker sync.Mutex
|
2021-01-26 20:28:46 +08:00
|
|
|
|
|
|
|
|
|
|
addXRealIPHeader bool
|
|
|
|
|
|
addXForwardedForHeader bool
|
|
|
|
|
|
addForwardedHeader bool
|
|
|
|
|
|
addXForwardedByHeader bool
|
|
|
|
|
|
addXForwardedHostHeader bool
|
|
|
|
|
|
addXForwardedProtoHeader bool
|
2020-09-13 19:27:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 初始化
|
|
|
|
|
|
func (this *ReverseProxyConfig) Init() error {
|
2020-09-27 10:03:24 +08:00
|
|
|
|
this.requestHostHasVariables = configutils.HasVariables(this.RequestHost)
|
|
|
|
|
|
this.requestURIHasVariables = configutils.HasVariables(this.RequestURI)
|
|
|
|
|
|
|
2020-09-15 14:44:38 +08:00
|
|
|
|
this.hasPrimaryOrigins = len(this.PrimaryOrigins) > 0
|
|
|
|
|
|
this.hasBackupOrigins = len(this.BackupOrigins) > 0
|
2020-09-13 19:27:47 +08:00
|
|
|
|
|
2020-09-15 14:44:38 +08:00
|
|
|
|
for _, origin := range this.PrimaryOrigins {
|
|
|
|
|
|
err := origin.Init()
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return err
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for _, origin := range this.BackupOrigins {
|
2020-09-13 19:27:47 +08:00
|
|
|
|
err := origin.Init()
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return err
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// scheduling
|
|
|
|
|
|
this.SetupScheduling(false)
|
|
|
|
|
|
|
2021-01-26 20:28:46 +08:00
|
|
|
|
// Header
|
2021-02-07 09:07:50 +08:00
|
|
|
|
if len(this.AddHeaders) == 0 {
|
|
|
|
|
|
// 默认加入两项
|
|
|
|
|
|
this.addXRealIPHeader = true
|
|
|
|
|
|
this.addXForwardedForHeader = true
|
|
|
|
|
|
this.addXForwardedByHeader = true
|
|
|
|
|
|
this.addXForwardedHostHeader = true
|
|
|
|
|
|
this.addXForwardedProtoHeader = true
|
|
|
|
|
|
} else {
|
|
|
|
|
|
this.addXRealIPHeader = lists.ContainsString(this.AddHeaders, "X-Real-IP")
|
|
|
|
|
|
this.addXForwardedForHeader = lists.ContainsString(this.AddHeaders, "X-Forwarded-For")
|
|
|
|
|
|
this.addXForwardedByHeader = lists.ContainsString(this.AddHeaders, "X-Forwarded-By")
|
|
|
|
|
|
this.addXForwardedHostHeader = lists.ContainsString(this.AddHeaders, "X-Forwarded-Host")
|
|
|
|
|
|
this.addXForwardedProtoHeader = lists.ContainsString(this.AddHeaders, "X-Forwarded-Proto")
|
|
|
|
|
|
}
|
2021-01-26 20:28:46 +08:00
|
|
|
|
|
2020-09-13 19:27:47 +08:00
|
|
|
|
return nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-09-15 14:44:38 +08:00
|
|
|
|
// 添加主源站配置
|
2020-09-21 20:21:20 +08:00
|
|
|
|
func (this *ReverseProxyConfig) AddPrimaryOrigin(origin *OriginConfig) {
|
2020-09-15 14:44:38 +08:00
|
|
|
|
this.PrimaryOrigins = append(this.PrimaryOrigins, origin)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 添加备用源站配置
|
2020-09-21 20:21:20 +08:00
|
|
|
|
func (this *ReverseProxyConfig) AddBackupOrigin(origin *OriginConfig) {
|
2020-09-15 14:44:38 +08:00
|
|
|
|
this.BackupOrigins = append(this.BackupOrigins, origin)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-09-13 19:27:47 +08:00
|
|
|
|
// 取得下一个可用的后端服务
|
2020-09-21 20:21:20 +08:00
|
|
|
|
func (this *ReverseProxyConfig) NextOrigin(call *shared.RequestCall) *OriginConfig {
|
2020-09-13 19:27:47 +08:00
|
|
|
|
this.schedulingLocker.Lock()
|
|
|
|
|
|
defer this.schedulingLocker.Unlock()
|
|
|
|
|
|
|
|
|
|
|
|
if this.schedulingObject == nil {
|
|
|
|
|
|
return nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if this.Scheduling != nil && call != nil && call.Options != nil {
|
|
|
|
|
|
for k, v := range this.Scheduling.Options {
|
|
|
|
|
|
call.Options[k] = v
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
candidate := this.schedulingObject.Next(call)
|
|
|
|
|
|
if candidate == nil {
|
|
|
|
|
|
// 启用备用服务器
|
|
|
|
|
|
if !this.schedulingIsBackup {
|
|
|
|
|
|
this.SetupScheduling(true)
|
|
|
|
|
|
|
|
|
|
|
|
candidate = this.schedulingObject.Next(call)
|
|
|
|
|
|
if candidate == nil {
|
|
|
|
|
|
return nil
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if candidate == nil {
|
|
|
|
|
|
return nil
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-09-21 20:21:20 +08:00
|
|
|
|
return candidate.(*OriginConfig)
|
2020-09-13 19:27:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 设置调度算法
|
|
|
|
|
|
func (this *ReverseProxyConfig) SetupScheduling(isBackup bool) {
|
|
|
|
|
|
if !isBackup {
|
|
|
|
|
|
this.schedulingLocker.Lock()
|
|
|
|
|
|
defer this.schedulingLocker.Unlock()
|
|
|
|
|
|
}
|
|
|
|
|
|
this.schedulingIsBackup = isBackup
|
|
|
|
|
|
|
|
|
|
|
|
if this.Scheduling == nil {
|
2020-09-15 14:44:38 +08:00
|
|
|
|
this.schedulingObject = &schedulingconfigs.RandomScheduling{}
|
2020-09-13 19:27:47 +08:00
|
|
|
|
} else {
|
|
|
|
|
|
typeCode := this.Scheduling.Code
|
2020-09-15 14:44:38 +08:00
|
|
|
|
s := schedulingconfigs.FindSchedulingType(typeCode)
|
2020-09-13 19:27:47 +08:00
|
|
|
|
if s == nil {
|
|
|
|
|
|
this.Scheduling = nil
|
2020-09-15 14:44:38 +08:00
|
|
|
|
this.schedulingObject = &schedulingconfigs.RandomScheduling{}
|
2020-09-13 19:27:47 +08:00
|
|
|
|
} else {
|
2020-09-15 14:44:38 +08:00
|
|
|
|
this.schedulingObject = s["instance"].(schedulingconfigs.SchedulingInterface)
|
2020-09-13 19:27:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-09-15 14:44:38 +08:00
|
|
|
|
if !isBackup {
|
|
|
|
|
|
for _, origin := range this.PrimaryOrigins {
|
|
|
|
|
|
if origin.IsOn {
|
2020-09-13 19:27:47 +08:00
|
|
|
|
this.schedulingObject.Add(origin)
|
2020-09-15 14:44:38 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
for _, origin := range this.BackupOrigins {
|
|
|
|
|
|
if origin.IsOn {
|
2020-09-13 19:27:47 +08:00
|
|
|
|
this.schedulingObject.Add(origin)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
this.schedulingObject.Start()
|
|
|
|
|
|
}
|
2020-09-15 14:44:38 +08:00
|
|
|
|
|
|
|
|
|
|
// 获取调度配置对象
|
|
|
|
|
|
func (this *ReverseProxyConfig) FindSchedulingConfig() *SchedulingConfig {
|
|
|
|
|
|
if this.Scheduling == nil {
|
|
|
|
|
|
this.Scheduling = &SchedulingConfig{Code: "random"}
|
|
|
|
|
|
}
|
|
|
|
|
|
return this.Scheduling
|
|
|
|
|
|
}
|
2020-09-27 10:03:24 +08:00
|
|
|
|
|
|
|
|
|
|
// 判断RequestHost是否有变量
|
|
|
|
|
|
func (this *ReverseProxyConfig) RequestHostHasVariables() bool {
|
|
|
|
|
|
return this.requestHostHasVariables
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 判断RequestURI是否有变量
|
|
|
|
|
|
func (this *ReverseProxyConfig) RequestURIHasVariables() bool {
|
|
|
|
|
|
return this.requestURIHasVariables
|
|
|
|
|
|
}
|
2021-01-26 20:28:46 +08:00
|
|
|
|
|
|
|
|
|
|
// 是否添加X-Real-IP
|
|
|
|
|
|
func (this *ReverseProxyConfig) ShouldAddXRealIPHeader() bool {
|
|
|
|
|
|
return this.addXRealIPHeader
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 是否添加X-Forwarded-For
|
|
|
|
|
|
func (this *ReverseProxyConfig) ShouldAddXForwardedForHeader() bool {
|
|
|
|
|
|
return this.addXForwardedForHeader
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 是否添加X-Forwarded-By
|
|
|
|
|
|
func (this *ReverseProxyConfig) ShouldAddXForwardedByHeader() bool {
|
|
|
|
|
|
return this.addXForwardedByHeader
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 是否添加X-Forwarded-Host
|
|
|
|
|
|
func (this *ReverseProxyConfig) ShouldAddXForwardedHostHeader() bool {
|
|
|
|
|
|
return this.addXForwardedHostHeader
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 是否添加X-Forwarded-Proto
|
|
|
|
|
|
func (this *ReverseProxyConfig) ShouldAddXForwardedProtoHeader() bool {
|
|
|
|
|
|
return this.addXForwardedProtoHeader
|
|
|
|
|
|
}
|