mirror of
				https://github.com/TeaOSLab/EdgeCommon.git
				synced 2025-11-04 13:10:24 +08:00 
			
		
		
		
	实现HTTP部分功能
This commit is contained in:
		
							
								
								
									
										4
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								go.mod
									
									
									
									
									
								
							@@ -5,7 +5,9 @@ go 1.15
 | 
				
			|||||||
require (
 | 
					require (
 | 
				
			||||||
	github.com/go-yaml/yaml v2.1.0+incompatible
 | 
						github.com/go-yaml/yaml v2.1.0+incompatible
 | 
				
			||||||
	github.com/golang/protobuf v1.4.2
 | 
						github.com/golang/protobuf v1.4.2
 | 
				
			||||||
	github.com/iwind/TeaGo v0.0.0-20200910072805-729cffe36729
 | 
						github.com/iwind/TeaGo v0.0.0-20200923021120-f5d76441fe9e
 | 
				
			||||||
 | 
						github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
 | 
				
			||||||
 | 
						github.com/modern-go/reflect2 v1.0.1 // indirect
 | 
				
			||||||
	google.golang.org/grpc v1.32.0
 | 
						google.golang.org/grpc v1.32.0
 | 
				
			||||||
	google.golang.org/protobuf v1.25.0
 | 
						google.golang.org/protobuf v1.25.0
 | 
				
			||||||
	gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776
 | 
						gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										9
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										9
									
								
								go.sum
									
									
									
									
									
								
							@@ -45,13 +45,22 @@ github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/
 | 
				
			|||||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
 | 
					github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
 | 
				
			||||||
github.com/iwind/TeaGo v0.0.0-20200910072805-729cffe36729 h1:/v0WhSFVeNay/dA5zU9iCBXlgVDfxnztuanlauXE0gM=
 | 
					github.com/iwind/TeaGo v0.0.0-20200910072805-729cffe36729 h1:/v0WhSFVeNay/dA5zU9iCBXlgVDfxnztuanlauXE0gM=
 | 
				
			||||||
github.com/iwind/TeaGo v0.0.0-20200910072805-729cffe36729/go.mod h1:KU4mS7QNiZ7QWEuDBk1zw0/Q2LrAPZv3tycEFBsuUwc=
 | 
					github.com/iwind/TeaGo v0.0.0-20200910072805-729cffe36729/go.mod h1:KU4mS7QNiZ7QWEuDBk1zw0/Q2LrAPZv3tycEFBsuUwc=
 | 
				
			||||||
 | 
					github.com/iwind/TeaGo v0.0.0-20200923021120-f5d76441fe9e h1:/xn7wUvlwaoA5IkdBUctv2OQbJSZ0/Dw8qRJmn55sJk=
 | 
				
			||||||
 | 
					github.com/iwind/TeaGo v0.0.0-20200923021120-f5d76441fe9e/go.mod h1:KU4mS7QNiZ7QWEuDBk1zw0/Q2LrAPZv3tycEFBsuUwc=
 | 
				
			||||||
 | 
					github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68=
 | 
				
			||||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
 | 
					github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
 | 
				
			||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
 | 
					github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
 | 
				
			||||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
 | 
					github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
 | 
				
			||||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
 | 
					github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
 | 
				
			||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
 | 
					github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
 | 
				
			||||||
 | 
					github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
 | 
				
			||||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
 | 
					github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
 | 
				
			||||||
 | 
					github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
 | 
				
			||||||
 | 
					github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
 | 
				
			||||||
 | 
					github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg=
 | 
				
			||||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
 | 
					github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
 | 
				
			||||||
 | 
					github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
 | 
				
			||||||
 | 
					github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
 | 
				
			||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
 | 
					github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
 | 
				
			||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
 | 
					github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
 | 
				
			||||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
 | 
					github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										15
									
								
								pkg/configutils/state.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								pkg/configutils/state.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
				
			|||||||
 | 
					package configutils
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import "github.com/iwind/TeaGo/types"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type BoolState = int8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						BoolStateAll BoolState = 0 // 全部
 | 
				
			||||||
 | 
						BoolStateYes BoolState = 1 // 已安装
 | 
				
			||||||
 | 
						BoolStateNo  BoolState = 2 // 未安装
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func ToBoolState(v interface{}) BoolState {
 | 
				
			||||||
 | 
						return types.Int8(v)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										54
									
								
								pkg/configutils/variable.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								pkg/configutils/variable.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,54 @@
 | 
				
			|||||||
 | 
					package configutils
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"regexp"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
						"sync"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 变量信息存储类型
 | 
				
			||||||
 | 
					type VariableHolder string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var variableMapping = map[string][]interface{}{}
 | 
				
			||||||
 | 
					var variableLocker = sync.RWMutex{}
 | 
				
			||||||
 | 
					var regexpNamedVariable = regexp.MustCompile("\\${[\\w.-]+}")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 分析变量
 | 
				
			||||||
 | 
					func ParseVariables(source string, replacer func(varName string) (value string)) string {
 | 
				
			||||||
 | 
						variableLocker.RLock()
 | 
				
			||||||
 | 
						holders, found := variableMapping[source]
 | 
				
			||||||
 | 
						variableLocker.RUnlock()
 | 
				
			||||||
 | 
						if !found {
 | 
				
			||||||
 | 
							indexes := regexpNamedVariable.FindAllStringIndex(source, -1)
 | 
				
			||||||
 | 
							before := 0
 | 
				
			||||||
 | 
							for _, loc := range indexes {
 | 
				
			||||||
 | 
								holders = append(holders, []byte(source[before:loc[0]]))
 | 
				
			||||||
 | 
								holder := source[loc[0]+2 : loc[1]-1]
 | 
				
			||||||
 | 
								holders = append(holders, VariableHolder(holder))
 | 
				
			||||||
 | 
								before = loc[1]
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if before < len(source) {
 | 
				
			||||||
 | 
								holders = append(holders, []byte(source[before:]))
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							variableLocker.Lock()
 | 
				
			||||||
 | 
							variableMapping[source] = holders
 | 
				
			||||||
 | 
							variableLocker.Unlock()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// no variables
 | 
				
			||||||
 | 
						if len(holders) == 0 {
 | 
				
			||||||
 | 
							return source
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// replace
 | 
				
			||||||
 | 
						result := strings.Builder{}
 | 
				
			||||||
 | 
						for _, h := range holders {
 | 
				
			||||||
 | 
							holder, ok := h.(VariableHolder)
 | 
				
			||||||
 | 
							if ok {
 | 
				
			||||||
 | 
								result.WriteString(replacer(string(holder)))
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								result.Write(h.([]byte))
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return result.String()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										51
									
								
								pkg/configutils/variable_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								pkg/configutils/variable_test.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,51 @@
 | 
				
			|||||||
 | 
					package configutils
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"strconv"
 | 
				
			||||||
 | 
						"testing"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestParseVariables(t *testing.T) {
 | 
				
			||||||
 | 
						v := ParseVariables("hello, ${name}, world", func(s string) string {
 | 
				
			||||||
 | 
							return "Lu"
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						t.Log(v)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestParseNoVariables(t *testing.T) {
 | 
				
			||||||
 | 
						for i := 0; i < 2; i++ {
 | 
				
			||||||
 | 
							v := ParseVariables("hello, world", func(s string) string {
 | 
				
			||||||
 | 
								return "Lu"
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
							t.Log(v)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func BenchmarkParseVariables(b *testing.B) {
 | 
				
			||||||
 | 
						_ = ParseVariables("hello, ${name}, ${age}, ${gender}, ${home}, world", func(s string) string {
 | 
				
			||||||
 | 
							return "Lu"
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for i := 0; i < b.N; i++ {
 | 
				
			||||||
 | 
							_ = ParseVariables("hello, ${name}, ${age}, ${gender}, ${home}, world", func(s string) string {
 | 
				
			||||||
 | 
								return "Lu"
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func BenchmarkParseVariablesUnique(b *testing.B) {
 | 
				
			||||||
 | 
						for i := 0; i < b.N; i++ {
 | 
				
			||||||
 | 
							_ = ParseVariables("hello, ${name} "+strconv.Itoa(i%1000), func(s string) string {
 | 
				
			||||||
 | 
								return "Lu"
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func BenchmarkParseNoVariables(b *testing.B) {
 | 
				
			||||||
 | 
						for i := 0; i < b.N; i++ {
 | 
				
			||||||
 | 
							_ = ParseVariables("hello, world, "+fmt.Sprintf("%d", i%1000), func(s string) string {
 | 
				
			||||||
 | 
								return "Lu"
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										102
									
								
								pkg/nodeconfigs/node_config.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								pkg/nodeconfigs/node_config.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,102 @@
 | 
				
			|||||||
 | 
					package nodeconfigs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"encoding/json"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
 | 
				
			||||||
 | 
						"github.com/iwind/TeaGo/Tea"
 | 
				
			||||||
 | 
						"io/ioutil"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var sharedNodeConfig *NodeConfig = nil
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type NodeConfig struct {
 | 
				
			||||||
 | 
						Id      string                        `yaml:"id" json:"id"`
 | 
				
			||||||
 | 
						IsOn    bool                          `yaml:"isOn" json:"isOn"`
 | 
				
			||||||
 | 
						Servers []*serverconfigs.ServerConfig `yaml:"servers" json:"servers"`
 | 
				
			||||||
 | 
						Version int64                         `yaml:"version" json:"version"`
 | 
				
			||||||
 | 
						Name    string                        `yaml:"name" json:"name"`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 全局配置
 | 
				
			||||||
 | 
						GlobalConfig *serverconfigs.GlobalConfig `yaml:"globalConfig" json:"globalConfig"` // 全局配置
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 取得当前节点配置单例
 | 
				
			||||||
 | 
					func SharedNodeConfig() (*NodeConfig, error) {
 | 
				
			||||||
 | 
						shared.Locker.Lock()
 | 
				
			||||||
 | 
						defer shared.Locker.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if sharedNodeConfig != nil {
 | 
				
			||||||
 | 
							return sharedNodeConfig, nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						data, err := ioutil.ReadFile(Tea.ConfigFile("node.json"))
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return &NodeConfig{}, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						config := &NodeConfig{}
 | 
				
			||||||
 | 
						err = json.Unmarshal(data, &config)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return &NodeConfig{}, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sharedNodeConfig = config
 | 
				
			||||||
 | 
						return config, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 重置节点配置
 | 
				
			||||||
 | 
					func ResetNodeConfig(nodeConfig *NodeConfig) {
 | 
				
			||||||
 | 
						shared.Locker.Lock()
 | 
				
			||||||
 | 
						sharedNodeConfig = nodeConfig
 | 
				
			||||||
 | 
						shared.Locker.Unlock()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 根据网络地址和协议分组
 | 
				
			||||||
 | 
					func (this *NodeConfig) AvailableGroups() []*serverconfigs.ServerGroup {
 | 
				
			||||||
 | 
						groupMapping := map[string]*serverconfigs.ServerGroup{} // protocol://addr => Server Group
 | 
				
			||||||
 | 
						for _, server := range this.Servers {
 | 
				
			||||||
 | 
							if !server.IsOn {
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							for _, addr := range server.FullAddresses() {
 | 
				
			||||||
 | 
								group, ok := groupMapping[addr]
 | 
				
			||||||
 | 
								if ok {
 | 
				
			||||||
 | 
									group.Add(server)
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									group = serverconfigs.NewServerGroup(addr)
 | 
				
			||||||
 | 
									group.Add(server)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								groupMapping[addr] = group
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						result := []*serverconfigs.ServerGroup{}
 | 
				
			||||||
 | 
						for _, group := range groupMapping {
 | 
				
			||||||
 | 
							result = append(result, group)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return result
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *NodeConfig) Init() error {
 | 
				
			||||||
 | 
						for _, server := range this.Servers {
 | 
				
			||||||
 | 
							err := server.Init()
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 写入到文件
 | 
				
			||||||
 | 
					func (this *NodeConfig) Save() error {
 | 
				
			||||||
 | 
						shared.Locker.Lock()
 | 
				
			||||||
 | 
						defer shared.Locker.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						data, err := json.Marshal(this)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return ioutil.WriteFile(Tea.ConfigFile("node.json"), data, 0777)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										66
									
								
								pkg/nodeconfigs/node_config_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								pkg/nodeconfigs/node_config_test.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,66 @@
 | 
				
			|||||||
 | 
					package nodeconfigs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
 | 
				
			||||||
 | 
						_ "github.com/iwind/TeaGo/bootstrap"
 | 
				
			||||||
 | 
						"github.com/iwind/TeaGo/logs"
 | 
				
			||||||
 | 
						"testing"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestSharedNodeConfig(t *testing.T) {
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							config, err := SharedNodeConfig()
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								t.Fatal(err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							t.Log(config)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// read from memory cache
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							config, err := SharedNodeConfig()
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								t.Fatal(err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							t.Log(config)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestNodeConfig_Groups(t *testing.T) {
 | 
				
			||||||
 | 
						config := &NodeConfig{}
 | 
				
			||||||
 | 
						config.Servers = []*serverconfigs.ServerConfig{
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								IsOn: true,
 | 
				
			||||||
 | 
								HTTP: &serverconfigs.HTTPProtocolConfig{
 | 
				
			||||||
 | 
									BaseProtocol: serverconfigs.BaseProtocol{
 | 
				
			||||||
 | 
										IsOn: true,
 | 
				
			||||||
 | 
										Listen: []*serverconfigs.NetworkAddressConfig{
 | 
				
			||||||
 | 
											{
 | 
				
			||||||
 | 
												Protocol:  serverconfigs.ProtocolHTTP,
 | 
				
			||||||
 | 
												Host:      "127.0.0.1",
 | 
				
			||||||
 | 
												PortRange: "1234",
 | 
				
			||||||
 | 
											},
 | 
				
			||||||
 | 
											{
 | 
				
			||||||
 | 
												Protocol:  serverconfigs.ProtocolHTTP,
 | 
				
			||||||
 | 
												PortRange: "8080",
 | 
				
			||||||
 | 
											},
 | 
				
			||||||
 | 
										},
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								HTTP: &serverconfigs.HTTPProtocolConfig{
 | 
				
			||||||
 | 
									BaseProtocol: serverconfigs.BaseProtocol{
 | 
				
			||||||
 | 
										IsOn: true,
 | 
				
			||||||
 | 
										Listen: []*serverconfigs.NetworkAddressConfig{
 | 
				
			||||||
 | 
											{
 | 
				
			||||||
 | 
												Protocol:  serverconfigs.ProtocolHTTP,
 | 
				
			||||||
 | 
												PortRange: "8080",
 | 
				
			||||||
 | 
											},
 | 
				
			||||||
 | 
										},
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						logs.PrintAsJSON(config.AvailableGroups(), t)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -38,6 +38,8 @@ type Node struct {
 | 
				
			|||||||
	Code          string             `protobuf:"bytes,6,opt,name=code,proto3" json:"code,omitempty"`
 | 
						Code          string             `protobuf:"bytes,6,opt,name=code,proto3" json:"code,omitempty"`
 | 
				
			||||||
	UniqueId      string             `protobuf:"bytes,7,opt,name=uniqueId,proto3" json:"uniqueId,omitempty"`
 | 
						UniqueId      string             `protobuf:"bytes,7,opt,name=uniqueId,proto3" json:"uniqueId,omitempty"`
 | 
				
			||||||
	Secret        string             `protobuf:"bytes,8,opt,name=secret,proto3" json:"secret,omitempty"`
 | 
						Secret        string             `protobuf:"bytes,8,opt,name=secret,proto3" json:"secret,omitempty"`
 | 
				
			||||||
 | 
						Version       int64              `protobuf:"varint,9,opt,name=version,proto3" json:"version,omitempty"`
 | 
				
			||||||
 | 
						LatestVersion int64              `protobuf:"varint,10,opt,name=latestVersion,proto3" json:"latestVersion,omitempty"`
 | 
				
			||||||
	Cluster       *NodeCluster       `protobuf:"bytes,32,opt,name=cluster,proto3" json:"cluster,omitempty"`
 | 
						Cluster       *NodeCluster       `protobuf:"bytes,32,opt,name=cluster,proto3" json:"cluster,omitempty"`
 | 
				
			||||||
	Login         *NodeLogin         `protobuf:"bytes,33,opt,name=login,proto3" json:"login,omitempty"`
 | 
						Login         *NodeLogin         `protobuf:"bytes,33,opt,name=login,proto3" json:"login,omitempty"`
 | 
				
			||||||
	InstallStatus *NodeInstallStatus `protobuf:"bytes,34,opt,name=installStatus,proto3" json:"installStatus,omitempty"`
 | 
						InstallStatus *NodeInstallStatus `protobuf:"bytes,34,opt,name=installStatus,proto3" json:"installStatus,omitempty"`
 | 
				
			||||||
@@ -131,6 +133,20 @@ func (x *Node) GetSecret() string {
 | 
				
			|||||||
	return ""
 | 
						return ""
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (x *Node) GetVersion() int64 {
 | 
				
			||||||
 | 
						if x != nil {
 | 
				
			||||||
 | 
							return x.Version
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return 0
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (x *Node) GetLatestVersion() int64 {
 | 
				
			||||||
 | 
						if x != nil {
 | 
				
			||||||
 | 
							return x.LatestVersion
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return 0
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (x *Node) GetCluster() *NodeCluster {
 | 
					func (x *Node) GetCluster() *NodeCluster {
 | 
				
			||||||
	if x != nil {
 | 
						if x != nil {
 | 
				
			||||||
		return x.Cluster
 | 
							return x.Cluster
 | 
				
			||||||
@@ -161,7 +177,7 @@ var file_model_node_proto_rawDesc = []byte{
 | 
				
			|||||||
	0x1a, 0x16, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x6c, 0x6f, 0x67,
 | 
						0x1a, 0x16, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x6c, 0x6f, 0x67,
 | 
				
			||||||
	0x69, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5f,
 | 
						0x69, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5f,
 | 
				
			||||||
	0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x5f, 0x73, 0x74, 0x61,
 | 
						0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x5f, 0x73, 0x74, 0x61,
 | 
				
			||||||
	0x74, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xd9, 0x02, 0x0a, 0x04, 0x4e, 0x6f,
 | 
						0x74, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x99, 0x03, 0x0a, 0x04, 0x4e, 0x6f,
 | 
				
			||||||
	0x64, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02,
 | 
						0x64, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02,
 | 
				
			||||||
	0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
 | 
						0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
 | 
				
			||||||
	0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73,
 | 
						0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73,
 | 
				
			||||||
@@ -174,7 +190,11 @@ var file_model_node_proto_rawDesc = []byte{
 | 
				
			|||||||
	0x63, 0x6f, 0x64, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x49, 0x64,
 | 
						0x63, 0x6f, 0x64, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x49, 0x64,
 | 
				
			||||||
	0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x49, 0x64,
 | 
						0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x49, 0x64,
 | 
				
			||||||
	0x12, 0x16, 0x0a, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09,
 | 
						0x12, 0x16, 0x0a, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09,
 | 
				
			||||||
	0x52, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x29, 0x0a, 0x07, 0x63, 0x6c, 0x75, 0x73,
 | 
						0x52, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73,
 | 
				
			||||||
 | 
						0x69, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69,
 | 
				
			||||||
 | 
						0x6f, 0x6e, 0x12, 0x24, 0x0a, 0x0d, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x56, 0x65, 0x72, 0x73,
 | 
				
			||||||
 | 
						0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x6c, 0x61, 0x74, 0x65, 0x73,
 | 
				
			||||||
 | 
						0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x29, 0x0a, 0x07, 0x63, 0x6c, 0x75, 0x73,
 | 
				
			||||||
	0x74, 0x65, 0x72, 0x18, 0x20, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x70, 0x62, 0x2e, 0x4e,
 | 
						0x74, 0x65, 0x72, 0x18, 0x20, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x70, 0x62, 0x2e, 0x4e,
 | 
				
			||||||
	0x6f, 0x64, 0x65, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x07, 0x63, 0x6c, 0x75, 0x73,
 | 
						0x6f, 0x64, 0x65, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x07, 0x63, 0x6c, 0x75, 0x73,
 | 
				
			||||||
	0x74, 0x65, 0x72, 0x12, 0x23, 0x0a, 0x05, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x18, 0x21, 0x20, 0x01,
 | 
						0x74, 0x65, 0x72, 0x12, 0x23, 0x0a, 0x05, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x18, 0x21, 0x20, 0x01,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -236,6 +236,7 @@ type ListEnabledNodesMatchRequest struct {
 | 
				
			|||||||
	Size         int64 `protobuf:"varint,2,opt,name=size,proto3" json:"size,omitempty"`
 | 
						Size         int64 `protobuf:"varint,2,opt,name=size,proto3" json:"size,omitempty"`
 | 
				
			||||||
	ClusterId    int64 `protobuf:"varint,3,opt,name=clusterId,proto3" json:"clusterId,omitempty"`
 | 
						ClusterId    int64 `protobuf:"varint,3,opt,name=clusterId,proto3" json:"clusterId,omitempty"`
 | 
				
			||||||
	InstallState int32 `protobuf:"varint,4,opt,name=installState,proto3" json:"installState,omitempty"`
 | 
						InstallState int32 `protobuf:"varint,4,opt,name=installState,proto3" json:"installState,omitempty"`
 | 
				
			||||||
 | 
						ActiveState  int32 `protobuf:"varint,5,opt,name=activeState,proto3" json:"activeState,omitempty"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (x *ListEnabledNodesMatchRequest) Reset() {
 | 
					func (x *ListEnabledNodesMatchRequest) Reset() {
 | 
				
			||||||
@@ -298,6 +299,13 @@ func (x *ListEnabledNodesMatchRequest) GetInstallState() int32 {
 | 
				
			|||||||
	return 0
 | 
						return 0
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (x *ListEnabledNodesMatchRequest) GetActiveState() int32 {
 | 
				
			||||||
 | 
						if x != nil {
 | 
				
			||||||
 | 
							return x.ActiveState
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return 0
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type ListEnabledNodesMatchResponse struct {
 | 
					type ListEnabledNodesMatchResponse struct {
 | 
				
			||||||
	state         protoimpl.MessageState
 | 
						state         protoimpl.MessageState
 | 
				
			||||||
	sizeCache     protoimpl.SizeCache
 | 
						sizeCache     protoimpl.SizeCache
 | 
				
			||||||
@@ -911,6 +919,7 @@ type CountAllEnabledNodesMatchRequest struct {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	ClusterId    int64 `protobuf:"varint,1,opt,name=clusterId,proto3" json:"clusterId,omitempty"`
 | 
						ClusterId    int64 `protobuf:"varint,1,opt,name=clusterId,proto3" json:"clusterId,omitempty"`
 | 
				
			||||||
	InstallState int32 `protobuf:"varint,2,opt,name=installState,proto3" json:"installState,omitempty"`
 | 
						InstallState int32 `protobuf:"varint,2,opt,name=installState,proto3" json:"installState,omitempty"`
 | 
				
			||||||
 | 
						ActiveState  int32 `protobuf:"varint,3,opt,name=activeState,proto3" json:"activeState,omitempty"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (x *CountAllEnabledNodesMatchRequest) Reset() {
 | 
					func (x *CountAllEnabledNodesMatchRequest) Reset() {
 | 
				
			||||||
@@ -959,6 +968,13 @@ func (x *CountAllEnabledNodesMatchRequest) GetInstallState() int32 {
 | 
				
			|||||||
	return 0
 | 
						return 0
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (x *CountAllEnabledNodesMatchRequest) GetActiveState() int32 {
 | 
				
			||||||
 | 
						if x != nil {
 | 
				
			||||||
 | 
							return x.ActiveState
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return 0
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type CountAllEnabledNodesMatchResponse struct {
 | 
					type CountAllEnabledNodesMatchResponse struct {
 | 
				
			||||||
	state         protoimpl.MessageState
 | 
						state         protoimpl.MessageState
 | 
				
			||||||
	sizeCache     protoimpl.SizeCache
 | 
						sizeCache     protoimpl.SizeCache
 | 
				
			||||||
@@ -1171,7 +1187,7 @@ var file_service_node_proto_rawDesc = []byte{
 | 
				
			|||||||
	0x34, 0x0a, 0x1c, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x6c, 0x6c, 0x45, 0x6e, 0x61, 0x62, 0x6c,
 | 
						0x34, 0x0a, 0x1c, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x6c, 0x6c, 0x45, 0x6e, 0x61, 0x62, 0x6c,
 | 
				
			||||||
	0x65, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
 | 
						0x65, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
 | 
				
			||||||
	0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05,
 | 
						0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05,
 | 
				
			||||||
	0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x8c, 0x01, 0x0a, 0x1c, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x6e,
 | 
						0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0xae, 0x01, 0x0a, 0x1c, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x6e,
 | 
				
			||||||
	0x61, 0x62, 0x6c, 0x65, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52,
 | 
						0x61, 0x62, 0x6c, 0x65, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52,
 | 
				
			||||||
	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74,
 | 
						0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74,
 | 
				
			||||||
	0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x12,
 | 
						0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x12,
 | 
				
			||||||
@@ -1180,136 +1196,140 @@ var file_service_node_proto_rawDesc = []byte{
 | 
				
			|||||||
	0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x64,
 | 
						0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x64,
 | 
				
			||||||
	0x12, 0x22, 0x0a, 0x0c, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65,
 | 
						0x12, 0x22, 0x0a, 0x0c, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65,
 | 
				
			||||||
	0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x53,
 | 
						0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x53,
 | 
				
			||||||
	0x74, 0x61, 0x74, 0x65, 0x22, 0x3f, 0x0a, 0x1d, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x6e, 0x61, 0x62,
 | 
						0x74, 0x61, 0x74, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x53, 0x74,
 | 
				
			||||||
	0x6c, 0x65, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73,
 | 
						0x61, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x61, 0x63, 0x74, 0x69, 0x76,
 | 
				
			||||||
	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1e, 0x0a, 0x05, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x18, 0x01,
 | 
						0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x22, 0x3f, 0x0a, 0x1d, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x6e,
 | 
				
			||||||
	0x20, 0x03, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x70, 0x62, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x05,
 | 
						0x61, 0x62, 0x6c, 0x65, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52,
 | 
				
			||||||
	0x6e, 0x6f, 0x64, 0x65, 0x73, 0x22, 0x2c, 0x0a, 0x12, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65,
 | 
						0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1e, 0x0a, 0x05, 0x6e, 0x6f, 0x64, 0x65, 0x73,
 | 
				
			||||||
 | 
						0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x70, 0x62, 0x2e, 0x4e, 0x6f, 0x64, 0x65,
 | 
				
			||||||
 | 
						0x52, 0x05, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x22, 0x2c, 0x0a, 0x12, 0x44, 0x69, 0x73, 0x61, 0x62,
 | 
				
			||||||
 | 
						0x6c, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a,
 | 
				
			||||||
 | 
						0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x6e,
 | 
				
			||||||
 | 
						0x6f, 0x64, 0x65, 0x49, 0x64, 0x22, 0x15, 0x0a, 0x13, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65,
 | 
				
			||||||
 | 
						0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x82, 0x01, 0x0a,
 | 
				
			||||||
 | 
						0x11, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65,
 | 
				
			||||||
 | 
						0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01,
 | 
				
			||||||
 | 
						0x28, 0x03, 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61,
 | 
				
			||||||
 | 
						0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1c,
 | 
				
			||||||
 | 
						0x0a, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28,
 | 
				
			||||||
 | 
						0x03, 0x52, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x05,
 | 
				
			||||||
 | 
						0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x62,
 | 
				
			||||||
 | 
						0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x05, 0x4c, 0x6f, 0x67, 0x69,
 | 
				
			||||||
 | 
						0x6e, 0x22, 0x30, 0x0a, 0x16, 0x46, 0x69, 0x6e, 0x64, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64,
 | 
				
			||||||
	0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6e,
 | 
						0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6e,
 | 
				
			||||||
	0x6f, 0x64, 0x65, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x6e, 0x6f, 0x64,
 | 
						0x6f, 0x64, 0x65, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x6e, 0x6f, 0x64,
 | 
				
			||||||
	0x65, 0x49, 0x64, 0x22, 0x15, 0x0a, 0x13, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x6f,
 | 
						0x65, 0x49, 0x64, 0x22, 0x37, 0x0a, 0x17, 0x46, 0x69, 0x6e, 0x64, 0x45, 0x6e, 0x61, 0x62, 0x6c,
 | 
				
			||||||
	0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x82, 0x01, 0x0a, 0x11, 0x55,
 | 
						0x65, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c,
 | 
				
			||||||
	0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
 | 
						0x0a, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x70,
 | 
				
			||||||
	0x12, 0x16, 0x0a, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03,
 | 
						0x62, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x22, 0x1a, 0x0a, 0x18,
 | 
				
			||||||
	0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65,
 | 
						0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x73, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69,
 | 
				
			||||||
	0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09,
 | 
						0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x37, 0x0a, 0x19, 0x43, 0x6f, 0x6d, 0x70,
 | 
				
			||||||
	0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52,
 | 
						0x6f, 0x73, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73,
 | 
				
			||||||
	0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x05, 0x4c, 0x6f,
 | 
						0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x4a, 0x53, 0x4f,
 | 
				
			||||||
	0x67, 0x69, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x62, 0x2e, 0x4e,
 | 
						0x4e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x4a, 0x53, 0x4f,
 | 
				
			||||||
	0x6f, 0x64, 0x65, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x05, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x22,
 | 
						0x4e, 0x22, 0x13, 0x0a, 0x11, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52,
 | 
				
			||||||
	0x30, 0x0a, 0x16, 0x46, 0x69, 0x6e, 0x64, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4e, 0x6f,
 | 
						0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x14, 0x0a, 0x12, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x74,
 | 
				
			||||||
	0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x6f, 0x64,
 | 
						0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x51, 0x0a, 0x17,
 | 
				
			||||||
	0x65, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49,
 | 
						0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73,
 | 
				
			||||||
	0x64, 0x22, 0x37, 0x0a, 0x17, 0x46, 0x69, 0x6e, 0x64, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64,
 | 
						0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49,
 | 
				
			||||||
	0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x04,
 | 
						0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x12,
 | 
				
			||||||
	0x6e, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x70, 0x62, 0x2e,
 | 
						0x1e, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x4a, 0x53, 0x4f, 0x4e, 0x18, 0x02, 0x20,
 | 
				
			||||||
	0x4e, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x22, 0x1a, 0x0a, 0x18, 0x43, 0x6f,
 | 
						0x01, 0x28, 0x0c, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x4a, 0x53, 0x4f, 0x4e, 0x22,
 | 
				
			||||||
	0x6d, 0x70, 0x6f, 0x73, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52,
 | 
						0x42, 0x0a, 0x22, 0x53, 0x79, 0x6e, 0x63, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x56, 0x65, 0x72, 0x73,
 | 
				
			||||||
	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x37, 0x0a, 0x19, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x73,
 | 
						0x69, 0x6f, 0x6e, 0x57, 0x69, 0x74, 0x68, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65,
 | 
				
			||||||
	0x65, 0x4e, 0x6f, 0x64, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f,
 | 
						0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72,
 | 
				
			||||||
	0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x4a, 0x53, 0x4f, 0x4e, 0x18,
 | 
						0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65,
 | 
				
			||||||
	0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x4a, 0x53, 0x4f, 0x4e, 0x22,
 | 
						0x72, 0x49, 0x64, 0x22, 0x25, 0x0a, 0x23, 0x53, 0x79, 0x6e, 0x63, 0x4e, 0x6f, 0x64, 0x65, 0x73,
 | 
				
			||||||
	0x13, 0x0a, 0x11, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71,
 | 
						0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x57, 0x69, 0x74, 0x68, 0x43, 0x6c, 0x75, 0x73, 0x74,
 | 
				
			||||||
	0x75, 0x65, 0x73, 0x74, 0x22, 0x14, 0x0a, 0x12, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x74, 0x72, 0x65,
 | 
						0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x86, 0x01, 0x0a, 0x20, 0x43,
 | 
				
			||||||
	0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x51, 0x0a, 0x17, 0x55, 0x70,
 | 
						0x6f, 0x75, 0x6e, 0x74, 0x41, 0x6c, 0x6c, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4e, 0x6f,
 | 
				
			||||||
	0x64, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65,
 | 
						0x64, 0x65, 0x73, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
 | 
				
			||||||
	0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x18,
 | 
						0x1c, 0x0a, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01,
 | 
				
			||||||
	0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x12, 0x1e, 0x0a,
 | 
						0x28, 0x03, 0x52, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x64, 0x12, 0x22, 0x0a,
 | 
				
			||||||
	0x0a, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x4a, 0x53, 0x4f, 0x4e, 0x18, 0x02, 0x20, 0x01, 0x28,
 | 
						0x0c, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20,
 | 
				
			||||||
	0x0c, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x4a, 0x53, 0x4f, 0x4e, 0x22, 0x42, 0x0a,
 | 
						0x01, 0x28, 0x05, 0x52, 0x0c, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74,
 | 
				
			||||||
	0x22, 0x53, 0x79, 0x6e, 0x63, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f,
 | 
						0x65, 0x12, 0x20, 0x0a, 0x0b, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65,
 | 
				
			||||||
	0x6e, 0x57, 0x69, 0x74, 0x68, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75,
 | 
						0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x53, 0x74,
 | 
				
			||||||
	0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x64,
 | 
						0x61, 0x74, 0x65, 0x22, 0x39, 0x0a, 0x21, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x6c, 0x6c, 0x45,
 | 
				
			||||||
	0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49,
 | 
					 | 
				
			||||||
	0x64, 0x22, 0x25, 0x0a, 0x23, 0x53, 0x79, 0x6e, 0x63, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x56, 0x65,
 | 
					 | 
				
			||||||
	0x72, 0x73, 0x69, 0x6f, 0x6e, 0x57, 0x69, 0x74, 0x68, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72,
 | 
					 | 
				
			||||||
	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x64, 0x0a, 0x20, 0x43, 0x6f, 0x75, 0x6e,
 | 
					 | 
				
			||||||
	0x74, 0x41, 0x6c, 0x6c, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x73,
 | 
					 | 
				
			||||||
	0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09,
 | 
					 | 
				
			||||||
	0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52,
 | 
					 | 
				
			||||||
	0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x64, 0x12, 0x22, 0x0a, 0x0c, 0x69, 0x6e,
 | 
					 | 
				
			||||||
	0x73, 0x74, 0x61, 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05,
 | 
					 | 
				
			||||||
	0x52, 0x0c, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x22, 0x39,
 | 
					 | 
				
			||||||
	0x0a, 0x21, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x6c, 0x6c, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65,
 | 
					 | 
				
			||||||
	0x64, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f,
 | 
					 | 
				
			||||||
	0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01,
 | 
					 | 
				
			||||||
	0x28, 0x03, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x58, 0x0a, 0x1c, 0x55, 0x70, 0x64,
 | 
					 | 
				
			||||||
	0x61, 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x73, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c,
 | 
					 | 
				
			||||||
	0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x6f, 0x64,
 | 
					 | 
				
			||||||
	0x65, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49,
 | 
					 | 
				
			||||||
	0x64, 0x12, 0x20, 0x0a, 0x0b, 0x69, 0x73, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x64,
 | 
					 | 
				
			||||||
	0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, 0x73, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c,
 | 
					 | 
				
			||||||
	0x6c, 0x65, 0x64, 0x22, 0x2c, 0x0a, 0x12, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x4e, 0x6f,
 | 
					 | 
				
			||||||
	0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x6f, 0x64,
 | 
					 | 
				
			||||||
	0x65, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49,
 | 
					 | 
				
			||||||
	0x64, 0x22, 0x15, 0x0a, 0x13, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x4e, 0x6f, 0x64, 0x65,
 | 
					 | 
				
			||||||
	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x8f, 0x08, 0x0a, 0x0b, 0x4e, 0x6f, 0x64,
 | 
					 | 
				
			||||||
	0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x3b, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61,
 | 
					 | 
				
			||||||
	0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x15, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x65, 0x61,
 | 
					 | 
				
			||||||
	0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e,
 | 
					 | 
				
			||||||
	0x70, 0x62, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73,
 | 
					 | 
				
			||||||
	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x59, 0x0a, 0x14, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x6c,
 | 
					 | 
				
			||||||
	0x6c, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x12, 0x1f, 0x2e,
 | 
					 | 
				
			||||||
	0x70, 0x62, 0x2e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x6c, 0x6c, 0x45, 0x6e, 0x61, 0x62, 0x6c,
 | 
					 | 
				
			||||||
	0x65, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20,
 | 
					 | 
				
			||||||
	0x2e, 0x70, 0x62, 0x2e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x6c, 0x6c, 0x45, 0x6e, 0x61, 0x62,
 | 
					 | 
				
			||||||
	0x6c, 0x65, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
 | 
					 | 
				
			||||||
	0x12, 0x68, 0x0a, 0x19, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x6c, 0x6c, 0x45, 0x6e, 0x61, 0x62,
 | 
					 | 
				
			||||||
	0x6c, 0x65, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x24, 0x2e,
 | 
					 | 
				
			||||||
	0x70, 0x62, 0x2e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x6c, 0x6c, 0x45, 0x6e, 0x61, 0x62, 0x6c,
 | 
					 | 
				
			||||||
	0x65, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75,
 | 
					 | 
				
			||||||
	0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x6c,
 | 
					 | 
				
			||||||
	0x6c, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x4d, 0x61, 0x74,
 | 
					 | 
				
			||||||
	0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5c, 0x0a, 0x15, 0x6c, 0x69,
 | 
					 | 
				
			||||||
	0x73, 0x74, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x4d, 0x61,
 | 
					 | 
				
			||||||
	0x74, 0x63, 0x68, 0x12, 0x20, 0x2e, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x6e, 0x61,
 | 
					 | 
				
			||||||
	0x62, 0x6c, 0x65, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65,
 | 
					 | 
				
			||||||
	0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x45,
 | 
					 | 
				
			||||||
	0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x4d, 0x61, 0x74, 0x63, 0x68,
 | 
						0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x4d, 0x61, 0x74, 0x63, 0x68,
 | 
				
			||||||
	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x0b, 0x64, 0x69, 0x73, 0x61,
 | 
						0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e,
 | 
				
			||||||
	0x62, 0x6c, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x16, 0x2e, 0x70, 0x62, 0x2e, 0x44, 0x69, 0x73,
 | 
						0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x58,
 | 
				
			||||||
	0x61, 0x62, 0x6c, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
 | 
						0x0a, 0x1c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x73, 0x49, 0x6e,
 | 
				
			||||||
	0x17, 0x2e, 0x70, 0x62, 0x2e, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x6f, 0x64, 0x65,
 | 
						0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16,
 | 
				
			||||||
	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61,
 | 
						0x0a, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06,
 | 
				
			||||||
	0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x15, 0x2e, 0x70, 0x62, 0x2e, 0x55, 0x70, 0x64, 0x61,
 | 
						0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x69, 0x73, 0x49, 0x6e, 0x73, 0x74,
 | 
				
			||||||
	0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e,
 | 
						0x61, 0x6c, 0x6c, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, 0x73, 0x49,
 | 
				
			||||||
	0x70, 0x62, 0x2e, 0x52, 0x50, 0x43, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x75, 0x63, 0x63,
 | 
						0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x22, 0x2c, 0x0a, 0x12, 0x49, 0x6e, 0x73, 0x74,
 | 
				
			||||||
	0x65, 0x73, 0x73, 0x12, 0x4a, 0x0a, 0x0f, 0x66, 0x69, 0x6e, 0x64, 0x45, 0x6e, 0x61, 0x62, 0x6c,
 | 
						0x61, 0x6c, 0x6c, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16,
 | 
				
			||||||
	0x65, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x1a, 0x2e, 0x70, 0x62, 0x2e, 0x46, 0x69, 0x6e, 0x64,
 | 
						0x0a, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06,
 | 
				
			||||||
	0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65,
 | 
						0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x22, 0x15, 0x0a, 0x13, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c,
 | 
				
			||||||
	0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x70, 0x62, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x45, 0x6e, 0x61, 0x62,
 | 
						0x6c, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x8f, 0x08,
 | 
				
			||||||
	0x6c, 0x65, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
 | 
						0x0a, 0x0b, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x3b, 0x0a,
 | 
				
			||||||
	0x50, 0x0a, 0x11, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x73, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x43, 0x6f,
 | 
						0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x15, 0x2e, 0x70, 0x62,
 | 
				
			||||||
	0x6e, 0x66, 0x69, 0x67, 0x12, 0x1c, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x73,
 | 
						0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65,
 | 
				
			||||||
	0x65, 0x4e, 0x6f, 0x64, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65,
 | 
						0x73, 0x74, 0x1a, 0x16, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x6f,
 | 
				
			||||||
	0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x73, 0x65, 0x4e,
 | 
						0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x59, 0x0a, 0x14, 0x63, 0x6f,
 | 
				
			||||||
	0x6f, 0x64, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
 | 
						0x75, 0x6e, 0x74, 0x41, 0x6c, 0x6c, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4e, 0x6f, 0x64,
 | 
				
			||||||
	0x65, 0x12, 0x3f, 0x0a, 0x0a, 0x6e, 0x6f, 0x64, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12,
 | 
						0x65, 0x73, 0x12, 0x1f, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x6c, 0x6c,
 | 
				
			||||||
	0x15, 0x2e, 0x70, 0x62, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52,
 | 
						0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75,
 | 
				
			||||||
	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x70, 0x62, 0x2e, 0x4e, 0x6f, 0x64, 0x65,
 | 
						0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x6c,
 | 
				
			||||||
	0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x28, 0x01,
 | 
						0x6c, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x52, 0x65, 0x73,
 | 
				
			||||||
	0x30, 0x01, 0x12, 0x45, 0x0a, 0x10, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65,
 | 
						0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x68, 0x0a, 0x19, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x6c,
 | 
				
			||||||
	0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1b, 0x2e, 0x70, 0x62, 0x2e, 0x55, 0x70, 0x64, 0x61,
 | 
						0x6c, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x4d, 0x61, 0x74,
 | 
				
			||||||
	0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75,
 | 
						0x63, 0x68, 0x12, 0x24, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x6c, 0x6c,
 | 
				
			||||||
	0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x70, 0x62, 0x2e, 0x52, 0x50, 0x43, 0x55, 0x70, 0x64, 0x61,
 | 
						0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x4d, 0x61, 0x74, 0x63,
 | 
				
			||||||
	0x74, 0x65, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x6e, 0x0a, 0x1b, 0x73, 0x79, 0x6e,
 | 
						0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x6f,
 | 
				
			||||||
	0x63, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x57, 0x69, 0x74,
 | 
						0x75, 0x6e, 0x74, 0x41, 0x6c, 0x6c, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4e, 0x6f, 0x64,
 | 
				
			||||||
	0x68, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, 0x26, 0x2e, 0x70, 0x62, 0x2e, 0x53, 0x79,
 | 
						0x65, 0x73, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
 | 
				
			||||||
	0x6e, 0x63, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x57, 0x69,
 | 
						0x5c, 0x0a, 0x15, 0x6c, 0x69, 0x73, 0x74, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4e, 0x6f,
 | 
				
			||||||
	0x74, 0x68, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
 | 
						0x64, 0x65, 0x73, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x20, 0x2e, 0x70, 0x62, 0x2e, 0x4c, 0x69,
 | 
				
			||||||
	0x1a, 0x27, 0x2e, 0x70, 0x62, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x56,
 | 
						0x73, 0x74, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x4d, 0x61,
 | 
				
			||||||
	0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x57, 0x69, 0x74, 0x68, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65,
 | 
						0x74, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x70, 0x62, 0x2e,
 | 
				
			||||||
	0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4f, 0x0a, 0x15, 0x75, 0x70, 0x64,
 | 
						0x4c, 0x69, 0x73, 0x74, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x73,
 | 
				
			||||||
 | 
						0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a,
 | 
				
			||||||
 | 
						0x0b, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x16, 0x2e, 0x70,
 | 
				
			||||||
 | 
						0x62, 0x2e, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71,
 | 
				
			||||||
 | 
						0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x70, 0x62, 0x2e, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c,
 | 
				
			||||||
 | 
						0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a,
 | 
				
			||||||
 | 
						0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x15, 0x2e, 0x70, 0x62,
 | 
				
			||||||
 | 
						0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65,
 | 
				
			||||||
 | 
						0x73, 0x74, 0x1a, 0x14, 0x2e, 0x70, 0x62, 0x2e, 0x52, 0x50, 0x43, 0x55, 0x70, 0x64, 0x61, 0x74,
 | 
				
			||||||
 | 
						0x65, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x4a, 0x0a, 0x0f, 0x66, 0x69, 0x6e, 0x64,
 | 
				
			||||||
 | 
						0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x1a, 0x2e, 0x70, 0x62,
 | 
				
			||||||
 | 
						0x2e, 0x46, 0x69, 0x6e, 0x64, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4e, 0x6f, 0x64, 0x65,
 | 
				
			||||||
 | 
						0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x70, 0x62, 0x2e, 0x46, 0x69, 0x6e,
 | 
				
			||||||
 | 
						0x64, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70,
 | 
				
			||||||
 | 
						0x6f, 0x6e, 0x73, 0x65, 0x12, 0x50, 0x0a, 0x11, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x73, 0x65, 0x4e,
 | 
				
			||||||
 | 
						0x6f, 0x64, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1c, 0x2e, 0x70, 0x62, 0x2e, 0x43,
 | 
				
			||||||
 | 
						0x6f, 0x6d, 0x70, 0x6f, 0x73, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
 | 
				
			||||||
 | 
						0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x6f, 0x6d,
 | 
				
			||||||
 | 
						0x70, 0x6f, 0x73, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65,
 | 
				
			||||||
 | 
						0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3f, 0x0a, 0x0a, 0x6e, 0x6f, 0x64, 0x65, 0x53, 0x74,
 | 
				
			||||||
 | 
						0x72, 0x65, 0x61, 0x6d, 0x12, 0x15, 0x2e, 0x70, 0x62, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x74,
 | 
				
			||||||
 | 
						0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x70, 0x62,
 | 
				
			||||||
 | 
						0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f,
 | 
				
			||||||
 | 
						0x6e, 0x73, 0x65, 0x28, 0x01, 0x30, 0x01, 0x12, 0x45, 0x0a, 0x10, 0x75, 0x70, 0x64, 0x61, 0x74,
 | 
				
			||||||
 | 
						0x65, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1b, 0x2e, 0x70, 0x62,
 | 
				
			||||||
 | 
						0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75,
 | 
				
			||||||
 | 
						0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x70, 0x62, 0x2e, 0x52, 0x50,
 | 
				
			||||||
 | 
						0x43, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x6e,
 | 
				
			||||||
 | 
						0x0a, 0x1b, 0x73, 0x79, 0x6e, 0x63, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x56, 0x65, 0x72, 0x73, 0x69,
 | 
				
			||||||
 | 
						0x6f, 0x6e, 0x57, 0x69, 0x74, 0x68, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, 0x26, 0x2e,
 | 
				
			||||||
 | 
						0x70, 0x62, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x56, 0x65, 0x72, 0x73,
 | 
				
			||||||
 | 
						0x69, 0x6f, 0x6e, 0x57, 0x69, 0x74, 0x68, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65,
 | 
				
			||||||
 | 
						0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x70, 0x62, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x4e,
 | 
				
			||||||
 | 
						0x6f, 0x64, 0x65, 0x73, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x57, 0x69, 0x74, 0x68, 0x43,
 | 
				
			||||||
 | 
						0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4f,
 | 
				
			||||||
 | 
						0x0a, 0x15, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x73, 0x49, 0x6e,
 | 
				
			||||||
 | 
						0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x12, 0x20, 0x2e, 0x70, 0x62, 0x2e, 0x55, 0x70, 0x64,
 | 
				
			||||||
	0x61, 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x73, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c,
 | 
						0x61, 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x73, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c,
 | 
				
			||||||
	0x65, 0x64, 0x12, 0x20, 0x2e, 0x70, 0x62, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x6f,
 | 
						0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x70, 0x62, 0x2e, 0x52,
 | 
				
			||||||
	0x64, 0x65, 0x49, 0x73, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x52, 0x65, 0x71,
 | 
						0x50, 0x43, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12,
 | 
				
			||||||
	0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x70, 0x62, 0x2e, 0x52, 0x50, 0x43, 0x55, 0x70, 0x64,
 | 
						0x3e, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x16,
 | 
				
			||||||
	0x61, 0x74, 0x65, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x3e, 0x0a, 0x0b, 0x69, 0x6e,
 | 
						0x2e, 0x70, 0x62, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x4e, 0x6f, 0x64, 0x65, 0x52,
 | 
				
			||||||
	0x73, 0x74, 0x61, 0x6c, 0x6c, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x16, 0x2e, 0x70, 0x62, 0x2e, 0x49,
 | 
						0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x70, 0x62, 0x2e, 0x49, 0x6e, 0x73, 0x74,
 | 
				
			||||||
	0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
 | 
						0x61, 0x6c, 0x6c, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42,
 | 
				
			||||||
	0x74, 0x1a, 0x17, 0x2e, 0x70, 0x62, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x4e, 0x6f,
 | 
						0x06, 0x5a, 0x04, 0x2e, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 | 
				
			||||||
	0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x06, 0x5a, 0x04, 0x2e, 0x2f,
 | 
					 | 
				
			||||||
	0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var (
 | 
					var (
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,6 +16,8 @@ message Node {
 | 
				
			|||||||
	string code = 6;
 | 
						string code = 6;
 | 
				
			||||||
	string uniqueId = 7;
 | 
						string uniqueId = 7;
 | 
				
			||||||
	string secret = 8;
 | 
						string secret = 8;
 | 
				
			||||||
 | 
						int64 version = 9;
 | 
				
			||||||
 | 
						int64 latestVersion = 10;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	NodeCluster cluster = 32;
 | 
						NodeCluster cluster = 32;
 | 
				
			||||||
	NodeLogin login = 33;
 | 
						NodeLogin login = 33;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -73,6 +73,7 @@ message ListEnabledNodesMatchRequest {
 | 
				
			|||||||
	int64 size = 2;
 | 
						int64 size = 2;
 | 
				
			||||||
	int64 clusterId = 3;
 | 
						int64 clusterId = 3;
 | 
				
			||||||
	int32 installState = 4;
 | 
						int32 installState = 4;
 | 
				
			||||||
 | 
						int32 activeState = 5;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
message ListEnabledNodesMatchResponse {
 | 
					message ListEnabledNodesMatchResponse {
 | 
				
			||||||
@@ -141,6 +142,7 @@ message SyncNodesVersionWithClusterResponse {
 | 
				
			|||||||
message CountAllEnabledNodesMatchRequest {
 | 
					message CountAllEnabledNodesMatchRequest {
 | 
				
			||||||
	int64 clusterId = 1;
 | 
						int64 clusterId = 1;
 | 
				
			||||||
	int32 installState = 2;
 | 
						int32 installState = 2;
 | 
				
			||||||
 | 
						int32 activeState = 3;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
message CountAllEnabledNodesMatchResponse {
 | 
					message CountAllEnabledNodesMatchResponse {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +0,0 @@
 | 
				
			|||||||
package serverconfigs
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type ComponentConfig struct {
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,4 +0,0 @@
 | 
				
			|||||||
package serverconfigs
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type FilterConfig struct {
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,13 +1,5 @@
 | 
				
			|||||||
package serverconfigs
 | 
					package serverconfigs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/configutils"
 | 
					 | 
				
			||||||
	"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
var globalConfig *GlobalConfig = nil
 | 
					 | 
				
			||||||
var globalConfigFile = "global.yaml"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 全局设置
 | 
					// 全局设置
 | 
				
			||||||
type GlobalConfig struct {
 | 
					type GlobalConfig struct {
 | 
				
			||||||
	HTTPAll struct {
 | 
						HTTPAll struct {
 | 
				
			||||||
@@ -22,22 +14,6 @@ type GlobalConfig struct {
 | 
				
			|||||||
	UDP    struct{} `yaml:"udp" json:"udp"`
 | 
						UDP    struct{} `yaml:"udp" json:"udp"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func SharedGlobalConfig() *GlobalConfig {
 | 
					 | 
				
			||||||
	shared.Locker.Lock()
 | 
					 | 
				
			||||||
	defer shared.Locker.Unlock()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if globalConfig != nil {
 | 
					 | 
				
			||||||
		return globalConfig
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	err := configutils.UnmarshalYamlFile(globalConfigFile, globalConfig)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		configutils.LogError("[SharedGlobalConfig]" + err.Error())
 | 
					 | 
				
			||||||
		globalConfig = &GlobalConfig{}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return globalConfig
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (this *GlobalConfig) Init() error {
 | 
					func (this *GlobalConfig) Init() error {
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
package serverconfigs
 | 
					package serverconfigs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/configutils"
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/configutils"
 | 
				
			||||||
	"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
 | 
				
			||||||
	"github.com/iwind/TeaGo/Tea"
 | 
						"github.com/iwind/TeaGo/Tea"
 | 
				
			||||||
	"github.com/iwind/TeaGo/logs"
 | 
						"github.com/iwind/TeaGo/logs"
 | 
				
			||||||
@@ -14,12 +14,12 @@ import (
 | 
				
			|||||||
// 日志存储策略
 | 
					// 日志存储策略
 | 
				
			||||||
// 存储在configs/accesslog.storage.$id.conf
 | 
					// 存储在configs/accesslog.storage.$id.conf
 | 
				
			||||||
type HTTPAccessLogStoragePolicy struct {
 | 
					type HTTPAccessLogStoragePolicy struct {
 | 
				
			||||||
	Id      int64                  `yaml:"id" json:"id"`
 | 
						Id         int64                          `yaml:"id" json:"id"`
 | 
				
			||||||
	Name    string                 `yaml:"name" json:"name"`
 | 
						Name       string                         `yaml:"name" json:"name"`
 | 
				
			||||||
	IsOn    bool                   `yaml:"isOn" json:"isOn"`
 | 
						IsOn       bool                           `yaml:"isOn" json:"isOn"`
 | 
				
			||||||
	Type    string                 `yaml:"type" json:"type"`       // 存储类型
 | 
						Type       string                         `yaml:"type" json:"type"`              // 存储类型
 | 
				
			||||||
	Options map[string]interface{} `yaml:"options" json:"options"` // 存储选项
 | 
						Options    map[string]interface{}         `yaml:"options" json:"options"`        // 存储选项
 | 
				
			||||||
	Conds   []*shared.RequestCond  `yaml:"conds" json:"conds"`     // 请求条件
 | 
						CondGroups []*shared.HTTPRequestCondGroup `yaml:"condGroups" json:"condsGroups"` // 请求条件
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 创建新策略
 | 
					// 创建新策略
 | 
				
			||||||
@@ -49,8 +49,8 @@ func NewAccessLogStoragePolicyFromId(id string) *HTTPAccessLogStoragePolicy {
 | 
				
			|||||||
// 校验
 | 
					// 校验
 | 
				
			||||||
func (this *HTTPAccessLogStoragePolicy) Init() error {
 | 
					func (this *HTTPAccessLogStoragePolicy) Init() error {
 | 
				
			||||||
	// cond
 | 
						// cond
 | 
				
			||||||
	if len(this.Conds) > 0 {
 | 
						if len(this.CondGroups) > 0 {
 | 
				
			||||||
		for _, cond := range this.Conds {
 | 
							for _, cond := range this.CondGroups {
 | 
				
			||||||
			err := cond.Init()
 | 
								err := cond.Init()
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				return err
 | 
									return err
 | 
				
			||||||
@@ -95,10 +95,10 @@ func (this *HTTPAccessLogStoragePolicy) MatchKeyword(keyword string) (matched bo
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// 匹配条件
 | 
					// 匹配条件
 | 
				
			||||||
func (this *HTTPAccessLogStoragePolicy) MatchConds(formatter func(string) string) bool {
 | 
					func (this *HTTPAccessLogStoragePolicy) MatchConds(formatter func(string) string) bool {
 | 
				
			||||||
	if len(this.Conds) == 0 {
 | 
						if len(this.CondGroups) == 0 {
 | 
				
			||||||
		return true
 | 
							return true
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	for _, cond := range this.Conds {
 | 
						for _, cond := range this.CondGroups {
 | 
				
			||||||
		if !cond.Match(formatter) {
 | 
							if !cond.Match(formatter) {
 | 
				
			||||||
			return false
 | 
								return false
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
package serverconfigs
 | 
					package serverconfigs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/configutils"
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/configutils"
 | 
				
			||||||
	"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
 | 
				
			||||||
	"github.com/iwind/TeaGo/Tea"
 | 
						"github.com/iwind/TeaGo/Tea"
 | 
				
			||||||
	"github.com/iwind/TeaGo/files"
 | 
						"github.com/iwind/TeaGo/files"
 | 
				
			||||||
@@ -29,7 +29,7 @@ type HTTPCachePolicy struct {
 | 
				
			|||||||
	SkipResponseSetCookie          bool     `yaml:"skipSetCookie" json:"skipSetCookie"`                       // 是否跳过响应的Set-Cookie Header
 | 
						SkipResponseSetCookie          bool     `yaml:"skipSetCookie" json:"skipSetCookie"`                       // 是否跳过响应的Set-Cookie Header
 | 
				
			||||||
	EnableRequestCachePragma       bool     `yaml:"enableRequestCachePragma" json:"enableRequestCachePragma"` // 是否支持客户端的Pragma: no-cache
 | 
						EnableRequestCachePragma       bool     `yaml:"enableRequestCachePragma" json:"enableRequestCachePragma"` // 是否支持客户端的Pragma: no-cache
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Cond []*shared.RequestCond `yaml:"cond" json:"cond"`
 | 
						CondGroups []*shared.HTTPRequestCondGroup `yaml:"condGroups" json:"condGroups"`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	life     time.Duration
 | 
						life     time.Duration
 | 
				
			||||||
	maxSize  int64
 | 
						maxSize  int64
 | 
				
			||||||
@@ -86,8 +86,8 @@ func (this *HTTPCachePolicy) Init() error {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// cond
 | 
						// cond
 | 
				
			||||||
	if len(this.Cond) > 0 {
 | 
						if len(this.CondGroups) > 0 {
 | 
				
			||||||
		for _, cond := range this.Cond {
 | 
							for _, cond := range this.CondGroups {
 | 
				
			||||||
			err := cond.Init()
 | 
								err := cond.Init()
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				return err
 | 
									return err
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,3 +5,7 @@ type HTTPCacheRef struct {
 | 
				
			|||||||
	IsOn          bool  `yaml:"isOn" json:"isOn"`                   // 是否开启
 | 
						IsOn          bool  `yaml:"isOn" json:"isOn"`                   // 是否开启
 | 
				
			||||||
	CachePolicyId int64 `yaml:"cachePolicyId" json:"cachePolicyId"` // 缓存策略ID
 | 
						CachePolicyId int64 `yaml:"cachePolicyId" json:"cachePolicyId"` // 缓存策略ID
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *HTTPCacheRef) Init() error {
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,3 +5,7 @@ type HTTPCharsetConfig struct {
 | 
				
			|||||||
	IsOn    bool   `yaml:"isOn" json:"isOn"`       // 是否启用
 | 
						IsOn    bool   `yaml:"isOn" json:"isOn"`       // 是否启用
 | 
				
			||||||
	Charset string `yaml:"charset" json:"charset"` // 字符集
 | 
						Charset string `yaml:"charset" json:"charset"` // 字符集
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *HTTPCharsetConfig) Init() error {
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										8
									
								
								pkg/serverconfigs/http_filter_config.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								pkg/serverconfigs/http_filter_config.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
				
			|||||||
 | 
					package serverconfigs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type HTTPFilterPolicy struct {
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *HTTPFilterPolicy) Init() error {
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										11
									
								
								pkg/serverconfigs/http_filter_ref.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								pkg/serverconfigs/http_filter_ref.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
				
			|||||||
 | 
					package serverconfigs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type HTTPFilterRef struct {
 | 
				
			||||||
 | 
						IsPrior        bool  `yaml:"isPrior" json:"isPrior"`
 | 
				
			||||||
 | 
						IsOn           bool  `yaml:"isOn" json:"isOn"`
 | 
				
			||||||
 | 
						FilterPolicyId int64 `yaml:"filterPolicyId" json:"filterPolicyId"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *HTTPFilterRef) Init() error {
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -5,3 +5,7 @@ type HTTPFirewallRef struct {
 | 
				
			|||||||
	IsOn             bool  `yaml:"isOn" json:"isOn"`
 | 
						IsOn             bool  `yaml:"isOn" json:"isOn"`
 | 
				
			||||||
	FirewallPolicyId int64 `yaml:"firewallPolicyId" json:"firewallPolicyId"`
 | 
						FirewallPolicyId int64 `yaml:"firewallPolicyId" json:"firewallPolicyId"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *HTTPFirewallRef) Init() error {
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,22 +1,26 @@
 | 
				
			|||||||
package serverconfigs
 | 
					package serverconfigs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
 | 
				
			||||||
	"regexp"
 | 
						"regexp"
 | 
				
			||||||
 | 
						"strconv"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type HTTPLocationConfig struct {
 | 
					type HTTPLocationConfig struct {
 | 
				
			||||||
	Id              int64                 `yaml:"id" json:"id"`                           // ID
 | 
						Id              int64                          `yaml:"id" json:"id"`                           // ID
 | 
				
			||||||
	IsOn            bool                  `yaml:"isOn" json:"isOn"`                       // 是否启用
 | 
						IsOn            bool                           `yaml:"isOn" json:"isOn"`                       // 是否启用
 | 
				
			||||||
	Pattern         string                `yaml:"pattern" json:"pattern"`                 // 匹配规则 TODO 未来支持更多样的匹配规则
 | 
						Pattern         string                         `yaml:"pattern" json:"pattern"`                 // 匹配规则 TODO 未来支持更多样的匹配规则
 | 
				
			||||||
	Name            string                `yaml:"name" json:"name"`                       // 名称
 | 
						Name            string                         `yaml:"name" json:"name"`                       // 名称
 | 
				
			||||||
	Web             *HTTPWebConfig        `yaml:"web" json:"web"`                         // Web配置
 | 
						Web             *HTTPWebConfig                 `yaml:"web" json:"web"`                         // Web配置
 | 
				
			||||||
	URLPrefix       string                `yaml:"urlPrefix" json:"urlPrefix"`             // 实际的URL前缀,TODO 未来支持变量
 | 
						URLPrefix       string                         `yaml:"urlPrefix" json:"urlPrefix"`             // 实际的URL前缀,TODO 未来支持变量
 | 
				
			||||||
	Description     string                `yaml:"description" json:"description"`         // 描述
 | 
						Description     string                         `yaml:"description" json:"description"`         // 描述
 | 
				
			||||||
	ReverseProxyRef *ReverseProxyRef      `yaml:"reverseProxyRef" json:"reverseProxyRef"` // 反向代理引用
 | 
						ReverseProxyRef *ReverseProxyRef               `yaml:"reverseProxyRef" json:"reverseProxyRef"` // 反向代理引用
 | 
				
			||||||
	ReverseProxy    *ReverseProxyConfig   `yaml:"reverseProxy" json:"reverseProxy"`       // 反向代理设置
 | 
						ReverseProxy    *ReverseProxyConfig            `yaml:"reverseProxy" json:"reverseProxy"`       // 反向代理设置
 | 
				
			||||||
	IsBreak         bool                  `yaml:"isBreak" json:"isBreak"`                 // 终止向下解析
 | 
						IsBreak         bool                           `yaml:"isBreak" json:"isBreak"`                 // 终止向下解析
 | 
				
			||||||
	Children        []*HTTPLocationConfig `yaml:"children" json:"children"`               // 子规则
 | 
						Children        []*HTTPLocationConfig          `yaml:"children" json:"children"`               // 子规则
 | 
				
			||||||
 | 
						CondGroups      []*shared.HTTPRequestCondGroup `yaml:"condGroups" json:"condGroups"`           // 匹配条件 TODO
 | 
				
			||||||
 | 
						AutoFlush       bool                           `yaml:"autoFlush" json:"autoFlush"`             // 自动Flush TODO
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	patternType HTTPLocationPatternType // 规则类型:LocationPattern*
 | 
						patternType HTTPLocationPatternType // 规则类型:LocationPattern*
 | 
				
			||||||
	prefix      string                  // 前缀
 | 
						prefix      string                  // 前缀
 | 
				
			||||||
@@ -55,6 +59,14 @@ func (this *HTTPLocationConfig) Init() error {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// conds
 | 
				
			||||||
 | 
						for _, group := range this.CondGroups {
 | 
				
			||||||
 | 
							err := group.Init()
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -209,3 +221,81 @@ func (this *HTTPLocationConfig) parsePattern() error {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 判断是否匹配路径
 | 
				
			||||||
 | 
					// TODO 支持子Location
 | 
				
			||||||
 | 
					func (this *HTTPLocationConfig) Match(path string, formatter func(source string) string) (vars map[string]string, isMatched bool) {
 | 
				
			||||||
 | 
						// 判断条件
 | 
				
			||||||
 | 
						if len(this.CondGroups) > 0 {
 | 
				
			||||||
 | 
							for _, condGroup := range this.CondGroups {
 | 
				
			||||||
 | 
								if !condGroup.IsOn {
 | 
				
			||||||
 | 
									continue
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if !condGroup.Match(formatter) {
 | 
				
			||||||
 | 
									return nil, false
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if this.patternType == HTTPLocationPatternTypePrefix {
 | 
				
			||||||
 | 
							if this.reverse {
 | 
				
			||||||
 | 
								if this.caseInsensitive {
 | 
				
			||||||
 | 
									return nil, !strings.HasPrefix(strings.ToLower(path), strings.ToLower(this.prefix))
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									return nil, !strings.HasPrefix(path, this.prefix)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								if this.caseInsensitive {
 | 
				
			||||||
 | 
									return nil, strings.HasPrefix(strings.ToLower(path), strings.ToLower(this.prefix))
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									return nil, strings.HasPrefix(path, this.prefix)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if this.patternType == HTTPLocationPatternTypeExact {
 | 
				
			||||||
 | 
							if this.reverse {
 | 
				
			||||||
 | 
								if this.caseInsensitive {
 | 
				
			||||||
 | 
									return nil, strings.ToLower(path) != strings.ToLower(this.path)
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									return nil, path != this.path
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								if this.caseInsensitive {
 | 
				
			||||||
 | 
									return nil, strings.ToLower(path) == strings.ToLower(this.path)
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									return nil, path == this.path
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// TODO 正则表达式匹配会让请求延迟0.01-0.02ms,可以使用缓存加速正则匹配,因为大部分路径都是不变的
 | 
				
			||||||
 | 
						if this.patternType == HTTPLocationPatternTypeRegexp {
 | 
				
			||||||
 | 
							if this.reg != nil {
 | 
				
			||||||
 | 
								if this.reverse {
 | 
				
			||||||
 | 
									return nil, !this.reg.MatchString(path)
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									b := this.reg.MatchString(path)
 | 
				
			||||||
 | 
									if b {
 | 
				
			||||||
 | 
										result := map[string]string{}
 | 
				
			||||||
 | 
										matches := this.reg.FindStringSubmatch(path)
 | 
				
			||||||
 | 
										subNames := this.reg.SubexpNames()
 | 
				
			||||||
 | 
										for index, value := range matches {
 | 
				
			||||||
 | 
											result[strconv.Itoa(index)] = value
 | 
				
			||||||
 | 
											subName := subNames[index]
 | 
				
			||||||
 | 
											if len(subName) > 0 {
 | 
				
			||||||
 | 
												result[subName] = value
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										return result, true
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									return nil, b
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return nil, this.reverse
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil, false
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										17
									
								
								pkg/serverconfigs/http_location_config_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								pkg/serverconfigs/http_location_config_test.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,17 @@
 | 
				
			|||||||
 | 
					package serverconfigs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"regexp"
 | 
				
			||||||
 | 
						"testing"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestHTTPLocationConfig_Match_Reg(t *testing.T) {
 | 
				
			||||||
 | 
						randString := "1024"
 | 
				
			||||||
 | 
						reg := regexp.MustCompile(`(?P<num>\d+)`)
 | 
				
			||||||
 | 
						before := time.Now()
 | 
				
			||||||
 | 
						subNames := reg.SubexpNames()
 | 
				
			||||||
 | 
						match := reg.FindStringSubmatch(randString)
 | 
				
			||||||
 | 
						t.Log(time.Since(before).Seconds()*1000, "ms")
 | 
				
			||||||
 | 
						t.Log(subNames[1], "=", match[1])
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -1,8 +1,14 @@
 | 
				
			|||||||
package serverconfigs
 | 
					package serverconfigs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 跳转到HTTPS配置
 | 
					// 跳转到HTTPS配置
 | 
				
			||||||
// TODO 支持跳转的状态码选择
 | 
					 | 
				
			||||||
type HTTPRedirectToHTTPSConfig struct {
 | 
					type HTTPRedirectToHTTPSConfig struct {
 | 
				
			||||||
	IsPrior bool `yaml:"isPrior" json:"isPrior"` // 是否覆盖
 | 
						IsPrior bool   `yaml:"isPrior" json:"isPrior"` // 是否覆盖
 | 
				
			||||||
	IsOn    bool `yaml:"isOn" json:"isOn"`       // 是否开启
 | 
						IsOn    bool   `yaml:"isOn" json:"isOn"`       // 是否开启
 | 
				
			||||||
 | 
						Status  int    `yaml:"status" json:"status"`   // 跳转用的状态码
 | 
				
			||||||
 | 
						Host    string `yaml:"host" json:"host"`       // 跳转后的Host
 | 
				
			||||||
 | 
						Port    int    `yaml:"port" json:"port"`       // 跳转后的端口
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *HTTPRedirectToHTTPSConfig) Init() error {
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										18
									
								
								pkg/serverconfigs/http_shutdown_config.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								pkg/serverconfigs/http_shutdown_config.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,18 @@
 | 
				
			|||||||
 | 
					package serverconfigs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 关闭页面配置
 | 
				
			||||||
 | 
					type HTTPShutdownConfig struct {
 | 
				
			||||||
 | 
						IsPrior bool   `yaml:"isPrior" json:"isPrior"`
 | 
				
			||||||
 | 
						IsOn    bool   `yaml:"isOn" json:"isOn"`
 | 
				
			||||||
 | 
						URL     string `yaml:"url" json:"url"`
 | 
				
			||||||
 | 
						Status  int    `yaml:"status" json:"status"`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// TODO 可以自定义文本
 | 
				
			||||||
 | 
						// TODO 可以自定义Content-Type
 | 
				
			||||||
 | 
						// TODO 可以设置是否立即断开与客户端的连接
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 校验
 | 
				
			||||||
 | 
					func (this *HTTPShutdownConfig) Init() error {
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -1,18 +0,0 @@
 | 
				
			|||||||
package serverconfigs
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 关闭页面配置
 | 
					 | 
				
			||||||
type HTTPShutdownConfig struct {
 | 
					 | 
				
			||||||
	IsOn   bool   `yaml:"isOn" json:"isOn"`
 | 
					 | 
				
			||||||
	URL    string `yaml:"url" json:"url"`
 | 
					 | 
				
			||||||
	Status int    `yaml:"status" json:"status"`
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 获取新对象
 | 
					 | 
				
			||||||
func NewHTTPShutdownConfig() *HTTPShutdownConfig {
 | 
					 | 
				
			||||||
	return &HTTPShutdownConfig{}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 校验
 | 
					 | 
				
			||||||
func (this *HTTPShutdownConfig) Init() error {
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -27,9 +27,156 @@ type HTTPWebConfig struct {
 | 
				
			|||||||
	RequestHeaderPolicy     *shared.HTTPHeaderPolicy    `yaml:"requestHeaderPolicy" json:"requestHeaderPolicy"`         // 请求Header策略
 | 
						RequestHeaderPolicy     *shared.HTTPHeaderPolicy    `yaml:"requestHeaderPolicy" json:"requestHeaderPolicy"`         // 请求Header策略
 | 
				
			||||||
	ResponseHeaderPolicyRef *shared.HTTPHeaderPolicyRef `yaml:"responseHeaderPolicyRef" json:"responseHeaderPolicyRef"` // 响应Header`
 | 
						ResponseHeaderPolicyRef *shared.HTTPHeaderPolicyRef `yaml:"responseHeaderPolicyRef" json:"responseHeaderPolicyRef"` // 响应Header`
 | 
				
			||||||
	ResponseHeaderPolicy    *shared.HTTPHeaderPolicy    `yaml:"responseHeaderPolicy" json:"responseHeaderPolicy"`       // 响应Header策略
 | 
						ResponseHeaderPolicy    *shared.HTTPHeaderPolicy    `yaml:"responseHeaderPolicy" json:"responseHeaderPolicy"`       // 响应Header策略
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						FilterRefs     []*HTTPFilterRef    `yaml:"filterRefs" json:"filterRefs"`         // 筛选配置 TODO
 | 
				
			||||||
 | 
						FilterPolicies []*HTTPFilterPolicy `yaml:"filterPolicies" json:"filterPolicies"` // 筛选策略
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (this *HTTPWebConfig) Init() error {
 | 
					func (this *HTTPWebConfig) Init() error {
 | 
				
			||||||
 | 
						// 路径规则
 | 
				
			||||||
 | 
						if len(this.Locations) > 0 {
 | 
				
			||||||
 | 
							for _, location := range this.Locations {
 | 
				
			||||||
 | 
								err := location.Init()
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									return err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// gzip
 | 
				
			||||||
 | 
						if this.Gzip != nil {
 | 
				
			||||||
 | 
							err := this.Gzip.Init()
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// charset
 | 
				
			||||||
 | 
						if this.Charset != nil {
 | 
				
			||||||
 | 
							err := this.Charset.Init()
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// shutdown
 | 
				
			||||||
 | 
						if this.Shutdown != nil {
 | 
				
			||||||
 | 
							err := this.Shutdown.Init()
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// pages
 | 
				
			||||||
 | 
						if len(this.Pages) > 0 {
 | 
				
			||||||
 | 
							for _, page := range this.Pages {
 | 
				
			||||||
 | 
								err := page.Init()
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									return err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// redirectToHTTPS
 | 
				
			||||||
 | 
						if this.RedirectToHttps != nil {
 | 
				
			||||||
 | 
							err := this.RedirectToHttps.Init()
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// accessLog
 | 
				
			||||||
 | 
						if this.AccessLogRef != nil {
 | 
				
			||||||
 | 
							err := this.AccessLogRef.Init()
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// stat
 | 
				
			||||||
 | 
						if this.StatRef != nil {
 | 
				
			||||||
 | 
							err := this.StatRef.Init()
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// cache
 | 
				
			||||||
 | 
						if this.CacheRef != nil {
 | 
				
			||||||
 | 
							err := this.CacheRef.Init()
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// firewall
 | 
				
			||||||
 | 
						if this.FirewallRef != nil {
 | 
				
			||||||
 | 
							err := this.FirewallRef.Init()
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// websocket
 | 
				
			||||||
 | 
						if this.WebsocketRef != nil {
 | 
				
			||||||
 | 
							err := this.WebsocketRef.Init()
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if this.Websocket != nil {
 | 
				
			||||||
 | 
							err := this.Websocket.Init()
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// request header
 | 
				
			||||||
 | 
						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
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// response header
 | 
				
			||||||
 | 
						if this.ResponseHeaderPolicyRef != nil {
 | 
				
			||||||
 | 
							err := this.ResponseHeaderPolicyRef.Init()
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if this.ResponseHeaderPolicy != nil {
 | 
				
			||||||
 | 
							err := this.ResponseHeaderPolicy.Init()
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// filters
 | 
				
			||||||
 | 
						if this.FilterRefs != nil {
 | 
				
			||||||
 | 
							for _, ref := range this.FilterRefs {
 | 
				
			||||||
 | 
								err := ref.Init()
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									return err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if this.FilterPolicies != nil {
 | 
				
			||||||
 | 
							for _, policy := range this.FilterPolicies {
 | 
				
			||||||
 | 
								err := policy.Init()
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									return err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
package serverconfigs
 | 
					package serverconfigs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/configutils"
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/configutils"
 | 
				
			||||||
	"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
 | 
				
			||||||
	"github.com/iwind/TeaGo/maps"
 | 
						"github.com/iwind/TeaGo/maps"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,3 +5,7 @@ type HTTPWebsocketRef struct {
 | 
				
			|||||||
	IsOn        bool  `yaml:"isOn" json:"isOn"`
 | 
						IsOn        bool  `yaml:"isOn" json:"isOn"`
 | 
				
			||||||
	WebsocketId int64 `yaml:"websocketId" json:"websocketId"`
 | 
						WebsocketId int64 `yaml:"websocketId" json:"websocketId"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *HTTPWebsocketRef) Init() error {
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -33,8 +33,10 @@ type OriginConfig struct {
 | 
				
			|||||||
	RequestURI string `yaml:"requestURI" json:"requestURI"` // 转发后的请求URI TODO
 | 
						RequestURI string `yaml:"requestURI" json:"requestURI"` // 转发后的请求URI TODO
 | 
				
			||||||
	Host       string `yaml:"host" json:"host"`             // 自定义主机名 TODO
 | 
						Host       string `yaml:"host" json:"host"`             // 自定义主机名 TODO
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	RequestHeaders  *shared.HTTPHeaderPolicy `yaml:"requestHeaders" json:"requestHeaders"` // 请求Header设置 TODO
 | 
						RequestHeaderPolicyRef  *shared.HTTPHeaderPolicyRef `yaml:"requestHeaderPolicyRef" json:"requestHeaderPolicyRef"`   // 请求Header
 | 
				
			||||||
	ResponseHeaders *shared.HTTPHeaderPolicy `yaml:"responseHeaders" json:"responseHeaders"`
 | 
						RequestHeaderPolicy     *shared.HTTPHeaderPolicy    `yaml:"requestHeaderPolicy" json:"requestHeaderPolicy"`         // 请求Header策略
 | 
				
			||||||
 | 
						ResponseHeaderPolicyRef *shared.HTTPHeaderPolicyRef `yaml:"responseHeaderPolicyRef" json:"responseHeaderPolicyRef"` // 响应Header`
 | 
				
			||||||
 | 
						ResponseHeaderPolicy    *shared.HTTPHeaderPolicy    `yaml:"responseHeaderPolicy" json:"responseHeaderPolicy"`       // 响应Header策略
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 健康检查URL,目前支持:
 | 
						// 健康检查URL,目前支持:
 | 
				
			||||||
	// - http|https 返回2xx-3xx认为成功
 | 
						// - http|https 返回2xx-3xx认为成功
 | 
				
			||||||
@@ -61,6 +63,8 @@ type OriginConfig struct {
 | 
				
			|||||||
	uniqueKey string
 | 
						uniqueKey string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	hasAddrVariables bool // 地址中是否含有变量
 | 
						hasAddrVariables bool // 地址中是否含有变量
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						realAddr string // 最终的Addr TODO
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 校验
 | 
					// 校验
 | 
				
			||||||
@@ -77,23 +81,29 @@ func (this *OriginConfig) Init() error {
 | 
				
			|||||||
	this.uniqueKey = strconv.FormatInt(this.Id, 10) + "@" + fmt.Sprintf("%d", this.Version)
 | 
						this.uniqueKey = strconv.FormatInt(this.Id, 10) + "@" + fmt.Sprintf("%d", this.Version)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// failTimeout
 | 
						// failTimeout
 | 
				
			||||||
	this.connTimeoutDuration = this.ConnTimeout.Duration()
 | 
						if this.ConnTimeout != nil {
 | 
				
			||||||
 | 
							this.connTimeoutDuration = this.ConnTimeout.Duration()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// readTimeout
 | 
						// readTimeout
 | 
				
			||||||
	this.readTimeoutDuration = this.ReadTimeout.Duration()
 | 
						if this.ReadTimeout != nil {
 | 
				
			||||||
 | 
							this.readTimeoutDuration = this.ReadTimeout.Duration()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// idleTimeout
 | 
						// idleTimeout
 | 
				
			||||||
	this.idleTimeoutDuration = this.IdleTimeout.Duration()
 | 
						if this.IdleTimeout != nil {
 | 
				
			||||||
 | 
							this.idleTimeoutDuration = this.IdleTimeout.Duration()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Headers
 | 
						// Headers
 | 
				
			||||||
	if this.RequestHeaders != nil {
 | 
						if this.RequestHeaderPolicy != nil {
 | 
				
			||||||
		err := this.RequestHeaders.Init()
 | 
							err := this.RequestHeaderPolicy.Init()
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return err
 | 
								return err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if this.ResponseHeaders != nil {
 | 
						if this.ResponseHeaderPolicy != nil {
 | 
				
			||||||
		err := this.ResponseHeaders.Init()
 | 
							err := this.ResponseHeaderPolicy.Init()
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return err
 | 
								return err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -116,10 +126,6 @@ func (this *OriginConfig) Init() error {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	// TODO init health check
 | 
						// TODO init health check
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// headers
 | 
					 | 
				
			||||||
	this.hasRequestHeaders = this.RequestHeaders != nil && !this.RequestHeaders.IsEmpty()
 | 
					 | 
				
			||||||
	this.hasRequestHeaders = this.ResponseHeaders != nil && !this.ResponseHeaders.IsEmpty()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// host
 | 
						// host
 | 
				
			||||||
	this.hasHost = len(this.Host) > 0
 | 
						this.hasHost = len(this.Host) > 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -168,3 +174,13 @@ func (this *OriginConfig) Connect() (net.Conn, error) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	return nil, errors.New("invalid scheme '" + this.Addr.Protocol.String() + "'")
 | 
						return nil, errors.New("invalid scheme '" + this.Addr.Protocol.String() + "'")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 获取最终请求的地址
 | 
				
			||||||
 | 
					func (this *OriginConfig) RealAddr() string {
 | 
				
			||||||
 | 
						return this.realAddr
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 设置最终请求的地址 TODO 需要实现
 | 
				
			||||||
 | 
					func (this *OriginConfig) SetRealAddr(realAddr string) {
 | 
				
			||||||
 | 
						this.realAddr = realAddr
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,8 +10,6 @@ type ServerConfig struct {
 | 
				
			|||||||
	Id          int64               `yaml:"id" json:"id"`                   // ID
 | 
						Id          int64               `yaml:"id" json:"id"`                   // ID
 | 
				
			||||||
	Type        string              `yaml:"type" json:"type"`               // 类型
 | 
						Type        string              `yaml:"type" json:"type"`               // 类型
 | 
				
			||||||
	IsOn        bool                `yaml:"isOn" json:"isOn"`               // 是否开启
 | 
						IsOn        bool                `yaml:"isOn" json:"isOn"`               // 是否开启
 | 
				
			||||||
	Components  []*ComponentConfig  `yaml:"components" json:"components"`   // 组件
 | 
					 | 
				
			||||||
	Filters     []*FilterConfig     `yaml:"filters" json:"filters"`         // 过滤器
 | 
					 | 
				
			||||||
	Name        string              `yaml:"name" json:"name"`               // 名称
 | 
						Name        string              `yaml:"name" json:"name"`               // 名称
 | 
				
			||||||
	Description string              `yaml:"description" json:"description"` // 描述
 | 
						Description string              `yaml:"description" json:"description"` // 描述
 | 
				
			||||||
	ServerNames []*ServerNameConfig `yaml:"serverNames" json:"serverNames"` // 域名
 | 
						ServerNames []*ServerNameConfig `yaml:"serverNames" json:"serverNames"` // 域名
 | 
				
			||||||
@@ -93,6 +91,13 @@ func (this *ServerConfig) Init() error {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if this.Web != nil {
 | 
				
			||||||
 | 
							err := this.Web.Init()
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
package serverconfigs
 | 
					package serverconfigs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/configutils"
 | 
					import "github.com/TeaOSLab/EdgeCommon/pkg/configutils"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type ServerNameType = string
 | 
					type ServerNameType = string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,3 +5,7 @@ type HTTPHeaderPolicyRef struct {
 | 
				
			|||||||
	IsOn           bool  `yaml:"isOn" json:"isOn"`
 | 
						IsOn           bool  `yaml:"isOn" json:"isOn"`
 | 
				
			||||||
	HeaderPolicyId int64 `yaml:"headerPolicyId" json:"headerPolicyId"`
 | 
						HeaderPolicyId int64 `yaml:"headerPolicyId" json:"headerPolicyId"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *HTTPHeaderPolicyRef) Init() error {
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										7
									
								
								pkg/serverconfigs/shared/http_header_ref.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								pkg/serverconfigs/shared/http_header_ref.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					package shared
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Header引用
 | 
				
			||||||
 | 
					type HTTPHeaderRef struct {
 | 
				
			||||||
 | 
						IsOn     bool  `yaml:"isOn" json:"isOn"`
 | 
				
			||||||
 | 
						HeaderId int64 `yaml:"headerId" json:"headerId"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -1,60 +0,0 @@
 | 
				
			|||||||
package shared
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// HeaderList定义
 | 
					 | 
				
			||||||
type HTTPHeaderPolicy struct {
 | 
					 | 
				
			||||||
	Id          int64  `yaml:"id" json:"id"`                   // ID
 | 
					 | 
				
			||||||
	Name        string `yaml:"name" json:"name"`               // 名称 TODO
 | 
					 | 
				
			||||||
	IsOn        bool   `yaml:"isOn" json:"isOn"`               // 是否启用 TODO
 | 
					 | 
				
			||||||
	Description string `yaml:"description" json:"description"` // 描述 TODO
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	AddHeaders     []*HTTPHeaderConfig `yaml:"addHeaders" json:"addHeaders"`         // TODO
 | 
					 | 
				
			||||||
	AddTrailers    []*HTTPHeaderConfig `yaml:"addTrailers" json:"addTrailers"`       // TODO
 | 
					 | 
				
			||||||
	SetHeaders     []*HTTPHeaderConfig `yaml:"setHeaders" json:"setHeaders"`         // TODO
 | 
					 | 
				
			||||||
	ReplaceHeaders []*HTTPHeaderConfig `yaml:"replaceHeaders" json:"replaceHeaders"` // 替换Header内容 TODO
 | 
					 | 
				
			||||||
	DeletedHeaders []string            `yaml:"deleteHeaders" json:"deleteHeaders"`   // 删除的Header TODO
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	Expires *HTTPExpireHeaderConfig `yaml:"expires" json:"expires"` // TODO
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 获取新对象
 | 
					 | 
				
			||||||
func NewHTTPHeaderPolicy() *HTTPHeaderPolicy {
 | 
					 | 
				
			||||||
	return &HTTPHeaderPolicy{}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 校验
 | 
					 | 
				
			||||||
func (this *HTTPHeaderPolicy) Init() error {
 | 
					 | 
				
			||||||
	for _, h := range this.AddHeaders {
 | 
					 | 
				
			||||||
		err := h.Init()
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for _, h := range this.AddTrailers {
 | 
					 | 
				
			||||||
		err := h.Init()
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for _, h := range this.SetHeaders {
 | 
					 | 
				
			||||||
		err := h.Init()
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for _, h := range this.ReplaceHeaders {
 | 
					 | 
				
			||||||
		err := h.Init()
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 判断是否为空
 | 
					 | 
				
			||||||
func (this *HTTPHeaderPolicy) IsEmpty() bool {
 | 
					 | 
				
			||||||
	return len(this.AddHeaders) == 0 && len(this.AddTrailers) == 0 && len(this.SetHeaders) == 0 && len(this.ReplaceHeaders) == 0 && this.Expires == nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,13 +0,0 @@
 | 
				
			|||||||
package shared
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"testing"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func TestHeaderList_FormatHeaders(t *testing.T) {
 | 
					 | 
				
			||||||
	list := NewHTTPHeaderPolicy()
 | 
					 | 
				
			||||||
	err := list.Init()
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		t.Fatal(err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										75
									
								
								pkg/serverconfigs/shared/http_headers_policy.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								pkg/serverconfigs/shared/http_headers_policy.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,75 @@
 | 
				
			|||||||
 | 
					package shared
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import "strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// HeaderList定义
 | 
				
			||||||
 | 
					type HTTPHeaderPolicy struct {
 | 
				
			||||||
 | 
						Id          int64  `yaml:"id" json:"id"`                   // ID
 | 
				
			||||||
 | 
						Name        string `yaml:"name" json:"name"`               // 名称 TODO
 | 
				
			||||||
 | 
						IsOn        bool   `yaml:"isOn" json:"isOn"`               // 是否启用 TODO
 | 
				
			||||||
 | 
						Description string `yaml:"description" json:"description"` // 描述 TODO
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						AddHeaderRefs     []*HTTPHeaderRef    `yaml:"addHeaderRefs" json:"addHeaderRefs"`
 | 
				
			||||||
 | 
						AddHeaders        []*HTTPHeaderConfig `yaml:"addHeaders" json:"addHeaders"`
 | 
				
			||||||
 | 
						AddTrailerRefs    []*HTTPHeaderRef    `yaml:"addTrailerRefs" json:"addTrailerRefs"`
 | 
				
			||||||
 | 
						AddTrailers       []*HTTPHeaderConfig `yaml:"addTrailers" json:"addTrailers"` // TODO
 | 
				
			||||||
 | 
						SetHeaderRefs     []*HTTPHeaderRef    `yaml:"setHeaderRefs" json:"setHeaderRefs"`
 | 
				
			||||||
 | 
						SetHeaders        []*HTTPHeaderConfig `yaml:"setHeaders" json:"setHeaders"`
 | 
				
			||||||
 | 
						ReplaceHeaderRefs []*HTTPHeaderRef    `yaml:"replaceHeaderRefs" json:"replaceHeaderRefs"`
 | 
				
			||||||
 | 
						ReplaceHeaders    []*HTTPHeaderConfig `yaml:"replaceHeaders" json:"replaceHeaders"` // 替换Header内容 TODO
 | 
				
			||||||
 | 
						DeleteHeaders     []string            `yaml:"deleteHeaders" json:"deleteHeaders"`   // 删除的Header
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Expires *HTTPExpireHeaderConfig `yaml:"expires" json:"expires"` // TODO
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						deleteHeaderMap map[string]bool // header => bool
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 校验
 | 
				
			||||||
 | 
					func (this *HTTPHeaderPolicy) Init() error {
 | 
				
			||||||
 | 
						for _, h := range this.AddHeaders {
 | 
				
			||||||
 | 
							err := h.Init()
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, h := range this.AddTrailers {
 | 
				
			||||||
 | 
							err := h.Init()
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, h := range this.SetHeaders {
 | 
				
			||||||
 | 
							err := h.Init()
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, h := range this.ReplaceHeaders {
 | 
				
			||||||
 | 
							err := h.Init()
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// delete
 | 
				
			||||||
 | 
						this.deleteHeaderMap = map[string]bool{}
 | 
				
			||||||
 | 
						for _, header := range this.DeleteHeaders {
 | 
				
			||||||
 | 
							this.deleteHeaderMap[strings.ToUpper(header)] = true
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 判断是否为空
 | 
				
			||||||
 | 
					func (this *HTTPHeaderPolicy) IsEmpty() bool {
 | 
				
			||||||
 | 
						return len(this.AddHeaders) == 0 && len(this.AddTrailers) == 0 && len(this.SetHeaders) == 0 && len(this.ReplaceHeaders) == 0 && this.Expires == nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 判断删除列表中是否包含某个Header
 | 
				
			||||||
 | 
					func (this *HTTPHeaderPolicy) ContainsDeletedHeader(header string) bool {
 | 
				
			||||||
 | 
						_, ok := this.deleteHeaderMap[strings.ToUpper(header)]
 | 
				
			||||||
 | 
						return ok
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										57
									
								
								pkg/serverconfigs/shared/http_headers_policy_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								pkg/serverconfigs/shared/http_headers_policy_test.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,57 @@
 | 
				
			|||||||
 | 
					package shared
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"github.com/iwind/TeaGo/assert"
 | 
				
			||||||
 | 
						"testing"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestHTTPHeaderPolicy_FormatHeaders(t *testing.T) {
 | 
				
			||||||
 | 
						policy := &HTTPHeaderPolicy{}
 | 
				
			||||||
 | 
						err := policy.Init()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							t.Fatal(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestHTTPHeaderPolicy_ShouldDeleteHeader(t *testing.T) {
 | 
				
			||||||
 | 
						a := assert.NewAssertion(t)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							policy := &HTTPHeaderPolicy{}
 | 
				
			||||||
 | 
							err := policy.Init()
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								t.Fatal(err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							a.IsFalse(policy.ContainsDeletedHeader("Origin"))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							policy := &HTTPHeaderPolicy{
 | 
				
			||||||
 | 
								DeleteHeaders: []string{"Hello", "World"},
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							err := policy.Init()
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								t.Fatal(err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							a.IsFalse(policy.ContainsDeletedHeader("Origin"))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							policy := &HTTPHeaderPolicy{
 | 
				
			||||||
 | 
								DeleteHeaders: []string{"origin"},
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							err := policy.Init()
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								t.Fatal(err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							a.IsTrue(policy.ContainsDeletedHeader("Origin"))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							policy := &HTTPHeaderPolicy{
 | 
				
			||||||
 | 
								DeleteHeaders: []string{"Origin"},
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							err := policy.Init()
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								t.Fatal(err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							a.IsTrue(policy.ContainsDeletedHeader("Origin"))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -17,8 +17,9 @@ import (
 | 
				
			|||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 重写条件定义
 | 
					// 重写条件定义
 | 
				
			||||||
type RequestCond struct {
 | 
					type HTTPRequestCond struct {
 | 
				
			||||||
	Id string `yaml:"id" json:"id"` // ID
 | 
						Id   string `yaml:"id" json:"id"`     // ID
 | 
				
			||||||
 | 
						IsOn bool   `yaml:"isOn" json:"isOn"` // 是否启用
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 要测试的字符串
 | 
						// 要测试的字符串
 | 
				
			||||||
	// 其中可以使用跟请求相关的参数,比如:
 | 
						// 其中可以使用跟请求相关的参数,比如:
 | 
				
			||||||
@@ -41,15 +42,8 @@ type RequestCond struct {
 | 
				
			|||||||
	arrayValue []string
 | 
						arrayValue []string
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 取得新对象
 | 
					 | 
				
			||||||
func NewRequestCond() *RequestCond {
 | 
					 | 
				
			||||||
	return &RequestCond{
 | 
					 | 
				
			||||||
		Id: stringutil.Rand(16),
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 校验配置
 | 
					// 校验配置
 | 
				
			||||||
func (this *RequestCond) Init() error {
 | 
					func (this *HTTPRequestCond) Init() error {
 | 
				
			||||||
	this.isInt = RegexpDigitNumber.MatchString(this.Value)
 | 
						this.isInt = RegexpDigitNumber.MatchString(this.Value)
 | 
				
			||||||
	this.isFloat = RegexpFloatNumber.MatchString(this.Value)
 | 
						this.isFloat = RegexpFloatNumber.MatchString(this.Value)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -144,7 +138,7 @@ func (this *RequestCond) Init() error {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 将此条件应用于请求,检查是否匹配
 | 
					// 将此条件应用于请求,检查是否匹配
 | 
				
			||||||
func (this *RequestCond) Match(formatter func(source string) string) bool {
 | 
					func (this *HTTPRequestCond) Match(formatter func(source string) string) bool {
 | 
				
			||||||
	paramValue := formatter(this.Param)
 | 
						paramValue := formatter(this.Param)
 | 
				
			||||||
	switch this.Operator {
 | 
						switch this.Operator {
 | 
				
			||||||
	case RequestCondOperatorRegexp:
 | 
						case RequestCondOperatorRegexp:
 | 
				
			||||||
@@ -361,7 +355,7 @@ func (this *RequestCond) Match(formatter func(source string) string) bool {
 | 
				
			|||||||
	return false
 | 
						return false
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (this *RequestCond) ipToInt64(ip net.IP) int64 {
 | 
					func (this *HTTPRequestCond) ipToInt64(ip net.IP) int64 {
 | 
				
			||||||
	if len(ip) == 0 {
 | 
						if len(ip) == 0 {
 | 
				
			||||||
		return 0
 | 
							return 0
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
							
								
								
									
										38
									
								
								pkg/serverconfigs/shared/http_request_cond_group.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								pkg/serverconfigs/shared/http_request_cond_group.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,38 @@
 | 
				
			|||||||
 | 
					package shared
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 请求条件分组
 | 
				
			||||||
 | 
					type HTTPRequestCondGroup struct {
 | 
				
			||||||
 | 
						IsOn      bool               `yaml:"isOn" json:"isOn"`           // 是否启用
 | 
				
			||||||
 | 
						Connector string             `yaml:"connector" json:"connector"` // 条件之间的关系
 | 
				
			||||||
 | 
						Conds     []*HTTPRequestCond `yaml:"conds" json:"conds"`         // 条件列表
 | 
				
			||||||
 | 
						IsReverse bool               `yaml:"isReverse" json:"isReverse"` // 是否反向匹配
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 初始化
 | 
				
			||||||
 | 
					func (this *HTTPRequestCondGroup) Init() error {
 | 
				
			||||||
 | 
						if len(this.Conds) > 0 {
 | 
				
			||||||
 | 
							for _, cond := range this.Conds {
 | 
				
			||||||
 | 
								err := cond.Init()
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									return err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *HTTPRequestCondGroup) Match(formatter func(source string) string) bool {
 | 
				
			||||||
 | 
						if !this.IsOn {
 | 
				
			||||||
 | 
							return !this.IsReverse
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for _, cond := range this.Conds {
 | 
				
			||||||
 | 
							isMatched := cond.Match(formatter)
 | 
				
			||||||
 | 
							if this.Connector == "or" && isMatched {
 | 
				
			||||||
 | 
								return !this.IsReverse
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if this.Connector == "and" && !isMatched {
 | 
				
			||||||
 | 
								return this.IsReverse
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return !this.IsReverse
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -14,7 +14,7 @@ func TestRequestCond_Compare1(t *testing.T) {
 | 
				
			|||||||
	a := assert.NewAssertion(t)
 | 
						a := assert.NewAssertion(t)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "/hello",
 | 
								Param:    "/hello",
 | 
				
			||||||
			Operator: RequestCondOperatorRegexp,
 | 
								Operator: RequestCondOperatorRegexp,
 | 
				
			||||||
			Value:    "abc",
 | 
								Value:    "abc",
 | 
				
			||||||
@@ -26,7 +26,7 @@ func TestRequestCond_Compare1(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "/hello",
 | 
								Param:    "/hello",
 | 
				
			||||||
			Operator: RequestCondOperatorRegexp,
 | 
								Operator: RequestCondOperatorRegexp,
 | 
				
			||||||
			Value:    "/\\w+",
 | 
								Value:    "/\\w+",
 | 
				
			||||||
@@ -38,7 +38,7 @@ func TestRequestCond_Compare1(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "/article/123.html",
 | 
								Param:    "/article/123.html",
 | 
				
			||||||
			Operator: RequestCondOperatorRegexp,
 | 
								Operator: RequestCondOperatorRegexp,
 | 
				
			||||||
			Value:    `^/article/\d+\.html$`,
 | 
								Value:    `^/article/\d+\.html$`,
 | 
				
			||||||
@@ -50,7 +50,7 @@ func TestRequestCond_Compare1(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "/hello",
 | 
								Param:    "/hello",
 | 
				
			||||||
			Operator: RequestCondOperatorRegexp,
 | 
								Operator: RequestCondOperatorRegexp,
 | 
				
			||||||
			Value:    "[",
 | 
								Value:    "[",
 | 
				
			||||||
@@ -62,7 +62,7 @@ func TestRequestCond_Compare1(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "/hello",
 | 
								Param:    "/hello",
 | 
				
			||||||
			Operator: RequestCondOperatorNotRegexp,
 | 
								Operator: RequestCondOperatorNotRegexp,
 | 
				
			||||||
			Value:    "abc",
 | 
								Value:    "abc",
 | 
				
			||||||
@@ -74,7 +74,7 @@ func TestRequestCond_Compare1(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "/hello",
 | 
								Param:    "/hello",
 | 
				
			||||||
			Operator: RequestCondOperatorNotRegexp,
 | 
								Operator: RequestCondOperatorNotRegexp,
 | 
				
			||||||
			Value:    "/\\w+",
 | 
								Value:    "/\\w+",
 | 
				
			||||||
@@ -86,7 +86,7 @@ func TestRequestCond_Compare1(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "123.123",
 | 
								Param:    "123.123",
 | 
				
			||||||
			Operator: RequestCondOperatorEqInt,
 | 
								Operator: RequestCondOperatorEqInt,
 | 
				
			||||||
			Value:    "123",
 | 
								Value:    "123",
 | 
				
			||||||
@@ -98,7 +98,7 @@ func TestRequestCond_Compare1(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "123",
 | 
								Param:    "123",
 | 
				
			||||||
			Operator: RequestCondOperatorEqInt,
 | 
								Operator: RequestCondOperatorEqInt,
 | 
				
			||||||
			Value:    "123",
 | 
								Value:    "123",
 | 
				
			||||||
@@ -110,7 +110,7 @@ func TestRequestCond_Compare1(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "abc",
 | 
								Param:    "abc",
 | 
				
			||||||
			Operator: RequestCondOperatorEqInt,
 | 
								Operator: RequestCondOperatorEqInt,
 | 
				
			||||||
			Value:    "abc",
 | 
								Value:    "abc",
 | 
				
			||||||
@@ -122,7 +122,7 @@ func TestRequestCond_Compare1(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "123",
 | 
								Param:    "123",
 | 
				
			||||||
			Operator: RequestCondOperatorEqFloat,
 | 
								Operator: RequestCondOperatorEqFloat,
 | 
				
			||||||
			Value:    "123",
 | 
								Value:    "123",
 | 
				
			||||||
@@ -134,7 +134,7 @@ func TestRequestCond_Compare1(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "123.0",
 | 
								Param:    "123.0",
 | 
				
			||||||
			Operator: RequestCondOperatorEqFloat,
 | 
								Operator: RequestCondOperatorEqFloat,
 | 
				
			||||||
			Value:    "123",
 | 
								Value:    "123",
 | 
				
			||||||
@@ -146,7 +146,7 @@ func TestRequestCond_Compare1(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "123.123",
 | 
								Param:    "123.123",
 | 
				
			||||||
			Operator: RequestCondOperatorEqFloat,
 | 
								Operator: RequestCondOperatorEqFloat,
 | 
				
			||||||
			Value:    "123.12",
 | 
								Value:    "123.12",
 | 
				
			||||||
@@ -158,7 +158,7 @@ func TestRequestCond_Compare1(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "123",
 | 
								Param:    "123",
 | 
				
			||||||
			Operator: RequestCondOperatorGtFloat,
 | 
								Operator: RequestCondOperatorGtFloat,
 | 
				
			||||||
			Value:    "1",
 | 
								Value:    "1",
 | 
				
			||||||
@@ -170,7 +170,7 @@ func TestRequestCond_Compare1(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "123",
 | 
								Param:    "123",
 | 
				
			||||||
			Operator: RequestCondOperatorGtFloat,
 | 
								Operator: RequestCondOperatorGtFloat,
 | 
				
			||||||
			Value:    "125",
 | 
								Value:    "125",
 | 
				
			||||||
@@ -182,7 +182,7 @@ func TestRequestCond_Compare1(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "125",
 | 
								Param:    "125",
 | 
				
			||||||
			Operator: RequestCondOperatorGteFloat,
 | 
								Operator: RequestCondOperatorGteFloat,
 | 
				
			||||||
			Value:    "125",
 | 
								Value:    "125",
 | 
				
			||||||
@@ -194,7 +194,7 @@ func TestRequestCond_Compare1(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "125",
 | 
								Param:    "125",
 | 
				
			||||||
			Operator: RequestCondOperatorLtFloat,
 | 
								Operator: RequestCondOperatorLtFloat,
 | 
				
			||||||
			Value:    "127",
 | 
								Value:    "127",
 | 
				
			||||||
@@ -206,7 +206,7 @@ func TestRequestCond_Compare1(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "125",
 | 
								Param:    "125",
 | 
				
			||||||
			Operator: RequestCondOperatorLteFloat,
 | 
								Operator: RequestCondOperatorLteFloat,
 | 
				
			||||||
			Value:    "127",
 | 
								Value:    "127",
 | 
				
			||||||
@@ -218,7 +218,7 @@ func TestRequestCond_Compare1(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "125",
 | 
								Param:    "125",
 | 
				
			||||||
			Operator: RequestCondOperatorEqString,
 | 
								Operator: RequestCondOperatorEqString,
 | 
				
			||||||
			Value:    "125",
 | 
								Value:    "125",
 | 
				
			||||||
@@ -230,7 +230,7 @@ func TestRequestCond_Compare1(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "125",
 | 
								Param:    "125",
 | 
				
			||||||
			Operator: RequestCondOperatorNeqString,
 | 
								Operator: RequestCondOperatorNeqString,
 | 
				
			||||||
			Value:    "125",
 | 
								Value:    "125",
 | 
				
			||||||
@@ -242,7 +242,7 @@ func TestRequestCond_Compare1(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "125",
 | 
								Param:    "125",
 | 
				
			||||||
			Operator: RequestCondOperatorNeqString,
 | 
								Operator: RequestCondOperatorNeqString,
 | 
				
			||||||
			Value:    "127",
 | 
								Value:    "127",
 | 
				
			||||||
@@ -254,7 +254,7 @@ func TestRequestCond_Compare1(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "/hello/world",
 | 
								Param:    "/hello/world",
 | 
				
			||||||
			Operator: RequestCondOperatorHasPrefix,
 | 
								Operator: RequestCondOperatorHasPrefix,
 | 
				
			||||||
			Value:    "/hello",
 | 
								Value:    "/hello",
 | 
				
			||||||
@@ -266,7 +266,7 @@ func TestRequestCond_Compare1(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "/hello/world",
 | 
								Param:    "/hello/world",
 | 
				
			||||||
			Operator: RequestCondOperatorHasPrefix,
 | 
								Operator: RequestCondOperatorHasPrefix,
 | 
				
			||||||
			Value:    "/hello2",
 | 
								Value:    "/hello2",
 | 
				
			||||||
@@ -278,7 +278,7 @@ func TestRequestCond_Compare1(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "/hello/world",
 | 
								Param:    "/hello/world",
 | 
				
			||||||
			Operator: RequestCondOperatorHasSuffix,
 | 
								Operator: RequestCondOperatorHasSuffix,
 | 
				
			||||||
			Value:    "world",
 | 
								Value:    "world",
 | 
				
			||||||
@@ -290,7 +290,7 @@ func TestRequestCond_Compare1(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "/hello/world",
 | 
								Param:    "/hello/world",
 | 
				
			||||||
			Operator: RequestCondOperatorHasSuffix,
 | 
								Operator: RequestCondOperatorHasSuffix,
 | 
				
			||||||
			Value:    "world/",
 | 
								Value:    "world/",
 | 
				
			||||||
@@ -302,7 +302,7 @@ func TestRequestCond_Compare1(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "/hello/world",
 | 
								Param:    "/hello/world",
 | 
				
			||||||
			Operator: RequestCondOperatorContainsString,
 | 
								Operator: RequestCondOperatorContainsString,
 | 
				
			||||||
			Value:    "wo",
 | 
								Value:    "wo",
 | 
				
			||||||
@@ -314,7 +314,7 @@ func TestRequestCond_Compare1(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "/hello/world",
 | 
								Param:    "/hello/world",
 | 
				
			||||||
			Operator: RequestCondOperatorContainsString,
 | 
								Operator: RequestCondOperatorContainsString,
 | 
				
			||||||
			Value:    "wr",
 | 
								Value:    "wr",
 | 
				
			||||||
@@ -326,7 +326,7 @@ func TestRequestCond_Compare1(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "/hello/world",
 | 
								Param:    "/hello/world",
 | 
				
			||||||
			Operator: RequestCondOperatorNotContainsString,
 | 
								Operator: RequestCondOperatorNotContainsString,
 | 
				
			||||||
			Value:    "HELLO",
 | 
								Value:    "HELLO",
 | 
				
			||||||
@@ -338,7 +338,7 @@ func TestRequestCond_Compare1(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "/hello/world",
 | 
								Param:    "/hello/world",
 | 
				
			||||||
			Operator: RequestCondOperatorNotContainsString,
 | 
								Operator: RequestCondOperatorNotContainsString,
 | 
				
			||||||
			Value:    "hello",
 | 
								Value:    "hello",
 | 
				
			||||||
@@ -354,7 +354,7 @@ func TestRequestCond_IP(t *testing.T) {
 | 
				
			|||||||
	a := assert.NewAssertion(t)
 | 
						a := assert.NewAssertion(t)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "hello",
 | 
								Param:    "hello",
 | 
				
			||||||
			Operator: RequestCondOperatorEqIP,
 | 
								Operator: RequestCondOperatorEqIP,
 | 
				
			||||||
			Value:    "hello",
 | 
								Value:    "hello",
 | 
				
			||||||
@@ -366,7 +366,7 @@ func TestRequestCond_IP(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "192.168.1.100",
 | 
								Param:    "192.168.1.100",
 | 
				
			||||||
			Operator: RequestCondOperatorEqIP,
 | 
								Operator: RequestCondOperatorEqIP,
 | 
				
			||||||
			Value:    "hello",
 | 
								Value:    "hello",
 | 
				
			||||||
@@ -378,7 +378,7 @@ func TestRequestCond_IP(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "192.168.1.100",
 | 
								Param:    "192.168.1.100",
 | 
				
			||||||
			Operator: RequestCondOperatorEqIP,
 | 
								Operator: RequestCondOperatorEqIP,
 | 
				
			||||||
			Value:    "192.168.1.100",
 | 
								Value:    "192.168.1.100",
 | 
				
			||||||
@@ -390,7 +390,7 @@ func TestRequestCond_IP(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "192.168.1.100",
 | 
								Param:    "192.168.1.100",
 | 
				
			||||||
			Operator: RequestCondOperatorGtIP,
 | 
								Operator: RequestCondOperatorGtIP,
 | 
				
			||||||
			Value:    "192.168.1.90",
 | 
								Value:    "192.168.1.90",
 | 
				
			||||||
@@ -402,7 +402,7 @@ func TestRequestCond_IP(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "192.168.1.100",
 | 
								Param:    "192.168.1.100",
 | 
				
			||||||
			Operator: RequestCondOperatorGteIP,
 | 
								Operator: RequestCondOperatorGteIP,
 | 
				
			||||||
			Value:    "192.168.1.90",
 | 
								Value:    "192.168.1.90",
 | 
				
			||||||
@@ -414,7 +414,7 @@ func TestRequestCond_IP(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "192.168.1.80",
 | 
								Param:    "192.168.1.80",
 | 
				
			||||||
			Operator: RequestCondOperatorLtIP,
 | 
								Operator: RequestCondOperatorLtIP,
 | 
				
			||||||
			Value:    "192.168.1.90",
 | 
								Value:    "192.168.1.90",
 | 
				
			||||||
@@ -426,7 +426,7 @@ func TestRequestCond_IP(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "192.168.0.100",
 | 
								Param:    "192.168.0.100",
 | 
				
			||||||
			Operator: RequestCondOperatorLteIP,
 | 
								Operator: RequestCondOperatorLteIP,
 | 
				
			||||||
			Value:    "192.168.1.90",
 | 
								Value:    "192.168.1.90",
 | 
				
			||||||
@@ -438,7 +438,7 @@ func TestRequestCond_IP(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "192.168.0.100",
 | 
								Param:    "192.168.0.100",
 | 
				
			||||||
			Operator: RequestCondOperatorIPRange,
 | 
								Operator: RequestCondOperatorIPRange,
 | 
				
			||||||
			Value:    "192.168.0.90,",
 | 
								Value:    "192.168.0.90,",
 | 
				
			||||||
@@ -450,7 +450,7 @@ func TestRequestCond_IP(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "192.168.0.100",
 | 
								Param:    "192.168.0.100",
 | 
				
			||||||
			Operator: RequestCondOperatorIPRange,
 | 
								Operator: RequestCondOperatorIPRange,
 | 
				
			||||||
			Value:    "192.168.0.90,192.168.1.100",
 | 
								Value:    "192.168.0.90,192.168.1.100",
 | 
				
			||||||
@@ -462,7 +462,7 @@ func TestRequestCond_IP(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "192.168.0.100",
 | 
								Param:    "192.168.0.100",
 | 
				
			||||||
			Operator: RequestCondOperatorIPRange,
 | 
								Operator: RequestCondOperatorIPRange,
 | 
				
			||||||
			Value:    ",192.168.1.100",
 | 
								Value:    ",192.168.1.100",
 | 
				
			||||||
@@ -474,7 +474,7 @@ func TestRequestCond_IP(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "192.168.1.100",
 | 
								Param:    "192.168.1.100",
 | 
				
			||||||
			Operator: RequestCondOperatorIPRange,
 | 
								Operator: RequestCondOperatorIPRange,
 | 
				
			||||||
			Value:    "192.168.0.90,192.168.1.99",
 | 
								Value:    "192.168.0.90,192.168.1.99",
 | 
				
			||||||
@@ -486,7 +486,7 @@ func TestRequestCond_IP(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "192.168.1.100",
 | 
								Param:    "192.168.1.100",
 | 
				
			||||||
			Operator: RequestCondOperatorIPRange,
 | 
								Operator: RequestCondOperatorIPRange,
 | 
				
			||||||
			Value:    "192.168.0.90/24",
 | 
								Value:    "192.168.0.90/24",
 | 
				
			||||||
@@ -498,7 +498,7 @@ func TestRequestCond_IP(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "192.168.1.100",
 | 
								Param:    "192.168.1.100",
 | 
				
			||||||
			Operator: RequestCondOperatorIPRange,
 | 
								Operator: RequestCondOperatorIPRange,
 | 
				
			||||||
			Value:    "192.168.0.90/18",
 | 
								Value:    "192.168.0.90/18",
 | 
				
			||||||
@@ -510,7 +510,7 @@ func TestRequestCond_IP(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "192.168.1.100",
 | 
								Param:    "192.168.1.100",
 | 
				
			||||||
			Operator: RequestCondOperatorIPRange,
 | 
								Operator: RequestCondOperatorIPRange,
 | 
				
			||||||
			Value:    "a/18",
 | 
								Value:    "a/18",
 | 
				
			||||||
@@ -522,7 +522,7 @@ func TestRequestCond_IP(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "192.168.1.100",
 | 
								Param:    "192.168.1.100",
 | 
				
			||||||
			Operator: RequestCondOperatorIPMod10,
 | 
								Operator: RequestCondOperatorIPMod10,
 | 
				
			||||||
			Value:    "6",
 | 
								Value:    "6",
 | 
				
			||||||
@@ -534,7 +534,7 @@ func TestRequestCond_IP(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "192.168.1.100",
 | 
								Param:    "192.168.1.100",
 | 
				
			||||||
			Operator: RequestCondOperatorIPMod100,
 | 
								Operator: RequestCondOperatorIPMod100,
 | 
				
			||||||
			Value:    "76",
 | 
								Value:    "76",
 | 
				
			||||||
@@ -546,7 +546,7 @@ func TestRequestCond_IP(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "192.168.1.100",
 | 
								Param:    "192.168.1.100",
 | 
				
			||||||
			Operator: RequestCondOperatorIPMod,
 | 
								Operator: RequestCondOperatorIPMod,
 | 
				
			||||||
			Value:    "10,6",
 | 
								Value:    "10,6",
 | 
				
			||||||
@@ -585,7 +585,7 @@ func TestRequestCondIPCompare(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{}
 | 
							cond := HTTPRequestCond{}
 | 
				
			||||||
		t.Log(cond.ipToInt64(net.ParseIP("192.168.1.100")))
 | 
							t.Log(cond.ipToInt64(net.ParseIP("192.168.1.100")))
 | 
				
			||||||
		t.Log(cond.ipToInt64(net.ParseIP("192.168.1.99")))
 | 
							t.Log(cond.ipToInt64(net.ParseIP("192.168.1.99")))
 | 
				
			||||||
		t.Log(cond.ipToInt64(net.ParseIP("0.0.0.0")))
 | 
							t.Log(cond.ipToInt64(net.ParseIP("0.0.0.0")))
 | 
				
			||||||
@@ -600,7 +600,7 @@ func TestRequestCond_In(t *testing.T) {
 | 
				
			|||||||
	a := assert.NewAssertion(t)
 | 
						a := assert.NewAssertion(t)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "a",
 | 
								Param:    "a",
 | 
				
			||||||
			Operator: RequestCondOperatorIn,
 | 
								Operator: RequestCondOperatorIn,
 | 
				
			||||||
			Value:    `a`,
 | 
								Value:    `a`,
 | 
				
			||||||
@@ -612,7 +612,7 @@ func TestRequestCond_In(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "a",
 | 
								Param:    "a",
 | 
				
			||||||
			Operator: RequestCondOperatorIn,
 | 
								Operator: RequestCondOperatorIn,
 | 
				
			||||||
			Value:    `["a", "b"]`,
 | 
								Value:    `["a", "b"]`,
 | 
				
			||||||
@@ -624,7 +624,7 @@ func TestRequestCond_In(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "c",
 | 
								Param:    "c",
 | 
				
			||||||
			Operator: RequestCondOperatorNotIn,
 | 
								Operator: RequestCondOperatorNotIn,
 | 
				
			||||||
			Value:    `["a", "b"]`,
 | 
								Value:    `["a", "b"]`,
 | 
				
			||||||
@@ -636,7 +636,7 @@ func TestRequestCond_In(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "a",
 | 
								Param:    "a",
 | 
				
			||||||
			Operator: RequestCondOperatorNotIn,
 | 
								Operator: RequestCondOperatorNotIn,
 | 
				
			||||||
			Value:    `["a", "b"]`,
 | 
								Value:    `["a", "b"]`,
 | 
				
			||||||
@@ -652,7 +652,7 @@ func TestRequestCond_File(t *testing.T) {
 | 
				
			|||||||
	a := assert.NewAssertion(t)
 | 
						a := assert.NewAssertion(t)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "a",
 | 
								Param:    "a",
 | 
				
			||||||
			Operator: RequestCondOperatorFileExt,
 | 
								Operator: RequestCondOperatorFileExt,
 | 
				
			||||||
			Value:    `["jpeg", "jpg", "png"]`,
 | 
								Value:    `["jpeg", "jpg", "png"]`,
 | 
				
			||||||
@@ -664,7 +664,7 @@ func TestRequestCond_File(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "a.gif",
 | 
								Param:    "a.gif",
 | 
				
			||||||
			Operator: RequestCondOperatorFileExt,
 | 
								Operator: RequestCondOperatorFileExt,
 | 
				
			||||||
			Value:    `["jpeg", "jpg", "png"]`,
 | 
								Value:    `["jpeg", "jpg", "png"]`,
 | 
				
			||||||
@@ -676,7 +676,7 @@ func TestRequestCond_File(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "a.png",
 | 
								Param:    "a.png",
 | 
				
			||||||
			Operator: RequestCondOperatorFileExt,
 | 
								Operator: RequestCondOperatorFileExt,
 | 
				
			||||||
			Value:    `["jpeg", "jpg", "png"]`,
 | 
								Value:    `["jpeg", "jpg", "png"]`,
 | 
				
			||||||
@@ -688,7 +688,7 @@ func TestRequestCond_File(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "a.png",
 | 
								Param:    "a.png",
 | 
				
			||||||
			Operator: RequestCondOperatorFileExist,
 | 
								Operator: RequestCondOperatorFileExist,
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -699,7 +699,7 @@ func TestRequestCond_File(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    Tea.Root + "/README.md",
 | 
								Param:    Tea.Root + "/README.md",
 | 
				
			||||||
			Operator: RequestCondOperatorFileExist,
 | 
								Operator: RequestCondOperatorFileExist,
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -710,7 +710,7 @@ func TestRequestCond_File(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    Tea.Root + "/README.md?v=1",
 | 
								Param:    Tea.Root + "/README.md?v=1",
 | 
				
			||||||
			Operator: RequestCondOperatorFileExist,
 | 
								Operator: RequestCondOperatorFileExist,
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -721,7 +721,7 @@ func TestRequestCond_File(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    Tea.Root,
 | 
								Param:    Tea.Root,
 | 
				
			||||||
			Operator: RequestCondOperatorFileExist,
 | 
								Operator: RequestCondOperatorFileExist,
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -732,7 +732,7 @@ func TestRequestCond_File(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    Tea.Root,
 | 
								Param:    Tea.Root,
 | 
				
			||||||
			Operator: RequestCondOperatorFileExist,
 | 
								Operator: RequestCondOperatorFileExist,
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -743,7 +743,7 @@ func TestRequestCond_File(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "a.png",
 | 
								Param:    "a.png",
 | 
				
			||||||
			Operator: RequestCondOperatorFileNotExist,
 | 
								Operator: RequestCondOperatorFileNotExist,
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -754,7 +754,7 @@ func TestRequestCond_File(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    Tea.Root + "/README.md",
 | 
								Param:    Tea.Root + "/README.md",
 | 
				
			||||||
			Operator: RequestCondOperatorFileNotExist,
 | 
								Operator: RequestCondOperatorFileNotExist,
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -769,7 +769,7 @@ func TestRequestCond_MimeType(t *testing.T) {
 | 
				
			|||||||
	a := assert.NewAssertion(t)
 | 
						a := assert.NewAssertion(t)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "text/html; charset=utf-8",
 | 
								Param:    "text/html; charset=utf-8",
 | 
				
			||||||
			Operator: RequestCondOperatorFileMimeType,
 | 
								Operator: RequestCondOperatorFileMimeType,
 | 
				
			||||||
			Value:    `["text/html"]`,
 | 
								Value:    `["text/html"]`,
 | 
				
			||||||
@@ -781,7 +781,7 @@ func TestRequestCond_MimeType(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "text/html; charset=utf-8",
 | 
								Param:    "text/html; charset=utf-8",
 | 
				
			||||||
			Operator: RequestCondOperatorFileMimeType,
 | 
								Operator: RequestCondOperatorFileMimeType,
 | 
				
			||||||
			Value:    `["text/*"]`,
 | 
								Value:    `["text/*"]`,
 | 
				
			||||||
@@ -793,7 +793,7 @@ func TestRequestCond_MimeType(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "text/html; charset=utf-8",
 | 
								Param:    "text/html; charset=utf-8",
 | 
				
			||||||
			Operator: RequestCondOperatorFileMimeType,
 | 
								Operator: RequestCondOperatorFileMimeType,
 | 
				
			||||||
			Value:    `["image/*"]`,
 | 
								Value:    `["image/*"]`,
 | 
				
			||||||
@@ -805,7 +805,7 @@ func TestRequestCond_MimeType(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "text/plain; charset=utf-8",
 | 
								Param:    "text/plain; charset=utf-8",
 | 
				
			||||||
			Operator: RequestCondOperatorFileMimeType,
 | 
								Operator: RequestCondOperatorFileMimeType,
 | 
				
			||||||
			Value:    `["text/html", "image/jpeg", "image/png"]`,
 | 
								Value:    `["text/html", "image/jpeg", "image/png"]`,
 | 
				
			||||||
@@ -821,7 +821,7 @@ func TestRequestCond_Version(t *testing.T) {
 | 
				
			|||||||
	a := assert.NewAssertion(t)
 | 
						a := assert.NewAssertion(t)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "1.0",
 | 
								Param:    "1.0",
 | 
				
			||||||
			Operator: RequestCondOperatorVersionRange,
 | 
								Operator: RequestCondOperatorVersionRange,
 | 
				
			||||||
			Value:    `1.0,1.1`,
 | 
								Value:    `1.0,1.1`,
 | 
				
			||||||
@@ -833,7 +833,7 @@ func TestRequestCond_Version(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "1.0",
 | 
								Param:    "1.0",
 | 
				
			||||||
			Operator: RequestCondOperatorVersionRange,
 | 
								Operator: RequestCondOperatorVersionRange,
 | 
				
			||||||
			Value:    `1.0,`,
 | 
								Value:    `1.0,`,
 | 
				
			||||||
@@ -845,7 +845,7 @@ func TestRequestCond_Version(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "1.0",
 | 
								Param:    "1.0",
 | 
				
			||||||
			Operator: RequestCondOperatorVersionRange,
 | 
								Operator: RequestCondOperatorVersionRange,
 | 
				
			||||||
			Value:    `,1.1`,
 | 
								Value:    `,1.1`,
 | 
				
			||||||
@@ -857,7 +857,7 @@ func TestRequestCond_Version(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "0.9",
 | 
								Param:    "0.9",
 | 
				
			||||||
			Operator: RequestCondOperatorVersionRange,
 | 
								Operator: RequestCondOperatorVersionRange,
 | 
				
			||||||
			Value:    `1.0,1.1`,
 | 
								Value:    `1.0,1.1`,
 | 
				
			||||||
@@ -869,7 +869,7 @@ func TestRequestCond_Version(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "0.9",
 | 
								Param:    "0.9",
 | 
				
			||||||
			Operator: RequestCondOperatorVersionRange,
 | 
								Operator: RequestCondOperatorVersionRange,
 | 
				
			||||||
			Value:    `1.0`,
 | 
								Value:    `1.0`,
 | 
				
			||||||
@@ -881,7 +881,7 @@ func TestRequestCond_Version(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "1.1",
 | 
								Param:    "1.1",
 | 
				
			||||||
			Operator: RequestCondOperatorVersionRange,
 | 
								Operator: RequestCondOperatorVersionRange,
 | 
				
			||||||
			Value:    `1.0`,
 | 
								Value:    `1.0`,
 | 
				
			||||||
@@ -903,7 +903,7 @@ func TestRequestCond_Mod(t *testing.T) {
 | 
				
			|||||||
	a := assert.NewAssertion(t)
 | 
						a := assert.NewAssertion(t)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "1",
 | 
								Param:    "1",
 | 
				
			||||||
			Operator: RequestCondOperatorMod,
 | 
								Operator: RequestCondOperatorMod,
 | 
				
			||||||
			Value:    "1",
 | 
								Value:    "1",
 | 
				
			||||||
@@ -915,7 +915,7 @@ func TestRequestCond_Mod(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "1",
 | 
								Param:    "1",
 | 
				
			||||||
			Operator: RequestCondOperatorMod,
 | 
								Operator: RequestCondOperatorMod,
 | 
				
			||||||
			Value:    "2",
 | 
								Value:    "2",
 | 
				
			||||||
@@ -927,7 +927,7 @@ func TestRequestCond_Mod(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "3",
 | 
								Param:    "3",
 | 
				
			||||||
			Operator: RequestCondOperatorMod,
 | 
								Operator: RequestCondOperatorMod,
 | 
				
			||||||
			Value:    "3",
 | 
								Value:    "3",
 | 
				
			||||||
@@ -939,7 +939,7 @@ func TestRequestCond_Mod(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "1",
 | 
								Param:    "1",
 | 
				
			||||||
			Operator: RequestCondOperatorMod,
 | 
								Operator: RequestCondOperatorMod,
 | 
				
			||||||
			Value:    "11,1",
 | 
								Value:    "11,1",
 | 
				
			||||||
@@ -951,7 +951,7 @@ func TestRequestCond_Mod(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "3",
 | 
								Param:    "3",
 | 
				
			||||||
			Operator: RequestCondOperatorMod,
 | 
								Operator: RequestCondOperatorMod,
 | 
				
			||||||
			Value:    "11,3",
 | 
								Value:    "11,3",
 | 
				
			||||||
@@ -963,7 +963,7 @@ func TestRequestCond_Mod(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    "4",
 | 
								Param:    "4",
 | 
				
			||||||
			Operator: RequestCondOperatorMod,
 | 
								Operator: RequestCondOperatorMod,
 | 
				
			||||||
			Value:    "2,0",
 | 
								Value:    "2,0",
 | 
				
			||||||
@@ -975,7 +975,7 @@ func TestRequestCond_Mod(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for i := 0; i < 100; i++ {
 | 
						for i := 0; i < 100; i++ {
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    fmt.Sprintf("%d", i),
 | 
								Param:    fmt.Sprintf("%d", i),
 | 
				
			||||||
			Operator: RequestCondOperatorMod10,
 | 
								Operator: RequestCondOperatorMod10,
 | 
				
			||||||
			Value:    fmt.Sprintf("%d", i%10),
 | 
								Value:    fmt.Sprintf("%d", i%10),
 | 
				
			||||||
@@ -987,7 +987,7 @@ func TestRequestCond_Mod(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for i := 0; i < 2000; i++ {
 | 
						for i := 0; i < 2000; i++ {
 | 
				
			||||||
		cond := RequestCond{
 | 
							cond := HTTPRequestCond{
 | 
				
			||||||
			Param:    fmt.Sprintf("%d", i),
 | 
								Param:    fmt.Sprintf("%d", i),
 | 
				
			||||||
			Operator: RequestCondOperatorMod100,
 | 
								Operator: RequestCondOperatorMod100,
 | 
				
			||||||
			Value:    fmt.Sprintf("%d", i%100),
 | 
								Value:    fmt.Sprintf("%d", i%100),
 | 
				
			||||||
@@ -6,7 +6,7 @@ import (
 | 
				
			|||||||
	"crypto/x509/pkix"
 | 
						"crypto/x509/pkix"
 | 
				
			||||||
	"encoding/pem"
 | 
						"encoding/pem"
 | 
				
			||||||
	"errors"
 | 
						"errors"
 | 
				
			||||||
	"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/configutils"
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/configutils"
 | 
				
			||||||
	"github.com/iwind/TeaGo/Tea"
 | 
						"github.com/iwind/TeaGo/Tea"
 | 
				
			||||||
	"github.com/iwind/TeaGo/files"
 | 
						"github.com/iwind/TeaGo/files"
 | 
				
			||||||
	"github.com/iwind/TeaGo/lists"
 | 
						"github.com/iwind/TeaGo/lists"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
package sslconfigs
 | 
					package sslconfigs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/configutils"
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/configutils"
 | 
				
			||||||
	"strconv"
 | 
						"strconv"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user