mirror of
				https://github.com/TeaOSLab/EdgeCommon.git
				synced 2025-11-04 05:00:24 +08:00 
			
		
		
		
	实现基本的反向代理
This commit is contained in:
		@@ -2,10 +2,16 @@ package serverconfigs
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
 | 
					import "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 健康检查设置
 | 
				
			||||||
type HealthCheckConfig struct {
 | 
					type HealthCheckConfig struct {
 | 
				
			||||||
	IsOn        bool                `yaml:"isOn" json:"isOn"`               // 是否开启 TODO
 | 
						IsOn        bool                 `yaml:"isOn" json:"isOn"`               // 是否开启 TODO
 | 
				
			||||||
	URL         string              `yaml:"url" json:"url"`                 // TODO
 | 
						URL         string               `yaml:"url" json:"url"`                 // TODO
 | 
				
			||||||
	Interval    int                 `yaml:"interval" json:"interval"`       // TODO
 | 
						Interval    int                  `yaml:"interval" json:"interval"`       // TODO
 | 
				
			||||||
	StatusCodes []int               `yaml:"statusCodes" json:"statusCodes"` // TODO
 | 
						StatusCodes []int                `yaml:"statusCodes" json:"statusCodes"` // TODO
 | 
				
			||||||
	Timeout     *shared.TimeDuration `yaml:"timeout" json:"timeout"`         // 超时时间 TODO
 | 
						Timeout     *shared.TimeDuration `yaml:"timeout" json:"timeout"`         // 超时时间 TODO
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 初始化
 | 
				
			||||||
 | 
					func (this *HealthCheckConfig) Init() error {
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,8 @@
 | 
				
			|||||||
package serverconfigs
 | 
					package serverconfigs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/configutils"
 | 
				
			||||||
 | 
						"github.com/iwind/TeaGo/rands"
 | 
				
			||||||
	"github.com/iwind/TeaGo/types"
 | 
						"github.com/iwind/TeaGo/types"
 | 
				
			||||||
	"regexp"
 | 
						"regexp"
 | 
				
			||||||
	"strconv"
 | 
						"strconv"
 | 
				
			||||||
@@ -12,14 +14,19 @@ var regexpSinglePort = regexp.MustCompile(`^\d+$`)
 | 
				
			|||||||
// 网络地址配置
 | 
					// 网络地址配置
 | 
				
			||||||
type NetworkAddressConfig struct {
 | 
					type NetworkAddressConfig struct {
 | 
				
			||||||
	Protocol  Protocol `yaml:"protocol" json:"protocol"`   // 协议,http、tcp、tcp4、tcp6、unix、udp等
 | 
						Protocol  Protocol `yaml:"protocol" json:"protocol"`   // 协议,http、tcp、tcp4、tcp6、unix、udp等
 | 
				
			||||||
	Host      string   `yaml:"host" json:"host"`           // 主机地址或主机名
 | 
						Host      string   `yaml:"host" json:"host"`           // 主机地址或主机名,支持变量
 | 
				
			||||||
	PortRange string   `yaml:"portRange" json:"portRange"` // 端口范围,支持 8080、8080-8090、8080:8090
 | 
						PortRange string   `yaml:"portRange" json:"portRange"` // 端口范围,支持 8080、8080-8090、8080:8090
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	minPort int
 | 
						minPort int
 | 
				
			||||||
	maxPort int
 | 
						maxPort int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						hostHasVariables bool
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 初始化
 | 
				
			||||||
func (this *NetworkAddressConfig) Init() error {
 | 
					func (this *NetworkAddressConfig) Init() error {
 | 
				
			||||||
 | 
						this.hostHasVariables = configutils.HasVariables(this.Host)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 8080
 | 
						// 8080
 | 
				
			||||||
	if regexpSinglePort.MatchString(this.PortRange) {
 | 
						if regexpSinglePort.MatchString(this.PortRange) {
 | 
				
			||||||
		this.minPort = types.Int(this.PortRange)
 | 
							this.minPort = types.Int(this.PortRange)
 | 
				
			||||||
@@ -56,6 +63,7 @@ func (this *NetworkAddressConfig) Init() error {
 | 
				
			|||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 所有的地址列表,包含scheme
 | 
				
			||||||
func (this *NetworkAddressConfig) FullAddresses() []string {
 | 
					func (this *NetworkAddressConfig) FullAddresses() []string {
 | 
				
			||||||
	if this.Protocol == ProtocolUnix {
 | 
						if this.Protocol == ProtocolUnix {
 | 
				
			||||||
		return []string{this.Protocol.String() + ":" + this.Host}
 | 
							return []string{this.Protocol.String() + ":" + this.Host}
 | 
				
			||||||
@@ -68,3 +76,16 @@ func (this *NetworkAddressConfig) FullAddresses() []string {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	return result
 | 
						return result
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 选择其中一个地址
 | 
				
			||||||
 | 
					func (this *NetworkAddressConfig) PickAddress() string {
 | 
				
			||||||
 | 
						if this.maxPort > this.minPort {
 | 
				
			||||||
 | 
							return this.Host + ":" + strconv.Itoa(rands.Int(this.minPort, this.maxPort))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return this.Host + ":" + strconv.Itoa(this.minPort)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 判断Host是否包含变量
 | 
				
			||||||
 | 
					func (this *NetworkAddressConfig) HostHasVariables() bool {
 | 
				
			||||||
 | 
						return this.hostHasVariables
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -55,3 +55,51 @@ func TestNetworkAddressConfig_FullAddresses(t *testing.T) {
 | 
				
			|||||||
		t.Log(addr.FullAddresses())
 | 
							t.Log(addr.FullAddresses())
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestNetworkAddressConfig_PickAddress(t *testing.T) {
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							addr := &NetworkAddressConfig{
 | 
				
			||||||
 | 
								Host:      "127.0.0.1",
 | 
				
			||||||
 | 
								PortRange: "1234",
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							err := addr.Init()
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								t.Fatal(err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							t.Log(addr.PickAddress())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							addr := &NetworkAddressConfig{
 | 
				
			||||||
 | 
								Host:      "127.0.0.1",
 | 
				
			||||||
 | 
								PortRange: "8000-9000",
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							err := addr.Init()
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								t.Fatal(err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							t.Log(addr.PickAddress())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							addr := &NetworkAddressConfig{
 | 
				
			||||||
 | 
								Host:      "127.0.0.1",
 | 
				
			||||||
 | 
								PortRange: "8000-8001",
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							err := addr.Init()
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								t.Fatal(err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							t.Log(addr.PickAddress())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							addr := &NetworkAddressConfig{
 | 
				
			||||||
 | 
								Host:      "127.0.0.1",
 | 
				
			||||||
 | 
								PortRange: "9000-8000",
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							err := addr.Init()
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								t.Fatal(err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							t.Log(addr.PickAddress())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,6 +2,7 @@ package serverconfigs
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/configutils"
 | 
				
			||||||
	"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
 | 
				
			||||||
	"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/sslconfigs"
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/sslconfigs"
 | 
				
			||||||
	"strconv"
 | 
						"strconv"
 | 
				
			||||||
@@ -27,8 +28,9 @@ type OriginConfig struct {
 | 
				
			|||||||
	MaxConns     int                  `yaml:"maxConns" json:"maxConns"`       // 最大并发连接数 TODO
 | 
						MaxConns     int                  `yaml:"maxConns" json:"maxConns"`       // 最大并发连接数 TODO
 | 
				
			||||||
	MaxIdleConns int                  `yaml:"idleConns" json:"idleConns"`     // 最大空闲连接数 TODO
 | 
						MaxIdleConns int                  `yaml:"idleConns" json:"idleConns"`     // 最大空闲连接数 TODO
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	RequestURI string `yaml:"requestURI" json:"requestURI"` // 转发后的请求URI TODO
 | 
						StripPrefix string `yaml:"stripPrefix" json:"stripPrefix"` // 去除URL前缀
 | 
				
			||||||
	Host       string `yaml:"host" json:"host"`             // 自定义主机名 TODO
 | 
						RequestURI  string `yaml:"requestURI" json:"requestURI"`   // 转发后的请求URI TODO
 | 
				
			||||||
 | 
						RequestHost string `yaml:"requestHost" json:"requestHost"` // 自定义主机名 TODO
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	RequestHeaderPolicyRef  *shared.HTTPHeaderPolicyRef `yaml:"requestHeaderPolicyRef" json:"requestHeaderPolicyRef"`   // 请求Header
 | 
						RequestHeaderPolicyRef  *shared.HTTPHeaderPolicyRef `yaml:"requestHeaderPolicyRef" json:"requestHeaderPolicyRef"`   // 请求Header
 | 
				
			||||||
	RequestHeaderPolicy     *shared.HTTPHeaderPolicy    `yaml:"requestHeaderPolicy" json:"requestHeaderPolicy"`         // 请求Header策略
 | 
						RequestHeaderPolicy     *shared.HTTPHeaderPolicy    `yaml:"requestHeaderPolicy" json:"requestHeaderPolicy"`         // 请求Header策略
 | 
				
			||||||
@@ -55,17 +57,29 @@ type OriginConfig struct {
 | 
				
			|||||||
	hasRequestHeaders  bool
 | 
						hasRequestHeaders  bool
 | 
				
			||||||
	hasResponseHeaders bool
 | 
						hasResponseHeaders bool
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	hasHost bool
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	uniqueKey string
 | 
						uniqueKey string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	hasAddrVariables bool // 地址中是否含有变量
 | 
						requestHostHasVariables bool
 | 
				
			||||||
 | 
						requestURIHasVariables  bool
 | 
				
			||||||
	realAddr string // 最终的Addr TODO
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 校验
 | 
					// 校验
 | 
				
			||||||
func (this *OriginConfig) Init() error {
 | 
					func (this *OriginConfig) Init() error {
 | 
				
			||||||
 | 
						// URL
 | 
				
			||||||
 | 
						this.requestHostHasVariables = configutils.HasVariables(this.RequestHost)
 | 
				
			||||||
 | 
						this.requestURIHasVariables = configutils.HasVariables(this.RequestURI)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// unique key
 | 
				
			||||||
 | 
						this.uniqueKey = strconv.FormatInt(this.Id, 10) + "@" + strconv.Itoa(this.Version) + "@" + fmt.Sprintf("%p", this)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// addr
 | 
				
			||||||
 | 
						if this.Addr != nil {
 | 
				
			||||||
 | 
							err := this.Addr.Init()
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 证书
 | 
						// 证书
 | 
				
			||||||
	if this.Cert != nil {
 | 
						if this.Cert != nil {
 | 
				
			||||||
		err := this.Cert.Init()
 | 
							err := this.Cert.Init()
 | 
				
			||||||
@@ -74,9 +88,6 @@ func (this *OriginConfig) Init() error {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// unique key
 | 
					 | 
				
			||||||
	this.uniqueKey = strconv.FormatInt(this.Id, 10) + "@" + fmt.Sprintf("%d", this.Version)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// failTimeout
 | 
						// failTimeout
 | 
				
			||||||
	if this.ConnTimeout != nil {
 | 
						if this.ConnTimeout != nil {
 | 
				
			||||||
		this.connTimeoutDuration = this.ConnTimeout.Duration()
 | 
							this.connTimeoutDuration = this.ConnTimeout.Duration()
 | 
				
			||||||
@@ -133,14 +144,13 @@ func (this *OriginConfig) Init() error {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// TODO init health check
 | 
						// health check
 | 
				
			||||||
 | 
						if this.HealthCheck != nil {
 | 
				
			||||||
	// host
 | 
							err := this.HealthCheck.Init()
 | 
				
			||||||
	this.hasHost = len(this.Host) > 0
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
	// variables
 | 
							}
 | 
				
			||||||
	// TODO 在host和port中支持变量
 | 
						}
 | 
				
			||||||
	this.hasAddrVariables = false
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -159,17 +169,32 @@ func (this *OriginConfig) CandidateWeight() uint {
 | 
				
			|||||||
	return this.Weight
 | 
						return this.Weight
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 获取最终请求的地址
 | 
					 | 
				
			||||||
func (this *OriginConfig) RealAddr() string {
 | 
					 | 
				
			||||||
	return this.realAddr
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 设置最终请求的地址 TODO 需要实现
 | 
					 | 
				
			||||||
func (this *OriginConfig) SetRealAddr(realAddr string) {
 | 
					 | 
				
			||||||
	this.realAddr = realAddr
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 连接超时时间
 | 
					// 连接超时时间
 | 
				
			||||||
func (this *OriginConfig) ConnTimeoutDuration() time.Duration {
 | 
					func (this *OriginConfig) ConnTimeoutDuration() time.Duration {
 | 
				
			||||||
	return this.connTimeoutDuration
 | 
						return this.connTimeoutDuration
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 读取超时时间
 | 
				
			||||||
 | 
					func (this *OriginConfig) ReadTimeoutDuration() time.Duration {
 | 
				
			||||||
 | 
						return this.readTimeoutDuration
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 休眠超时时间
 | 
				
			||||||
 | 
					func (this *OriginConfig) IdleTimeoutDuration() time.Duration {
 | 
				
			||||||
 | 
						return this.idleTimeoutDuration
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 判断RequestHost是否有变量
 | 
				
			||||||
 | 
					func (this *OriginConfig) RequestHostHasVariables() bool {
 | 
				
			||||||
 | 
						return this.requestHostHasVariables
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 判断RequestURI是否有变量
 | 
				
			||||||
 | 
					func (this *OriginConfig) RequestURIHasVariables() bool {
 | 
				
			||||||
 | 
						return this.requestURIHasVariables
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 唯一Key
 | 
				
			||||||
 | 
					func (this *OriginConfig) UniqueKey() string {
 | 
				
			||||||
 | 
						return this.uniqueKey
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										15
									
								
								pkg/serverconfigs/origin_config_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								pkg/serverconfigs/origin_config_test.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
				
			|||||||
 | 
					package serverconfigs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import "testing"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestOriginConfig_UniqueKey(t *testing.T) {
 | 
				
			||||||
 | 
						origin := &OriginConfig{
 | 
				
			||||||
 | 
							Id:      1,
 | 
				
			||||||
 | 
							Version: 101,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						err := origin.Init()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							t.Fatal(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Log(origin.UniqueKey())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -72,6 +72,11 @@ func (this Protocol) Primary() Protocol {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Scheme
 | 
				
			||||||
 | 
					func (this Protocol) Scheme() string {
 | 
				
			||||||
 | 
						return string(this)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 转换为字符串
 | 
					// 转换为字符串
 | 
				
			||||||
func (this Protocol) String() string {
 | 
					func (this Protocol) String() string {
 | 
				
			||||||
	return string(this)
 | 
						return string(this)
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user