mirror of
https://github.com/TeaOSLab/EdgeCommon.git
synced 2026-04-25 23:45:17 +08:00
实现websocket基本功能
This commit is contained in:
@@ -1,11 +1,16 @@
|
||||
package serverconfigs
|
||||
|
||||
// 字符集设置
|
||||
type HTTPCharsetConfig struct {
|
||||
IsPrior bool `yaml:"isPrior" json:"isPrior"` // 是否覆盖
|
||||
IsOn bool `yaml:"isOn" json:"isOn"` // 是否启用
|
||||
Charset string `yaml:"charset" json:"charset"` // 字符集
|
||||
IsUpper bool `yaml:"isUpper" json:"isUpper"` // 是否要大写
|
||||
|
||||
// TODO 支持自定义字符集
|
||||
}
|
||||
|
||||
// 初始化
|
||||
func (this *HTTPCharsetConfig) Init() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -44,8 +44,15 @@ func (this *HTTPLocationConfig) Init() error {
|
||||
}
|
||||
}
|
||||
|
||||
if this.ReverseProxyRef != nil {
|
||||
err := this.ReverseProxyRef.Init()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if this.ReverseProxy != nil {
|
||||
err := this.Web.Init()
|
||||
err := this.ReverseProxy.Init()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package serverconfigs
|
||||
|
||||
import "github.com/TeaOSLab/EdgeCommon/pkg/configutils"
|
||||
|
||||
// Web文档目录配置
|
||||
type HTTPRootConfig struct {
|
||||
IsPrior bool `yaml:"isPrior" json:"isPrior"` // 是否优先
|
||||
@@ -9,9 +11,17 @@ type HTTPRootConfig struct {
|
||||
StripPrefix string `yaml:"stripPrefix" json:"stripPrefix"` // 去除前缀
|
||||
DecodePath bool `yaml:"decodePath" json:"decodePath"` // 是否对请求路径进行解码
|
||||
IsBreak bool `yaml:"isBreak" json:"isBreak"` // 找不到文件的情况下是否终止
|
||||
|
||||
hasVariables bool
|
||||
}
|
||||
|
||||
// 初始化
|
||||
func (ths *HTTPRootConfig) Init() error {
|
||||
func (this *HTTPRootConfig) Init() error {
|
||||
this.hasVariables = configutils.HasVariables(this.Dir)
|
||||
return nil
|
||||
}
|
||||
|
||||
// 判断是否有变量
|
||||
func (this *HTTPRootConfig) HasVariables() bool {
|
||||
return this.hasVariables
|
||||
}
|
||||
|
||||
43
pkg/serverconfigs/http_root_config_test.go
Normal file
43
pkg/serverconfigs/http_root_config_test.go
Normal file
@@ -0,0 +1,43 @@
|
||||
package serverconfigs
|
||||
|
||||
import (
|
||||
"github.com/iwind/TeaGo/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestHTTPRootConfig_HasVariables(t *testing.T) {
|
||||
a := assert.NewAssertion(t)
|
||||
|
||||
{
|
||||
rootConfig := &HTTPRootConfig{
|
||||
Dir: "",
|
||||
}
|
||||
err := rootConfig.Init()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
a.IsFalse(rootConfig.HasVariables())
|
||||
}
|
||||
|
||||
{
|
||||
rootConfig := &HTTPRootConfig{
|
||||
Dir: "/home/www",
|
||||
}
|
||||
err := rootConfig.Init()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
a.IsFalse(rootConfig.HasVariables())
|
||||
}
|
||||
|
||||
{
|
||||
rootConfig := &HTTPRootConfig{
|
||||
Dir: "/home/www/${prefix}/world",
|
||||
}
|
||||
err := rootConfig.Init()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
a.IsTrue(rootConfig.HasVariables())
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,6 @@ package serverconfigs
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/configutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -15,21 +14,16 @@ type HTTPWebsocketConfig struct {
|
||||
// 握手超时时间
|
||||
HandshakeTimeout *shared.TimeDuration `yaml:"handshakeTimeout" json:"handshakeTimeout"`
|
||||
|
||||
// 允许的域名,支持 www.example.com, example.com, .example.com, *.example.com
|
||||
// 允许的来源域名,支持 www.example.com, example.com, .example.com, *.example.com
|
||||
AllowAllOrigins bool `yaml:"allowAllOrigins" json:"allowAllOrigins"`
|
||||
Origins []string `yaml:"origins" json:"origins"`
|
||||
AllowedOrigins []string `yaml:"allowedOrigins" json:"allowedOrigins"`
|
||||
|
||||
// 转发方式
|
||||
ForwardMode HTTPWebsocketForwardMode `yaml:"forwardMode" json:"forwardMode"`
|
||||
// 向后传递的来源
|
||||
RequestSameOrigin bool `yaml:"requestSameOrigin" json:"requestSameOrigin"` // 和请求一致
|
||||
RequestOrigin string `yaml:"requestOrigin" json:"requestOrigin"` // 自行指定Origin,支持变量
|
||||
|
||||
handshakeTimeoutDuration time.Duration
|
||||
}
|
||||
|
||||
// 获取新对象
|
||||
func NewHTTPWebsocketConfig() *HTTPWebsocketConfig {
|
||||
return &HTTPWebsocketConfig{
|
||||
IsOn: true,
|
||||
}
|
||||
handshakeTimeoutDuration time.Duration
|
||||
requestOriginHasVariables bool
|
||||
}
|
||||
|
||||
// 校验
|
||||
@@ -39,6 +33,9 @@ func (this *HTTPWebsocketConfig) Init() error {
|
||||
this.handshakeTimeoutDuration = this.HandshakeTimeout.Duration()
|
||||
}
|
||||
|
||||
// requestOrigin
|
||||
this.requestOriginHasVariables = configutils.HasVariables(this.RequestOrigin)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -47,20 +44,15 @@ func (this *HTTPWebsocketConfig) HandshakeTimeoutDuration() time.Duration {
|
||||
return this.handshakeTimeoutDuration
|
||||
}
|
||||
|
||||
// 转发模式名称
|
||||
func (this *HTTPWebsocketConfig) ForwardModeSummary() maps.Map {
|
||||
for _, mode := range AllWebsocketForwardModes() {
|
||||
if mode["mode"] == this.ForwardMode {
|
||||
return mode
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// 匹配域名
|
||||
func (this *HTTPWebsocketConfig) MatchOrigin(origin string) bool {
|
||||
if this.AllowAllOrigins {
|
||||
return true
|
||||
}
|
||||
return configutils.MatchDomains(this.Origins, origin)
|
||||
return configutils.MatchDomains(this.AllowedOrigins, origin)
|
||||
}
|
||||
|
||||
// 判断请求Origin是否有变量
|
||||
func (this *HTTPWebsocketConfig) RequestOriginHasVariables() bool {
|
||||
return this.requestOriginHasVariables
|
||||
}
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
package serverconfigs
|
||||
|
||||
import "github.com/iwind/TeaGo/maps"
|
||||
|
||||
// Websocket转发类型
|
||||
type HTTPWebsocketForwardMode = string
|
||||
|
||||
const (
|
||||
HTTPWebsocketForwardModeWebsocket = "websocket"
|
||||
HTTPWebsocketForwardModeHttp = "http"
|
||||
)
|
||||
|
||||
// 所有的转发方式
|
||||
func AllWebsocketForwardModes() []maps.Map {
|
||||
return []maps.Map{
|
||||
{
|
||||
"name": "Websocket连接",
|
||||
"mode": HTTPWebsocketForwardModeWebsocket,
|
||||
"description": "通过Websocket连接后端服务器并发送数据",
|
||||
},
|
||||
{
|
||||
"name": "HTTP连接",
|
||||
"mode": HTTPWebsocketForwardModeHttp,
|
||||
"description": "通过HTTP PUT转发服务器到后端服务器",
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,9 @@
|
||||
package serverconfigs
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/sslconfigs"
|
||||
"net"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -96,12 +93,24 @@ func (this *OriginConfig) Init() error {
|
||||
}
|
||||
|
||||
// Headers
|
||||
if this.RequestHeaderPolicyRef != nil {
|
||||
err := this.RequestHeaderPolicyRef.Init()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if this.RequestHeaderPolicy != nil {
|
||||
err := this.RequestHeaderPolicy.Init()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if this.ResponseHeaderPolicyRef != nil {
|
||||
err := this.ResponseHeaderPolicyRef.Init()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if this.ResponseHeaderPolicy != nil {
|
||||
err := this.ResponseHeaderPolicy.Init()
|
||||
if err != nil {
|
||||
@@ -150,31 +159,6 @@ func (this *OriginConfig) CandidateWeight() uint {
|
||||
return this.Weight
|
||||
}
|
||||
|
||||
// 连接源站
|
||||
func (this *OriginConfig) Connect() (net.Conn, error) {
|
||||
if this.Addr == nil {
|
||||
return nil, errors.New("origin server address should not be empty")
|
||||
}
|
||||
|
||||
switch this.Addr.Protocol {
|
||||
case "", ProtocolTCP:
|
||||
// TODO 支持TCP4/TCP6
|
||||
// TODO 支持指定特定网卡
|
||||
// TODO Addr支持端口范围,如果有多个端口时,随机一个端口使用
|
||||
return net.DialTimeout("tcp", this.Addr.Host+":"+this.Addr.PortRange, this.connTimeoutDuration)
|
||||
case ProtocolTLS:
|
||||
// TODO 支持TCP4/TCP6
|
||||
// TODO 支持指定特定网卡
|
||||
// TODO Addr支持端口范围,如果有多个端口时,随机一个端口使用
|
||||
// TODO 支持使用证书
|
||||
return tls.Dial("tcp", this.Addr.Host+":"+this.Addr.PortRange, &tls.Config{})
|
||||
}
|
||||
|
||||
// TODO 支持从Unix、Pipe、HTTP、HTTPS中读取数据
|
||||
|
||||
return nil, errors.New("invalid scheme '" + this.Addr.Protocol.String() + "'")
|
||||
}
|
||||
|
||||
// 获取最终请求的地址
|
||||
func (this *OriginConfig) RealAddr() string {
|
||||
return this.realAddr
|
||||
@@ -184,3 +168,8 @@ func (this *OriginConfig) RealAddr() string {
|
||||
func (this *OriginConfig) SetRealAddr(realAddr string) {
|
||||
this.realAddr = realAddr
|
||||
}
|
||||
|
||||
// 连接超时时间
|
||||
func (this *OriginConfig) ConnTimeoutDuration() time.Duration {
|
||||
return this.connTimeoutDuration
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@ type ReverseProxyConfig struct {
|
||||
BackupOriginRefs []*OriginRef `yaml:"backupOriginRefs" json:"backupOriginRefs"` // 备用源站引用
|
||||
Scheduling *SchedulingConfig `yaml:"scheduling" json:"scheduling"` // 调度算法选项
|
||||
|
||||
// TODO 可以设置同后端交互的主机名(Host),并支持变量
|
||||
|
||||
hasPrimaryOrigins bool
|
||||
hasBackupOrigins bool
|
||||
schedulingIsBackup bool
|
||||
|
||||
@@ -6,3 +6,8 @@ type ReverseProxyRef struct {
|
||||
IsOn bool `yaml:"isOn" json:"isOn"` // 是否启用
|
||||
ReverseProxyId int64 `yaml:"reverseProxyId" json:"reverseProxyId"` // 反向代理ID
|
||||
}
|
||||
|
||||
// 初始化
|
||||
func (this *ReverseProxyRef) Init() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -84,6 +84,13 @@ func (this *ServerConfig) Init() error {
|
||||
}
|
||||
}
|
||||
|
||||
if this.ReverseProxyRef != nil {
|
||||
err := this.ReverseProxyRef.Init()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if this.ReverseProxy != nil {
|
||||
err := this.ReverseProxy.Init()
|
||||
if err != nil {
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
package shared
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/configutils"
|
||||
)
|
||||
|
||||
var regexpNamedVariable = regexp.MustCompile("\\${[\\w.-]+}")
|
||||
|
||||
// 头部信息定义
|
||||
type HTTPHeaderConfig struct {
|
||||
Id int64 `yaml:"id" json:"id"` // ID
|
||||
@@ -26,7 +24,7 @@ func NewHeaderConfig() *HTTPHeaderConfig {
|
||||
|
||||
// 校验
|
||||
func (this *HTTPHeaderConfig) Init() error {
|
||||
this.hasVariables = regexpNamedVariable.MatchString(this.Value)
|
||||
this.hasVariables = configutils.HasVariables(this.Value)
|
||||
|
||||
if this.Status != nil {
|
||||
err := this.Status.Init()
|
||||
|
||||
Reference in New Issue
Block a user