Compare commits
165 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4e4acc327d | ||
|
|
f73251f57d | ||
|
|
d9350839f3 | ||
|
|
25269adaae | ||
|
|
351337fcbc | ||
|
|
505b6b6c9e | ||
|
|
1b6a5001e8 | ||
|
|
443a3f3ec3 | ||
|
|
e4861c3fa1 | ||
|
|
8ba8528c98 | ||
|
|
4d0b1c7e0c | ||
|
|
3de4223023 | ||
|
|
5f29576049 | ||
|
|
4adb8117f8 | ||
|
|
2d304b19b8 | ||
|
|
8e605cce67 | ||
|
|
0d53785620 | ||
|
|
73ee81da78 | ||
|
|
a600fc9cd3 | ||
|
|
cc0b2fd74f | ||
|
|
e54cfa7765 | ||
|
|
7c5c600e31 | ||
|
|
c6f9126ae2 | ||
|
|
5478e6a956 | ||
|
|
3945e94f71 | ||
|
|
9cd3618d9b | ||
|
|
4389ffb397 | ||
|
|
debb72c2d3 | ||
|
|
b314f7e96c | ||
|
|
823e519d58 | ||
|
|
5a54390f1d | ||
|
|
704d3af982 | ||
|
|
96b48f2bbc | ||
|
|
4a1c9be931 | ||
|
|
f0dc9e0577 | ||
|
|
1cf38864de | ||
|
|
5f9e7e981c | ||
|
|
7073467128 | ||
|
|
adc4b945e7 | ||
|
|
12f6a1e3ce | ||
|
|
4f89360902 | ||
|
|
d422dc6b85 | ||
|
|
0dc678e38a | ||
|
|
05de67318b | ||
|
|
575e916088 | ||
|
|
489795dba0 | ||
|
|
3e8fc126b8 | ||
|
|
64c3d76fb2 | ||
|
|
3bd3ef5f78 | ||
|
|
827eeeb506 | ||
|
|
36cf357984 | ||
|
|
46140bbdb5 | ||
|
|
6a671f67bc | ||
|
|
ea991f5a97 | ||
|
|
5bcbf29fc6 | ||
|
|
e70d6bb33b | ||
|
|
8a8803cee9 | ||
|
|
184fbd384e | ||
|
|
fc3c607c8d | ||
|
|
1760e8b9c8 | ||
|
|
deea02b1ab | ||
|
|
7f0822000c | ||
|
|
6a36625bc2 | ||
|
|
eca0b997f8 | ||
|
|
8746107b73 | ||
|
|
729311f605 | ||
|
|
99a2801591 | ||
|
|
8a045c77c9 | ||
|
|
619ae043e2 | ||
|
|
9ee5c896d1 | ||
|
|
4209969214 | ||
|
|
a59c84ef0d | ||
|
|
988aca8d84 | ||
|
|
310875f8ec | ||
|
|
615fdc24d8 | ||
|
|
acd78085fa | ||
|
|
0d90dde90b | ||
|
|
3996a051ff | ||
|
|
dd14b4ab3d | ||
|
|
e50bcdf181 | ||
|
|
a145b799a2 | ||
|
|
cad0fd5ff2 | ||
|
|
57c249b791 | ||
|
|
7ee1cc9cf4 | ||
|
|
605b01db64 | ||
|
|
bbe76743b1 | ||
|
|
53563f040f | ||
|
|
9226001362 | ||
|
|
4270c08ab7 | ||
|
|
671fd5dcc2 | ||
|
|
e8a3dfba71 | ||
|
|
ba41c16123 | ||
|
|
490a17558c | ||
|
|
61f7a14428 | ||
|
|
a7336fafbf | ||
|
|
7dbf5add34 | ||
|
|
7c5c6267d4 | ||
|
|
8fdc98cde9 | ||
|
|
d4413b8afe | ||
|
|
826bf7bf7d | ||
|
|
c6e95eda15 | ||
|
|
539016c2f6 | ||
|
|
92f4ea0dc4 | ||
|
|
d430eebe8c | ||
|
|
30ff3ecde5 | ||
|
|
f0b5f6ed76 | ||
|
|
4c7de6bdc2 | ||
|
|
412704c9f3 | ||
|
|
f264426099 | ||
|
|
03a6e9ccb9 | ||
|
|
9b899dff74 | ||
|
|
5bfd5de90d | ||
|
|
2177f97bdb | ||
|
|
5340e5ad52 | ||
|
|
06a3db911c | ||
|
|
a7ae7ea2db | ||
|
|
f949e31c0f | ||
|
|
d0e1dfe1af | ||
|
|
083ccfed7d | ||
|
|
347bbe1b96 | ||
|
|
16cf11b366 | ||
|
|
01e211560d | ||
|
|
96ce664202 | ||
|
|
2b8191001b | ||
|
|
6799f3f9ae | ||
|
|
55e2c38cd8 | ||
|
|
534d8e471d | ||
|
|
3c81bd6d5d | ||
|
|
f2d087a6ce | ||
|
|
2497a81e09 | ||
|
|
972b487db8 | ||
|
|
170e6ebfb8 | ||
|
|
9e80750309 | ||
|
|
f056a9c5bd | ||
|
|
6a42827ebd | ||
|
|
2d25c385fa | ||
|
|
8a6c20db01 | ||
|
|
22d00a6c92 | ||
|
|
51f8fd0f31 | ||
|
|
15708ec1bb | ||
|
|
b6667fc323 | ||
|
|
43cf3b57dd | ||
|
|
58dcab31ae | ||
|
|
712a9397a1 | ||
|
|
fe00446003 | ||
|
|
c098732e51 | ||
|
|
5c1a9fb8ff | ||
|
|
4b52a9703b | ||
|
|
1aebbc8e39 | ||
|
|
9df5a409e6 | ||
|
|
c9bb7fb8a5 | ||
|
|
6a2803187e | ||
|
|
3c5c961cd5 | ||
|
|
be5c6b12bb | ||
|
|
e6af6b6575 | ||
|
|
65be70d015 | ||
|
|
117c89ff62 | ||
|
|
6d8156b10b | ||
|
|
9cc9c4e2b3 | ||
|
|
7271046cb3 | ||
|
|
2a67b2b2d6 | ||
|
|
31de0d5112 | ||
|
|
e80ea8a0e2 | ||
|
|
c08d7c48f2 | ||
|
|
e44e54fbf4 |
75
.golangci.yaml
Normal file
75
.golangci.yaml
Normal file
@@ -0,0 +1,75 @@
|
||||
# https://golangci-lint.run/usage/configuration/
|
||||
|
||||
linters:
|
||||
enable-all: true
|
||||
disable:
|
||||
- ifshort
|
||||
- exhaustivestruct
|
||||
- golint
|
||||
- nosnakecase
|
||||
- scopelint
|
||||
- varcheck
|
||||
- structcheck
|
||||
- interfacer
|
||||
- maligned
|
||||
- deadcode
|
||||
- dogsled
|
||||
- wrapcheck
|
||||
- wastedassign
|
||||
- varnamelen
|
||||
- testpackage
|
||||
- thelper
|
||||
- nilerr
|
||||
- sqlclosecheck
|
||||
- paralleltest
|
||||
- nonamedreturns
|
||||
- nlreturn
|
||||
- nakedret
|
||||
- ireturn
|
||||
- interfacebloat
|
||||
- gosmopolitan
|
||||
- gomnd
|
||||
- goerr113
|
||||
- gochecknoglobals
|
||||
- exhaustruct
|
||||
- errorlint
|
||||
- depguard
|
||||
- exhaustive
|
||||
- containedctx
|
||||
- wsl
|
||||
- cyclop
|
||||
- dupword
|
||||
- errchkjson
|
||||
- contextcheck
|
||||
- tagalign
|
||||
- dupl
|
||||
- forbidigo
|
||||
- funlen
|
||||
- goconst
|
||||
- godox
|
||||
- gosec
|
||||
- lll
|
||||
- nestif
|
||||
- revive
|
||||
- unparam
|
||||
- stylecheck
|
||||
- gocritic
|
||||
- gofumpt
|
||||
- gomoddirectives
|
||||
- godot
|
||||
- gofmt
|
||||
- gocognit
|
||||
- mirror
|
||||
- gocyclo
|
||||
- gochecknoinits
|
||||
- gci
|
||||
- maintidx
|
||||
- prealloc
|
||||
- goimports
|
||||
- errname
|
||||
- musttag
|
||||
- forcetypeassert
|
||||
- whitespace
|
||||
- noctx
|
||||
- tagliatelle
|
||||
- nilnil
|
||||
19
README.md
19
README.md
@@ -3,15 +3,16 @@ GoEdge公共配置项。
|
||||
目录结构:
|
||||
~~~
|
||||
pkg/
|
||||
dnsconfigs - 域名解析和NameServer相关配置
|
||||
messageconfigs - 消息通知相关配置
|
||||
monitorconfigs - 监控相关配置
|
||||
nodeconfigs - 边缘节点相关配置
|
||||
nodeutils - 边缘节点相关函数
|
||||
serverconfigs - 网站服务相关配置
|
||||
systemconfigs - 系统全局配置
|
||||
reporterconfigs - 区域监控终端配置
|
||||
userconfigs - 用户相关配置
|
||||
dnsconfigs/ - 域名解析和NameServer相关配置
|
||||
langs/ 多语言配置
|
||||
messageconfigs/ - 消息通知相关配置
|
||||
monitorconfigs/ - 监控相关配置
|
||||
nodeconfigs/ - 边缘节点相关配置
|
||||
nodeutils/ - 边缘节点相关函数
|
||||
serverconfigs/ - 网站服务相关配置
|
||||
systemconfigs/ - 系统全局配置
|
||||
reporterconfigs/ - 区域监控终端配置
|
||||
userconfigs/ - 用户相关配置
|
||||
|
||||
configutils/ - 配置公共函数等
|
||||
iplibrary/ - IP库
|
||||
|
||||
@@ -1,3 +1,31 @@
|
||||
每次 `.proto` 文件有更新的时候,请运行 `build.sh` 重新生成相应的源代码。
|
||||
# 脚本使用指南
|
||||
|
||||
如果文件名有更改,请清空 `pkg/rpc/pb/*.go` 文件,然后再次运行 `build.sh`。
|
||||
## 编译多语言相关源文件
|
||||
~~~bash
|
||||
./build-messages.sh
|
||||
~~~
|
||||
|
||||
## 编译API相关源文件
|
||||
在使用 `build.sh` 编译 `.proto` 文件之前,你需要确保已经为 `protoc` 安装了对应的插件:
|
||||
~~~bash
|
||||
# install protoc-gen-go plugin
|
||||
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
|
||||
|
||||
# install protoc-gen-go-grpc plugin
|
||||
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
|
||||
~~~
|
||||
|
||||
之后每次 `.proto` 文件有更新的时候,请运行 `build.sh` 重新生成相应的Go源代码和`rpc.json`文件:
|
||||
~~~bash
|
||||
./build.sh
|
||||
~~~
|
||||
|
||||
如果文件名有更改,请清空 `pkg/rpc/pb/*.go` 文件,然后再次运行 `build.sh`。
|
||||
|
||||
|
||||
## 生成RPC列表文件
|
||||
运行:
|
||||
~~~bash
|
||||
./proto-json.sh
|
||||
~~~
|
||||
可以重新生成 `rpc.json` 文件。
|
||||
@@ -2,22 +2,27 @@
|
||||
|
||||
echo "starting ..."
|
||||
|
||||
function assert() {
|
||||
RESULT=$?
|
||||
if [ "${RESULT}" != "0" ]; then
|
||||
exit
|
||||
fi
|
||||
}
|
||||
|
||||
#rm -f ../pkg/rpc/pb/*.pb.go
|
||||
protoc --go_out=../pkg/rpc --proto_path=../pkg/rpc/protos ../pkg/rpc/protos/*.proto
|
||||
assert
|
||||
|
||||
protoc --go_out=plugins=grpc:../pkg/rpc --proto_path=../pkg/rpc/protos ../pkg/rpc/protos/*.proto
|
||||
RESULT=$?
|
||||
if [ "${RESULT}" != "0" ]; then
|
||||
exit
|
||||
fi
|
||||
protoc --go-grpc_out=../pkg/rpc --go-grpc_opt=require_unimplemented_servers=false --proto_path=../pkg/rpc/protos ../pkg/rpc/protos/*.proto
|
||||
assert
|
||||
|
||||
protoc --go_out=plugins=grpc:../pkg/rpc --proto_path=../pkg/rpc/protos ../pkg/rpc/protos/models/*.proto
|
||||
protoc --go_out=../pkg/rpc --proto_path=../pkg/rpc/protos ../pkg/rpc/protos/models/*.proto
|
||||
RESULT=$?
|
||||
if [ "${RESULT}" != "0" ]; then
|
||||
exit
|
||||
fi
|
||||
assert
|
||||
|
||||
|
||||
# generate rpc.json
|
||||
./proto-json.sh --quiet
|
||||
assert
|
||||
|
||||
echo "ok"
|
||||
1678
build/rpc.json
1678
build/rpc.json
File diff suppressed because it is too large
Load Diff
@@ -285,9 +285,9 @@ func init() {
|
||||
}
|
||||
}
|
||||
|
||||
messageMapJSON, err := json.Marshal(filteredMessages)
|
||||
if err != nil {
|
||||
fmt.Println("[ERROR]marshal message map failed: " + err.Error())
|
||||
messageMapJSON, jsonErr := json.Marshal(filteredMessages)
|
||||
if jsonErr != nil {
|
||||
fmt.Println("[ERROR]marshal message map failed: " + jsonErr.Error())
|
||||
return
|
||||
}
|
||||
err = os.WriteFile(targetFile, []byte(`// generated by 'langs generate'
|
||||
@@ -296,6 +296,17 @@ window.LANG_MESSAGES = `+string(messageMapJSON)+";\n"), 0666)
|
||||
fmt.Println("[ERROR]write file '" + targetFile + "' failed: " + err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// base.js
|
||||
if lang == "zh-cn" {
|
||||
var baseJSFile = filepath.Dir(targetFile) + "/base.js"
|
||||
err = os.WriteFile(baseJSFile, []byte(`// generated by 'langs generate'
|
||||
window.LANG_MESSAGES_BASE = `+string(messageMapJSON)+";\n"), 0666)
|
||||
if err != nil {
|
||||
fmt.Println("[ERROR]write file '" + baseJSFile + "' failed: " + err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
18
go.mod
18
go.mod
@@ -1,21 +1,19 @@
|
||||
module github.com/TeaOSLab/EdgeCommon
|
||||
|
||||
go 1.18
|
||||
go 1.21
|
||||
|
||||
require (
|
||||
github.com/golang/protobuf v1.5.2
|
||||
github.com/iwind/TeaGo v0.0.0-20230623080147-cd1e53b4915f
|
||||
github.com/tdewolff/minify/v2 v2.12.7
|
||||
golang.org/x/net v0.8.0
|
||||
google.golang.org/grpc v1.45.0
|
||||
google.golang.org/protobuf v1.27.1
|
||||
golang.org/x/net v0.24.0
|
||||
google.golang.org/grpc v1.62.0
|
||||
google.golang.org/protobuf v1.33.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/kr/text v0.2.0 // indirect
|
||||
github.com/tdewolff/parse/v2 v2.6.6 // indirect
|
||||
golang.org/x/sys v0.6.0 // indirect
|
||||
golang.org/x/text v0.8.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20220317150908-0efb43f6373e // indirect
|
||||
golang.org/x/sys v0.19.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240228224816-df926f6c8641 // indirect
|
||||
)
|
||||
|
||||
164
go.sum
164
go.sum
@@ -1,156 +1,38 @@
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cheekybits/is v0.0.0-20150225183255-68e9c0620927/go.mod h1:h/aW8ynjgkuj+NQRlZcDbAbM1ORAbXjXX77sX7T289U=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
|
||||
github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/djherbis/atime v1.1.0/go.mod h1:28OF6Y8s3NQWwacXc5eZTsEsiMzp7LF8MbXE+XJPdBE=
|
||||
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||
github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
||||
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
||||
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/iwind/TeaGo v0.0.0-20230623080147-cd1e53b4915f h1:xo6XmXLtveKcwcZAXV6VMxkWNzy/2dStfHEnyowsGAE=
|
||||
github.com/iwind/TeaGo v0.0.0-20230623080147-cd1e53b4915f/go.mod h1:fi/Pq+/5m2HZoseM+39dMF57ANXRt6w4PkGu3NXPc5s=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/matryer/try v0.0.0-20161228173917-9ac251b645a2/go.mod h1:0KeJpeMD6o+O4hW7qJOT7vyQPKrWmj26uf5wMc/IiIs=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/tdewolff/minify/v2 v2.12.7 h1:pBzz2tAfz5VghOXiQIsSta6srhmTeinQPjRDHWoumCA=
|
||||
github.com/tdewolff/minify/v2 v2.12.7/go.mod h1:ZRKTheiOGyLSK8hOZWWv+YoJAECzDivNgAlVYDHp/Ws=
|
||||
github.com/tdewolff/parse/v2 v2.6.6 h1:Yld+0CrKUJaCV78DL1G2nk3C9lKrxyRTux5aaK/AkDo=
|
||||
github.com/tdewolff/parse/v2 v2.6.6/go.mod h1:woz0cgbLwFdtbjJu8PIKxhW05KplTFQkOdX78o+Jgrs=
|
||||
github.com/tdewolff/test v1.0.7/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE=
|
||||
github.com/tdewolff/test v1.0.9 h1:SswqJCmeN4B+9gEAi/5uqT0qpi1y2/2O47V/1hhGZT0=
|
||||
github.com/tdewolff/test v1.0.9/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE=
|
||||
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ=
|
||||
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
|
||||
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
|
||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||
golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
|
||||
golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
|
||||
golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
|
||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto v0.0.0-20220317150908-0efb43f6373e h1:fNKDNuUyC4WH+inqDMpfXDdfvwfYILbsX+oskGZ8hxg=
|
||||
google.golang.org/genproto v0.0.0-20220317150908-0efb43f6373e/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
|
||||
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/grpc v1.45.0 h1:NEpgUqV3Z+ZjkqMsxMg11IaDrXY4RY6CQukSGK0uI1M=
|
||||
google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240228224816-df926f6c8641 h1:DKU1r6Tj5s1vlU/moGhuGz7E3xRfwjdAfDzbsaQJtEY=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240228224816-df926f6c8641/go.mod h1:UCOku4NytXMJuLQE5VuqA5lX3PcHCBo8pxNyvkf4xBs=
|
||||
google.golang.org/grpc v1.62.0 h1:HQKZ/fa1bXkX1oFOvSjmZEUL8wLSaZTjCcLAlmZRtdk=
|
||||
google.golang.org/grpc v1.62.0/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
|
||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I=
|
||||
google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
|
||||
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
|
||||
@@ -1,41 +1,10 @@
|
||||
package configutils
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"math/big"
|
||||
"net"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// IPString2Long 将IP转换为整型
|
||||
// 注意IPv6没有顺序
|
||||
func IPString2Long(ip string) uint64 {
|
||||
if len(ip) == 0 {
|
||||
return 0
|
||||
}
|
||||
var netIP = net.ParseIP(ip)
|
||||
if len(netIP) == 0 {
|
||||
return 0
|
||||
}
|
||||
return IP2Long(netIP)
|
||||
}
|
||||
|
||||
// IP2Long 将IP对象转换为整型
|
||||
func IP2Long(netIP net.IP) uint64 {
|
||||
if len(netIP) == 0 {
|
||||
return 0
|
||||
}
|
||||
|
||||
var b4 = netIP.To4()
|
||||
if b4 != nil {
|
||||
return uint64(binary.BigEndian.Uint32(b4.To4()))
|
||||
}
|
||||
|
||||
var i = big.NewInt(0)
|
||||
i.SetBytes(netIP.To16())
|
||||
return i.Uint64()
|
||||
}
|
||||
|
||||
// IsIPv4 检查是否为IPv4
|
||||
func IsIPv4(netIP net.IP) bool {
|
||||
if len(netIP) == 0 {
|
||||
@@ -69,28 +38,6 @@ func IPVersion(netIP net.IP) int {
|
||||
return 0
|
||||
}
|
||||
|
||||
// ParseCIDR 计算CIDR最大值
|
||||
func ParseCIDR(cidr string) (ipFrom string, ipTo string, err error) {
|
||||
_, ipNet, err := net.ParseCIDR(cidr)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
ipFrom = ipNet.IP.String()
|
||||
Loop:
|
||||
for i := len(ipNet.Mask) - 1; i >= 0; i-- {
|
||||
for j := 7; j >= 0; j-- {
|
||||
var m = ipNet.Mask[i] >> (7 - j) & 1 // 读取某位bit
|
||||
if m == 0 {
|
||||
ipNet.IP[i] |= 1 << j // 将此位置为1
|
||||
} else {
|
||||
break Loop
|
||||
}
|
||||
}
|
||||
}
|
||||
ipTo = ipNet.IP.String()
|
||||
return
|
||||
}
|
||||
|
||||
// QuoteIP 为IPv6加上括号
|
||||
func QuoteIP(ip string) string {
|
||||
if len(ip) == 0 {
|
||||
|
||||
@@ -3,25 +3,12 @@
|
||||
package configutils_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/configutils"
|
||||
"github.com/iwind/TeaGo/assert"
|
||||
"net"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestParseCIDR(t *testing.T) {
|
||||
t.Log(configutils.ParseCIDR("192.168.1.1/32"))
|
||||
t.Log(configutils.ParseCIDR("192.168.1.1/24"))
|
||||
t.Log(configutils.ParseCIDR("192.168.1.1/16"))
|
||||
}
|
||||
|
||||
func TestIPString2Long(t *testing.T) {
|
||||
for _, ip := range []string{"127.0.0.1", "192.168.1.100", "::1", "fd00:6868:6868:0:10ac:d056:3bf6:7452", "fd00:6868:6868:0:10ac:d056:3bf6:7453", "2001:0db8:85a3:0000:0000:8a2e:0370:7334", "wrong ip"} {
|
||||
t.Log(fmt.Sprintf("%42s", ip), "=>", configutils.IPString2Long(ip))
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsIPv4(t *testing.T) {
|
||||
t.Log(configutils.IsIPv4(net.ParseIP("192.168.1.100")))
|
||||
t.Log(configutils.IsIPv4(net.ParseIP("::1")))
|
||||
@@ -40,7 +27,6 @@ func TestIPVersion(t *testing.T) {
|
||||
a.IsTrue(configutils.IPVersion(net.ParseIP("2001:0db8:85a3:0000:0000:8a2e:0370:7334")) == 6)
|
||||
}
|
||||
|
||||
|
||||
func TestQuoteIP(t *testing.T) {
|
||||
t.Log(configutils.QuoteIP(configutils.QuoteIP("2001:da8:22::10")))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
|
||||
var whitespaceReg = regexp.MustCompile(`\s+`)
|
||||
|
||||
// 关键词匹配
|
||||
// MatchKeyword 关键词匹配
|
||||
func MatchKeyword(source, keyword string) bool {
|
||||
if len(keyword) == 0 {
|
||||
return false
|
||||
@@ -16,7 +16,7 @@ func MatchKeyword(source, keyword string) bool {
|
||||
pieces := whitespaceReg.Split(keyword, -1)
|
||||
source = strings.ToLower(source)
|
||||
for _, piece := range pieces {
|
||||
if strings.Index(source, strings.ToLower(piece)) > -1 {
|
||||
if strings.Contains(source, strings.ToLower(piece)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,30 @@
|
||||
package configutils
|
||||
|
||||
import (
|
||||
"crypto/sha1"
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
stringutil "github.com/iwind/TeaGo/utils/string"
|
||||
"net/url"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// VariableHolder 变量信息存储类型
|
||||
type VariableHolder string
|
||||
type VariableHolders = []interface{}
|
||||
type VariableHolder struct {
|
||||
Param string
|
||||
Modifiers []string
|
||||
}
|
||||
type VariableHolders = []any
|
||||
|
||||
var variableMapping = map[string][]interface{}{} // source => [holder1, ...]
|
||||
var variableLocker = sync.RWMutex{}
|
||||
var regexpNamedVariable = regexp.MustCompile(`\${[@\w.-]+}`)
|
||||
var variableMapping = map[string][]any{} // source => [holder1, ...]
|
||||
var variableLocker = &sync.RWMutex{}
|
||||
var regexpNamedVariable = regexp.MustCompile(`\${[@\w.|-]+}`)
|
||||
|
||||
var stringBuilderPool = sync.Pool{
|
||||
New: func() interface{} {
|
||||
New: func() any {
|
||||
return &strings.Builder{}
|
||||
},
|
||||
}
|
||||
@@ -46,7 +55,11 @@ func ParseVariables(source string, replacer func(varName string) (value string))
|
||||
var h = holders[0]
|
||||
holder, ok := h.(VariableHolder)
|
||||
if ok {
|
||||
return replacer(string(holder))
|
||||
var value = replacer(holder.Param)
|
||||
if holder.Modifiers != nil {
|
||||
value = doStringModifiers(value, holder.Modifiers)
|
||||
}
|
||||
return replacer(value)
|
||||
}
|
||||
return source
|
||||
}
|
||||
@@ -58,7 +71,11 @@ func ParseVariables(source string, replacer func(varName string) (value string))
|
||||
for _, h := range holders {
|
||||
holder, ok := h.(VariableHolder)
|
||||
if ok {
|
||||
builder.WriteString(replacer(string(holder)))
|
||||
var value = replacer(holder.Param)
|
||||
if holder.Modifiers != nil {
|
||||
value = doStringModifiers(value, holder.Modifiers)
|
||||
}
|
||||
builder.WriteString(value)
|
||||
} else {
|
||||
builder.Write(h.([]byte))
|
||||
}
|
||||
@@ -86,11 +103,15 @@ func ParseVariablesFromHolders(holders VariableHolders, replacer func(varName st
|
||||
}
|
||||
|
||||
// replace
|
||||
result := strings.Builder{}
|
||||
var result = strings.Builder{}
|
||||
for _, h := range holders {
|
||||
holder, ok := h.(VariableHolder)
|
||||
if ok {
|
||||
result.WriteString(replacer(string(holder)))
|
||||
var value = replacer(holder.Param)
|
||||
if holder.Modifiers != nil {
|
||||
value = doStringModifiers(value, holder.Modifiers)
|
||||
}
|
||||
result.WriteString(value)
|
||||
} else {
|
||||
result.Write(h.([]byte))
|
||||
}
|
||||
@@ -100,12 +121,24 @@ func ParseVariablesFromHolders(holders VariableHolders, replacer func(varName st
|
||||
|
||||
// ParseHolders 分析占位
|
||||
func ParseHolders(source string) (holders VariableHolders) {
|
||||
indexes := regexpNamedVariable.FindAllStringIndex(source, -1)
|
||||
before := 0
|
||||
var indexes = regexpNamedVariable.FindAllStringIndex(source, -1)
|
||||
var 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))
|
||||
var holder = source[loc[0]+2 : loc[1]-1]
|
||||
|
||||
if strings.Contains(holder, "|") {
|
||||
var holderPieces = strings.Split(holder, "|")
|
||||
holders = append(holders, VariableHolder{
|
||||
Param: holderPieces[0],
|
||||
Modifiers: holderPieces[1:],
|
||||
})
|
||||
} else {
|
||||
holders = append(holders, VariableHolder{
|
||||
Param: holder,
|
||||
Modifiers: nil,
|
||||
})
|
||||
}
|
||||
before = loc[1]
|
||||
}
|
||||
if before < len(source) {
|
||||
@@ -121,3 +154,36 @@ func HasVariables(source string) bool {
|
||||
}
|
||||
return regexpNamedVariable.MatchString(source)
|
||||
}
|
||||
|
||||
// 执行变量后的修饰符
|
||||
func doStringModifiers(value string, modifiers []string) string {
|
||||
for _, modifier := range modifiers {
|
||||
switch modifier {
|
||||
case "urlEncode":
|
||||
value = url.QueryEscape(value)
|
||||
case "urlDecode":
|
||||
value2, err := url.QueryUnescape(value)
|
||||
if err == nil {
|
||||
value = value2
|
||||
}
|
||||
case "base64Encode":
|
||||
value = base64.StdEncoding.EncodeToString([]byte(value))
|
||||
case "base64Decode":
|
||||
value2, err := base64.StdEncoding.DecodeString(value)
|
||||
if err == nil {
|
||||
value = string(value2)
|
||||
}
|
||||
case "md5":
|
||||
value = stringutil.Md5(value)
|
||||
case "sha1":
|
||||
value = fmt.Sprintf("%x", sha1.Sum([]byte(value)))
|
||||
case "sha256":
|
||||
value = fmt.Sprintf("%x", sha256.Sum256([]byte(value)))
|
||||
case "toLowerCase":
|
||||
value = strings.ToLower(value)
|
||||
case "toUpperCase":
|
||||
value = strings.ToUpper(value)
|
||||
}
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package configutils
|
||||
package configutils_test
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/configutils"
|
||||
"github.com/iwind/TeaGo/assert"
|
||||
"github.com/iwind/TeaGo/types"
|
||||
"runtime"
|
||||
"strconv"
|
||||
@@ -8,48 +10,128 @@ import (
|
||||
)
|
||||
|
||||
func TestParseVariables(t *testing.T) {
|
||||
var a = assert.NewAssertion(t)
|
||||
|
||||
{
|
||||
v := ParseVariables("hello, ${name}, world", func(s string) string {
|
||||
var v = configutils.ParseVariables("hello, ${name}, world", func(s string) string {
|
||||
return "Lu"
|
||||
})
|
||||
t.Log(v)
|
||||
a.IsTrue(v == "hello, Lu, world")
|
||||
}
|
||||
{
|
||||
v := ParseVariables("hello, world", func(s string) string {
|
||||
var v = configutils.ParseVariables("hello, world", func(s string) string {
|
||||
return "Lu"
|
||||
})
|
||||
t.Log(v)
|
||||
a.IsTrue(v == "hello, world")
|
||||
}
|
||||
{
|
||||
v := ParseVariables("${name}", func(s string) string {
|
||||
var v = configutils.ParseVariables("${name}", func(s string) string {
|
||||
return "Lu"
|
||||
})
|
||||
t.Log(v)
|
||||
a.IsTrue(v == "Lu")
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseNoVariables(t *testing.T) {
|
||||
for i := 0; i < 2; i++ {
|
||||
v := ParseVariables("hello, world", func(s string) string {
|
||||
var v = configutils.ParseVariables("hello, world", func(s string) string {
|
||||
return "Lu"
|
||||
})
|
||||
t.Log(v)
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseVariables_Modifier(t *testing.T) {
|
||||
t.Log(configutils.ParseVariables("${url|urlEncode}", func(varName string) (value string) {
|
||||
switch varName {
|
||||
case "url":
|
||||
return "/hello/world?a=1"
|
||||
}
|
||||
return "${" + varName + "}"
|
||||
}))
|
||||
t.Log(configutils.ParseVariables("${url|urlDecode}", func(varName string) (value string) {
|
||||
switch varName {
|
||||
case "url":
|
||||
return "%2Fhello%2Fworld%3Fa%3D1"
|
||||
}
|
||||
return "${" + varName + "}"
|
||||
}))
|
||||
t.Log(configutils.ParseVariables("${url|urlDecode|urlEncode}", func(varName string) (value string) {
|
||||
switch varName {
|
||||
case "url":
|
||||
return "%2Fhello%2Fworld%3Fa%3D1"
|
||||
}
|
||||
return "${" + varName + "}"
|
||||
}))
|
||||
t.Log(configutils.ParseVariables("${var|base64Encode}", func(varName string) (value string) {
|
||||
switch varName {
|
||||
case "var":
|
||||
return "123456"
|
||||
}
|
||||
return "${" + varName + "}"
|
||||
}))
|
||||
t.Log(configutils.ParseVariables("${var|base64Encode|base64Decode}", func(varName string) (value string) {
|
||||
switch varName {
|
||||
case "var":
|
||||
return "123456"
|
||||
}
|
||||
return "${" + varName + "}"
|
||||
}))
|
||||
t.Log(configutils.ParseVariables("${var|md5}", func(varName string) (value string) {
|
||||
switch varName {
|
||||
case "var":
|
||||
return "123456"
|
||||
}
|
||||
return "${" + varName + "}"
|
||||
}))
|
||||
t.Log(configutils.ParseVariables("${var|sha1}", func(varName string) (value string) {
|
||||
switch varName {
|
||||
case "var":
|
||||
return "123456"
|
||||
}
|
||||
return "${" + varName + "}"
|
||||
}))
|
||||
t.Log(configutils.ParseVariables("${var|sha256}", func(varName string) (value string) {
|
||||
switch varName {
|
||||
case "var":
|
||||
return "123456"
|
||||
}
|
||||
return "${" + varName + "}"
|
||||
}))
|
||||
t.Log(configutils.ParseVariables("${var|toLowerCase}", func(varName string) (value string) {
|
||||
switch varName {
|
||||
case "var":
|
||||
return "ABC"
|
||||
}
|
||||
return "${" + varName + "}"
|
||||
}))
|
||||
t.Log(configutils.ParseVariables("${var|toUpperCase}", func(varName string) (value string) {
|
||||
switch varName {
|
||||
case "var":
|
||||
return "abc"
|
||||
}
|
||||
return "${" + varName + "}"
|
||||
}))
|
||||
}
|
||||
|
||||
func TestParseHolders(t *testing.T) {
|
||||
var holders = ParseHolders("hello, ${name}, world")
|
||||
var holders = configutils.ParseHolders("hello, ${name|urlencode}, world")
|
||||
t.Log("===holders begin===")
|
||||
for _, h := range holders {
|
||||
t.Log(types.String(h))
|
||||
}
|
||||
t.Log("===holders end===")
|
||||
|
||||
t.Log("parse result:", ParseVariablesFromHolders(holders, func(s string) string {
|
||||
t.Log("parse result:", configutils.ParseVariablesFromHolders(holders, func(s string) string {
|
||||
return "[" + s + "]"
|
||||
}))
|
||||
}
|
||||
|
||||
func BenchmarkParseVariables(b *testing.B) {
|
||||
_ = ParseVariables("hello, ${name}, ${age}, ${gender}, ${home}, world", func(s string) string {
|
||||
_ = configutils.ParseVariables("hello, ${name}, ${age}, ${gender}, ${home}, world", func(s string) string {
|
||||
return "Lu"
|
||||
})
|
||||
|
||||
@@ -57,7 +139,7 @@ func BenchmarkParseVariables(b *testing.B) {
|
||||
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
_ = ParseVariables("hello, ${name}, ${age}, ${gender}, ${home}, world", func(s string) string {
|
||||
_ = configutils.ParseVariables("hello, ${name}, ${age}, ${gender}, ${home}, world", func(s string) string {
|
||||
return "Lu"
|
||||
})
|
||||
}
|
||||
@@ -65,10 +147,10 @@ func BenchmarkParseVariables(b *testing.B) {
|
||||
}
|
||||
|
||||
func BenchmarkParseVariablesFromHolders(b *testing.B) {
|
||||
var holders = ParseHolders("hello, ${name}, ${age}, ${gender}, ${home}, world")
|
||||
var holders = configutils.ParseHolders("hello, ${name}, ${age}, ${gender}, ${home}, world")
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = ParseVariablesFromHolders(holders, func(s string) string {
|
||||
_ = configutils.ParseVariablesFromHolders(holders, func(s string) string {
|
||||
return "Lu"
|
||||
})
|
||||
}
|
||||
@@ -76,7 +158,7 @@ func BenchmarkParseVariablesFromHolders(b *testing.B) {
|
||||
|
||||
func BenchmarkParseVariablesUnique(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = ParseVariables("hello, ${name} "+strconv.Itoa(i), func(s string) string {
|
||||
_ = configutils.ParseVariables("hello, ${name} "+strconv.Itoa(i%100_000), func(s string) string {
|
||||
return "Lu"
|
||||
})
|
||||
}
|
||||
@@ -86,7 +168,7 @@ func BenchmarkParseVariablesUnique_Single(b *testing.B) {
|
||||
runtime.GOMAXPROCS(1)
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = ParseVariables("${name}", func(s string) string {
|
||||
_ = configutils.ParseVariables("${name}", func(s string) string {
|
||||
return "Lu"
|
||||
})
|
||||
}
|
||||
@@ -94,7 +176,7 @@ func BenchmarkParseVariablesUnique_Single(b *testing.B) {
|
||||
|
||||
func BenchmarkParseNoVariables(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = ParseVariables("hello, world", func(s string) string {
|
||||
_ = configutils.ParseVariables("hello, world", func(s string) string {
|
||||
return "Lu"
|
||||
})
|
||||
}
|
||||
@@ -102,7 +184,7 @@ func BenchmarkParseNoVariables(b *testing.B) {
|
||||
|
||||
func BenchmarkParseEmpty(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = ParseVariables("", func(s string) string {
|
||||
_ = configutils.ParseVariables("", func(s string) string {
|
||||
return "Lu"
|
||||
})
|
||||
}
|
||||
|
||||
@@ -13,9 +13,9 @@ func (this *DetailedError) Code() string {
|
||||
return this.code
|
||||
}
|
||||
|
||||
func NewDetailedError(code string, error string) *DetailedError {
|
||||
func NewDetailedError(code string, errString string) *DetailedError {
|
||||
return &DetailedError{
|
||||
msg: error,
|
||||
msg: errString,
|
||||
code: code,
|
||||
}
|
||||
}
|
||||
|
||||
3
pkg/iplibrary/.gitignore
vendored
3
pkg/iplibrary/.gitignore
vendored
@@ -1 +1,2 @@
|
||||
*-plus.db
|
||||
*-plus.db
|
||||
internal-ip-library-test.db
|
||||
@@ -33,7 +33,7 @@ func InitDefault() error {
|
||||
}
|
||||
|
||||
var library = NewIPLibrary()
|
||||
err := library.InitFromData(ipLibraryData, "")
|
||||
err := library.InitFromData(ipLibraryData, "", ReaderVersionV1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -53,19 +53,31 @@ func LookupIP(ip string) *QueryResult {
|
||||
return defaultLibrary.LookupIP(ip)
|
||||
}
|
||||
|
||||
// LookupIPSummaries 查询一组IP对应的区域描述
|
||||
func LookupIPSummaries(ipList []string) map[string]string /** ip => summary **/ {
|
||||
var result = map[string]string{}
|
||||
for _, ip := range ipList {
|
||||
var region = LookupIP(ip)
|
||||
if region != nil && region.IsOk() {
|
||||
result[ip] = region.Summary()
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
type IPLibrary struct {
|
||||
reader *Reader
|
||||
reader ReaderInterface
|
||||
}
|
||||
|
||||
func NewIPLibrary() *IPLibrary {
|
||||
return &IPLibrary{}
|
||||
}
|
||||
|
||||
func NewIPLibraryWithReader(reader *Reader) *IPLibrary {
|
||||
func NewIPLibraryWithReader(reader ReaderInterface) *IPLibrary {
|
||||
return &IPLibrary{reader: reader}
|
||||
}
|
||||
|
||||
func (this *IPLibrary) InitFromData(data []byte, password string) error {
|
||||
func (this *IPLibrary) InitFromData(data []byte, password string, version ReaderVersion) error {
|
||||
if len(data) == 0 || this.reader != nil {
|
||||
return nil
|
||||
}
|
||||
@@ -87,7 +99,12 @@ func (this *IPLibrary) InitFromData(data []byte, password string) error {
|
||||
_ = gzipReader.Close()
|
||||
}()
|
||||
|
||||
libReader, err := NewReader(gzipReader)
|
||||
var libReader ReaderInterface
|
||||
if version == ReaderVersionV2 {
|
||||
libReader, err = NewReaderV2(gzipReader)
|
||||
} else {
|
||||
libReader, err = NewReaderV1(gzipReader)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ import (
|
||||
func TestIPLibrary_Init(t *testing.T) {
|
||||
var lib = iplibrary.NewIPLibrary()
|
||||
|
||||
err := lib.InitFromData(iplibrary.DefaultIPLibraryData(), "")
|
||||
err := lib.InitFromData(iplibrary.DefaultIPLibraryData(), "", iplibrary.ReaderVersionV1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -38,7 +38,7 @@ func TestIPLibrary_Lookup(t *testing.T) {
|
||||
|
||||
var before = time.Now()
|
||||
|
||||
err := lib.InitFromData(iplibrary.DefaultIPLibraryData(), "")
|
||||
err := lib.InitFromData(iplibrary.DefaultIPLibraryData(), "", iplibrary.ReaderVersionV1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -69,7 +69,7 @@ func TestIPLibrary_Lookup(t *testing.T) {
|
||||
|
||||
func TestIPLibrary_LookupIP(t *testing.T) {
|
||||
var lib = iplibrary.NewIPLibrary()
|
||||
err := lib.InitFromData(iplibrary.DefaultIPLibraryData(), "")
|
||||
err := lib.InitFromData(iplibrary.DefaultIPLibraryData(), "", iplibrary.ReaderVersionV1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -86,9 +86,44 @@ func TestIPLibrary_LookupIP(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestIPLibrary_LookupIP_Summary(t *testing.T) {
|
||||
var lib = iplibrary.NewIPLibrary()
|
||||
err := lib.InitFromData(iplibrary.DefaultIPLibraryData(), "", iplibrary.ReaderVersionV1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
for _, ip := range []string{
|
||||
"66.249.66.69",
|
||||
"123456", // wrong ip
|
||||
"", // empty
|
||||
} {
|
||||
var result = lib.LookupIP(ip)
|
||||
if result.IsOk() {
|
||||
t.Log(ip, "=>", "region summary:", result.RegionSummary(), "summary:", result.Summary())
|
||||
} else {
|
||||
t.Log(ip, "=>", "region summary:", result.RegionSummary(), "summary:", result.Summary())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestIPLibrary_LookupIPSummaries(t *testing.T) {
|
||||
_ = iplibrary.InitDefault()
|
||||
t.Logf("%+v", iplibrary.LookupIPSummaries([]string{
|
||||
"127.0.0.1",
|
||||
"8.8.8.8",
|
||||
"4.4.4.4",
|
||||
"202.96.0.20",
|
||||
"111.197.165.199",
|
||||
"66.249.66.69",
|
||||
"2222", // wrong ip
|
||||
"2406:8c00:0:3401:133:18:168:70", // ipv6
|
||||
}))
|
||||
}
|
||||
|
||||
func BenchmarkIPLibrary_Lookup(b *testing.B) {
|
||||
var lib = iplibrary.NewIPLibrary()
|
||||
err := lib.InitFromData(iplibrary.DefaultIPLibraryData(), "")
|
||||
err := lib.InitFromData(iplibrary.DefaultIPLibraryData(), "", iplibrary.ReaderVersionV1)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -6,20 +6,34 @@ import (
|
||||
"github.com/iwind/TeaGo/types"
|
||||
)
|
||||
|
||||
type ipv4Item struct {
|
||||
type ipv4ItemV1 struct {
|
||||
IPFrom uint32
|
||||
IPTo uint32
|
||||
|
||||
Region *ipRegion
|
||||
}
|
||||
|
||||
type ipv6Item struct {
|
||||
type ipv6ItemV1 struct {
|
||||
IPFrom uint64
|
||||
IPTo uint64
|
||||
|
||||
Region *ipRegion
|
||||
}
|
||||
|
||||
type ipv4ItemV2 struct {
|
||||
IPFrom [4]byte
|
||||
IPTo [4]byte
|
||||
|
||||
Region *ipRegion
|
||||
}
|
||||
|
||||
type ipv6ItemV2 struct {
|
||||
IPFrom [16]byte
|
||||
IPTo [16]byte
|
||||
|
||||
Region *ipRegion
|
||||
}
|
||||
|
||||
type ipRegion struct {
|
||||
CountryId uint16
|
||||
ProvinceId uint16
|
||||
|
||||
@@ -4,11 +4,14 @@ package iplibrary
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/configutils"
|
||||
"io"
|
||||
"math/big"
|
||||
"net"
|
||||
"runtime"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -20,8 +23,8 @@ type Reader struct {
|
||||
|
||||
regionMap map[string]*ipRegion // 缓存重复的区域用来节约内存
|
||||
|
||||
ipV4Items []*ipv4Item
|
||||
ipV6Items []*ipv6Item
|
||||
ipV4Items []ipv4ItemV1
|
||||
ipV6Items []ipv6ItemV1
|
||||
|
||||
lastIPFrom uint64
|
||||
lastCountryId uint16
|
||||
@@ -31,11 +34,18 @@ type Reader struct {
|
||||
lastProviderId uint16
|
||||
}
|
||||
|
||||
// NewReader 创建新Reader对象
|
||||
func NewReader(reader io.Reader) (*Reader, error) {
|
||||
// NewReaderV1 创建新Reader对象
|
||||
func NewReaderV1(reader io.Reader) (*Reader, error) {
|
||||
var libReader = &Reader{
|
||||
regionMap: map[string]*ipRegion{},
|
||||
}
|
||||
|
||||
if runtime.NumCPU() >= 4 /** CPU数量较多的通常有着大内存 **/ {
|
||||
libReader.ipV4Items = make([]ipv4ItemV1, 0, 6_000_000)
|
||||
} else {
|
||||
libReader.ipV4Items = make([]ipv4ItemV1, 0, 600_000)
|
||||
}
|
||||
|
||||
err := libReader.load(reader)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -46,7 +56,7 @@ func NewReader(reader io.Reader) (*Reader, error) {
|
||||
// 从Reader中加载数据
|
||||
func (this *Reader) load(reader io.Reader) error {
|
||||
var buf = make([]byte, 1024)
|
||||
var metaLine = []byte{}
|
||||
var metaLine []byte
|
||||
var metaLineFound = false
|
||||
var dataBuf = []byte{}
|
||||
for {
|
||||
@@ -123,7 +133,7 @@ func (this *Reader) Lookup(ip net.IP) *QueryResult {
|
||||
return &QueryResult{}
|
||||
}
|
||||
|
||||
var ipLong = configutils.IP2Long(ip)
|
||||
var ipLong = this.ip2long(ip)
|
||||
var isV4 = configutils.IsIPv4(ip)
|
||||
var resultItem any
|
||||
if isV4 {
|
||||
@@ -162,11 +172,11 @@ func (this *Reader) Meta() *Meta {
|
||||
return this.meta
|
||||
}
|
||||
|
||||
func (this *Reader) IPv4Items() []*ipv4Item {
|
||||
func (this *Reader) IPv4Items() []ipv4ItemV1 {
|
||||
return this.ipV4Items
|
||||
}
|
||||
|
||||
func (this *Reader) IPv6Items() []*ipv6Item {
|
||||
func (this *Reader) IPv6Items() []ipv6ItemV1 {
|
||||
return this.ipV6Items
|
||||
}
|
||||
|
||||
@@ -296,13 +306,13 @@ func (this *Reader) parseLine(line []byte) error {
|
||||
}
|
||||
|
||||
if version == "4" {
|
||||
this.ipV4Items = append(this.ipV4Items, &ipv4Item{
|
||||
this.ipV4Items = append(this.ipV4Items, ipv4ItemV1{
|
||||
IPFrom: uint32(ipFrom),
|
||||
IPTo: uint32(ipTo),
|
||||
Region: region,
|
||||
})
|
||||
} else {
|
||||
this.ipV6Items = append(this.ipV6Items, &ipv6Item{
|
||||
this.ipV6Items = append(this.ipV6Items, ipv6ItemV1{
|
||||
IPFrom: ipFrom,
|
||||
IPTo: ipTo,
|
||||
Region: region,
|
||||
@@ -320,3 +330,18 @@ func (this *Reader) decodeUint64(s string) uint64 {
|
||||
i, _ := strconv.ParseUint(s, 10, 64)
|
||||
return i
|
||||
}
|
||||
|
||||
func (this *Reader) ip2long(netIP net.IP) uint64 {
|
||||
if len(netIP) == 0 {
|
||||
return 0
|
||||
}
|
||||
|
||||
var b4 = netIP.To4()
|
||||
if b4 != nil {
|
||||
return uint64(binary.BigEndian.Uint32(b4.To4()))
|
||||
}
|
||||
|
||||
var i = big.NewInt(0)
|
||||
i.SetBytes(netIP.To16())
|
||||
return i.Uint64()
|
||||
}
|
||||
|
||||
@@ -5,15 +5,17 @@ package iplibrary
|
||||
import (
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type FileReader struct {
|
||||
rawReader *Reader
|
||||
password string
|
||||
rawReader ReaderInterface
|
||||
//password string
|
||||
}
|
||||
|
||||
func NewFileReader(path string, password string) (*FileReader, error) {
|
||||
@@ -25,10 +27,15 @@ func NewFileReader(path string, password string) (*FileReader, error) {
|
||||
_ = fp.Close()
|
||||
}()
|
||||
|
||||
return NewFileDataReader(fp, password)
|
||||
var version = ReaderVersionV1
|
||||
if strings.HasSuffix(filepath.Base(path), ".v2.db") {
|
||||
version = ReaderVersionV2
|
||||
}
|
||||
|
||||
return NewFileDataReader(fp, password, version)
|
||||
}
|
||||
|
||||
func NewFileDataReader(dataReader io.Reader, password string) (*FileReader, error) {
|
||||
func NewFileDataReader(dataReader io.Reader, password string, readerVersion ReaderVersion) (*FileReader, error) {
|
||||
if len(password) > 0 {
|
||||
data, err := io.ReadAll(dataReader)
|
||||
if err != nil {
|
||||
@@ -45,10 +52,15 @@ func NewFileDataReader(dataReader io.Reader, password string) (*FileReader, erro
|
||||
|
||||
gzReader, err := gzip.NewReader(dataReader)
|
||||
if err != nil {
|
||||
return nil, errors.New("create gzip reader failed: " + err.Error())
|
||||
return nil, fmt.Errorf("create gzip reader failed: %w", err)
|
||||
}
|
||||
|
||||
reader, err := NewReader(gzReader)
|
||||
var reader ReaderInterface
|
||||
if readerVersion == ReaderVersionV2 {
|
||||
reader, err = NewReaderV2(gzReader)
|
||||
} else {
|
||||
reader, err = NewReaderV1(gzReader)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -59,13 +71,13 @@ func NewFileDataReader(dataReader io.Reader, password string) (*FileReader, erro
|
||||
}
|
||||
|
||||
func (this *FileReader) Meta() *Meta {
|
||||
return this.rawReader.meta
|
||||
return this.rawReader.Meta()
|
||||
}
|
||||
|
||||
func (this *FileReader) Lookup(ip net.IP) *QueryResult {
|
||||
return this.rawReader.Lookup(ip)
|
||||
}
|
||||
|
||||
func (this *FileReader) RawReader() *Reader {
|
||||
func (this *FileReader) RawReader() ReaderInterface {
|
||||
return this.rawReader
|
||||
}
|
||||
|
||||
@@ -6,12 +6,13 @@ import (
|
||||
"encoding/json"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/iplibrary"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
stringutil "github.com/iwind/TeaGo/utils/string"
|
||||
"net"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestNewFileReader(t *testing.T) {
|
||||
reader, err := iplibrary.NewFileReader("./ip-20c1461c.db", "123456")
|
||||
reader, err := iplibrary.NewFileReader("./default_ip_library_plus_test.go", stringutil.Md5("123456"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
18
pkg/iplibrary/reader_interface.go
Normal file
18
pkg/iplibrary/reader_interface.go
Normal file
@@ -0,0 +1,18 @@
|
||||
// Copyright 2024 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
|
||||
package iplibrary
|
||||
|
||||
import "net"
|
||||
|
||||
type ReaderVersion = int
|
||||
|
||||
const (
|
||||
ReaderVersionV1 ReaderVersion = 0
|
||||
ReaderVersionV2 ReaderVersion = 2
|
||||
)
|
||||
|
||||
type ReaderInterface interface {
|
||||
Meta() *Meta
|
||||
Lookup(ip net.IP) *QueryResult
|
||||
Destroy()
|
||||
}
|
||||
@@ -183,12 +183,51 @@ func (this *QueryResult) Summary() string {
|
||||
return strings.Join(pieces, " ")
|
||||
}
|
||||
|
||||
func (this *QueryResult) RegionSummary() string {
|
||||
if this.item == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
var pieces = []string{}
|
||||
var countryName = this.CountryName()
|
||||
var provinceName = this.ProvinceName()
|
||||
var cityName = this.CityName()
|
||||
var townName = this.TownName()
|
||||
|
||||
if len(countryName) > 0 {
|
||||
pieces = append(pieces, countryName)
|
||||
}
|
||||
if len(provinceName) > 0 && !lists.ContainsString(pieces, provinceName) {
|
||||
pieces = append(pieces, provinceName)
|
||||
}
|
||||
if len(cityName) > 0 && !lists.ContainsString(pieces, cityName) && !lists.ContainsString(pieces, strings.TrimSuffix(cityName, "市")) {
|
||||
pieces = append(pieces, cityName)
|
||||
}
|
||||
if len(townName) > 0 && !lists.ContainsString(pieces, townName) && !lists.ContainsString(pieces, strings.TrimSuffix(townName, "县")) {
|
||||
pieces = append(pieces, townName)
|
||||
}
|
||||
|
||||
return strings.Join(pieces, " ")
|
||||
}
|
||||
|
||||
func (this *QueryResult) realCountryId() uint16 {
|
||||
if this.item != nil {
|
||||
switch item := this.item.(type) {
|
||||
case *ipv4Item:
|
||||
case *ipv4ItemV1:
|
||||
return item.Region.CountryId
|
||||
case *ipv6Item:
|
||||
case ipv4ItemV1:
|
||||
return item.Region.CountryId
|
||||
case *ipv6ItemV1:
|
||||
return item.Region.CountryId
|
||||
case ipv6ItemV1:
|
||||
return item.Region.CountryId
|
||||
case *ipv4ItemV2:
|
||||
return item.Region.CountryId
|
||||
case ipv4ItemV2:
|
||||
return item.Region.CountryId
|
||||
case *ipv6ItemV2:
|
||||
return item.Region.CountryId
|
||||
case ipv6ItemV2:
|
||||
return item.Region.CountryId
|
||||
}
|
||||
|
||||
@@ -199,9 +238,21 @@ func (this *QueryResult) realCountryId() uint16 {
|
||||
func (this *QueryResult) realProvinceId() uint16 {
|
||||
if this.item != nil {
|
||||
switch item := this.item.(type) {
|
||||
case *ipv4Item:
|
||||
case *ipv4ItemV1:
|
||||
return item.Region.ProvinceId
|
||||
case *ipv6Item:
|
||||
case ipv4ItemV1:
|
||||
return item.Region.ProvinceId
|
||||
case *ipv6ItemV1:
|
||||
return item.Region.ProvinceId
|
||||
case ipv6ItemV1:
|
||||
return item.Region.ProvinceId
|
||||
case *ipv4ItemV2:
|
||||
return item.Region.ProvinceId
|
||||
case ipv4ItemV2:
|
||||
return item.Region.ProvinceId
|
||||
case *ipv6ItemV2:
|
||||
return item.Region.ProvinceId
|
||||
case ipv6ItemV2:
|
||||
return item.Region.ProvinceId
|
||||
}
|
||||
|
||||
@@ -212,9 +263,21 @@ func (this *QueryResult) realProvinceId() uint16 {
|
||||
func (this *QueryResult) realCityId() uint32 {
|
||||
if this.item != nil {
|
||||
switch item := this.item.(type) {
|
||||
case *ipv4Item:
|
||||
case *ipv4ItemV1:
|
||||
return item.Region.CityId
|
||||
case *ipv6Item:
|
||||
case ipv4ItemV1:
|
||||
return item.Region.CityId
|
||||
case *ipv6ItemV1:
|
||||
return item.Region.CityId
|
||||
case ipv6ItemV1:
|
||||
return item.Region.CityId
|
||||
case *ipv4ItemV2:
|
||||
return item.Region.CityId
|
||||
case ipv4ItemV2:
|
||||
return item.Region.CityId
|
||||
case *ipv6ItemV2:
|
||||
return item.Region.CityId
|
||||
case ipv6ItemV2:
|
||||
return item.Region.CityId
|
||||
}
|
||||
|
||||
@@ -225,9 +288,21 @@ func (this *QueryResult) realCityId() uint32 {
|
||||
func (this *QueryResult) realTownId() uint32 {
|
||||
if this.item != nil {
|
||||
switch item := this.item.(type) {
|
||||
case *ipv4Item:
|
||||
case *ipv4ItemV1:
|
||||
return item.Region.TownId
|
||||
case *ipv6Item:
|
||||
case ipv4ItemV1:
|
||||
return item.Region.TownId
|
||||
case *ipv6ItemV1:
|
||||
return item.Region.TownId
|
||||
case ipv6ItemV1:
|
||||
return item.Region.TownId
|
||||
case *ipv4ItemV2:
|
||||
return item.Region.TownId
|
||||
case ipv4ItemV2:
|
||||
return item.Region.TownId
|
||||
case *ipv6ItemV2:
|
||||
return item.Region.TownId
|
||||
case ipv6ItemV2:
|
||||
return item.Region.TownId
|
||||
}
|
||||
|
||||
@@ -238,9 +313,21 @@ func (this *QueryResult) realTownId() uint32 {
|
||||
func (this *QueryResult) realProviderId() uint16 {
|
||||
if this.item != nil {
|
||||
switch item := this.item.(type) {
|
||||
case *ipv4Item:
|
||||
case *ipv4ItemV1:
|
||||
return item.Region.ProviderId
|
||||
case *ipv6Item:
|
||||
case ipv4ItemV1:
|
||||
return item.Region.ProviderId
|
||||
case *ipv6ItemV1:
|
||||
return item.Region.ProviderId
|
||||
case ipv6ItemV1:
|
||||
return item.Region.ProviderId
|
||||
case *ipv4ItemV2:
|
||||
return item.Region.ProviderId
|
||||
case ipv4ItemV2:
|
||||
return item.Region.ProviderId
|
||||
case *ipv6ItemV2:
|
||||
return item.Region.ProviderId
|
||||
case ipv6ItemV2:
|
||||
return item.Region.ProviderId
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ import (
|
||||
|
||||
func TestNewReader(t *testing.T) {
|
||||
var buf = &bytes.Buffer{}
|
||||
var writer = iplibrary.NewWriter(buf, &iplibrary.Meta{
|
||||
var writer = iplibrary.NewWriterV1(buf, &iplibrary.Meta{
|
||||
Author: "GoEdge <https://goedge.cn>",
|
||||
})
|
||||
|
||||
@@ -63,7 +63,7 @@ func TestNewReader(t *testing.T) {
|
||||
|
||||
var stat = &runtime.MemStats{}
|
||||
runtime.ReadMemStats(stat)
|
||||
reader, err := iplibrary.NewReader(buf)
|
||||
reader, err := iplibrary.NewReaderV2(buf)
|
||||
|
||||
var stat2 = &runtime.MemStats{}
|
||||
runtime.ReadMemStats(stat2)
|
||||
@@ -115,7 +115,7 @@ func BenchmarkNewReader(b *testing.B) {
|
||||
runtime.GOMAXPROCS(1)
|
||||
|
||||
var buf = &bytes.Buffer{}
|
||||
var writer = iplibrary.NewWriter(buf, &iplibrary.Meta{
|
||||
var writer = iplibrary.NewWriterV1(buf, &iplibrary.Meta{
|
||||
Author: "GoEdge <https://goedge.cn>",
|
||||
})
|
||||
|
||||
@@ -135,7 +135,7 @@ func BenchmarkNewReader(b *testing.B) {
|
||||
}
|
||||
}
|
||||
|
||||
reader, err := iplibrary.NewReader(buf)
|
||||
reader, err := iplibrary.NewReaderV2(buf)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
|
||||
360
pkg/iplibrary/reader_v2.go
Normal file
360
pkg/iplibrary/reader_v2.go
Normal file
@@ -0,0 +1,360 @@
|
||||
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
|
||||
package iplibrary
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io"
|
||||
"net"
|
||||
"runtime"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ReaderV2 IP库Reader V2
|
||||
type ReaderV2 struct {
|
||||
meta *Meta
|
||||
|
||||
regionMap map[string]*ipRegion // 缓存重复的区域用来节约内存
|
||||
|
||||
ipV4Items []ipv4ItemV2
|
||||
ipV6Items []ipv6ItemV2
|
||||
|
||||
lastCountryId uint16
|
||||
lastProvinceId uint16
|
||||
lastCityId uint32
|
||||
lastTownId uint32
|
||||
lastProviderId uint16
|
||||
}
|
||||
|
||||
// NewReaderV2 创建新Reader对象
|
||||
func NewReaderV2(reader io.Reader) (*ReaderV2, error) {
|
||||
var libReader = &ReaderV2{
|
||||
regionMap: map[string]*ipRegion{},
|
||||
}
|
||||
|
||||
if runtime.NumCPU() >= 4 /** CPU数量较多的通常有着大内存 **/ {
|
||||
libReader.ipV4Items = make([]ipv4ItemV2, 0, 6_000_000)
|
||||
} else {
|
||||
libReader.ipV4Items = make([]ipv4ItemV2, 0, 600_000)
|
||||
}
|
||||
|
||||
err := libReader.load(reader)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return libReader, nil
|
||||
}
|
||||
|
||||
// 从Reader中加载数据
|
||||
func (this *ReaderV2) load(reader io.Reader) error {
|
||||
var buf = make([]byte, 1024)
|
||||
var metaLine []byte
|
||||
var metaLineFound = false
|
||||
var dataBuf = []byte{}
|
||||
for {
|
||||
n, err := reader.Read(buf)
|
||||
if n > 0 {
|
||||
var data = buf[:n]
|
||||
dataBuf = append(dataBuf, data...)
|
||||
if metaLineFound {
|
||||
left, err := this.parse(dataBuf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dataBuf = left
|
||||
} else {
|
||||
var index = bytes.IndexByte(dataBuf, '\n')
|
||||
if index > 0 {
|
||||
metaLine = dataBuf[:index]
|
||||
dataBuf = dataBuf[index+1:]
|
||||
metaLineFound = true
|
||||
var meta = &Meta{}
|
||||
err = json.Unmarshal(metaLine, &meta)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
meta.Init()
|
||||
this.meta = meta
|
||||
|
||||
left, err := this.parse(dataBuf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dataBuf = left
|
||||
}
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
if err != io.EOF {
|
||||
return err
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
sort.Slice(this.ipV4Items, func(i, j int) bool {
|
||||
var from0 = this.ipV4Items[i].IPFrom
|
||||
var to0 = this.ipV4Items[i].IPTo
|
||||
var from1 = this.ipV4Items[j].IPFrom
|
||||
var to1 = this.ipV4Items[j].IPTo
|
||||
if from0 == from1 {
|
||||
return bytes.Compare(to0[:], to1[:]) < 0
|
||||
}
|
||||
return bytes.Compare(from0[:], from1[:]) < 0
|
||||
})
|
||||
|
||||
sort.Slice(this.ipV6Items, func(i, j int) bool {
|
||||
var from0 = this.ipV6Items[i].IPFrom
|
||||
var to0 = this.ipV6Items[i].IPTo
|
||||
var from1 = this.ipV6Items[j].IPFrom
|
||||
var to1 = this.ipV6Items[j].IPTo
|
||||
if from0 == from1 {
|
||||
return bytes.Compare(to0[:], to1[:]) < 0
|
||||
}
|
||||
return bytes.Compare(from0[:], from1[:]) < 0
|
||||
})
|
||||
|
||||
// 清理内存
|
||||
this.regionMap = nil
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (this *ReaderV2) Lookup(ip net.IP) *QueryResult {
|
||||
if ip == nil {
|
||||
return &QueryResult{}
|
||||
}
|
||||
|
||||
var isV4 = ip.To4() != nil
|
||||
var resultItem any
|
||||
if isV4 {
|
||||
sort.Search(len(this.ipV4Items), func(i int) bool {
|
||||
var item = this.ipV4Items[i]
|
||||
if bytes.Compare(item.IPFrom[:], ip) <= 0 {
|
||||
if bytes.Compare(item.IPTo[:], ip) >= 0 {
|
||||
resultItem = item
|
||||
return false
|
||||
}
|
||||
return false
|
||||
}
|
||||
return true
|
||||
})
|
||||
} else {
|
||||
sort.Search(len(this.ipV6Items), func(i int) bool {
|
||||
var item = this.ipV6Items[i]
|
||||
if bytes.Compare(item.IPFrom[:], ip) <= 0 {
|
||||
if bytes.Compare(item.IPTo[:], ip) >= 0 {
|
||||
resultItem = item
|
||||
return false
|
||||
}
|
||||
return false
|
||||
}
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
||||
return &QueryResult{
|
||||
item: resultItem,
|
||||
meta: this.meta,
|
||||
}
|
||||
}
|
||||
|
||||
func (this *ReaderV2) Meta() *Meta {
|
||||
return this.meta
|
||||
}
|
||||
|
||||
func (this *ReaderV2) IPv4Items() []ipv4ItemV2 {
|
||||
return this.ipV4Items
|
||||
}
|
||||
|
||||
func (this *ReaderV2) IPv6Items() []ipv6ItemV2 {
|
||||
return this.ipV6Items
|
||||
}
|
||||
|
||||
func (this *ReaderV2) Destroy() {
|
||||
this.meta = nil
|
||||
this.regionMap = nil
|
||||
this.ipV4Items = nil
|
||||
this.ipV6Items = nil
|
||||
}
|
||||
|
||||
// 分析数据
|
||||
func (this *ReaderV2) parse(data []byte) (left []byte, err error) {
|
||||
if len(data) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
for {
|
||||
if len(data) == 0 {
|
||||
break
|
||||
}
|
||||
|
||||
var offset int
|
||||
if data[0] == '|' {
|
||||
offset = 1 + 8 + 1
|
||||
} else if data[0] == '4' {
|
||||
offset = 2 + 8 + 1
|
||||
} else if data[0] == '6' {
|
||||
offset = 2 + 32 + 1
|
||||
}
|
||||
|
||||
var index = bytes.IndexByte(data[offset:], '\n')
|
||||
if index >= 0 {
|
||||
index += offset
|
||||
var line = data[:index]
|
||||
err = this.parseLine(line)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data = data[index+1:]
|
||||
} else {
|
||||
left = data
|
||||
break
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 单行分析
|
||||
func (this *ReaderV2) parseLine(line []byte) error {
|
||||
if len(line) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
const maxPieces = 8
|
||||
var pieces []string
|
||||
|
||||
var offset int
|
||||
if line[0] == '|' {
|
||||
offset = 1 + 8 + 1
|
||||
pieces = append(pieces, "", string(line[1:5]), string(line[5:9]))
|
||||
} else if line[0] == '4' {
|
||||
offset = 2 + 8 + 1
|
||||
pieces = append(pieces, "", string(line[2:6]), string(line[6:10]))
|
||||
} else if line[0] == '6' {
|
||||
offset = 2 + 32 + 1
|
||||
pieces = append(pieces, "6", string(line[2:18]), string(line[18:34]))
|
||||
}
|
||||
|
||||
pieces = append(pieces, strings.Split(string(line[offset:]), "|")...)
|
||||
|
||||
var countPieces = len(pieces)
|
||||
if countPieces < maxPieces { // 补足一行
|
||||
for i := 0; i < maxPieces-countPieces; i++ {
|
||||
pieces = append(pieces, "")
|
||||
}
|
||||
} else if countPieces > maxPieces {
|
||||
return errors.New("invalid ip definition '" + string(line) + "'")
|
||||
}
|
||||
|
||||
var version = pieces[0]
|
||||
if len(version) == 0 {
|
||||
version = "4"
|
||||
}
|
||||
|
||||
if version != "4" && version != "6" {
|
||||
return errors.New("invalid ip version '" + string(line) + "'")
|
||||
}
|
||||
|
||||
// ip range
|
||||
var ipFromV4 [4]byte
|
||||
var ipToV4 [4]byte
|
||||
|
||||
var ipFromV6 [16]byte
|
||||
var ipToV6 [16]byte
|
||||
|
||||
if version == "6" {
|
||||
ipFromV6 = [16]byte([]byte(pieces[1]))
|
||||
ipToV6 = [16]byte([]byte(pieces[2]))
|
||||
} else {
|
||||
ipFromV4 = [4]byte([]byte(pieces[1]))
|
||||
ipToV4 = [4]byte([]byte(pieces[2]))
|
||||
}
|
||||
|
||||
// country
|
||||
var countryId uint16
|
||||
if pieces[3] == "+" {
|
||||
countryId = this.lastCountryId
|
||||
} else {
|
||||
countryId = uint16(this.decodeUint64(pieces[3]))
|
||||
}
|
||||
this.lastCountryId = countryId
|
||||
|
||||
var provinceId uint16
|
||||
if pieces[4] == "+" {
|
||||
provinceId = this.lastProvinceId
|
||||
} else {
|
||||
provinceId = uint16(this.decodeUint64(pieces[4]))
|
||||
}
|
||||
this.lastProvinceId = provinceId
|
||||
|
||||
// city
|
||||
var cityId uint32
|
||||
if pieces[5] == "+" {
|
||||
cityId = this.lastCityId
|
||||
} else {
|
||||
cityId = uint32(this.decodeUint64(pieces[5]))
|
||||
}
|
||||
this.lastCityId = cityId
|
||||
|
||||
// town
|
||||
var townId uint32
|
||||
if pieces[6] == "+" {
|
||||
townId = this.lastTownId
|
||||
} else {
|
||||
townId = uint32(this.decodeUint64(pieces[6]))
|
||||
}
|
||||
this.lastTownId = townId
|
||||
|
||||
// provider
|
||||
var providerId uint16
|
||||
if pieces[7] == "+" {
|
||||
providerId = this.lastProviderId
|
||||
} else {
|
||||
providerId = uint16(this.decodeUint64(pieces[7]))
|
||||
}
|
||||
this.lastProviderId = providerId
|
||||
|
||||
var hash = HashRegion(countryId, provinceId, cityId, townId, providerId)
|
||||
|
||||
region, ok := this.regionMap[hash]
|
||||
if !ok {
|
||||
region = &ipRegion{
|
||||
CountryId: countryId,
|
||||
ProvinceId: provinceId,
|
||||
CityId: cityId,
|
||||
TownId: townId,
|
||||
ProviderId: providerId,
|
||||
}
|
||||
this.regionMap[hash] = region
|
||||
}
|
||||
|
||||
if version == "4" {
|
||||
this.ipV4Items = append(this.ipV4Items, ipv4ItemV2{
|
||||
IPFrom: ipFromV4,
|
||||
IPTo: ipToV4,
|
||||
Region: region,
|
||||
})
|
||||
} else {
|
||||
this.ipV6Items = append(this.ipV6Items, ipv6ItemV2{
|
||||
IPFrom: ipFromV6,
|
||||
IPTo: ipToV6,
|
||||
Region: region,
|
||||
})
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (this *ReaderV2) decodeUint64(s string) uint64 {
|
||||
if this.meta != nil && this.meta.Version == Version2 {
|
||||
i, _ := strconv.ParseUint(s, 32, 64)
|
||||
return i
|
||||
}
|
||||
i, _ := strconv.ParseUint(s, 10, 64)
|
||||
return i
|
||||
}
|
||||
@@ -4,6 +4,7 @@ package iplibrary
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
"io"
|
||||
@@ -76,7 +77,7 @@ func (this *Updater) Init() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
return errors.New("read ip library file failed '" + err.Error() + "'")
|
||||
return fmt.Errorf("read ip library file failed '%w'", err)
|
||||
}
|
||||
defer func() {
|
||||
_ = fp.Close()
|
||||
@@ -167,7 +168,7 @@ func (this *Updater) Loop() error {
|
||||
// write to file
|
||||
fp, err := os.OpenFile(path, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666)
|
||||
if err != nil {
|
||||
return errors.New("create ip library file failed: " + err.Error())
|
||||
return fmt.Errorf("create ip library file failed: %w", err)
|
||||
}
|
||||
|
||||
var isOk = false
|
||||
@@ -195,7 +196,7 @@ func (this *Updater) Loop() error {
|
||||
err = this.loadFile(fp)
|
||||
_ = fp.Close()
|
||||
if err != nil {
|
||||
return errors.New("load file failed: " + err.Error())
|
||||
return fmt.Errorf("load file failed: %w", err)
|
||||
}
|
||||
|
||||
isOk = true
|
||||
@@ -213,9 +214,14 @@ func (this *Updater) Loop() error {
|
||||
func (this *Updater) loadFile(fp *os.File) error {
|
||||
this.source.LogInfo("load ip library from '" + fp.Name() + "' ...")
|
||||
|
||||
fileReader, err := NewFileDataReader(fp, "")
|
||||
var version = ReaderVersionV1
|
||||
if strings.HasSuffix(fp.Name(), ".v2.db") {
|
||||
version = ReaderVersionV2
|
||||
}
|
||||
|
||||
fileReader, err := NewFileDataReader(fp, "", version)
|
||||
if err != nil {
|
||||
return errors.New("load ip library from reader failed: " + err.Error())
|
||||
return fmt.Errorf("load ip library from reader failed: %w", err)
|
||||
}
|
||||
|
||||
var reader = fileReader.RawReader()
|
||||
@@ -227,7 +233,7 @@ func (this *Updater) loadFile(fp *os.File) error {
|
||||
func (this *Updater) createDefaultFile(sourcePath string, dir string) error {
|
||||
sourceFp, err := os.Open(sourcePath)
|
||||
if err != nil {
|
||||
return errors.New("prepare to copy file to 'ip-library.db' failed: " + err.Error())
|
||||
return fmt.Errorf("prepare to copy file to 'ip-library.db' failed: %w", err)
|
||||
}
|
||||
defer func() {
|
||||
_ = sourceFp.Close()
|
||||
@@ -235,14 +241,14 @@ func (this *Updater) createDefaultFile(sourcePath string, dir string) error {
|
||||
|
||||
dstFp, err := os.Create(dir + "/ip-library.db")
|
||||
if err != nil {
|
||||
return errors.New("prepare to copy file to 'ip-library.db' failed: " + err.Error())
|
||||
return fmt.Errorf("prepare to copy file to 'ip-library.db' failed: %w", err)
|
||||
}
|
||||
defer func() {
|
||||
_ = dstFp.Close()
|
||||
}()
|
||||
_, err = io.Copy(dstFp, sourceFp)
|
||||
if err != nil {
|
||||
return errors.New("copy file to 'ip-library.db' failed: " + err.Error())
|
||||
return fmt.Errorf("copy file to 'ip-library.db' failed: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -3,42 +3,19 @@
|
||||
package iplibrary
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"encoding/binary"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/configutils"
|
||||
"hash"
|
||||
"io"
|
||||
"math/big"
|
||||
"net"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type hashWriter struct {
|
||||
rawWriter io.Writer
|
||||
hash hash.Hash
|
||||
}
|
||||
|
||||
func newHashWriter(writer io.Writer) *hashWriter {
|
||||
return &hashWriter{
|
||||
rawWriter: writer,
|
||||
hash: md5.New(),
|
||||
}
|
||||
}
|
||||
|
||||
func (this *hashWriter) Write(p []byte) (n int, err error) {
|
||||
n, err = this.rawWriter.Write(p)
|
||||
this.hash.Write(p)
|
||||
return
|
||||
}
|
||||
|
||||
func (this *hashWriter) Sum() string {
|
||||
return fmt.Sprintf("%x", this.hash.Sum(nil))
|
||||
}
|
||||
|
||||
type Writer struct {
|
||||
type WriterV1 struct {
|
||||
writer *hashWriter
|
||||
meta *Meta
|
||||
|
||||
@@ -50,21 +27,21 @@ type Writer struct {
|
||||
lastProviderId int64
|
||||
}
|
||||
|
||||
func NewWriter(writer io.Writer, meta *Meta) *Writer {
|
||||
func NewWriterV1(writer io.Writer, meta *Meta) *WriterV1 {
|
||||
if meta == nil {
|
||||
meta = &Meta{}
|
||||
}
|
||||
meta.Version = Version2
|
||||
meta.CreatedAt = time.Now().Unix()
|
||||
|
||||
var libWriter = &Writer{
|
||||
var libWriter = &WriterV1{
|
||||
writer: newHashWriter(writer),
|
||||
meta: meta,
|
||||
}
|
||||
return libWriter
|
||||
}
|
||||
|
||||
func (this *Writer) WriteMeta() error {
|
||||
func (this *WriterV1) WriteMeta() error {
|
||||
metaJSON, err := json.Marshal(this.meta)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -77,7 +54,7 @@ func (this *Writer) WriteMeta() error {
|
||||
return err
|
||||
}
|
||||
|
||||
func (this *Writer) Write(ipFrom string, ipTo string, countryId int64, provinceId int64, cityId int64, townId int64, providerId int64) error {
|
||||
func (this *WriterV1) Write(ipFrom string, ipTo string, countryId int64, provinceId int64, cityId int64, townId int64, providerId int64) error {
|
||||
// validate IP
|
||||
var fromIP = net.ParseIP(ipFrom)
|
||||
if fromIP == nil {
|
||||
@@ -100,11 +77,14 @@ func (this *Writer) Write(ipFrom string, ipTo string, countryId int64, provinceI
|
||||
pieces = append(pieces, "")
|
||||
} else {
|
||||
pieces = append(pieces, "6")
|
||||
|
||||
// we do NOT support v6 yet
|
||||
return nil
|
||||
}
|
||||
|
||||
// 1
|
||||
var fromIPLong = configutils.IP2Long(fromIP)
|
||||
var toIPLong = configutils.IP2Long(toIP)
|
||||
var fromIPLong = this.ip2long(fromIP)
|
||||
var toIPLong = this.ip2long(toIP)
|
||||
|
||||
if toIPLong < fromIPLong {
|
||||
fromIPLong, toIPLong = toIPLong, fromIPLong
|
||||
@@ -193,10 +173,25 @@ func (this *Writer) Write(ipFrom string, ipTo string, countryId int64, provinceI
|
||||
return err
|
||||
}
|
||||
|
||||
func (this *Writer) Sum() string {
|
||||
func (this *WriterV1) Sum() string {
|
||||
return this.writer.Sum()
|
||||
}
|
||||
|
||||
func (this *Writer) formatUint64(i uint64) string {
|
||||
func (this *WriterV1) formatUint64(i uint64) string {
|
||||
return strconv.FormatUint(i, 32)
|
||||
}
|
||||
|
||||
func (this *WriterV1) ip2long(netIP net.IP) uint64 {
|
||||
if len(netIP) == 0 {
|
||||
return 0
|
||||
}
|
||||
|
||||
var b4 = netIP.To4()
|
||||
if b4 != nil {
|
||||
return uint64(binary.BigEndian.Uint32(b4.To4()))
|
||||
}
|
||||
|
||||
var i = big.NewInt(0)
|
||||
i.SetBytes(netIP.To16())
|
||||
return i.Uint64()
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ type FileWriter struct {
|
||||
gzWriter *gzip.Writer
|
||||
password string
|
||||
|
||||
rawWriter *Writer
|
||||
rawWriter WriterInterface
|
||||
}
|
||||
|
||||
func NewFileWriter(path string, meta *Meta, password string) (*FileWriter, error) {
|
||||
@@ -29,7 +29,7 @@ func NewFileWriter(path string, meta *Meta, password string) (*FileWriter, error
|
||||
var writer = &FileWriter{
|
||||
fp: fp,
|
||||
gzWriter: gzWriter,
|
||||
rawWriter: NewWriter(gzWriter, meta),
|
||||
rawWriter: NewWriterV1(gzWriter, meta),
|
||||
password: password,
|
||||
}
|
||||
return writer, nil
|
||||
@@ -64,11 +64,13 @@ func (this *FileWriter) Close() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(data) > 0 {
|
||||
encodedData, err := NewEncrypt().Encode(data, this.password)
|
||||
if err != nil {
|
||||
return err
|
||||
encodedData, encodeErr := NewEncrypt().Encode(data, this.password)
|
||||
if encodeErr != nil {
|
||||
return encodeErr
|
||||
}
|
||||
_ = os.Remove(filePath)
|
||||
err = os.WriteFile(filePath, encodedData, 0666)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -6,13 +6,14 @@ import (
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/iplibrary"
|
||||
"github.com/iwind/TeaGo/rands"
|
||||
"github.com/iwind/TeaGo/types"
|
||||
stringutil "github.com/iwind/TeaGo/utils/string"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestNewFileWriter(t *testing.T) {
|
||||
writer, err := iplibrary.NewFileWriter("./internal-ip-library-test.db", &iplibrary.Meta{
|
||||
Author: "GoEdge",
|
||||
}, "")
|
||||
}, stringutil.Md5("123456"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
9
pkg/iplibrary/writer_interface.go
Normal file
9
pkg/iplibrary/writer_interface.go
Normal file
@@ -0,0 +1,9 @@
|
||||
// Copyright 2024 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
|
||||
package iplibrary
|
||||
|
||||
type WriterInterface interface {
|
||||
WriteMeta() error
|
||||
Write(ipFrom string, ipTo string, countryId int64, provinceId int64, cityId int64, townId int64, providerId int64) error
|
||||
Sum() string
|
||||
}
|
||||
190
pkg/iplibrary/writer_v2.go
Normal file
190
pkg/iplibrary/writer_v2.go
Normal file
@@ -0,0 +1,190 @@
|
||||
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
|
||||
package iplibrary
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/md5"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"hash"
|
||||
"io"
|
||||
"net"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type hashWriter struct {
|
||||
rawWriter io.Writer
|
||||
hash hash.Hash
|
||||
}
|
||||
|
||||
func newHashWriter(writer io.Writer) *hashWriter {
|
||||
return &hashWriter{
|
||||
rawWriter: writer,
|
||||
hash: md5.New(),
|
||||
}
|
||||
}
|
||||
|
||||
func (this *hashWriter) Write(p []byte) (n int, err error) {
|
||||
n, err = this.rawWriter.Write(p)
|
||||
this.hash.Write(p)
|
||||
return
|
||||
}
|
||||
|
||||
func (this *hashWriter) Sum() string {
|
||||
return fmt.Sprintf("%x", this.hash.Sum(nil))
|
||||
}
|
||||
|
||||
type WriterV2 struct {
|
||||
writer *hashWriter
|
||||
meta *Meta
|
||||
|
||||
lastCountryId int64
|
||||
lastProvinceId int64
|
||||
lastCityId int64
|
||||
lastTownId int64
|
||||
lastProviderId int64
|
||||
}
|
||||
|
||||
func NewWriterV2(writer io.Writer, meta *Meta) *WriterV2 {
|
||||
if meta == nil {
|
||||
meta = &Meta{}
|
||||
}
|
||||
meta.Version = Version2
|
||||
meta.CreatedAt = time.Now().Unix()
|
||||
|
||||
var libWriter = &WriterV2{
|
||||
writer: newHashWriter(writer),
|
||||
meta: meta,
|
||||
}
|
||||
return libWriter
|
||||
}
|
||||
|
||||
func (this *WriterV2) WriteMeta() error {
|
||||
metaJSON, err := json.Marshal(this.meta)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = this.writer.Write(metaJSON)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = this.writer.Write([]byte("\n"))
|
||||
return err
|
||||
}
|
||||
|
||||
func (this *WriterV2) Write(ipFrom string, ipTo string, countryId int64, provinceId int64, cityId int64, townId int64, providerId int64) error {
|
||||
// validate IP
|
||||
var fromIP = net.ParseIP(ipFrom)
|
||||
if fromIP == nil {
|
||||
return errors.New("invalid 'ipFrom': '" + ipFrom + "'")
|
||||
}
|
||||
var fromIsIPv4 = fromIP.To4() != nil
|
||||
var toIP = net.ParseIP(ipTo)
|
||||
if toIP == nil {
|
||||
return errors.New("invalid 'ipTo': " + ipTo)
|
||||
}
|
||||
var toIsIPv4 = toIP.To4() != nil
|
||||
if fromIsIPv4 != toIsIPv4 {
|
||||
return errors.New("'ipFrom(" + ipFrom + ")' and 'ipTo(" + ipTo + ")' should have the same IP version")
|
||||
}
|
||||
|
||||
var pieces = []string{}
|
||||
|
||||
// 0
|
||||
if fromIsIPv4 {
|
||||
pieces = append(pieces, "")
|
||||
} else {
|
||||
pieces = append(pieces, "6")
|
||||
}
|
||||
|
||||
// 1
|
||||
if bytes.Compare(fromIP, toIP) > 0 {
|
||||
fromIP, toIP = toIP, fromIP
|
||||
}
|
||||
|
||||
if fromIsIPv4 {
|
||||
pieces = append(pieces, string(fromIP.To4())+string(toIP.To4()))
|
||||
} else {
|
||||
pieces = append(pieces, string(fromIP.To16())+string(toIP.To16()))
|
||||
}
|
||||
|
||||
// 2
|
||||
if countryId > 0 {
|
||||
if countryId == this.lastCountryId {
|
||||
pieces = append(pieces, "+")
|
||||
} else {
|
||||
pieces = append(pieces, this.formatUint64(uint64(countryId)))
|
||||
}
|
||||
} else {
|
||||
pieces = append(pieces, "")
|
||||
}
|
||||
this.lastCountryId = countryId
|
||||
|
||||
// 3
|
||||
if provinceId > 0 {
|
||||
if provinceId == this.lastProvinceId {
|
||||
pieces = append(pieces, "+")
|
||||
} else {
|
||||
pieces = append(pieces, this.formatUint64(uint64(provinceId)))
|
||||
}
|
||||
} else {
|
||||
pieces = append(pieces, "")
|
||||
}
|
||||
this.lastProvinceId = provinceId
|
||||
|
||||
// 4
|
||||
if cityId > 0 {
|
||||
if cityId == this.lastCityId {
|
||||
pieces = append(pieces, "+")
|
||||
} else {
|
||||
pieces = append(pieces, this.formatUint64(uint64(cityId)))
|
||||
}
|
||||
} else {
|
||||
pieces = append(pieces, "")
|
||||
}
|
||||
this.lastCityId = cityId
|
||||
|
||||
// 5
|
||||
if townId > 0 {
|
||||
if townId == this.lastTownId {
|
||||
pieces = append(pieces, "+")
|
||||
} else {
|
||||
pieces = append(pieces, this.formatUint64(uint64(townId)))
|
||||
}
|
||||
} else {
|
||||
pieces = append(pieces, "")
|
||||
}
|
||||
this.lastTownId = townId
|
||||
|
||||
// 6
|
||||
if providerId > 0 {
|
||||
if providerId == this.lastProviderId {
|
||||
pieces = append(pieces, "+")
|
||||
} else {
|
||||
pieces = append(pieces, this.formatUint64(uint64(providerId)))
|
||||
}
|
||||
} else {
|
||||
pieces = append(pieces, "")
|
||||
}
|
||||
this.lastProviderId = providerId
|
||||
|
||||
_, err := this.writer.Write([]byte(strings.TrimRight(strings.Join(pieces, "|"), "|")))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = this.writer.Write([]byte("\n"))
|
||||
return err
|
||||
}
|
||||
|
||||
func (this *WriterV2) Sum() string {
|
||||
return this.writer.Sum()
|
||||
}
|
||||
|
||||
func (this *WriterV2) formatUint64(i uint64) string {
|
||||
return strconv.FormatUint(i, 32)
|
||||
}
|
||||
@@ -5,12 +5,14 @@ package iplibrary_test
|
||||
import (
|
||||
"bytes"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/iplibrary"
|
||||
"github.com/iwind/TeaGo/logs"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestNewWriter(t *testing.T) {
|
||||
//write
|
||||
var buf = &bytes.Buffer{}
|
||||
var writer = iplibrary.NewWriter(buf, &iplibrary.Meta{
|
||||
var writer = iplibrary.NewWriterV1(buf, &iplibrary.Meta{
|
||||
Author: "GoEdge <https://goedge.cn>",
|
||||
})
|
||||
|
||||
@@ -39,6 +41,27 @@ func TestNewWriter(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = writer.Write("10.0.0.1", "10.0.0.2", 101, 201, 301, 401, 501)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = writer.Write("10.0.0.3", "10.0.0.4", 101, 201, 301, 401, 501)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
t.Log(buf.String())
|
||||
t.Log("sum:", writer.Sum())
|
||||
|
||||
// read
|
||||
reader, err := iplibrary.NewReaderV2(buf)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
logs.PrintAsJSON(reader.IPv4Items(), t)
|
||||
logs.PrintAsJSON(reader.IPv6Items(), t)
|
||||
|
||||
_ = reader
|
||||
}
|
||||
78
pkg/iputils/cidr.go
Normal file
78
pkg/iputils/cidr.go
Normal file
@@ -0,0 +1,78 @@
|
||||
// Copyright 2024 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
|
||||
package iputils
|
||||
|
||||
import (
|
||||
"net"
|
||||
)
|
||||
|
||||
type CIDR struct {
|
||||
rawIPNet *net.IPNet
|
||||
}
|
||||
|
||||
func ParseCIDR(s string) (*CIDR, error) {
|
||||
_, ipNet, err := net.ParseCIDR(s)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &CIDR{
|
||||
rawIPNet: ipNet,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (this *CIDR) IsIPv4() bool {
|
||||
return this.rawIPNet.IP.To4() != nil
|
||||
}
|
||||
|
||||
func (this *CIDR) IsIPv6() bool {
|
||||
return this.rawIPNet.IP.To4() == nil
|
||||
}
|
||||
|
||||
func (this *CIDR) From() net.IP {
|
||||
return this.rawIPNet.IP
|
||||
}
|
||||
|
||||
func (this *CIDR) To() net.IP {
|
||||
var start = this.rawIPNet.IP.To4()
|
||||
if start != nil {
|
||||
return bitsOr(bitsAnd(start, this.rawIPNet.Mask), bitsXor(this.rawIPNet.Mask[:4], []byte{0xff, 0xff, 0xff, 0xff}))
|
||||
}
|
||||
|
||||
start = this.rawIPNet.IP.To16()
|
||||
return bitsOr(bitsAnd(start, this.rawIPNet.Mask), bitsXor(this.rawIPNet.Mask[:16], []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}))
|
||||
}
|
||||
|
||||
func (this *CIDR) Contains(ip net.IP) bool {
|
||||
return this.rawIPNet.Contains(ip)
|
||||
}
|
||||
|
||||
func (this *CIDR) String() string {
|
||||
return this.rawIPNet.String()
|
||||
}
|
||||
|
||||
func bitsAnd(x []byte, y []byte) []byte {
|
||||
var l = len(x)
|
||||
var z = make([]byte, l)
|
||||
for i := 0; i < l; i++ {
|
||||
z[i] = x[i] & y[i]
|
||||
}
|
||||
return z
|
||||
}
|
||||
|
||||
func bitsOr(x []byte, y []byte) []byte {
|
||||
var l = len(x)
|
||||
var z = make([]byte, l)
|
||||
for i := 0; i < l; i++ {
|
||||
z[i] = x[i] | y[i]
|
||||
}
|
||||
return z
|
||||
}
|
||||
|
||||
func bitsXor(x []byte, y []byte) []byte {
|
||||
var l = len(x)
|
||||
var z = make([]byte, l)
|
||||
for i := 0; i < l; i++ {
|
||||
z[i] = x[i] ^ y[i]
|
||||
}
|
||||
return z
|
||||
}
|
||||
21
pkg/iputils/cidr_test.go
Normal file
21
pkg/iputils/cidr_test.go
Normal file
@@ -0,0 +1,21 @@
|
||||
// Copyright 2024 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
|
||||
package iputils_test
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/iputils"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestParseCIDR(t *testing.T) {
|
||||
for _, cidrString := range []string{
|
||||
"192.168.2.100/24",
|
||||
"2607:5300:203:afac::/125",
|
||||
} {
|
||||
cidr, err := iputils.ParseCIDR(cidrString)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Log(cidr, "=> [", cidr.From(), "-", cidr.To(), "]")
|
||||
}
|
||||
}
|
||||
260
pkg/iputils/ip.go
Normal file
260
pkg/iputils/ip.go
Normal file
@@ -0,0 +1,260 @@
|
||||
// Copyright 2024 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
|
||||
package iputils
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"math"
|
||||
"math/big"
|
||||
"net"
|
||||
"strconv"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type IP struct {
|
||||
rawIP net.IP
|
||||
bigInt *big.Int
|
||||
}
|
||||
|
||||
var uint32BigInt = big.NewInt(int64(math.MaxUint32))
|
||||
|
||||
func ParseIP(ipString string) IP {
|
||||
return NewIP(net.ParseIP(ipString))
|
||||
}
|
||||
|
||||
func NewIP(rawIP net.IP) IP {
|
||||
if rawIP == nil {
|
||||
return IP{}
|
||||
}
|
||||
|
||||
if rawIP.To4() == nil {
|
||||
var bigInt = big.NewInt(0)
|
||||
bigInt.SetBytes(rawIP.To16())
|
||||
bigInt.Add(bigInt, uint32BigInt)
|
||||
return IP{
|
||||
rawIP: rawIP,
|
||||
bigInt: bigInt,
|
||||
}
|
||||
}
|
||||
|
||||
return IP{
|
||||
rawIP: rawIP,
|
||||
}
|
||||
}
|
||||
|
||||
func IsIPv4(ipString string) bool {
|
||||
var rawIP = net.ParseIP(ipString)
|
||||
return rawIP != nil && rawIP.To4() != nil
|
||||
}
|
||||
|
||||
func IsIPv6(ipString string) bool {
|
||||
var rawIP = net.ParseIP(ipString)
|
||||
return rawIP != nil && rawIP.To4() == nil && rawIP.To16() != nil
|
||||
}
|
||||
|
||||
func IsSameVersion(ip1 string, ip2 string) bool {
|
||||
return IsIPv4(ip1) == IsIPv4(ip2)
|
||||
}
|
||||
|
||||
func IsValid(ipString string) bool {
|
||||
return net.ParseIP(ipString) != nil
|
||||
}
|
||||
|
||||
func CompareLong(i1 string, i2 string) int {
|
||||
if i1 == "" {
|
||||
i1 = "0"
|
||||
}
|
||||
if i2 == "" {
|
||||
i2 = "0"
|
||||
}
|
||||
|
||||
var l = len(i1) - len(i2)
|
||||
if l > 0 {
|
||||
return 1
|
||||
}
|
||||
if l < 0 {
|
||||
return -1
|
||||
}
|
||||
|
||||
if i1 > i2 {
|
||||
return 1
|
||||
}
|
||||
if i1 < i2 {
|
||||
return -1
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
var bigIntPool = &sync.Pool{
|
||||
New: func() any {
|
||||
return big.NewInt(0)
|
||||
},
|
||||
}
|
||||
|
||||
func ToLong(ip string) string {
|
||||
var rawIP = net.ParseIP(ip)
|
||||
if rawIP == nil {
|
||||
return "0"
|
||||
}
|
||||
|
||||
var i4 = rawIP.To4()
|
||||
if i4 != nil {
|
||||
return strconv.FormatUint(uint64(binary.BigEndian.Uint32(i4)), 10)
|
||||
}
|
||||
|
||||
var bigInt = bigIntPool.Get().(*big.Int)
|
||||
bigInt.SetBytes(rawIP.To16())
|
||||
bigInt.Add(bigInt, uint32BigInt)
|
||||
var s = bigInt.String()
|
||||
bigIntPool.Put(bigInt)
|
||||
return s
|
||||
}
|
||||
|
||||
func ToHex(ip string) string {
|
||||
if len(ip) == 0 {
|
||||
return ""
|
||||
}
|
||||
var rawIP = net.ParseIP(ip)
|
||||
if rawIP == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
if rawIP.To4() != nil {
|
||||
return hex.EncodeToString(rawIP.To4())
|
||||
}
|
||||
|
||||
return hex.EncodeToString(rawIP.To16())
|
||||
}
|
||||
|
||||
func ToBytes(ip string) []byte {
|
||||
if len(ip) == 0 {
|
||||
return nil
|
||||
}
|
||||
var rawIP = net.ParseIP(ip)
|
||||
if rawIP == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if rawIP.To4() != nil {
|
||||
return rawIP.To4()
|
||||
}
|
||||
|
||||
return rawIP.To16()
|
||||
}
|
||||
|
||||
func CompareBytes(b1 []byte, b2 []byte) int {
|
||||
var l1 = len(b1)
|
||||
var l2 = len(b2)
|
||||
if l1 < l2 {
|
||||
return -1
|
||||
}
|
||||
if l1 > l2 {
|
||||
return 1
|
||||
}
|
||||
return bytes.Compare(b1, b2)
|
||||
}
|
||||
|
||||
func CompareIP(ip1 string, ip2 string) int {
|
||||
return CompareBytes(ToBytes(ip1), ToBytes(ip2))
|
||||
}
|
||||
|
||||
func ToLittleLong(ip string) string {
|
||||
var rawIP = net.ParseIP(ip)
|
||||
if rawIP == nil {
|
||||
return "0"
|
||||
}
|
||||
|
||||
var i4 = rawIP.To4()
|
||||
if i4 != nil {
|
||||
return strconv.FormatUint(uint64(binary.BigEndian.Uint32(i4)), 10)
|
||||
}
|
||||
|
||||
var bigInt = bigIntPool.Get().(*big.Int)
|
||||
bigInt.SetBytes(rawIP.To16())
|
||||
var s = bigInt.String()
|
||||
bigIntPool.Put(bigInt)
|
||||
return s
|
||||
}
|
||||
|
||||
func (this IP) ToLong() string {
|
||||
if this.rawIP == nil {
|
||||
return "0"
|
||||
}
|
||||
if this.bigInt != nil {
|
||||
return this.bigInt.String()
|
||||
}
|
||||
return strconv.FormatUint(uint64(binary.BigEndian.Uint32(this.rawIP.To4())), 10)
|
||||
}
|
||||
|
||||
func (this IP) Mod(d int) int {
|
||||
if this.rawIP == nil {
|
||||
return 0
|
||||
}
|
||||
if this.bigInt != nil {
|
||||
return int(this.bigInt.Mod(this.bigInt, big.NewInt(int64(d))).Int64())
|
||||
}
|
||||
return int(binary.BigEndian.Uint32(this.rawIP.To4()) % uint32(d))
|
||||
}
|
||||
|
||||
func (this IP) Compare(anotherIP IP) int {
|
||||
if this.rawIP == nil {
|
||||
if anotherIP.rawIP == nil {
|
||||
return 0
|
||||
}
|
||||
return -1
|
||||
} else if anotherIP.rawIP == nil {
|
||||
return 1
|
||||
}
|
||||
|
||||
if this.bigInt != nil {
|
||||
if anotherIP.bigInt == nil {
|
||||
return 1 // IPv6 always greater than IPv4
|
||||
}
|
||||
return this.bigInt.Cmp(anotherIP.bigInt)
|
||||
}
|
||||
|
||||
if anotherIP.bigInt == nil {
|
||||
var i1 = binary.BigEndian.Uint32(this.rawIP.To4())
|
||||
var i2 = binary.BigEndian.Uint32(anotherIP.rawIP.To4())
|
||||
|
||||
if i1 > i2 {
|
||||
return 1
|
||||
}
|
||||
if i1 < i2 {
|
||||
return -1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
return -1
|
||||
}
|
||||
|
||||
func (this IP) Between(ipFrom IP, ipTo IP) bool {
|
||||
return ipFrom.Compare(this) <= 0 && ipTo.Compare(this) >= 0
|
||||
}
|
||||
|
||||
func (this IP) IsIPv4() bool {
|
||||
return this.rawIP != nil && this.bigInt == nil
|
||||
}
|
||||
|
||||
func (this IP) IsIPv6() bool {
|
||||
return this.bigInt != nil
|
||||
}
|
||||
|
||||
func (this IP) IsValid() bool {
|
||||
return this.rawIP != nil
|
||||
}
|
||||
|
||||
func (this IP) Raw() net.IP {
|
||||
return this.rawIP
|
||||
}
|
||||
|
||||
func (this IP) String() string {
|
||||
if this.rawIP == nil {
|
||||
return ""
|
||||
}
|
||||
return this.rawIP.String()
|
||||
}
|
||||
258
pkg/iputils/ip_test.go
Normal file
258
pkg/iputils/ip_test.go
Normal file
@@ -0,0 +1,258 @@
|
||||
// Copyright 2024 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
|
||||
package iputils_test
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/iputils"
|
||||
"github.com/iwind/TeaGo/assert"
|
||||
"runtime"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestIP_ParseIP(t *testing.T) {
|
||||
var a = assert.NewAssertion(t)
|
||||
|
||||
{
|
||||
var i = iputils.ParseIP("127.0.0.1")
|
||||
a.IsTrue(i.IsIPv4())
|
||||
a.IsFalse(i.IsIPv6())
|
||||
a.IsTrue(i.IsValid())
|
||||
a.IsTrue(iputils.IsIPv4("127.0.0.1"))
|
||||
a.IsFalse(iputils.IsIPv6("127.0.0.1"))
|
||||
t.Log(i.String(), i.ToLong())
|
||||
t.Log("raw:", i.Raw())
|
||||
a.IsTrue(iputils.IsValid("127.0.0.1"))
|
||||
}
|
||||
|
||||
{
|
||||
var i = iputils.ParseIP("0.0.0.1")
|
||||
a.IsTrue(i.IsIPv4())
|
||||
a.IsFalse(i.IsIPv6())
|
||||
t.Log(i.String(), i.ToLong())
|
||||
}
|
||||
|
||||
for j := 0; j < 3; j++ /** repeat test **/ {
|
||||
var i = iputils.ParseIP("::1")
|
||||
a.IsFalse(i.IsIPv4())
|
||||
a.IsTrue(i.IsIPv6())
|
||||
a.IsTrue(i.IsValid())
|
||||
t.Log(i.String(), i.ToLong())
|
||||
}
|
||||
|
||||
{
|
||||
{
|
||||
var i = iputils.ParseIP("2001:db8:0:1::1:101")
|
||||
t.Log(i.String(), i.ToLong())
|
||||
a.IsFalse(i.IsIPv4())
|
||||
a.IsTrue(i.IsIPv6())
|
||||
a.IsFalse(iputils.IsIPv4("2001:db8:0:1::1:101"))
|
||||
a.IsTrue(iputils.IsIPv6("2001:db8:0:1::1:101"))
|
||||
a.IsTrue(i.IsValid())
|
||||
}
|
||||
|
||||
{
|
||||
var i = iputils.ParseIP("2001:db8:0:1::1:102")
|
||||
t.Log(i.String(), i.ToLong())
|
||||
a.IsFalse(i.IsIPv4())
|
||||
a.IsTrue(i.IsIPv6())
|
||||
a.IsTrue(i.IsValid())
|
||||
}
|
||||
|
||||
{
|
||||
var i = iputils.ParseIP("2001:db8:0:1::2:101")
|
||||
t.Log(i.String(), i.ToLong())
|
||||
a.IsFalse(i.IsIPv4())
|
||||
a.IsTrue(i.IsIPv6())
|
||||
a.IsTrue(i.IsValid())
|
||||
a.IsTrue(iputils.IsValid("2001:db8:0:1::2:101"))
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
var i = iputils.ParseIP("WRONG IP")
|
||||
t.Log(i.String(), i.ToLong())
|
||||
a.IsFalse(i.IsIPv4())
|
||||
a.IsFalse(i.IsIPv6())
|
||||
a.IsFalse(i.IsValid())
|
||||
a.IsFalse(iputils.IsValid("WRONG IP"))
|
||||
a.IsFalse(iputils.IsIPv4("WRONG IP"))
|
||||
a.IsFalse(iputils.IsIPv6("WRONG IP"))
|
||||
}
|
||||
}
|
||||
|
||||
func TestIP_Mod(t *testing.T) {
|
||||
for _, ip := range []string{
|
||||
"127.0.0.1",
|
||||
"::1",
|
||||
"2001:db8:0:1::1:101",
|
||||
"2001:db8:0:1::1:102",
|
||||
"WRONG IP",
|
||||
} {
|
||||
var i = iputils.ParseIP(ip)
|
||||
t.Log(ip, "=>", i.ToLong(), "=>", i.Mod(5))
|
||||
}
|
||||
}
|
||||
|
||||
func TestIP_Compare(t *testing.T) {
|
||||
var a = assert.NewAssertion(t)
|
||||
|
||||
{
|
||||
var i1 = iputils.ParseIP("127.0.0.1")
|
||||
var i2 = iputils.ParseIP("127.0.0.1")
|
||||
a.IsTrue(i1.Compare(i2) == 0)
|
||||
}
|
||||
|
||||
{
|
||||
var i1 = iputils.ParseIP("127.0.0.1")
|
||||
var i2 = iputils.ParseIP("127.0.0.2")
|
||||
a.IsTrue(i1.Compare(i2) == -1)
|
||||
}
|
||||
|
||||
{
|
||||
var i1 = iputils.ParseIP("127.0.0.2")
|
||||
var i2 = iputils.ParseIP("127.0.0.1")
|
||||
a.IsTrue(i1.Compare(i2) == 1)
|
||||
}
|
||||
|
||||
{
|
||||
var i1 = iputils.ParseIP("2001:db8:0:1::101")
|
||||
var i2 = iputils.ParseIP("127.0.0.1")
|
||||
a.IsTrue(i1.Compare(i2) == 1)
|
||||
}
|
||||
|
||||
{
|
||||
var i1 = iputils.ParseIP("127.0.0.1")
|
||||
var i2 = iputils.ParseIP("2001:db8:0:1::101")
|
||||
a.IsTrue(i1.Compare(i2) == -1)
|
||||
}
|
||||
|
||||
{
|
||||
var i1 = iputils.ParseIP("2001:db8:0:1::101")
|
||||
var i2 = iputils.ParseIP("2001:db8:0:1::101")
|
||||
a.IsTrue(i1.Compare(i2) == 0)
|
||||
}
|
||||
|
||||
{
|
||||
var i1 = iputils.ParseIP("2001:db8:0:1::101")
|
||||
var i2 = iputils.ParseIP("2001:db8:0:1::102")
|
||||
a.IsTrue(i1.Compare(i2) == -1)
|
||||
}
|
||||
|
||||
{
|
||||
var i1 = iputils.ParseIP("2001:db8:0:1::102")
|
||||
var i2 = iputils.ParseIP("2001:db8:0:1::101")
|
||||
a.IsTrue(i1.Compare(i2) == 1)
|
||||
}
|
||||
|
||||
{
|
||||
var i1 = iputils.ParseIP("2001:db8:0:1::2:100")
|
||||
var i2 = iputils.ParseIP("2001:db8:0:1::1:101")
|
||||
a.IsTrue(i1.Compare(i2) == 1)
|
||||
}
|
||||
}
|
||||
|
||||
func TestIP_Between(t *testing.T) {
|
||||
var a = assert.NewAssertion(t)
|
||||
a.IsTrue(iputils.ParseIP("127.0.0.2").Between(iputils.ParseIP("127.0.0.1"), iputils.ParseIP("127.0.0.3")))
|
||||
a.IsTrue(iputils.ParseIP("127.0.0.1").Between(iputils.ParseIP("127.0.0.1"), iputils.ParseIP("127.0.0.3")))
|
||||
a.IsFalse(iputils.ParseIP("127.0.0.2").Between(iputils.ParseIP("127.0.0.3"), iputils.ParseIP("127.0.0.4")))
|
||||
a.IsFalse(iputils.ParseIP("127.0.0.5").Between(iputils.ParseIP("127.0.0.3"), iputils.ParseIP("127.0.0.4")))
|
||||
a.IsFalse(iputils.ParseIP("127.0.0.2").Between(iputils.ParseIP("127.0.0.3"), iputils.ParseIP("127.0.0.1")))
|
||||
}
|
||||
|
||||
func TestIP_ToLong(t *testing.T) {
|
||||
for _, ip := range []string{
|
||||
"127.0.0.1",
|
||||
"192.168.1.100",
|
||||
"::1",
|
||||
"fd00:6868:6868:0:10ac:d056:3bf6:7452",
|
||||
"fd00:6868:6868:0:10ac:d056:3bf6:7453",
|
||||
"2001:0db8:85a3:0000:0000:8a2e:0370:7334",
|
||||
"2001:db8:0:1::101",
|
||||
"2001:db8:0:2::101",
|
||||
"wrong ip",
|
||||
} {
|
||||
var goIP = iputils.ParseIP(ip)
|
||||
t.Log(ip, "=>", "\n", goIP.String(), "\n", "=>", "\n", "long1:", goIP.ToLong(), "\n", "long2:", iputils.ToLong(ip), "\n", "little long:", iputils.ToLittleLong(ip))
|
||||
}
|
||||
}
|
||||
|
||||
func TestIP_CompareLong(t *testing.T) {
|
||||
var a = assert.NewAssertion(t)
|
||||
a.IsTrue(iputils.CompareLong("1", "2") == -1)
|
||||
a.IsTrue(iputils.CompareLong("11", "2") == 1)
|
||||
a.IsTrue(iputils.CompareLong("11", "22") == -1)
|
||||
a.IsTrue(iputils.CompareLong("22", "101") == -1)
|
||||
a.IsTrue(iputils.CompareLong("33", "22") == 1)
|
||||
a.IsTrue(iputils.CompareLong("101", "22") == 1)
|
||||
a.IsTrue(iputils.CompareLong("22", "22") == 0)
|
||||
}
|
||||
|
||||
func TestIP_Memory(t *testing.T) {
|
||||
var list []iputils.IP
|
||||
|
||||
var stat1 = &runtime.MemStats{}
|
||||
runtime.ReadMemStats(stat1)
|
||||
|
||||
for i := 0; i < 1_000_000; i++ {
|
||||
list = append(list, iputils.ParseIP("fd00:6868:6868:0:10ac:d056:3bf6:7452"))
|
||||
}
|
||||
|
||||
//runtime.GC()
|
||||
|
||||
var stat2 = &runtime.MemStats{}
|
||||
runtime.ReadMemStats(stat2)
|
||||
|
||||
t.Log((stat2.Alloc-stat1.Alloc)>>10, "KB", (stat2.HeapInuse-stat1.HeapInuse)>>10, "KB")
|
||||
|
||||
// hold the memory
|
||||
for _, v := range list {
|
||||
_ = v
|
||||
}
|
||||
}
|
||||
|
||||
func TestToBytes(t *testing.T) {
|
||||
var a = assert.NewAssertion(t)
|
||||
a.IsTrue(len(iputils.ToBytes("a")) == 0)
|
||||
a.IsTrue(len(iputils.ToBytes("192.168.1.100")) == 4)
|
||||
a.IsTrue(len(iputils.ToBytes("::1")) == 16)
|
||||
}
|
||||
|
||||
func TestCompareIP(t *testing.T) {
|
||||
var a = assert.NewAssertion(t)
|
||||
a.IsTrue(iputils.CompareIP("a", "b") == 0)
|
||||
a.IsTrue(iputils.CompareIP("192.168.1.100", "192.168.1.1") > 0)
|
||||
a.IsTrue(iputils.CompareIP("192.168.1.100", "10.168.1.1") > 0)
|
||||
a.IsTrue(iputils.CompareIP("192.168.1.100", "192.168.2.1") < 0)
|
||||
a.IsTrue(iputils.CompareIP("192.168.1.100", "::1") < 0)
|
||||
a.IsTrue(iputils.CompareIP("::1", "192.168.1.100") > 0)
|
||||
a.IsTrue(iputils.CompareIP("192.168.1.100", "192.168.1.100") == 0)
|
||||
}
|
||||
|
||||
func TestIsSameVersion(t *testing.T) {
|
||||
var a = assert.NewAssertion(t)
|
||||
a.IsTrue(iputils.IsSameVersion("192.168.1.1", "10.0.0.1"))
|
||||
a.IsTrue(iputils.IsSameVersion("::1", "::5"))
|
||||
a.IsFalse(iputils.IsSameVersion("192.168.1.1", "::5"))
|
||||
}
|
||||
|
||||
func BenchmarkParse(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
iputils.ParseIP("fd00:6868:6868:0:10ac:d056:3bf6:7452")
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkToLongV4(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
iputils.ToLong("192.168.2.100")
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkToLongV6(b *testing.B) {
|
||||
runtime.GOMAXPROCS(1)
|
||||
b.ReportAllocs()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
iputils.ToLong("fd00:6868:6868:0:10ac:d056:3bf6:7452")
|
||||
}
|
||||
}
|
||||
@@ -43,8 +43,10 @@ const (
|
||||
AdminCommon_MenuSettingDNS langs.MessageCode = "admin_common@menu_setting_dns" // DNS设置
|
||||
AdminCommon_MenuSettingHealthCheck langs.MessageCode = "admin_common@menu_setting_health_check" // 健康检查
|
||||
AdminCommon_MenuSettingMetrics langs.MessageCode = "admin_common@menu_setting_metrics" // 统计指标
|
||||
AdminCommon_MenuSettingSecurityPolicy langs.MessageCode = "admin_common@menu_setting_security_policy" // 网络安全
|
||||
AdminCommon_MenuSettingWAFPolicy langs.MessageCode = "admin_common@menu_setting_waf_policy" // WAF策略
|
||||
AdminCommon_MenuSettingWebP langs.MessageCode = "admin_common@menu_setting_webp" // WebP
|
||||
AdminCommon_MenuSettingWebPPolicy langs.MessageCode = "admin_common@menu_setting_webp_policy" // WebP策略
|
||||
AdminCommon_ServerError langs.MessageCode = "admin_common@server_error" // 服务器出了点小问题,请联系技术人员处理。
|
||||
AdminCommon_System langs.MessageCode = "admin_common@system" // 系统
|
||||
AdminDashboard_DiskUsageWarning langs.MessageCode = "admin_dashboard@disk_usage_warning" // 当前服务器磁盘空间不足,请立即扩充容量,文件路径:%s,已使用:%dG,已使用比例:%.2f%%,仅剩余空间:%.2f%%。<br/>如果是因为本机数据库数据过多,你可以:<a href="/settings/database/clean">[清理访问日志]</a> <a href="https://goedge.cn/docs/APINode/QA.md" target="_blank">[调整数据库binlog设置]</a>
|
||||
@@ -94,6 +96,7 @@ const (
|
||||
AdminMenu_NSRoutes langs.MessageCode = "admin_menu@ns_routes" // 线路管理
|
||||
AdminMenu_NSSettings langs.MessageCode = "admin_menu@ns_settings" // 全局配置
|
||||
AdminMenu_NSUserPlans langs.MessageCode = "admin_menu@ns_user_plans" // 用户套餐
|
||||
AdminMenu_PlanList langs.MessageCode = "admin_menu@plan_list" // 套餐列表
|
||||
AdminMenu_PlanUserPlans langs.MessageCode = "admin_menu@plan_user_plans" // 已购套餐
|
||||
AdminMenu_Plans langs.MessageCode = "admin_menu@plans" // 套餐管理
|
||||
AdminMenu_ServerAccessLogPolicies langs.MessageCode = "admin_menu@server_access_log_policies" // 日志策略
|
||||
@@ -115,6 +118,8 @@ const (
|
||||
AdminMenu_Settings langs.MessageCode = "admin_menu@settings" // 系统设置
|
||||
AdminMenu_TicketCategory langs.MessageCode = "admin_menu@ticket_category" // 分类
|
||||
AdminMenu_Tickets langs.MessageCode = "admin_menu@tickets" // 工单系统
|
||||
AdminMenu_UserList langs.MessageCode = "admin_menu@user_list" // 用户列表
|
||||
AdminMenu_UserScripts langs.MessageCode = "admin_menu@user_scripts" // 用户脚本
|
||||
AdminMenu_UserSettings langs.MessageCode = "admin_menu@user_settings" // 用户设置
|
||||
AdminMenu_Users langs.MessageCode = "admin_menu@users" // 平台用户
|
||||
AdminProfile_LogUpdateProfile langs.MessageCode = "admin_profile@log_update_profile" // 修改个人资料
|
||||
@@ -145,6 +150,7 @@ const (
|
||||
AdminUpdate_LogIgnoreVersion langs.MessageCode = "admin_update@log_ignore_version" // 忽略升级版本 %s
|
||||
AdminUpdate_LogResetIgnoreVersion langs.MessageCode = "admin_update@log_reset_ignore_version" // 重置忽略升级版本
|
||||
AdminUpdate_LogUpdateCheckSettings langs.MessageCode = "admin_update@log_update_check_settings" // 修改检查更新设置
|
||||
AdminUserUI_LogUpdateUISettings langs.MessageCode = "admin_user_ui@log_update_ui_settings" // 修改用户界面设置
|
||||
APINode_LogCreateAPINode langs.MessageCode = "api_node@log_create_api_node" // 创建API节点 %d
|
||||
APINode_LogDeleteAPINode langs.MessageCode = "api_node@log_delete_api_node" // 删除API节点 %d
|
||||
APINode_LogUpdateAPINode langs.MessageCode = "api_node@log_update_api_node" // 修改API节点 %d
|
||||
@@ -234,12 +240,14 @@ const (
|
||||
MessageMediaInstance_LogCreateMessageMediaInstance langs.MessageCode = "message_media_instance@log_create_message_media_instance" // 创建消息媒介 %d
|
||||
MessageMediaInstance_LogDeleteMessageMediaInstance langs.MessageCode = "message_media_instance@log_delete_message_media_instance" // 删除消息媒介 %d
|
||||
MessageMediaInstance_LogUpdateMessageMediaInstance langs.MessageCode = "message_media_instance@log_update_message_media_instance" // 修改消息媒介 %d
|
||||
MessageReciever_LogUpdateClusterMessageReceivers langs.MessageCode = "message_reciever@log_update_cluster_message_receivers" // 修改集群 %d 消息接收人
|
||||
MessageReceiver_LogDeleteReceiver langs.MessageCode = "message_receiver@log_delete_receiver" // 删除接收人关联关系 %d
|
||||
MessageReceiver_LogUpdateClusterMessageReceivers langs.MessageCode = "message_receiver@log_update_cluster_message_receivers" // 修改集群 %d 消息接收人
|
||||
MessageRecipient_LogCreateMessageRecipient langs.MessageCode = "message_recipient@log_create_message_recipient" // 创建媒介接收人 %d
|
||||
MessageRecipient_LogDeleteMessageRecipient langs.MessageCode = "message_recipient@log_delete_message_recipient" // 删除媒介接收人 %d
|
||||
MessageRecipient_LogUpdateMessageRecipient langs.MessageCode = "message_recipient@log_update_message_recipient" // 修改媒介接收人 %d
|
||||
MessageTask_LogCreateTestingMessageTask langs.MessageCode = "message_task@log_create_testing_message_task" // 创建媒介测试任务 %d
|
||||
MessageTask_LogDeleteMessageTask langs.MessageCode = "message_task@log_delete_message_task" // 删除消息发送任务 %d
|
||||
MessageTask_LogUpdateMessageTaskStatus langs.MessageCode = "message_task@log_update_message_task_status" // 修改消息任务 %d 状态为 %d
|
||||
MetricChart_LogCreateMetricChart langs.MessageCode = "metric_chart@log_create_metric_chart" // 创建指标图表 %d
|
||||
MetricChart_LogDeleteMetricChart langs.MessageCode = "metric_chart@log_delete_metric_chart" // 删除指标图表 %d
|
||||
MetricChart_LogUpdateMetricChart langs.MessageCode = "metric_chart@log_update_metric_chart" // 修改指标图表 %d
|
||||
@@ -261,6 +269,8 @@ const (
|
||||
Node_LogUpNode langs.MessageCode = "node@log_up_node" // 手动上线节点 %d
|
||||
Node_LogUpdateNode langs.MessageCode = "node@log_update_node" // 修改节点 %d 基本信息
|
||||
Node_LogUpdateNodeInstallationStatus langs.MessageCode = "node@log_update_node_installation_status" // 修改节点安装状态 %d
|
||||
Node_LogUpdateNodeOff langs.MessageCode = "node@log_update_node_off" // 停用节点 %d
|
||||
Node_LogUpdateNodeOn langs.MessageCode = "node@log_update_node_on" // 启用节点 %d
|
||||
Node_LogUpgradeNodeRemotely langs.MessageCode = "node@log_upgrade_node_remotely" // 远程升级节点 %d
|
||||
Node_UngroupedLabel langs.MessageCode = "node@ungrouped_label" // 未分组
|
||||
NodeAction_LogCopyNodeActionsToCluster langs.MessageCode = "node_action@log_copy_node_actions_to_cluster" // 复制节点 %d 调度动作到集群
|
||||
@@ -288,6 +298,7 @@ const (
|
||||
NodeClusterMenu_SettingNotification langs.MessageCode = "node_cluster_menu@setting_notification" // 消息通知
|
||||
NodeClusterMenu_SettingPages langs.MessageCode = "node_cluster_menu@setting_pages" // 自定义页面
|
||||
NodeClusterMenu_SettingSchedule langs.MessageCode = "node_cluster_menu@setting_schedule" // 智能调度
|
||||
NodeClusterMenu_SettingSecurityPolicy langs.MessageCode = "node_cluster_menu@setting_security_policy" // 网络安全
|
||||
NodeClusterMenu_SettingServiceGlobal langs.MessageCode = "node_cluster_menu@setting_service_global" // 网站设置
|
||||
NodeClusterMenu_SettingSystemService langs.MessageCode = "node_cluster_menu@setting_system_service" // 系统服务
|
||||
NodeClusterMenu_SettingThresholds langs.MessageCode = "node_cluster_menu@setting_thresholds" // 阈值设置
|
||||
@@ -295,7 +306,7 @@ const (
|
||||
NodeClusterMenu_SettingUAM langs.MessageCode = "node_cluster_menu@setting_uam" // 5秒盾
|
||||
NodeClusterMenu_SettingWAFActions langs.MessageCode = "node_cluster_menu@setting_waf_actions" // WAF动作
|
||||
NodeClusterMenu_SettingWAFPolicy langs.MessageCode = "node_cluster_menu@setting_waf_policy" // WAF策略
|
||||
NodeClusterMenu_SettingWebP langs.MessageCode = "node_cluster_menu@setting_webp" // WebP
|
||||
NodeClusterMenu_SettingWebP langs.MessageCode = "node_cluster_menu@setting_webp" // WebP策略
|
||||
NodeClusterMenu_TabClusterDashboard langs.MessageCode = "node_cluster_menu@tab_cluster_dashboard" // 集群看板
|
||||
NodeClusterMenu_TabClusterDelete langs.MessageCode = "node_cluster_menu@tab_cluster_delete" // 删除集群
|
||||
NodeClusterMenu_TabClusterNodes langs.MessageCode = "node_cluster_menu@tab_cluster_nodes" // 节点列表
|
||||
@@ -440,6 +451,11 @@ const (
|
||||
Plan_LogDeletePlan langs.MessageCode = "plan@log_delete_plan" // 删除套餐 %d
|
||||
Plan_LogSortPlans langs.MessageCode = "plan@log_sort_plans" // 对套餐进行排序
|
||||
Plan_LogUpdatePlan langs.MessageCode = "plan@log_update_plan" // 修改套餐 %d
|
||||
Post_LogCreatePost langs.MessageCode = "post@log_create_post" // 创建文章 %d
|
||||
Post_LogDeletePost langs.MessageCode = "post@log_delete_post" // 删除文章 %d
|
||||
Post_LogPublishPost langs.MessageCode = "post@log_publish_post" // 发布文章 %d
|
||||
Post_LogUpdatePost langs.MessageCode = "post@log_update_post" // 修改文章 %d
|
||||
Post_ProductGlobal langs.MessageCode = "post@product_global" // 全站
|
||||
RegionCity_LogAddRegionCityCode langs.MessageCode = "region_city@log_add_region_city_code" // 添加城市/市 %d 别名 %s
|
||||
RegionCity_LogUpdateRegionCityCustom langs.MessageCode = "region_city@log_update_region_city_custom" // 定制城市 %d 信息
|
||||
RegionCountry_LogAddRegionCountryCode langs.MessageCode = "region_country@log_add_region_country_code" // 添加国家/地区 %d 别名 %s
|
||||
@@ -477,6 +493,7 @@ const (
|
||||
Server_LogCopyServerConfigs langs.MessageCode = "server@log_copy_server_configs" // 从网站 %d 中同步配置 %s
|
||||
Server_LogCreateServer langs.MessageCode = "server@log_create_server" // 创建网站 %d
|
||||
Server_LogDeleteServer langs.MessageCode = "server@log_delete_server" // 删除网站 %d
|
||||
Server_LogDeleteServers langs.MessageCode = "server@log_delete_servers" // 批量删除网站
|
||||
Server_LogDisableServer langs.MessageCode = "server@log_disable_server" // 停用网站 %d
|
||||
Server_LogEnableServer langs.MessageCode = "server@log_enable_server" // 启用网站 %d
|
||||
Server_LogSubmitAuditingServer langs.MessageCode = "server@log_submit_auditing_server" // 提交网站 %d 域名审核
|
||||
@@ -484,7 +501,7 @@ const (
|
||||
Server_LogUpdateServerBasic langs.MessageCode = "server@log_update_server_basic" // 修改网站 %d 基本信息
|
||||
Server_LogUpdateServerGroups langs.MessageCode = "server@log_update_server_groups" // 修改网站 %d 所属分组
|
||||
Server_LogUpdateServerIsOn langs.MessageCode = "server@log_update_server_is_on" // 修改网站 %d 启用状态
|
||||
Server_LogUpdateServerName langs.MessageCode = "server@log_update_server_name" // 修改网站名称
|
||||
Server_LogUpdateServerName langs.MessageCode = "server@log_update_server_name" // 修改网站 %d 名称
|
||||
Server_MenuAccesslogHistory langs.MessageCode = "server@menu_accesslog_history" // 历史
|
||||
Server_MenuAccesslogRealtime langs.MessageCode = "server@menu_accesslog_realtime" // 实时
|
||||
Server_MenuAccesslogToday langs.MessageCode = "server@menu_accesslog_today" // 今天
|
||||
@@ -507,6 +524,7 @@ const (
|
||||
Server_MenuSettingHTTPProxy langs.MessageCode = "server@menu_setting_http_proxy" // HTTP代理
|
||||
Server_MenuSettingHTTPS langs.MessageCode = "server@menu_setting_https" // HTTPS
|
||||
Server_MenuSettingLocations langs.MessageCode = "server@menu_setting_locations" // 路由规则
|
||||
Server_MenuSettingMultimedia langs.MessageCode = "server@menu_setting_multimedia" // 音视频设置
|
||||
Server_MenuSettingOptimization langs.MessageCode = "server@menu_setting_optimization" // 页面优化
|
||||
Server_MenuSettingOrigins langs.MessageCode = "server@menu_setting_origins" // 源站
|
||||
Server_MenuSettingOthers langs.MessageCode = "server@menu_setting_others" // 其他设置
|
||||
@@ -526,7 +544,6 @@ const (
|
||||
Server_MenuSettingUAM langs.MessageCode = "server@menu_setting_uam" // 5秒盾
|
||||
Server_MenuSettingUDP langs.MessageCode = "server@menu_setting_udp" // UDP
|
||||
Server_MenuSettingUDPProxy langs.MessageCode = "server@menu_setting_udp_proxy" // UDP代理
|
||||
Server_MenuSettingUnix langs.MessageCode = "server@menu_setting_unix" // Unix
|
||||
Server_MenuSettingUserAgents langs.MessageCode = "server@menu_setting_user_agents" // UA名单
|
||||
Server_MenuSettingWAF langs.MessageCode = "server@menu_setting_waf" // WAF
|
||||
Server_MenuSettingWebP langs.MessageCode = "server@menu_setting_webp" // WebP
|
||||
@@ -572,6 +589,7 @@ const (
|
||||
ServerGroup_LogDeleteServerGroup langs.MessageCode = "server_group@log_delete_server_group" // 删除网站分组 %d
|
||||
ServerGroup_LogSortServerGroups langs.MessageCode = "server_group@log_sort_server_groups" // 修改网站分组排序
|
||||
ServerGroup_LogUpdateServerGroup langs.MessageCode = "server_group@log_update_server_group" // 修改网站分组 %d
|
||||
ServerHls_LogUpdateHls langs.MessageCode = "server_hls@log_update_hls" // 修改Web %d 的HLS设置
|
||||
ServerHTTP3_LogUpdateClusterHTTP3Policy langs.MessageCode = "server_http3@log_update_cluster_http3_policy" // 修改集群 %d 的HTTP3策略设置
|
||||
ServerHTTP_LogUpdateHTTPSettings langs.MessageCode = "server_http@log_update_http_settings" // 修改网站 %d 的HTTP设置
|
||||
ServerHTTPHeader_LogCreateDeletingHeader langs.MessageCode = "server_http_header@log_create_deleting_header" // 添加删除的报头 HeaderPolicyId: %d, Name: %s
|
||||
@@ -588,6 +606,7 @@ const (
|
||||
ServerOrigin_LogCreateOrigin langs.MessageCode = "server_origin@log_create_origin" // 创建源站 %d
|
||||
ServerOrigin_LogDeleteOrigin langs.MessageCode = "server_origin@log_delete_origin" // 删除源站 %d
|
||||
ServerOrigin_LogUpdateOrigin langs.MessageCode = "server_origin@log_update_origin" // 修改源站 %d
|
||||
ServerOrigin_LogUpdateOriginIsOn langs.MessageCode = "server_origin@log_update_origin_is_on" // 修改源站 %d 启用状态
|
||||
ServerPage_LogCreatePage langs.MessageCode = "server_page@log_create_page" // 创建自定义页面 %d
|
||||
ServerPage_LogUpdateClusterPages langs.MessageCode = "server_page@log_update_cluster_pages" // 修改集群 %d 自定义页面策略
|
||||
ServerPage_LogUpdatePage langs.MessageCode = "server_page@log_update_page" // 修改自定义页面 %d
|
||||
@@ -610,6 +629,8 @@ const (
|
||||
ServerUAM_LogUpdateUAMSettings langs.MessageCode = "server_uam@log_update_uam_settings" // 修改Web %d 全站防护模式
|
||||
ServerUDP_LogUpdateUDPSettings langs.MessageCode = "server_udp@log_update_udp_settings" // 修改网站 %d UDP设置
|
||||
ServerUserAgent_LogUpdateUserAgents langs.MessageCode = "server_user_agent@log_update_user_agents" // 修改Web %d User-Agent设置
|
||||
ServerUserScript_LogPassUserScript langs.MessageCode = "server_user_script@log_pass_user_script" // 通过用户脚本 %d
|
||||
ServerUserScript_LogRejectUserScript langs.MessageCode = "server_user_script@log_reject_user_script" // 驳回用户脚本 %d
|
||||
ServerWAF_LogUpdateWAFSettings langs.MessageCode = "server_waf@log_update_waf_settings" // 修改Web %d 的WAF设置
|
||||
ServerWebP_LogUpdateClusterWebPPolicy langs.MessageCode = "server_webp@log_update_cluster_webp_policy" // 修改集群 %d 的WebP设置
|
||||
ServerWebsocket_LogUpdateWebsocketSettings langs.MessageCode = "server_websocket@log_update_websocket_settings" // 修改Web %d 的Websocket设置
|
||||
@@ -646,6 +667,7 @@ const (
|
||||
User_LogUpdateUserPricePeriod langs.MessageCode = "user@log_update_user_price_period" // 修改计费周期为 %s
|
||||
User_LogUpdateUserPriceType langs.MessageCode = "user@log_update_user_price_type" // 修改计费类型为 %s
|
||||
User_LogUpdateUserProfile langs.MessageCode = "user@log_update_user_profile" // 修改个人资料
|
||||
User_LogUpdateUserSmsSettings langs.MessageCode = "user@log_update_user_sms_settings" // 修改用户短信设置
|
||||
User_LogVerifyUser langs.MessageCode = "user@log_verify_user" // 审核用户:%d 结果:%s
|
||||
UserAccessKey_LogCreateUserAccessKey langs.MessageCode = "user_access_key@log_create_user_access_key" // 创建AccessKey %d
|
||||
UserAccessKey_LogDeleteUserAccessKey langs.MessageCode = "user_access_key@log_delete_user_access_key" // 删除AccessKey %d
|
||||
|
||||
@@ -4,6 +4,7 @@ package langs
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/configutils"
|
||||
"strings"
|
||||
)
|
||||
@@ -51,7 +52,7 @@ func (this *Lang) Compile() error {
|
||||
for code, oldMessage := range this.messageMap {
|
||||
message, err := this.get(code, 0)
|
||||
if err != nil {
|
||||
return errors.New("compile '" + string(code) + "': '" + oldMessage + "' failed: " + err.Error())
|
||||
return fmt.Errorf("compile '%s': '%s' failed: %w", string(code), oldMessage, err)
|
||||
}
|
||||
this.messageMap[code] = message
|
||||
}
|
||||
|
||||
@@ -90,7 +90,12 @@ func (this *Manager) GetMessage(langCode string, messageCode MessageCode, args .
|
||||
if lang.code != this.defaultLangCode {
|
||||
var defaultLang = this.langMap[this.defaultLangCode]
|
||||
if defaultLang != nil {
|
||||
return defaultLang.Get(messageCode)
|
||||
message = defaultLang.Get(messageCode)
|
||||
if len(args) == 0 {
|
||||
return message
|
||||
}
|
||||
|
||||
return fmt.Sprintf(message, args...)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
734
pkg/langs/messages/messages_en_us.go
Normal file
734
pkg/langs/messages/messages_en_us.go
Normal file
@@ -0,0 +1,734 @@
|
||||
// generated by run 'langs generate'
|
||||
|
||||
package messages
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/langs"
|
||||
)
|
||||
|
||||
func init() {
|
||||
langs.Load("en-us", map[langs.MessageCode]string{
|
||||
"acme_provider_account@log_create_acme_provider_account": "",
|
||||
"acme_provider_account@log_delete_acme_provider_account": "",
|
||||
"acme_provider_account@log_update_acme_provider_account": "",
|
||||
"acme_task@log_create_acme_task": "",
|
||||
"acme_task@log_delete_acme_task": "",
|
||||
"acme_task@log_run_acme_task": "",
|
||||
"acme_task@log_update_acme_task": "",
|
||||
"acme_user@log_create_acme_user": "",
|
||||
"acme_user@log_delete_acme_user": "",
|
||||
"acme_user@log_update_acme_user": "",
|
||||
"ad_network@log_create_ad_network": "",
|
||||
"ad_network@log_delete_ad_network": "",
|
||||
"ad_network@log_update_ad_network": "",
|
||||
"ad_package@log_create_ad_package": "",
|
||||
"ad_package@log_delete_ad_package": "",
|
||||
"ad_package@log_update_ad_package": "",
|
||||
"ad_package_instance@log_create_ad_package_instance": "",
|
||||
"ad_package_instance@log_delete_ad_package_instance": "",
|
||||
"ad_package_instance@log_update_ad_package_instance": "",
|
||||
"ad_package_period@log_create_ad_package_period": "",
|
||||
"ad_package_period@log_delete_ad_package_period": "",
|
||||
"ad_package_period@log_update_ad_package_period": "",
|
||||
"ad_package_price@log_create_ad_package_price": "",
|
||||
"ad_package_price@log_update_ad_package_price": "",
|
||||
"admin@log_create_admin": "",
|
||||
"admin@log_delete_admin": "",
|
||||
"admin@log_update_admin": "",
|
||||
"admin_common@canceled": "Canceled",
|
||||
"admin_common@log_system_error": "system error: %s",
|
||||
"admin_common@menu_setting_basic": "Basic Settings",
|
||||
"admin_common@menu_setting_cache": "Cache Settings",
|
||||
"admin_common@menu_setting_cache_policy": "Cache Policy",
|
||||
"admin_common@menu_setting_ddos_protection": "DDoS Protection",
|
||||
"admin_common@menu_setting_dns": "DNS Settings",
|
||||
"admin_common@menu_setting_health_check": "Health Check",
|
||||
"admin_common@menu_setting_metrics": "Metrics",
|
||||
"admin_common@menu_setting_security_policy": "Networking Security",
|
||||
"admin_common@menu_setting_waf_policy": "WAF Policy",
|
||||
"admin_common@menu_setting_webp": "WebP",
|
||||
"admin_common@menu_setting_webp_policy": "WebP Policy",
|
||||
"admin_common@server_error": "There is a internal error, please report to administrator.",
|
||||
"admin_common@system": "System",
|
||||
"admin_dashboard@disk_usage_warning": "当前服务器磁盘空间不足,请立即扩充容量,文件路径:%s,已使用:%dG,已使用比例:%.2f%%,仅剩余空间:%.2f%%。<br/>如果是因为本机数据库数据过多,你可以:<a href=\"/settings/database/clean\">[清理访问日志]</a> <a href=\"https://goedge.cn/docs/APINode/QA.md\" target=\"_blank\">[调整数据库binlog设置]</a>",
|
||||
"admin_dashboard@ui_dns": "DNS",
|
||||
"admin_dashboard@ui_events": "Events",
|
||||
"admin_dashboard@ui_overview": "Overview",
|
||||
"admin_dashboard@ui_user": "Users",
|
||||
"admin_dashboard@ui_waf": "WAF",
|
||||
"admin_login@log_failed": "",
|
||||
"admin_login@log_otp_verified_success": "",
|
||||
"admin_login@log_success": "",
|
||||
"admin_login@log_system_error": "",
|
||||
"admin_login@log_update_login": "",
|
||||
"admin_menu@admin_recipients": "Notification Medias",
|
||||
"admin_menu@admins": "System Users",
|
||||
"admin_menu@dashboard": "Dashboard",
|
||||
"admin_menu@dns": "DNS Service",
|
||||
"admin_menu@dns_clusters": "Clusters",
|
||||
"admin_menu@dns_issues": "Issues",
|
||||
"admin_menu@dns_providers": "DNS Providers",
|
||||
"admin_menu@finance": "Finance",
|
||||
"admin_menu@finance_accounts": "Accounts",
|
||||
"admin_menu@finance_bills": "Bills",
|
||||
"admin_menu@finance_fee": "Fee Settings",
|
||||
"admin_menu@finance_income": "Reports",
|
||||
"admin_menu@finance_logs": "Logs",
|
||||
"admin_menu@finance_orders": "Orders",
|
||||
"admin_menu@finance_packages": "Traffic Packages",
|
||||
"admin_menu@logs": "Audit Logs",
|
||||
"admin_menu@node_anti_ddos_products": "Anti-DDoS Product",
|
||||
"admin_menu@node_clusters": "Clusters",
|
||||
"admin_menu@node_distributed_monitors": "Distributed Monitors",
|
||||
"admin_menu@node_ip_list": "Node IPs",
|
||||
"admin_menu@node_logs": "Node Logs",
|
||||
"admin_menu@node_regions": "Regions",
|
||||
"admin_menu@node_ssh_grants": "SSH Grants",
|
||||
"admin_menu@nodes": "Edge Nodes",
|
||||
"admin_menu@ns": "Edge DNS",
|
||||
"admin_menu@ns_access_logs": "Access Logs",
|
||||
"admin_menu@ns_clusters": "Clusters",
|
||||
"admin_menu@ns_domain_batch_operations": "Batch",
|
||||
"admin_menu@ns_domain_groups": "Domain Groups",
|
||||
"admin_menu@ns_domains": "Domains",
|
||||
"admin_menu@ns_node_logs": "Node Logs",
|
||||
"admin_menu@ns_plans": "Plans",
|
||||
"admin_menu@ns_resolve_test": "Testing",
|
||||
"admin_menu@ns_routes": "Routes",
|
||||
"admin_menu@ns_settings": "Settings",
|
||||
"admin_menu@ns_user_plans": "User Plans",
|
||||
"admin_menu@plan_list": "Plans",
|
||||
"admin_menu@plan_user_plans": "User Plans",
|
||||
"admin_menu@plans": "Plans",
|
||||
"admin_menu@server_access_log_policies": "Access Log Policies",
|
||||
"admin_menu@server_access_logs": "Access Logs",
|
||||
"admin_menu@server_cache_policies": "Cache Policies",
|
||||
"admin_menu@server_certs": "Certificates",
|
||||
"admin_menu@server_global_settings": "Global Settings",
|
||||
"admin_menu@server_groups": "Site Groups",
|
||||
"admin_menu@server_ip_lists": "IP List",
|
||||
"admin_menu@server_metrics": "Metrics",
|
||||
"admin_menu@server_purge_fetch_caches": "Cache Management",
|
||||
"admin_menu@server_scripts": "Script Libraries",
|
||||
"admin_menu@server_traffic_stats": "Traffic Statistics",
|
||||
"admin_menu@server_waf_policies": "WAF Policies",
|
||||
"admin_menu@servers": "Sites",
|
||||
"admin_menu@setting_advanced_settings": "Advanced Settings",
|
||||
"admin_menu@setting_authority": "Commercial Authority",
|
||||
"admin_menu@setting_basic_settings": "Basic Settings",
|
||||
"admin_menu@settings": "Settings",
|
||||
"admin_menu@ticket_category": "Categories",
|
||||
"admin_menu@tickets": "Tickets",
|
||||
"admin_menu@user_list": "Users",
|
||||
"admin_menu@user_scripts": "User Scripts",
|
||||
"admin_menu@user_settings": "User Settings",
|
||||
"admin_menu@users": "Users",
|
||||
"admin_profile@log_update_profile": "",
|
||||
"admin_security@log_update_security_settings": "",
|
||||
"admin_server@log_update_server_http_settings": "",
|
||||
"admin_server@log_update_server_https_settings": "",
|
||||
"admin_setting@tab_access_log_databases": "Log Databases",
|
||||
"admin_setting@tab_admin_security_settings": "Security Settings",
|
||||
"admin_setting@tab_admin_server": "Admin Server Settings",
|
||||
"admin_setting@tab_admin_ui": "Admin System UI",
|
||||
"admin_setting@tab_api_nodes": "API Nodes",
|
||||
"admin_setting@tab_authority": "Commercial Authority",
|
||||
"admin_setting@tab_backup": "Backup",
|
||||
"admin_setting@tab_client_browsers": "Browser Management",
|
||||
"admin_setting@tab_client_operation_systems": "OS Management",
|
||||
"admin_setting@tab_database": "Database",
|
||||
"admin_setting@tab_ip_library": "IP Library",
|
||||
"admin_setting@tab_login": "My Login",
|
||||
"admin_setting@tab_monitor_nodes": "Monitor Nodes",
|
||||
"admin_setting@tab_profile": "My Profile",
|
||||
"admin_setting@tab_transfer": "Transfer",
|
||||
"admin_setting@tab_updates": "Updates",
|
||||
"admin_setting@tab_user_nodes": "User Nodes",
|
||||
"admin_setting@tab_user_ui": "User System UI",
|
||||
"admin_ui@default_product_name": "",
|
||||
"admin_ui@default_system_name": "",
|
||||
"admin_ui@log_update_ui_settings": "",
|
||||
"admin_update@log_ignore_version": "",
|
||||
"admin_update@log_reset_ignore_version": "",
|
||||
"admin_update@log_update_check_settings": "",
|
||||
"admin_user_ui@log_update_ui_settings": "",
|
||||
"api_node@log_create_api_node": "",
|
||||
"api_node@log_delete_api_node": "",
|
||||
"api_node@log_update_api_node": "",
|
||||
"client_browser@log_create_browser": "",
|
||||
"client_browser@log_update_client_browser": "",
|
||||
"client_system@log_create_system": "",
|
||||
"client_system@log_update_client_system": "",
|
||||
"database@log_delete_table": "",
|
||||
"database@log_truncate_table": "",
|
||||
"database@log_update_api_node_database_config": "",
|
||||
"database@log_update_clean_days": "",
|
||||
"db_node@log_create_db_node": "",
|
||||
"db_node@log_delete_db_node": "",
|
||||
"db_node@log_delete_table": "",
|
||||
"db_node@log_truncate_table": "",
|
||||
"db_node@log_update_db_node": "",
|
||||
"db_node@tab_nodes": "",
|
||||
"ddos_protection@log_update_cluster_ddos_protection": "",
|
||||
"ddos_protection@log_update_node_ddos_protection": "",
|
||||
"dns@log_create_domain": "",
|
||||
"dns@log_delete_domain": "",
|
||||
"dns@log_recover_domain": "",
|
||||
"dns@log_sync_cluster": "",
|
||||
"dns@log_sync_domain": "",
|
||||
"dns@log_update_cluster_dns": "",
|
||||
"dns@log_update_domain": "",
|
||||
"dns@log_update_node_dns": "",
|
||||
"dns_provider@log_create_dns_provider": "",
|
||||
"dns_provider@log_delete_dns_provider": "",
|
||||
"dns_provider@log_update_dns_provider": "",
|
||||
"dns_task@log_delete_all_dns_tasks": "",
|
||||
"dns_task@log_delete_dns_task": "",
|
||||
"finance@log_bill_generate_manually": "",
|
||||
"finance@log_update_user_order_config": "",
|
||||
"finance_fee@log_update_fee_setting": "",
|
||||
"http_access_log_policy@log_create_http_access_log_policy": "",
|
||||
"http_access_log_policy@log_delete_http_access_log_policy": "",
|
||||
"http_access_log_policy@log_test_http_access_log_policy": "",
|
||||
"http_access_log_policy@log_update_http_access_log_policy": "",
|
||||
"http_auth_policy@log_create_http_auth_policy": "",
|
||||
"http_auth_policy@log_update_http_auth_policy": "",
|
||||
"http_cache_task@log_create_http_cache_task_fetch": "",
|
||||
"http_cache_task@log_create_http_cache_task_purge": "",
|
||||
"http_cache_task@log_delete_http_cache_task": "",
|
||||
"http_cache_task@log_reset_http_cache_task": "",
|
||||
"http_fastcgi@log_create_http_fastcgi": "",
|
||||
"http_fastcgi@log_update_http_fastcgi": "",
|
||||
"http_location@log_create_http_location": "",
|
||||
"http_location@log_update_http_location": "",
|
||||
"http_rewrite_rule@log_create_rewrite_rule": "",
|
||||
"http_rewrite_rule@log_delete_rewrite_rule": "",
|
||||
"http_rewrite_rule@log_sort_rewrite_rules": "",
|
||||
"http_rewrite_rule@log_update_rewrite_rule": "",
|
||||
"ip_item@log_create_ip_item": "",
|
||||
"ip_item@log_delete_ip_item": "",
|
||||
"ip_item@log_read_all_ip_items": "",
|
||||
"ip_item@log_update_ip_item": "",
|
||||
"ip_library@log_finish_ip_library": "",
|
||||
"ip_library_artifact@log_cancel_ip_library_artifact": "",
|
||||
"ip_library_artifact@log_delete_ip_library_artifact": "",
|
||||
"ip_library_artifact@log_use_ip_library_artifact": "",
|
||||
"ip_library_file@log_delete_ip_library_file": "",
|
||||
"ip_library_file@log_generate_ip_library_file": "",
|
||||
"ip_library_file@log_upload_ip_library_file": "",
|
||||
"ip_list@log_bind_ip_list_waf_policy": "",
|
||||
"ip_list@log_create_ip_items_batch": "",
|
||||
"ip_list@log_create_ip_list": "",
|
||||
"ip_list@log_delete_ip_batch": "",
|
||||
"ip_list@log_delete_ip_list": "",
|
||||
"ip_list@log_export_ip_list": "",
|
||||
"ip_list@log_import_ip_list": "",
|
||||
"ip_list@log_unbind_ip_list_waf_policy": "",
|
||||
"ip_list@log_update_ip_list": "",
|
||||
"level@error": "",
|
||||
"level@info": "",
|
||||
"level@warn": "",
|
||||
"log@log_clean_all_logs": "",
|
||||
"log@log_clean_logs_days_before": "",
|
||||
"log@log_delete_log": "",
|
||||
"log@log_update_settings": "",
|
||||
"log@tag_access_log": "",
|
||||
"log@tag_listener": "",
|
||||
"log@tag_script": "",
|
||||
"log@tag_waf": "",
|
||||
"message@log_read_all": "",
|
||||
"message@log_read_messages": "",
|
||||
"message_media_instance@log_create_message_media_instance": "",
|
||||
"message_media_instance@log_delete_message_media_instance": "",
|
||||
"message_media_instance@log_update_message_media_instance": "",
|
||||
"message_receiver@log_delete_receiver": "",
|
||||
"message_receiver@log_update_cluster_message_receivers": "",
|
||||
"message_recipient@log_create_message_recipient": "",
|
||||
"message_recipient@log_delete_message_recipient": "",
|
||||
"message_recipient@log_update_message_recipient": "",
|
||||
"message_task@log_create_testing_message_task": "",
|
||||
"message_task@log_delete_message_task": "",
|
||||
"message_task@log_update_message_task_status": "",
|
||||
"metric_chart@log_create_metric_chart": "",
|
||||
"metric_chart@log_delete_metric_chart": "",
|
||||
"metric_chart@log_update_metric_chart": "",
|
||||
"metric_item@log_add_metric_item_to_cluster": "",
|
||||
"metric_item@log_create_metric_item": "",
|
||||
"metric_item@log_delete_metric_item": "",
|
||||
"metric_item@log_delete_metric_item_from_cluster": "",
|
||||
"metric_item@log_update_metric_item": "",
|
||||
"monitor_node@log_create_monitor_node": "",
|
||||
"monitor_node@log_delete_monitor_node": "",
|
||||
"monitor_node@log_update_monitor_node": "",
|
||||
"node@log_create_node": "",
|
||||
"node@log_create_node_batch": "",
|
||||
"node@log_delete_node_from_cluster": "",
|
||||
"node@log_install_node": "",
|
||||
"node@log_install_node_remotely": "",
|
||||
"node@log_start_node_remotely": "",
|
||||
"node@log_stop_node_remotely": "",
|
||||
"node@log_up_node": "",
|
||||
"node@log_update_node": "",
|
||||
"node@log_update_node_installation_status": "",
|
||||
"node@log_update_node_off": "",
|
||||
"node@log_update_node_on": "",
|
||||
"node@log_upgrade_node_remotely": "",
|
||||
"node@ungrouped_label": "",
|
||||
"node_action@log_copy_node_actions_to_cluster": "",
|
||||
"node_action@log_copy_node_actions_to_group": "",
|
||||
"node_action@log_create_node_action": "",
|
||||
"node_action@log_delete_node_action": "",
|
||||
"node_action@log_sort_node_actions": "",
|
||||
"node_action@log_update_node_action": "",
|
||||
"node_cache@log_update_node_cache_settings": "",
|
||||
"node_cluster@log_create_cluster": "",
|
||||
"node_cluster@log_delete_cluster": "",
|
||||
"node_cluster@log_pin_cluster": "",
|
||||
"node_cluster@log_run_cluster_health_check": "",
|
||||
"node_cluster@log_unpin_cluster": "",
|
||||
"node_cluster@log_update_cluster_basic_settings": "",
|
||||
"node_cluster@log_update_cluster_health_check": "",
|
||||
"node_cluster_menu@setting_basic": "Basic Settings",
|
||||
"node_cluster_menu@setting_cache_policy": "Cache Policy",
|
||||
"node_cluster_menu@setting_cc": "CC Policy",
|
||||
"node_cluster_menu@setting_ddos_protection": "DDoS Protection",
|
||||
"node_cluster_menu@setting_dns": "DNS Settings",
|
||||
"node_cluster_menu@setting_health_check": "Health Check",
|
||||
"node_cluster_menu@setting_http3": "HTTP/3",
|
||||
"node_cluster_menu@setting_metrics": "Metrics",
|
||||
"node_cluster_menu@setting_notification": "Notifications",
|
||||
"node_cluster_menu@setting_pages": "Pages",
|
||||
"node_cluster_menu@setting_schedule": "Scheduling",
|
||||
"node_cluster_menu@setting_security_policy": "Networking Security",
|
||||
"node_cluster_menu@setting_service_global": "Site Settings",
|
||||
"node_cluster_menu@setting_system_service": "System Service",
|
||||
"node_cluster_menu@setting_thresholds": "Thresholds",
|
||||
"node_cluster_menu@setting_toa": "TOA",
|
||||
"node_cluster_menu@setting_uam": "UAM Policy",
|
||||
"node_cluster_menu@setting_waf_actions": "WAF Actions",
|
||||
"node_cluster_menu@setting_waf_policy": "WAF Policy",
|
||||
"node_cluster_menu@setting_webp": "WebP Policy",
|
||||
"node_cluster_menu@tab_cluster_dashboard": "Dashboard",
|
||||
"node_cluster_menu@tab_cluster_delete": "Delete",
|
||||
"node_cluster_menu@tab_cluster_nodes": "Nodes",
|
||||
"node_cluster_menu@tab_cluster_settings": "Settings",
|
||||
"node_dns@log_update_node_dns": "",
|
||||
"node_grant@log_create_ssh_grant": "",
|
||||
"node_grant@log_delete_ssh_grant": "",
|
||||
"node_grant@log_update_ssh_grant": "",
|
||||
"node_grant@method_private_key": "",
|
||||
"node_grant@method_user_password": "",
|
||||
"node_group@log_create_node_group": "",
|
||||
"node_group@log_delete_node_group": "",
|
||||
"node_group@log_sort_node_groups": "",
|
||||
"node_group@log_update_node_group": "",
|
||||
"node_ip_address@log_delete_node_ip_address": "",
|
||||
"node_ip_address@log_down_node_ip_address": "",
|
||||
"node_ip_address@log_restore_node_ip_address": "",
|
||||
"node_ip_address@log_up_node_ip_address": "",
|
||||
"node_log@log_delete_node_logs_batch": "",
|
||||
"node_log@log_fix_all_logs": "",
|
||||
"node_log@log_fix_node_logs": "",
|
||||
"node_menu@create_multiple_nodes": "Create Batch",
|
||||
"node_menu@create_single_node": "Create",
|
||||
"node_menu@install_auto_register": "Auto-Register",
|
||||
"node_menu@install_manually": "Manually",
|
||||
"node_menu@install_remote": "Install Remotely(%d)",
|
||||
"node_menu@install_remote_upgrade": "Upgrade Remotely(%d)",
|
||||
"node_menu@setting_basic": "Basic Settings",
|
||||
"node_menu@setting_cache": "Cache Settings",
|
||||
"node_menu@setting_ddos_protection": "DDoS Protection",
|
||||
"node_menu@setting_dns": "DNS Settings",
|
||||
"node_menu@setting_schedule": "Scheduling",
|
||||
"node_menu@setting_ssh": "SSH",
|
||||
"node_menu@setting_system": "System Settings",
|
||||
"node_menu@setting_thresholds": "Thresholds",
|
||||
"node_price_item@log_create_node_price_item_bandwidth": "",
|
||||
"node_price_item@log_create_node_price_item_traffic": "",
|
||||
"node_price_item@log_delete_node_price_item": "",
|
||||
"node_price_item@log_update_node_price_item_bandwidth": "",
|
||||
"node_price_item@log_update_node_price_item_traffic": "",
|
||||
"node_region@log_create_node_region": "",
|
||||
"node_region@log_delete_node_region": "",
|
||||
"node_region@log_move_node_between_regions": "",
|
||||
"node_region@log_sort_node_regions": "",
|
||||
"node_region@log_update_node_region": "",
|
||||
"node_region_price@log_update_node_region_price": "",
|
||||
"node_schedule@log_reset_node_action_status": "",
|
||||
"node_schedule@log_update_node_schedule_basic": "",
|
||||
"node_ssh@log_update_node_ssh": "",
|
||||
"node_system@log_update_node_system_settings": "",
|
||||
"node_systemd@log_update_cluster_systemd_settings": "",
|
||||
"node_task@log_delete_all_node_tasks": "",
|
||||
"node_task@log_delete_node_task": "",
|
||||
"node_task@log_delete_node_tasks_batch": "",
|
||||
"node_threshold@log_create_node_threshold": "",
|
||||
"node_threshold@log_delete_node_threshold": "",
|
||||
"node_threshold@log_update_node_threshold": "",
|
||||
"node_toa@log_update_cluster_toa": "",
|
||||
"ns@log_create_ns_domains_batch": "",
|
||||
"ns@log_create_ns_records_batch": "",
|
||||
"ns@log_delete_ns_domains_batch": "",
|
||||
"ns@log_delete_ns_records_batch": "",
|
||||
"ns@log_disable_ns_records_batch": "",
|
||||
"ns@log_enable_ns_records_batch": "",
|
||||
"ns@log_import_records_batch": "",
|
||||
"ns@log_update_ns_records_batch": "",
|
||||
"ns@log_update_ns_user_config": "",
|
||||
"ns@setting_access_logs": "",
|
||||
"ns@setting_user": "",
|
||||
"ns_cluster@log_create_ns_cluster": "",
|
||||
"ns_cluster@log_delete_ns_cluster": "",
|
||||
"ns_cluster@log_update_ns_cluster_settings_access_log": "",
|
||||
"ns_cluster@log_update_ns_cluster_settings_answer": "",
|
||||
"ns_cluster@log_update_ns_cluster_settings_basic": "",
|
||||
"ns_cluster@log_update_ns_cluster_settings_ddos_protection": "",
|
||||
"ns_cluster@log_update_ns_cluster_settings_doh": "",
|
||||
"ns_cluster@log_update_ns_cluster_settings_recursion": "",
|
||||
"ns_cluster@log_update_ns_cluster_settings_soa": "",
|
||||
"ns_cluster@log_update_ns_cluster_settings_tcp": "",
|
||||
"ns_cluster@log_update_ns_cluster_settings_tls": "",
|
||||
"ns_cluster@log_update_ns_cluster_settings_udp": "",
|
||||
"ns_cluster@menu_access_logs": "",
|
||||
"ns_cluster@menu_answer_setting": "",
|
||||
"ns_cluster@menu_basic": "",
|
||||
"ns_cluster@menu_ddos_protection": "",
|
||||
"ns_cluster@menu_dns_recursion": "",
|
||||
"ns_cluster@menu_doh": "",
|
||||
"ns_cluster@menu_soa": "",
|
||||
"ns_cluster@menu_tcp": "",
|
||||
"ns_cluster@menu_tls": "",
|
||||
"ns_cluster@menu_udp": "",
|
||||
"ns_cluster@tab_delete": "",
|
||||
"ns_cluster@tab_nodes": "",
|
||||
"ns_cluster@tab_setting": "",
|
||||
"ns_domain@log_create_ns_domain": "",
|
||||
"ns_domain@log_create_ns_domains_batch": "",
|
||||
"ns_domain@log_delete_ns_domain": "",
|
||||
"ns_domain@log_update_ns_domain": "",
|
||||
"ns_domain@log_update_ns_domain_health_check": "",
|
||||
"ns_domain@log_update_ns_domain_status": "",
|
||||
"ns_domain@log_update_ns_domain_tsig": "",
|
||||
"ns_domain@log_validate_ns_domains": "",
|
||||
"ns_domain_group@log_create_ns_domain_group": "",
|
||||
"ns_domain_group@log_delete_ns_domain_group": "",
|
||||
"ns_domain_group@log_update_ns_domain_group": "",
|
||||
"ns_key@log_create_ns_key": "",
|
||||
"ns_key@log_delete_ns_key": "",
|
||||
"ns_key@log_update_ns_key": "",
|
||||
"ns_node@log_create_ns_node": "",
|
||||
"ns_node@log_delete_ns_node": "",
|
||||
"ns_node@log_install_ns_node_remotely": "",
|
||||
"ns_node@log_start_ns_node_remotely": "",
|
||||
"ns_node@log_stop_ns_node_remotely": "",
|
||||
"ns_node@log_update_ns_node": "",
|
||||
"ns_node@log_update_ns_node_installation_status": "",
|
||||
"ns_node_ssh@log_update_ns_node_ssh": "",
|
||||
"ns_plan@log_create_ns_plan": "",
|
||||
"ns_plan@log_delete_ns_plan": "",
|
||||
"ns_plan@log_sort_ns_plans": "",
|
||||
"ns_plan@log_update_ns_plan": "",
|
||||
"ns_record@log_create_ns_record": "",
|
||||
"ns_record@log_create_ns_records_batch": "",
|
||||
"ns_record@log_delete_ns_record": "",
|
||||
"ns_record@log_up_ns_record": "",
|
||||
"ns_record@log_update_ns_record": "",
|
||||
"ns_record@log_update_ns_record_health_check": "",
|
||||
"ns_route@log_create_ns_route": "",
|
||||
"ns_route@log_delete_ns_route": "",
|
||||
"ns_route@log_sort_ns_routes": "",
|
||||
"ns_route@log_update_ns_route": "",
|
||||
"ns_route_category@log_create_ns_route_category": "",
|
||||
"ns_route_category@log_delete_ns_route_category": "",
|
||||
"ns_route_category@log_sort_ns_route_categories": "",
|
||||
"ns_route_category@log_update_ns_route_category": "",
|
||||
"ns_user_plan@log_create_ns_user_plan": "",
|
||||
"ns_user_plan@log_delete_ns_user_plan": "",
|
||||
"ns_user_plan@log_update_ns_user_plan": "",
|
||||
"order_method@log_create_order_method": "",
|
||||
"order_method@log_delete_order_method": "",
|
||||
"order_method@log_update_order_method": "",
|
||||
"plan@log_create_plan": "",
|
||||
"plan@log_delete_plan": "",
|
||||
"plan@log_sort_plans": "",
|
||||
"plan@log_update_plan": "",
|
||||
"post@log_create_post": "",
|
||||
"post@log_delete_post": "",
|
||||
"post@log_publish_post": "",
|
||||
"post@log_update_post": "",
|
||||
"post@product_global": "",
|
||||
"region_city@log_add_region_city_code": "",
|
||||
"region_city@log_update_region_city_custom": "",
|
||||
"region_country@log_add_region_country_code": "",
|
||||
"region_country@log_update_region_country_custom": "",
|
||||
"region_country@region_china": "",
|
||||
"region_country@region_china_hk": "",
|
||||
"region_country@region_china_mainland": "",
|
||||
"region_country@region_china_mo": "",
|
||||
"region_country@region_china_tw": "",
|
||||
"region_country@region_greater_china": "",
|
||||
"region_provider@log_add_region_provider_code": "",
|
||||
"region_provider@log_update_region_provider_custom": "",
|
||||
"region_province@log_add_region_province_code": "",
|
||||
"region_province@log_update_region_province_custom": "",
|
||||
"region_town@log_add_region_town_code": "",
|
||||
"region_town@log_update_region_town_custom": "",
|
||||
"report_node@log_create_report_node": "",
|
||||
"report_node@log_delete_report_node": "",
|
||||
"report_node@log_update_report_node": "",
|
||||
"report_node_group@log_create_report_node_group": "",
|
||||
"report_node_group@log_delete_report_node_group": "",
|
||||
"report_node_group@log_update_report_node_group": "",
|
||||
"reverse_proxy@log_update_reverse_proxy_scheduling": "",
|
||||
"script@log_create_script": "",
|
||||
"script@log_delete_script": "",
|
||||
"script@log_publish_scripts": "",
|
||||
"script@log_update_script": "",
|
||||
"server@copy_setting_current_cluster": "Current Cluster: %s",
|
||||
"server@copy_setting_current_group": "Current Group: %s",
|
||||
"server@copy_setting_current_user": "Current User: %s",
|
||||
"server@copy_setting_select_cluster": "Select Cluster",
|
||||
"server@copy_setting_select_group": "Select Group",
|
||||
"server@copy_setting_select_server": "Select Site",
|
||||
"server@copy_setting_select_user": "Select User",
|
||||
"server@log_copy_server_configs": "从网站 %d 中同步配置 %s",
|
||||
"server@log_create_server": "创建网站 %d",
|
||||
"server@log_delete_server": "删除网站 %d",
|
||||
"server@log_delete_servers": "",
|
||||
"server@log_disable_server": "停用网站 %d",
|
||||
"server@log_enable_server": "启用网站 %d",
|
||||
"server@log_submit_auditing_server": "提交网站 %d 域名审核",
|
||||
"server@log_update_global_settings": "保存网站全局配置",
|
||||
"server@log_update_server_basic": "修改网站 %d 基本信息",
|
||||
"server@log_update_server_groups": "修改网站 %d 所属分组",
|
||||
"server@log_update_server_is_on": "修改网站 %d 启用状态",
|
||||
"server@log_update_server_name": "修改网站 %d 名称",
|
||||
"server@menu_accesslog_history": "History",
|
||||
"server@menu_accesslog_realtime": "Realtime",
|
||||
"server@menu_accesslog_today": "Today",
|
||||
"server@menu_dashboard": "Dashboard",
|
||||
"server@menu_setting_access_log": "Access Log",
|
||||
"server@menu_setting_auth": "Access Control",
|
||||
"server@menu_setting_basic": "Basic Settings",
|
||||
"server@menu_setting_cache": "Cache",
|
||||
"server@menu_setting_cc": "CC Protection",
|
||||
"server@menu_setting_charset": "Charset",
|
||||
"server@menu_setting_client_ip": "Client IP",
|
||||
"server@menu_setting_compression": "Compressions",
|
||||
"server@menu_setting_delete": "Delete",
|
||||
"server@menu_setting_dns": "DNS",
|
||||
"server@menu_setting_domains": "Server Names",
|
||||
"server@menu_setting_fastcgi": "Fastcgi",
|
||||
"server@menu_setting_group": "Group",
|
||||
"server@menu_setting_http": "HTTP",
|
||||
"server@menu_setting_http_headers": "HTTP Headers",
|
||||
"server@menu_setting_http_proxy": "HTTP Reverse Proxy",
|
||||
"server@menu_setting_https": "HTTPS",
|
||||
"server@menu_setting_locations": "Locations",
|
||||
"server@menu_setting_multimedia": "Audios & Videos",
|
||||
"server@menu_setting_optimization": "Content Optimizations",
|
||||
"server@menu_setting_origins": "Origin Sites",
|
||||
"server@menu_setting_others": "Others",
|
||||
"server@menu_setting_pages": "Pages",
|
||||
"server@menu_setting_plan": "Plan",
|
||||
"server@menu_setting_redirects": "URL Redirections",
|
||||
"server@menu_setting_referers": "Referers",
|
||||
"server@menu_setting_request_limit": "Request Limit",
|
||||
"server@menu_setting_rewrite_rules": "Rewrite Rules",
|
||||
"server@menu_setting_root": "Static Files",
|
||||
"server@menu_setting_scripts": "Scripts",
|
||||
"server@menu_setting_stat": "Statistics",
|
||||
"server@menu_setting_tcp": "TCP",
|
||||
"server@menu_setting_tcp_proxy": "TCP Reverse Proxy",
|
||||
"server@menu_setting_tls": "TLS",
|
||||
"server@menu_setting_traffic_limit": "Traffic Limit",
|
||||
"server@menu_setting_uam": "UAM",
|
||||
"server@menu_setting_udp": "UDP",
|
||||
"server@menu_setting_udp_proxy": "UDP Reverse Proxy",
|
||||
"server@menu_setting_user_agents": "UA List",
|
||||
"server@menu_setting_waf": "WAF",
|
||||
"server@menu_setting_webp": "WebP",
|
||||
"server@menu_setting_websocket": "Websocket",
|
||||
"server@menu_stat_clients": "Clients",
|
||||
"server@menu_stat_providers": "Providers",
|
||||
"server@menu_stat_regions": "Regions",
|
||||
"server@menu_stat_traffic": "Traffic",
|
||||
"server@menu_stat_waf": "WAF",
|
||||
"server@server_names_log_update_server_names": "修改网站 %d 域名",
|
||||
"server@tab_access_logs": "Access Logs",
|
||||
"server@tab_dashboard": "Dashboard",
|
||||
"server@tab_delete": "Delete",
|
||||
"server@tab_server_list": "Sites",
|
||||
"server@tab_settings": "Settings",
|
||||
"server@tab_stat": "Statistics",
|
||||
"server_access_log@log_update_access_log_setting": "",
|
||||
"server_auth@log_update_http_auth_settings": "",
|
||||
"server_cache@log_fetch_caches": "",
|
||||
"server_cache@log_purge_caches": "",
|
||||
"server_cache@log_update_cache_settings": "",
|
||||
"server_cache@log_update_cluster_cache_policy": "",
|
||||
"server_cache_policy@log_clean_all": "",
|
||||
"server_cache_policy@log_create_cache_policy": "",
|
||||
"server_cache_policy@log_delete_cache_policy": "",
|
||||
"server_cache_policy@log_fetch_caches": "",
|
||||
"server_cache_policy@log_purge_caches": "",
|
||||
"server_cache_policy@log_stat_caches": "",
|
||||
"server_cache_policy@log_test_reading": "",
|
||||
"server_cache_policy@log_test_writing": "",
|
||||
"server_cache_policy@log_update_cache_policy": "",
|
||||
"server_cc@log_update_cc_settings": "",
|
||||
"server_cc@log_update_cluster_http_cc_policy": "",
|
||||
"server_charset@log_update_charset_setting": "",
|
||||
"server_common@log_update_common_settings": "",
|
||||
"server_compression@log_update_compression_settings": "",
|
||||
"server_dns@log_regenerate_dns_name": "",
|
||||
"server_dns@log_update_dns_name": "",
|
||||
"server_dns@log_update_dns_settings": "",
|
||||
"server_fastcgi@log_update_http_fastcgi": "",
|
||||
"server_global_setting@log_update_cluster_global_server_config": "",
|
||||
"server_group@log_create_server_group": "",
|
||||
"server_group@log_delete_server_group": "",
|
||||
"server_group@log_sort_server_groups": "",
|
||||
"server_group@log_update_server_group": "",
|
||||
"server_hls@log_update_hls": "",
|
||||
"server_http3@log_update_cluster_http3_policy": "",
|
||||
"server_http@log_update_http_settings": "",
|
||||
"server_http_header@log_create_deleting_header": "",
|
||||
"server_http_header@log_create_non_standard_header": "",
|
||||
"server_http_header@log_create_setting_request_header": "",
|
||||
"server_http_header@log_create_setting_response_header": "",
|
||||
"server_http_header@log_delete_deleting_header": "",
|
||||
"server_http_header@log_delete_header": "",
|
||||
"server_http_header@log_delete_non_standard_header": "",
|
||||
"server_http_header@log_update_http_headers": "",
|
||||
"server_http_header@log_update_setting_header": "",
|
||||
"server_https@log_update_https_settings": "",
|
||||
"server_optimization@log_update_optimization_settings": "",
|
||||
"server_origin@log_create_origin": "",
|
||||
"server_origin@log_delete_origin": "",
|
||||
"server_origin@log_update_origin": "",
|
||||
"server_origin@log_update_origin_is_on": "",
|
||||
"server_page@log_create_page": "",
|
||||
"server_page@log_update_cluster_pages": "",
|
||||
"server_page@log_update_page": "",
|
||||
"server_page@log_update_pages": "",
|
||||
"server_redirect@log_update_redirects": "",
|
||||
"server_referer@log_update_referers": "",
|
||||
"server_request_limit@log_update_request_limit_settings": "",
|
||||
"server_reverse_proxy@log_update_location_reverse_proxy_settings": "",
|
||||
"server_reverse_proxy@log_update_server_group_reverse_proxy_settings": "",
|
||||
"server_reverse_proxy@log_update_server_reverse_proxy_settings": "",
|
||||
"server_root@log_update_root": "",
|
||||
"server_script@log_update_scripts": "",
|
||||
"server_stat@log_update_stat_settings": "",
|
||||
"server_tcp@log_update_tcp_settings": "",
|
||||
"server_tls@log_update_tls_settings": "",
|
||||
"server_traffic_limit@log_update_traffic_limit_settings": "",
|
||||
"server_traffic_stat@all_servers": "",
|
||||
"server_uam@log_update_cluster_uam_policy": "",
|
||||
"server_uam@log_update_server_uam_settings": "",
|
||||
"server_uam@log_update_uam_settings": "",
|
||||
"server_udp@log_update_udp_settings": "",
|
||||
"server_user_agent@log_update_user_agents": "",
|
||||
"server_user_script@log_pass_user_script": "",
|
||||
"server_user_script@log_reject_user_script": "",
|
||||
"server_waf@log_update_waf_settings": "",
|
||||
"server_webp@log_update_cluster_webp_policy": "",
|
||||
"server_websocket@log_update_websocket_settings": "",
|
||||
"ssl_cert@log_delete_ssl_cert": "",
|
||||
"ssl_cert@log_download_ssl_cert": "",
|
||||
"ssl_cert@log_download_ssl_cert_key": "",
|
||||
"ssl_cert@log_download_ssl_cert_zip": "",
|
||||
"ssl_cert@log_ocsp_ignore_ocsp_status": "",
|
||||
"ssl_cert@log_ocsp_reset_all_ocsp_status": "",
|
||||
"ssl_cert@log_ocsp_reset_ocsp_status": "",
|
||||
"ssl_cert@log_update_ssl_cert": "",
|
||||
"ssl_cert@log_upload_ssl_cert": "",
|
||||
"ssl_cert@log_upload_ssl_cert_batch": "",
|
||||
"ssl_cert@menu_apply": "",
|
||||
"ssl_cert@menu_certs": "",
|
||||
"ssl_cert@menu_ocsp": "",
|
||||
"system@home_page": "https://goedge.cn",
|
||||
"ticket_category@log_create_ticket_category": "",
|
||||
"ticket_category@log_delete_ticket_category": "",
|
||||
"ticket_category@log_update_ticket_category": "",
|
||||
"traffic_package@log_create_traffic_package": "",
|
||||
"traffic_package@log_delete_traffic_package": "",
|
||||
"traffic_package@log_update_traffic_package": "",
|
||||
"traffic_package_period@log_create_traffic_package_period": "",
|
||||
"traffic_package_period@log_delete_traffic_package_period": "",
|
||||
"traffic_package_period@log_update_traffic_package_period": "",
|
||||
"traffic_package_price@log_update_traffic_package_price": "",
|
||||
"user@log_create_user": "",
|
||||
"user@log_delete_user": "",
|
||||
"user@log_update_user": "",
|
||||
"user@log_update_user_email_settings": "",
|
||||
"user@log_update_user_features": "",
|
||||
"user@log_update_user_global_settings": "",
|
||||
"user@log_update_user_price_period": "",
|
||||
"user@log_update_user_price_type": "",
|
||||
"user@log_update_user_profile": "",
|
||||
"user@log_update_user_sms_settings": "",
|
||||
"user@log_verify_user": "",
|
||||
"user_access_key@log_create_user_access_key": "",
|
||||
"user_access_key@log_delete_user_access_key": "",
|
||||
"user_access_key@log_update_user_access_key_is_on": "",
|
||||
"user_account@log_update_user_account": "",
|
||||
"user_ad_instance@log_delete_user_ad_instance": "",
|
||||
"user_ad_instance@log_renew_user_ad_instance": "",
|
||||
"user_ad_instance@log_update_user_ad_instance_objects": "",
|
||||
"user_bill@log_pay_user_bill": "",
|
||||
"user_common@canceled": "",
|
||||
"user_common@log_system_error": "",
|
||||
"user_common@server_error": "",
|
||||
"user_common@system": "",
|
||||
"user_identity@log_cancel_user_identity": "",
|
||||
"user_identity@log_reject_user_identity": "",
|
||||
"user_identity@log_reset_user_identity": "",
|
||||
"user_identity@log_submit_user_identity": "",
|
||||
"user_identity@log_update_user_identity_enterprise": "",
|
||||
"user_identity@log_update_user_identity_individual": "",
|
||||
"user_identity@log_verify_user_identity": "",
|
||||
"user_login@log_update_login": "",
|
||||
"user_node@log_create_user_node": "",
|
||||
"user_node@log_delete_user_node": "",
|
||||
"user_node@log_update_user_node": "",
|
||||
"user_order@log_finish_user_order": "",
|
||||
"user_plan@log_bind_user_plan_to_server": "",
|
||||
"user_plan@log_buy_user_plan": "",
|
||||
"user_plan@log_cancel_user_plan_from_server": "",
|
||||
"user_plan@log_delete_user_plan": "",
|
||||
"user_plan@log_renew_user_plan": "",
|
||||
"user_ticket@log_create_user_ticket": "",
|
||||
"user_ticket_log@log_reply_ticket": "",
|
||||
"user_traffic_package@log_create_user_traffic_package": "",
|
||||
"user_traffic_package@log_delete_user_traffic_package": "",
|
||||
"waf@connector_and": "",
|
||||
"waf@connector_and_description": "",
|
||||
"waf@connector_or": "",
|
||||
"waf@connector_or_description": "",
|
||||
"waf@log_delete_ip_from_waf_policy": "",
|
||||
"waf@log_update_forbidden_countries": "",
|
||||
"waf@log_update_forbidden_provinces": "",
|
||||
"waf@log_update_ip_from_waf_policy": "",
|
||||
"waf_action@log_create_waf_action": "",
|
||||
"waf_action@log_delete_waf_action": "",
|
||||
"waf_action@log_update_waf_action": "",
|
||||
"waf_policy@log_create_waf_policy": "",
|
||||
"waf_policy@log_delete_waf_policy": "",
|
||||
"waf_policy@log_export_waf_policy": "",
|
||||
"waf_policy@log_import_waf_policy": "",
|
||||
"waf_policy@log_update_cluster_waf_policy": "",
|
||||
"waf_policy@log_update_waf_policy": "",
|
||||
"waf_policy@log_upgrade_waf_policy": "",
|
||||
"waf_rule_group@log_create_rule_group": "",
|
||||
"waf_rule_group@log_delete_rule_group": "",
|
||||
"waf_rule_group@log_sort_rule_groups": "",
|
||||
"waf_rule_group@log_update_rule_group": "",
|
||||
"waf_rule_group@log_update_rule_group_is_on": "",
|
||||
"waf_rule_set@log_delete_rule_set": "",
|
||||
"waf_rule_set@log_sort_rule_sets": "",
|
||||
"waf_rule_set@log_update_rule_set": "",
|
||||
"waf_rule_set@log_update_rule_set_is_on": "",
|
||||
})
|
||||
}
|
||||
@@ -44,8 +44,10 @@ func init() {
|
||||
"admin_common@menu_setting_dns": "DNS设置",
|
||||
"admin_common@menu_setting_health_check": "健康检查",
|
||||
"admin_common@menu_setting_metrics": "统计指标",
|
||||
"admin_common@menu_setting_security_policy": "网络安全",
|
||||
"admin_common@menu_setting_waf_policy": "WAF策略",
|
||||
"admin_common@menu_setting_webp": "WebP",
|
||||
"admin_common@menu_setting_webp_policy": "WebP策略",
|
||||
"admin_common@server_error": "服务器出了点小问题,请联系技术人员处理。",
|
||||
"admin_common@system": "系统",
|
||||
"admin_dashboard@disk_usage_warning": "当前服务器磁盘空间不足,请立即扩充容量,文件路径:%s,已使用:%dG,已使用比例:%.2f%%,仅剩余空间:%.2f%%。<br/>如果是因为本机数据库数据过多,你可以:<a href=\"/settings/database/clean\">[清理访问日志]</a> <a href=\"https://goedge.cn/docs/APINode/QA.md\" target=\"_blank\">[调整数据库binlog设置]</a>",
|
||||
@@ -95,6 +97,7 @@ func init() {
|
||||
"admin_menu@ns_routes": "线路管理",
|
||||
"admin_menu@ns_settings": "全局配置",
|
||||
"admin_menu@ns_user_plans": "用户套餐",
|
||||
"admin_menu@plan_list": "套餐列表",
|
||||
"admin_menu@plan_user_plans": "已购套餐",
|
||||
"admin_menu@plans": "套餐管理",
|
||||
"admin_menu@server_access_log_policies": "日志策略",
|
||||
@@ -116,6 +119,8 @@ func init() {
|
||||
"admin_menu@settings": "系统设置",
|
||||
"admin_menu@ticket_category": "分类",
|
||||
"admin_menu@tickets": "工单系统",
|
||||
"admin_menu@user_list": "用户列表",
|
||||
"admin_menu@user_scripts": "用户脚本",
|
||||
"admin_menu@user_settings": "用户设置",
|
||||
"admin_menu@users": "平台用户",
|
||||
"admin_profile@log_update_profile": "修改个人资料",
|
||||
@@ -146,6 +151,7 @@ func init() {
|
||||
"admin_update@log_ignore_version": "忽略升级版本 %s",
|
||||
"admin_update@log_reset_ignore_version": "重置忽略升级版本",
|
||||
"admin_update@log_update_check_settings": "修改检查更新设置",
|
||||
"admin_user_ui@log_update_ui_settings": "修改用户界面设置",
|
||||
"api_node@log_create_api_node": "创建API节点 %d",
|
||||
"api_node@log_delete_api_node": "删除API节点 %d",
|
||||
"api_node@log_update_api_node": "修改API节点 %d",
|
||||
@@ -235,12 +241,14 @@ func init() {
|
||||
"message_media_instance@log_create_message_media_instance": "创建消息媒介 %d",
|
||||
"message_media_instance@log_delete_message_media_instance": "删除消息媒介 %d",
|
||||
"message_media_instance@log_update_message_media_instance": "修改消息媒介 %d",
|
||||
"message_reciever@log_update_cluster_message_receivers": "修改集群 %d 消息接收人",
|
||||
"message_receiver@log_delete_receiver": "删除接收人关联关系 %d",
|
||||
"message_receiver@log_update_cluster_message_receivers": "修改集群 %d 消息接收人",
|
||||
"message_recipient@log_create_message_recipient": "创建媒介接收人 %d",
|
||||
"message_recipient@log_delete_message_recipient": "删除媒介接收人 %d",
|
||||
"message_recipient@log_update_message_recipient": "修改媒介接收人 %d",
|
||||
"message_task@log_create_testing_message_task": "创建媒介测试任务 %d",
|
||||
"message_task@log_delete_message_task": "删除消息发送任务 %d",
|
||||
"message_task@log_update_message_task_status": "修改消息任务 %d 状态为 %d",
|
||||
"metric_chart@log_create_metric_chart": "创建指标图表 %d",
|
||||
"metric_chart@log_delete_metric_chart": "删除指标图表 %d",
|
||||
"metric_chart@log_update_metric_chart": "修改指标图表 %d",
|
||||
@@ -262,6 +270,8 @@ func init() {
|
||||
"node@log_up_node": "手动上线节点 %d",
|
||||
"node@log_update_node": "修改节点 %d 基本信息",
|
||||
"node@log_update_node_installation_status": "修改节点安装状态 %d",
|
||||
"node@log_update_node_off": "停用节点 %d",
|
||||
"node@log_update_node_on": "启用节点 %d",
|
||||
"node@log_upgrade_node_remotely": "远程升级节点 %d",
|
||||
"node@ungrouped_label": "未分组",
|
||||
"node_action@log_copy_node_actions_to_cluster": "复制节点 %d 调度动作到集群",
|
||||
@@ -289,6 +299,7 @@ func init() {
|
||||
"node_cluster_menu@setting_notification": "消息通知",
|
||||
"node_cluster_menu@setting_pages": "自定义页面",
|
||||
"node_cluster_menu@setting_schedule": "智能调度",
|
||||
"node_cluster_menu@setting_security_policy": "网络安全",
|
||||
"node_cluster_menu@setting_service_global": "网站设置",
|
||||
"node_cluster_menu@setting_system_service": "系统服务",
|
||||
"node_cluster_menu@setting_thresholds": "阈值设置",
|
||||
@@ -296,7 +307,7 @@ func init() {
|
||||
"node_cluster_menu@setting_uam": "5秒盾",
|
||||
"node_cluster_menu@setting_waf_actions": "WAF动作",
|
||||
"node_cluster_menu@setting_waf_policy": "WAF策略",
|
||||
"node_cluster_menu@setting_webp": "WebP",
|
||||
"node_cluster_menu@setting_webp": "WebP策略",
|
||||
"node_cluster_menu@tab_cluster_dashboard": "集群看板",
|
||||
"node_cluster_menu@tab_cluster_delete": "删除集群",
|
||||
"node_cluster_menu@tab_cluster_nodes": "节点列表",
|
||||
@@ -441,6 +452,11 @@ func init() {
|
||||
"plan@log_delete_plan": "删除套餐 %d",
|
||||
"plan@log_sort_plans": "对套餐进行排序",
|
||||
"plan@log_update_plan": "修改套餐 %d",
|
||||
"post@log_create_post": "创建文章 %d",
|
||||
"post@log_delete_post": "删除文章 %d",
|
||||
"post@log_publish_post": "发布文章 %d",
|
||||
"post@log_update_post": "修改文章 %d",
|
||||
"post@product_global": "全站",
|
||||
"region_city@log_add_region_city_code": "添加城市/市 %d 别名 %s",
|
||||
"region_city@log_update_region_city_custom": "定制城市 %d 信息",
|
||||
"region_country@log_add_region_country_code": "添加国家/地区 %d 别名 %s",
|
||||
@@ -478,6 +494,7 @@ func init() {
|
||||
"server@log_copy_server_configs": "从网站 %d 中同步配置 %s",
|
||||
"server@log_create_server": "创建网站 %d",
|
||||
"server@log_delete_server": "删除网站 %d",
|
||||
"server@log_delete_servers": "批量删除网站",
|
||||
"server@log_disable_server": "停用网站 %d",
|
||||
"server@log_enable_server": "启用网站 %d",
|
||||
"server@log_submit_auditing_server": "提交网站 %d 域名审核",
|
||||
@@ -485,7 +502,7 @@ func init() {
|
||||
"server@log_update_server_basic": "修改网站 %d 基本信息",
|
||||
"server@log_update_server_groups": "修改网站 %d 所属分组",
|
||||
"server@log_update_server_is_on": "修改网站 %d 启用状态",
|
||||
"server@log_update_server_name": "修改网站名称",
|
||||
"server@log_update_server_name": "修改网站 %d 名称",
|
||||
"server@menu_accesslog_history": "历史",
|
||||
"server@menu_accesslog_realtime": "实时",
|
||||
"server@menu_accesslog_today": "今天",
|
||||
@@ -508,6 +525,7 @@ func init() {
|
||||
"server@menu_setting_http_proxy": "HTTP代理",
|
||||
"server@menu_setting_https": "HTTPS",
|
||||
"server@menu_setting_locations": "路由规则",
|
||||
"server@menu_setting_multimedia": "音视频设置",
|
||||
"server@menu_setting_optimization": "页面优化",
|
||||
"server@menu_setting_origins": "源站",
|
||||
"server@menu_setting_others": "其他设置",
|
||||
@@ -527,7 +545,6 @@ func init() {
|
||||
"server@menu_setting_uam": "5秒盾",
|
||||
"server@menu_setting_udp": "UDP",
|
||||
"server@menu_setting_udp_proxy": "UDP代理",
|
||||
"server@menu_setting_unix": "Unix",
|
||||
"server@menu_setting_user_agents": "UA名单",
|
||||
"server@menu_setting_waf": "WAF",
|
||||
"server@menu_setting_webp": "WebP",
|
||||
@@ -573,6 +590,7 @@ func init() {
|
||||
"server_group@log_delete_server_group": "删除网站分组 %d",
|
||||
"server_group@log_sort_server_groups": "修改网站分组排序",
|
||||
"server_group@log_update_server_group": "修改网站分组 %d",
|
||||
"server_hls@log_update_hls": "修改Web %d 的HLS设置",
|
||||
"server_http3@log_update_cluster_http3_policy": "修改集群 %d 的HTTP3策略设置",
|
||||
"server_http@log_update_http_settings": "修改网站 %d 的HTTP设置",
|
||||
"server_http_header@log_create_deleting_header": "添加删除的报头 HeaderPolicyId: %d, Name: %s",
|
||||
@@ -589,6 +607,7 @@ func init() {
|
||||
"server_origin@log_create_origin": "创建源站 %d",
|
||||
"server_origin@log_delete_origin": "删除源站 %d",
|
||||
"server_origin@log_update_origin": "修改源站 %d",
|
||||
"server_origin@log_update_origin_is_on": "修改源站 %d 启用状态",
|
||||
"server_page@log_create_page": "创建自定义页面 %d",
|
||||
"server_page@log_update_cluster_pages": "修改集群 %d 自定义页面策略",
|
||||
"server_page@log_update_page": "修改自定义页面 %d",
|
||||
@@ -611,6 +630,8 @@ func init() {
|
||||
"server_uam@log_update_uam_settings": "修改Web %d 全站防护模式",
|
||||
"server_udp@log_update_udp_settings": "修改网站 %d UDP设置",
|
||||
"server_user_agent@log_update_user_agents": "修改Web %d User-Agent设置",
|
||||
"server_user_script@log_pass_user_script": "通过用户脚本 %d",
|
||||
"server_user_script@log_reject_user_script": "驳回用户脚本 %d",
|
||||
"server_waf@log_update_waf_settings": "修改Web %d 的WAF设置",
|
||||
"server_webp@log_update_cluster_webp_policy": "修改集群 %d 的WebP设置",
|
||||
"server_websocket@log_update_websocket_settings": "修改Web %d 的Websocket设置",
|
||||
@@ -647,6 +668,7 @@ func init() {
|
||||
"user@log_update_user_price_period": "修改计费周期为 %s",
|
||||
"user@log_update_user_price_type": "修改计费类型为 %s",
|
||||
"user@log_update_user_profile": "修改个人资料",
|
||||
"user@log_update_user_sms_settings": "修改用户短信设置",
|
||||
"user@log_verify_user": "审核用户:%d 结果:%s",
|
||||
"user_access_key@log_create_user_access_key": "创建AccessKey %d",
|
||||
"user_access_key@log_delete_user_access_key": "删除AccessKey %d",
|
||||
|
||||
4
pkg/langs/protos/README.md
Normal file
4
pkg/langs/protos/README.md
Normal file
@@ -0,0 +1,4 @@
|
||||
After changing the messages, remember to run 'langs generate' to generate Go codes:
|
||||
~~~bash
|
||||
go run cmd/langs/main.go generate
|
||||
~~~
|
||||
19
pkg/langs/protos/en-us/admin_common.json
Normal file
19
pkg/langs/protos/en-us/admin_common.json
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"menu_setting_basic": "Basic Settings",
|
||||
"menu_setting_dns": "DNS Settings",
|
||||
"menu_setting_health_check": "Health Check",
|
||||
"menu_setting_cache_policy": "Cache Policy",
|
||||
"menu_setting_waf_policy": "WAF Policy",
|
||||
"menu_setting_webp": "WebP",
|
||||
"menu_setting_webp_policy": "WebP Policy",
|
||||
"menu_setting_metrics": "Metrics",
|
||||
"menu_setting_ddos_protection": "DDoS Protection",
|
||||
"menu_setting_security_policy": "Networking Security",
|
||||
"menu_setting_cache": "Cache Settings",
|
||||
|
||||
"system": "System",
|
||||
"canceled": "Canceled",
|
||||
|
||||
"server_error": "There is a internal error, please report to administrator.",
|
||||
"log_system_error": "system error: %s"
|
||||
}
|
||||
9
pkg/langs/protos/en-us/admin_dashboard.json
Normal file
9
pkg/langs/protos/en-us/admin_dashboard.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ui_overview": "Overview",
|
||||
"ui_waf": "WAF",
|
||||
"ui_dns": "DNS",
|
||||
"ui_user": "Users",
|
||||
"ui_events": "Events",
|
||||
|
||||
"disk_usage_warning": "当前服务器磁盘空间不足,请立即扩充容量,文件路径:%s,已使用:%dG,已使用比例:%.2f%%,仅剩余空间:%.2f%%。<br/>如果是因为本机数据库数据过多,你可以:<a href=\"/settings/database/clean\">[清理访问日志]</a> <a href=\"${lang.system@home_page}/docs/APINode/QA.md\" target=\"_blank\">[调整数据库binlog设置]</a>"
|
||||
}
|
||||
74
pkg/langs/protos/en-us/admin_menu.json
Normal file
74
pkg/langs/protos/en-us/admin_menu.json
Normal file
@@ -0,0 +1,74 @@
|
||||
{
|
||||
"dashboard": "Dashboard",
|
||||
"servers": "Sites",
|
||||
"server_access_logs": "Access Logs",
|
||||
"server_groups": "Site Groups",
|
||||
"server_certs": "Certificates",
|
||||
"server_traffic_stats": "Traffic Statistics",
|
||||
"server_cache_policies": "Cache Policies",
|
||||
"server_purge_fetch_caches": "Cache Management",
|
||||
"server_waf_policies": "WAF Policies",
|
||||
"server_ip_lists": "IP List",
|
||||
"server_access_log_policies": "Access Log Policies",
|
||||
"server_metrics": "Metrics",
|
||||
"server_scripts": "Script Libraries",
|
||||
"user_scripts": "User Scripts",
|
||||
"server_global_settings": "Global Settings",
|
||||
|
||||
"nodes": "Edge Nodes",
|
||||
"node_clusters": "Clusters",
|
||||
"node_logs": "Node Logs",
|
||||
"node_ip_list": "Node IPs",
|
||||
"node_regions": "Regions",
|
||||
"node_ssh_grants": "SSH Grants",
|
||||
"node_distributed_monitors": "Distributed Monitors",
|
||||
"node_anti_ddos_products": "Anti-DDoS Product",
|
||||
|
||||
"dns": "DNS Service",
|
||||
"dns_clusters": "Clusters",
|
||||
"dns_providers": "DNS Providers",
|
||||
"dns_issues": "Issues",
|
||||
|
||||
"ns": "Edge DNS",
|
||||
"ns_domains": "Domains",
|
||||
"ns_domain_groups": "Domain Groups",
|
||||
"ns_domain_batch_operations": "Batch",
|
||||
"ns_clusters": "Clusters",
|
||||
"ns_routes": "Routes",
|
||||
"ns_settings": "Settings",
|
||||
"ns_user_plans": "User Plans",
|
||||
"ns_plans": "Plans",
|
||||
"ns_access_logs": "Access Logs",
|
||||
"ns_node_logs": "Node Logs",
|
||||
"ns_resolve_test": "Testing",
|
||||
|
||||
"users": "Users",
|
||||
"user_list": "Users",
|
||||
"user_settings": "User Settings",
|
||||
|
||||
"finance": "Finance",
|
||||
"finance_bills": "Bills",
|
||||
"finance_accounts": "Accounts",
|
||||
"finance_logs": "Logs",
|
||||
"finance_orders": "Orders",
|
||||
"finance_income": "Reports",
|
||||
"finance_fee": "Fee Settings",
|
||||
"finance_packages": "Traffic Packages",
|
||||
|
||||
"plans": "Plans",
|
||||
"plan_list": "Plans",
|
||||
"plan_user_plans": "User Plans",
|
||||
|
||||
"tickets": "Tickets",
|
||||
"ticket_category": "Categories",
|
||||
|
||||
"admins": "System Users",
|
||||
"admin_recipients": "Notification Medias",
|
||||
|
||||
"logs": "Audit Logs",
|
||||
|
||||
"settings": "Settings",
|
||||
"setting_basic_settings": "Basic Settings",
|
||||
"setting_advanced_settings": "Advanced Settings",
|
||||
"setting_authority": "Commercial Authority"
|
||||
}
|
||||
20
pkg/langs/protos/en-us/admin_setting.json
Normal file
20
pkg/langs/protos/en-us/admin_setting.json
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"tab_admin_server": "Admin Server Settings",
|
||||
"tab_admin_ui": "Admin System UI",
|
||||
"tab_user_ui": "User System UI",
|
||||
"tab_admin_security_settings": "Security Settings",
|
||||
"tab_updates": "Updates",
|
||||
"tab_profile": "My Profile",
|
||||
"tab_login": "My Login",
|
||||
"tab_database": "Database",
|
||||
"tab_api_nodes": "API Nodes",
|
||||
"tab_user_nodes": "User Nodes",
|
||||
"tab_monitor_nodes": "Monitor Nodes", // deprecated
|
||||
"tab_ip_library": "IP Library",
|
||||
"tab_client_operation_systems": "OS Management",
|
||||
"tab_client_browsers": "Browser Management",
|
||||
"tab_authority": "Commercial Authority",
|
||||
"tab_access_log_databases": "Log Databases",
|
||||
"tab_transfer": "Transfer",
|
||||
"tab_backup": "Backup"
|
||||
}
|
||||
27
pkg/langs/protos/en-us/node_cluster_menu.json
Normal file
27
pkg/langs/protos/en-us/node_cluster_menu.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"setting_basic": "${lang.admin_common@menu_setting_basic}",
|
||||
"setting_dns": "${lang.admin_common@menu_setting_dns}",
|
||||
"setting_health_check": "${lang.admin_common@menu_setting_health_check}",
|
||||
"setting_service_global": "Site Settings",
|
||||
"setting_cache_policy": "${lang.admin_common@menu_setting_cache_policy}",
|
||||
"setting_waf_policy": "${lang.admin_common@menu_setting_waf_policy}",
|
||||
"setting_waf_actions": "WAF Actions",
|
||||
"setting_webp": "${lang.admin_common@menu_setting_webp_policy}",
|
||||
"setting_metrics": "${lang.admin_common@menu_setting_metrics}",
|
||||
"setting_ddos_protection": "${lang.admin_common@menu_setting_ddos_protection}",
|
||||
"setting_security_policy": "${lang.admin_common@menu_setting_security_policy}",
|
||||
"setting_uam": "UAM Policy",
|
||||
"setting_cc": "CC Policy",
|
||||
"setting_pages": "Pages",
|
||||
"setting_http3": "HTTP/3",
|
||||
"setting_schedule": "Scheduling",
|
||||
"setting_thresholds": "Thresholds",
|
||||
"setting_notification": "Notifications",
|
||||
"setting_system_service": "System Service",
|
||||
"setting_toa": "TOA",
|
||||
|
||||
"tab_cluster_dashboard": "Dashboard",
|
||||
"tab_cluster_nodes": "Nodes",
|
||||
"tab_cluster_settings": "Settings",
|
||||
"tab_cluster_delete": "Delete"
|
||||
}
|
||||
18
pkg/langs/protos/en-us/node_menu.json
Normal file
18
pkg/langs/protos/en-us/node_menu.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"create_single_node": "Create",
|
||||
"create_multiple_nodes": "Create Batch",
|
||||
"install_manually": "Manually",
|
||||
"install_auto_register": "Auto-Register",
|
||||
"install_remote": "Install Remotely(%d)", // Args: [Nodes Count]
|
||||
"install_remote_upgrade": "Upgrade Remotely(%d)", // Args: [Nodes Count]
|
||||
|
||||
"setting_basic": "${lang.admin_common@menu_setting_basic}",
|
||||
"setting_dns": "${lang.admin_common@menu_setting_dns}",
|
||||
"setting_cache": "${lang.admin_common@menu_setting_cache}",
|
||||
"setting_ddos_protection": "${lang.admin_common@menu_setting_ddos_protection}",
|
||||
"setting_ssh": "SSH",
|
||||
"setting_system": "System Settings",
|
||||
|
||||
"setting_schedule": "Scheduling",
|
||||
"setting_thresholds": "Thresholds"
|
||||
}
|
||||
88
pkg/langs/protos/en-us/server.json
Normal file
88
pkg/langs/protos/en-us/server.json
Normal file
@@ -0,0 +1,88 @@
|
||||
{
|
||||
"tab_dashboard": "Dashboard",
|
||||
"tab_stat": "Statistics",
|
||||
"tab_access_logs": "Access Logs",
|
||||
"tab_settings": "Settings",
|
||||
"tab_delete": "Delete",
|
||||
"tab_server_list": "Sites",
|
||||
|
||||
"menu_dashboard": "Dashboard",
|
||||
|
||||
"menu_accesslog_realtime": "Realtime",
|
||||
"menu_accesslog_today": "Today",
|
||||
"menu_accesslog_history": "History",
|
||||
|
||||
"menu_stat_traffic": "Traffic",
|
||||
"menu_stat_regions": "Regions",
|
||||
"menu_stat_providers": "Providers",
|
||||
"menu_stat_clients": "Clients",
|
||||
"menu_stat_waf": "WAF",
|
||||
|
||||
"menu_setting_basic": "Basic Settings",
|
||||
"menu_setting_dns": "DNS",
|
||||
"menu_setting_domains": "Server Names",
|
||||
"menu_setting_http": "HTTP",
|
||||
"menu_setting_https": "HTTPS",
|
||||
"menu_setting_origins": "Origin Sites",
|
||||
"menu_setting_redirects": "URL Redirections",
|
||||
"menu_setting_locations": "Locations",
|
||||
"menu_setting_rewrite_rules": "Rewrite Rules",
|
||||
"menu_setting_waf": "WAF",
|
||||
"menu_setting_cache": "Cache",
|
||||
"menu_setting_auth": "Access Control",
|
||||
"menu_setting_referers": "Referers",
|
||||
"menu_setting_user_agents": "UA List",
|
||||
"menu_setting_charset": "Charset",
|
||||
"menu_setting_access_log": "Access Log",
|
||||
"menu_setting_stat": "Statistics",
|
||||
"menu_setting_compression": "Compressions",
|
||||
"menu_setting_optimization": "Content Optimizations",
|
||||
"menu_setting_pages": "Pages",
|
||||
"menu_setting_http_headers": "HTTP Headers",
|
||||
"menu_setting_websocket": "Websocket",
|
||||
"menu_setting_webp": "WebP",
|
||||
"menu_setting_root": "Static Files",
|
||||
"menu_setting_fastcgi": "Fastcgi",
|
||||
"menu_setting_client_ip": "Client IP",
|
||||
"menu_setting_request_limit": "Request Limit",
|
||||
"menu_setting_others": "Others",
|
||||
"menu_setting_tcp": "TCP",
|
||||
"menu_setting_tls": "TLS",
|
||||
"menu_setting_udp": "UDP",
|
||||
"menu_setting_delete": "Delete",
|
||||
"menu_setting_http_proxy": "HTTP Reverse Proxy", // in site groups
|
||||
"menu_setting_tcp_proxy": "TCP Reverse Proxy", // in site groups
|
||||
"menu_setting_udp_proxy": "UDP Reverse Proxy", // in site groups
|
||||
"menu_setting_plan": "Plan",
|
||||
"menu_setting_group": "Group",
|
||||
"menu_setting_multimedia": "Audios & Videos",
|
||||
|
||||
"menu_setting_uam": "UAM",
|
||||
"menu_setting_cc": "CC Protection",
|
||||
"menu_setting_traffic_limit": "Traffic Limit",
|
||||
"menu_setting_scripts": "Scripts",
|
||||
|
||||
"copy_setting_current_group": "Current Group: %s",
|
||||
"copy_setting_current_user": "Current User: %s",
|
||||
"copy_setting_current_cluster": "Current Cluster: %s",
|
||||
"copy_setting_select_group": "Select Group",
|
||||
"copy_setting_select_user": "Select User",
|
||||
"copy_setting_select_cluster": "Select Cluster",
|
||||
"copy_setting_select_server": "Select Site",
|
||||
|
||||
"server_names_log_update_server_names": "修改网站 %d 域名",
|
||||
|
||||
"log_update_global_settings": "保存网站全局配置",
|
||||
"log_create_server": "创建网站 %d",
|
||||
"log_delete_server": "删除网站 %d",
|
||||
"log_update_server_basic": "修改网站 %d 基本信息",
|
||||
|
||||
"log_copy_server_configs": "从网站 %d 中同步配置 %s",
|
||||
|
||||
"log_submit_auditing_server": "提交网站 %d 域名审核",
|
||||
"log_update_server_groups": "修改网站 %d 所属分组",
|
||||
"log_enable_server": "启用网站 %d",
|
||||
"log_disable_server": "停用网站 %d",
|
||||
"log_update_server_name": "修改网站 %d 名称",
|
||||
"log_update_server_is_on":"修改网站 %d 启用状态"
|
||||
}
|
||||
3
pkg/langs/protos/en-us/system.json
Normal file
3
pkg/langs/protos/en-us/system.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"home_page": "https://goedge.cn"
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
After change the messages, remember to run 'langs generate' to generate Go codes.
|
||||
@@ -5,8 +5,10 @@
|
||||
"menu_setting_cache_policy": "缓存策略",
|
||||
"menu_setting_waf_policy": "WAF策略",
|
||||
"menu_setting_webp": "WebP",
|
||||
"menu_setting_webp_policy": "WebP策略",
|
||||
"menu_setting_metrics": "统计指标",
|
||||
"menu_setting_ddos_protection": "DDoS防护",
|
||||
"menu_setting_security_policy": "网络安全",
|
||||
"menu_setting_cache": "缓存设置",
|
||||
|
||||
"system": "系统",
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
"server_access_log_policies": "日志策略",
|
||||
"server_metrics": "统计指标",
|
||||
"server_scripts": "脚本库",
|
||||
"user_scripts": "用户脚本",
|
||||
"server_global_settings": "通用设置",
|
||||
|
||||
"nodes": "边缘节点",
|
||||
@@ -42,6 +43,7 @@
|
||||
"ns_resolve_test": "解析测试",
|
||||
|
||||
"users": "平台用户",
|
||||
"user_list": "用户列表",
|
||||
"user_settings": "用户设置",
|
||||
|
||||
"finance": "财务管理",
|
||||
@@ -54,6 +56,7 @@
|
||||
"finance_packages": "流量包",
|
||||
|
||||
"plans": "套餐管理",
|
||||
"plan_list": "套餐列表",
|
||||
"plan_user_plans": "已购套餐",
|
||||
|
||||
"tickets": "工单系统",
|
||||
|
||||
3
pkg/langs/protos/zh-cn/admin_user_ui.json
Normal file
3
pkg/langs/protos/zh-cn/admin_user_ui.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"log_update_ui_settings": "修改用户界面设置"
|
||||
}
|
||||
4
pkg/langs/protos/zh-cn/message_receiver.json
Normal file
4
pkg/langs/protos/zh-cn/message_receiver.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"log_update_cluster_message_receivers": "修改集群 %d 消息接收人",
|
||||
"log_delete_receiver": "删除接收人关联关系 %d"
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"log_update_cluster_message_receivers": "修改集群 %d 消息接收人"
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"log_delete_message_task": "删除消息发送任务 %d",
|
||||
"log_create_testing_message_task": "创建媒介测试任务 %d"
|
||||
"log_create_testing_message_task": "创建媒介测试任务 %d",
|
||||
"log_update_message_task_status": "修改消息任务 %d 状态为 %d"
|
||||
}
|
||||
@@ -11,5 +11,7 @@
|
||||
"log_update_node": "修改节点 %d 基本信息",
|
||||
"log_update_node_installation_status": "修改节点安装状态 %d",
|
||||
"log_up_node": "手动上线节点 %d",
|
||||
"log_update_node_on": "启用节点 %d",
|
||||
"log_update_node_off": "停用节点 %d",
|
||||
"log_delete_node_from_cluster": "从集群 %d 中删除节点 %d"
|
||||
}
|
||||
@@ -6,9 +6,10 @@
|
||||
"setting_cache_policy": "${lang.admin_common@menu_setting_cache_policy}",
|
||||
"setting_waf_policy": "${lang.admin_common@menu_setting_waf_policy}",
|
||||
"setting_waf_actions": "WAF动作",
|
||||
"setting_webp": "${lang.admin_common@menu_setting_webp}",
|
||||
"setting_webp": "${lang.admin_common@menu_setting_webp_policy}",
|
||||
"setting_metrics": "${lang.admin_common@menu_setting_metrics}",
|
||||
"setting_ddos_protection": "${lang.admin_common@menu_setting_ddos_protection}",
|
||||
"setting_security_policy": "${lang.admin_common@menu_setting_security_policy}",
|
||||
"setting_uam": "5秒盾",
|
||||
"setting_cc": "CC防护",
|
||||
"setting_pages": "自定义页面",
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"install_manually": "手动安装",
|
||||
"install_auto_register": "自动注册",
|
||||
"install_remote": "远程安装(%d)", // 参数:节点数量
|
||||
"install_remote_upgrade": "远程升级(%d)", // 参数:节点数量,
|
||||
"install_remote_upgrade": "远程升级(%d)", // 参数:节点数量
|
||||
|
||||
"setting_basic": "${lang.admin_common@menu_setting_basic}",
|
||||
"setting_dns": "${lang.admin_common@menu_setting_dns}",
|
||||
|
||||
8
pkg/langs/protos/zh-cn/post.json
Normal file
8
pkg/langs/protos/zh-cn/post.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"product_global": "全站",
|
||||
|
||||
"log_create_post": "创建文章 %d",
|
||||
"log_publish_post": "发布文章 %d",
|
||||
"log_delete_post": "删除文章 %d",
|
||||
"log_update_post": "修改文章 %d"
|
||||
}
|
||||
@@ -48,7 +48,6 @@
|
||||
"menu_setting_others": "其他设置",
|
||||
"menu_setting_tcp": "TCP",
|
||||
"menu_setting_tls": "TLS",
|
||||
"menu_setting_unix": "Unix",
|
||||
"menu_setting_udp": "UDP",
|
||||
"menu_setting_delete": "删除",
|
||||
"menu_setting_http_proxy": "HTTP代理", // 网站分组中使用
|
||||
@@ -56,6 +55,7 @@
|
||||
"menu_setting_udp_proxy": "UDP代理", // 网站分组中使用
|
||||
"menu_setting_plan": "套餐",
|
||||
"menu_setting_group": "分组",
|
||||
"menu_setting_multimedia": "音视频设置",
|
||||
|
||||
"menu_setting_uam": "5秒盾",
|
||||
"menu_setting_cc": "CC防护",
|
||||
@@ -83,6 +83,7 @@
|
||||
"log_update_server_groups": "修改网站 %d 所属分组",
|
||||
"log_enable_server": "启用网站 %d",
|
||||
"log_disable_server": "停用网站 %d",
|
||||
"log_update_server_name": "修改网站名称",
|
||||
"log_update_server_is_on":"修改网站 %d 启用状态"
|
||||
"log_update_server_name": "修改网站 %d 名称",
|
||||
"log_update_server_is_on":"修改网站 %d 启用状态",
|
||||
"log_delete_servers": "批量删除网站"
|
||||
}
|
||||
3
pkg/langs/protos/zh-cn/server_hls.json
Normal file
3
pkg/langs/protos/zh-cn/server_hls.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"log_update_hls": "修改Web %d 的HLS设置"
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"log_create_origin": "创建源站 %d",
|
||||
"log_delete_origin": "删除源站 %d",
|
||||
"log_update_origin": "修改源站 %d"
|
||||
"log_update_origin": "修改源站 %d",
|
||||
"log_update_origin_is_on": "修改源站 %d 启用状态"
|
||||
}
|
||||
4
pkg/langs/protos/zh-cn/server_user_script.json
Normal file
4
pkg/langs/protos/zh-cn/server_user_script.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"log_pass_user_script": "通过用户脚本 %d",
|
||||
"log_reject_user_script": "驳回用户脚本 %d"
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"log_update_user_email_settings": "修改用户邮件设置",
|
||||
"log_update_user_sms_settings": "修改用户短信设置",
|
||||
"log_update_user_global_settings": "修改用户设置",
|
||||
"log_create_user": "创建用户 %d",
|
||||
"log_delete_user": "删除用户 %d",
|
||||
|
||||
@@ -8,11 +8,15 @@ func init() {
|
||||
_ = DefaultWebPImagePolicy.Init()
|
||||
}
|
||||
|
||||
var DefaultWebPImagePolicy = &WebPImagePolicy{
|
||||
IsOn: true,
|
||||
RequireCache: true,
|
||||
MinLength: shared.NewSizeCapacity(0, shared.SizeCapacityUnitKB),
|
||||
MaxLength: shared.NewSizeCapacity(128, shared.SizeCapacityUnitMB),
|
||||
var DefaultWebPImagePolicy = NewWebPImagePolicy()
|
||||
|
||||
func NewWebPImagePolicy() *WebPImagePolicy {
|
||||
return &WebPImagePolicy{
|
||||
IsOn: true,
|
||||
RequireCache: true,
|
||||
MinLength: shared.NewSizeCapacity(0, shared.SizeCapacityUnitKB),
|
||||
MaxLength: shared.NewSizeCapacity(128, shared.SizeCapacityUnitMB),
|
||||
}
|
||||
}
|
||||
|
||||
// WebPImagePolicy WebP策略
|
||||
@@ -21,6 +25,7 @@ type WebPImagePolicy struct {
|
||||
RequireCache bool `yaml:"requireCache" json:"requireCache"` // 需要在缓存条件下进行
|
||||
MinLength *shared.SizeCapacity `yaml:"minLength" json:"minLength"` // 最小压缩对象比如4m, 24k
|
||||
MaxLength *shared.SizeCapacity `yaml:"maxLength" json:"maxLength"` // 最大压缩对象
|
||||
Quality int `yaml:"quality" json:"quality"` // 生成的图片质量:0-100
|
||||
|
||||
minLength int64
|
||||
maxLength int64
|
||||
|
||||
49
pkg/nodeconfigs/networking_security_policy.go
Normal file
49
pkg/nodeconfigs/networking_security_policy.go
Normal file
@@ -0,0 +1,49 @@
|
||||
// Copyright 2023 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
|
||||
package nodeconfigs
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
)
|
||||
|
||||
type NetworkSecurityStatus = string
|
||||
|
||||
const (
|
||||
NetworkSecurityStatusAuto NetworkSecurityStatus = "auto"
|
||||
NetworkSecurityStatusOn NetworkSecurityStatus = "on"
|
||||
NetworkSecurityStatusOff NetworkSecurityStatus = "off"
|
||||
)
|
||||
|
||||
// NetworkSecurityPolicy 节点网络安全策略
|
||||
type NetworkSecurityPolicy struct {
|
||||
Status NetworkSecurityStatus `json:"status"` // 启用状态
|
||||
|
||||
TCP struct{} `json:"tcp"` // TODO
|
||||
UDP struct{} `json:"udp"` // TODO
|
||||
ICMP struct{} `json:"icmp"` // TODO
|
||||
}
|
||||
|
||||
func NewNetworkSecurityPolicy() *NetworkSecurityPolicy {
|
||||
var policy = &NetworkSecurityPolicy{}
|
||||
policy.Status = NetworkSecurityStatusAuto
|
||||
return policy
|
||||
}
|
||||
|
||||
func (this *NetworkSecurityPolicy) Init() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (this *NetworkSecurityPolicy) AsJSON() ([]byte, error) {
|
||||
return json.Marshal(this)
|
||||
}
|
||||
|
||||
func (this *NetworkSecurityPolicy) IsOn() bool {
|
||||
return this.Status != NetworkSecurityStatusOff
|
||||
}
|
||||
|
||||
func (this *NetworkSecurityPolicy) IsSame(anotherPolicy *NetworkSecurityPolicy) bool {
|
||||
data1, _ := json.Marshal(this)
|
||||
data2, _ := json.Marshal(anotherPolicy)
|
||||
return bytes.Equal(data1, data2)
|
||||
}
|
||||
@@ -28,6 +28,8 @@ var uamPolicyLocker = &sync.RWMutex{}
|
||||
var httpCCPolicyLocker = &sync.RWMutex{}
|
||||
var http3PolicyLocker = &sync.RWMutex{}
|
||||
var httpPagesPolicyLocker = &sync.RWMutex{}
|
||||
var webPPolicyLocker = &sync.RWMutex{}
|
||||
var plansLocker = &sync.RWMutex{}
|
||||
|
||||
type ServerError struct {
|
||||
Id int64
|
||||
@@ -74,7 +76,6 @@ type NodeConfig struct {
|
||||
ParentNodes map[int64][]*ParentNodeConfig `yaml:"parentNodes" json:"parentNodes"` // clusterId => []*ParentNodeConfig
|
||||
|
||||
// 全局配置
|
||||
GlobalConfig *serverconfigs.GlobalConfig `yaml:"globalConfig" json:"globalConfig"` // 全局配置
|
||||
GlobalServerConfig *serverconfigs.GlobalServerConfig `yaml:"globalServerConfig" json:"globalServerConfig"` // 服务全局配置,用来替代 GlobalConfig
|
||||
ProductConfig *ProductConfig `yaml:"productConfig" json:"productConfig"`
|
||||
|
||||
@@ -88,25 +89,32 @@ type NodeConfig struct {
|
||||
AutoOpenPorts bool `yaml:"autoOpenPorts" json:"autoOpenPorts"` // 自动开放所需端口
|
||||
Clock *ClockConfig `yaml:"clock" json:"clock"` // 时钟配置
|
||||
AutoInstallNftables bool `yaml:"autoInstallNftables" json:"autoInstallNftables"` // 自动安装nftables
|
||||
AutoSystemTuning bool `yaml:"autoSystemTuning" json:"autoSystemTuning"` // 自动调整系统参数
|
||||
AutoTrimDisks bool `yaml:"autoTrimDisks" json:"autoTrimDisks"` // 自动执行TRIM
|
||||
|
||||
// 指标
|
||||
MetricItems []*serverconfigs.MetricItemConfig `yaml:"metricItems" json:"metricItems"`
|
||||
|
||||
// 自动白名单
|
||||
AllowedIPs []string `yaml:"allowedIPs" json:"allowedIPs"`
|
||||
IPAddresses []string `yaml:"ipAddresses" json:"ipAddresses"` // IP地址
|
||||
AllowedIPs []string `yaml:"allowedIPs" json:"allowedIPs"` // 自动IP白名单
|
||||
|
||||
// 脚本
|
||||
CommonScripts []*serverconfigs.CommonScript `yaml:"commonScripts" json:"commonScripts"`
|
||||
|
||||
WebPImagePolicies map[int64]*WebPImagePolicy `yaml:"webpImagePolicies" json:"webpImagePolicies"` // WebP相关配置,clusterId => *WebPImagePolicy
|
||||
UAMPolicies map[int64]*UAMPolicy `yaml:"uamPolicies" json:"uamPolicies"` // UAM相关配置,clusterId => *UAMPolicy
|
||||
HTTPCCPolicies map[int64]*HTTPCCPolicy `yaml:"httpCCPolicies" json:"httpCCPolicies"` // CC相关配置, clusterId => *HTTPCCPolicy
|
||||
HTTP3Policies map[int64]*HTTP3Policy `yaml:"http3Policies" json:"http3Policies"` // HTTP3相关配置, clusterId => *HTTP3Policy
|
||||
HTTPPagesPolicies map[int64]*HTTPPagesPolicy `yaml:"httpPagesPolicies" json:"httpPagesPolicies"` // 自定义页面,clusterId => *HTTPPagesPolicy
|
||||
WebPImagePolicies map[int64]*WebPImagePolicy `yaml:"webpImagePolicies" json:"webpImagePolicies"` // WebP相关配置,clusterId => *WebPImagePolicy
|
||||
UAMPolicies map[int64]*UAMPolicy `yaml:"uamPolicies" json:"uamPolicies"` // UAM相关配置,clusterId => *UAMPolicy
|
||||
HTTPCCPolicies map[int64]*HTTPCCPolicy `yaml:"httpCCPolicies" json:"httpCCPolicies"` // CC相关配置, clusterId => *HTTPCCPolicy
|
||||
HTTP3Policies map[int64]*HTTP3Policy `yaml:"http3Policies" json:"http3Policies"` // HTTP3相关配置, clusterId => *HTTP3Policy
|
||||
HTTPPagesPolicies map[int64]*HTTPPagesPolicy `yaml:"httpPagesPolicies" json:"httpPagesPolicies"` // 自定义页面,clusterId => *HTTPPagesPolicy
|
||||
NetworkSecurityPolicy *NetworkSecurityPolicy `yaml:"networkSecurityPolicy" json:"networkSecurityPolicy"` // 网络安全策略
|
||||
Plans map[int64]*serverconfigs.PlanConfig `yaml:"plans" json:"plans"` // 套餐 plan id => *serverconfigs.PlanConfig
|
||||
|
||||
// DNS
|
||||
DNSResolver *DNSResolverConfig `yaml:"dnsResolver" json:"dnsResolver"`
|
||||
|
||||
// Cluster
|
||||
ClusterSecret string `yaml:"clusterSecret" json:"clusterSecret"`
|
||||
|
||||
paddedId string
|
||||
|
||||
// firewall
|
||||
@@ -209,6 +217,12 @@ func CloneNodeConfig(nodeConfig *NodeConfig) (*NodeConfig, error) {
|
||||
httpPagesPolicyLocker.RLock()
|
||||
defer httpPagesPolicyLocker.RUnlock()
|
||||
|
||||
webPPolicyLocker.RLock()
|
||||
defer webPPolicyLocker.RUnlock()
|
||||
|
||||
plansLocker.RLock()
|
||||
defer plansLocker.RUnlock()
|
||||
|
||||
var newConfigValue = reflect.Indirect(reflect.ValueOf(&NodeConfig{}))
|
||||
var oldValue = reflect.Indirect(reflect.ValueOf(nodeConfig))
|
||||
var valueType = oldValue.Type()
|
||||
@@ -263,14 +277,6 @@ func (this *NodeConfig) Init(ctx context.Context) (err error, serverErrors []*Se
|
||||
}
|
||||
}
|
||||
|
||||
// global config
|
||||
if this.GlobalConfig != nil {
|
||||
err = this.GlobalConfig.Init()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// cache policy
|
||||
if len(this.HTTPCachePolicies) > 0 {
|
||||
for _, policy := range this.HTTPCachePolicies {
|
||||
@@ -383,14 +389,17 @@ func (this *NodeConfig) Init(ctx context.Context) (err error, serverErrors []*Se
|
||||
}
|
||||
|
||||
// webp image policy
|
||||
webPPolicyLocker.RLock()
|
||||
if this.WebPImagePolicies != nil {
|
||||
for _, policy := range this.WebPImagePolicies {
|
||||
err = policy.Init()
|
||||
if err != nil {
|
||||
webPPolicyLocker.RUnlock()
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
webPPolicyLocker.RUnlock()
|
||||
|
||||
// uam policy
|
||||
uamPolicyLocker.RLock()
|
||||
@@ -444,6 +453,19 @@ func (this *NodeConfig) Init(ctx context.Context) (err error, serverErrors []*Se
|
||||
}
|
||||
httpPagesPolicyLocker.RUnlock()
|
||||
|
||||
// plans
|
||||
plansLocker.RLock()
|
||||
if len(this.Plans) > 0 {
|
||||
for _, plan := range this.Plans {
|
||||
err = plan.Init()
|
||||
if err != nil {
|
||||
plansLocker.RUnlock()
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
plansLocker.RUnlock()
|
||||
|
||||
// dns resolver
|
||||
if this.DNSResolver != nil {
|
||||
err = this.DNSResolver.Init()
|
||||
@@ -463,13 +485,21 @@ func (this *NodeConfig) Init(ctx context.Context) (err error, serverErrors []*Se
|
||||
// api node addrs
|
||||
if len(this.APINodeAddrs) > 0 {
|
||||
for _, addr := range this.APINodeAddrs {
|
||||
err := addr.Init()
|
||||
err = addr.Init()
|
||||
if err != nil {
|
||||
return err, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// network security policy
|
||||
if this.NetworkSecurityPolicy != nil {
|
||||
err = this.NetworkSecurityPolicy.Init()
|
||||
if err != nil {
|
||||
return err, nil
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -598,9 +628,21 @@ func (this *NodeConfig) lookupWeb(server *serverconfigs.ServerConfig, web *serve
|
||||
if (web.FirewallPolicy.BlockOptions == nil || !web.FirewallPolicy.BlockOptions.IsPrior) && server.HTTPFirewallPolicy.BlockOptions != nil {
|
||||
web.FirewallPolicy.BlockOptions = server.HTTPFirewallPolicy.BlockOptions
|
||||
}
|
||||
if (web.FirewallPolicy.PageOptions == nil || !web.FirewallPolicy.PageOptions.IsPrior) && server.HTTPFirewallPolicy.PageOptions != nil {
|
||||
web.FirewallPolicy.PageOptions = server.HTTPFirewallPolicy.PageOptions
|
||||
}
|
||||
if (web.FirewallPolicy.CaptchaOptions == nil || !web.FirewallPolicy.CaptchaOptions.IsPrior) && server.HTTPFirewallPolicy.CaptchaOptions != nil {
|
||||
web.FirewallPolicy.CaptchaOptions = server.HTTPFirewallPolicy.CaptchaOptions
|
||||
}
|
||||
if (web.FirewallPolicy.Get302Options == nil || !web.FirewallPolicy.Get302Options.IsPrior) && server.HTTPFirewallPolicy.Get302Options != nil {
|
||||
web.FirewallPolicy.Get302Options = server.HTTPFirewallPolicy.Get302Options
|
||||
}
|
||||
if (web.FirewallPolicy.Post307Options == nil || !web.FirewallPolicy.Post307Options.IsPrior) && server.HTTPFirewallPolicy.Post307Options != nil {
|
||||
web.FirewallPolicy.Post307Options = server.HTTPFirewallPolicy.Post307Options
|
||||
}
|
||||
if (web.FirewallPolicy.JSCookieOptions == nil || !web.FirewallPolicy.JSCookieOptions.IsPrior) && server.HTTPFirewallPolicy.JSCookieOptions != nil {
|
||||
web.FirewallPolicy.JSCookieOptions = server.HTTPFirewallPolicy.JSCookieOptions
|
||||
}
|
||||
if (web.FirewallPolicy.SYNFlood == nil || !web.FirewallPolicy.SYNFlood.IsPrior) && server.HTTPFirewallPolicy.SYNFlood != nil {
|
||||
web.FirewallPolicy.SYNFlood = server.HTTPFirewallPolicy.SYNFlood
|
||||
}
|
||||
@@ -674,12 +716,22 @@ func (this *NodeConfig) UpdateCertOCSP(certId int64, ocsp []byte, expiresAt int6
|
||||
|
||||
// FindWebPImagePolicyWithClusterId 使用集群ID查找WebP策略
|
||||
func (this *NodeConfig) FindWebPImagePolicyWithClusterId(clusterId int64) *WebPImagePolicy {
|
||||
webPPolicyLocker.RLock()
|
||||
defer webPPolicyLocker.RUnlock()
|
||||
|
||||
if this.WebPImagePolicies == nil {
|
||||
return nil
|
||||
}
|
||||
return this.WebPImagePolicies[clusterId]
|
||||
}
|
||||
|
||||
// UpdateWebPImagePolicies 修改集群WebP策略
|
||||
func (this *NodeConfig) UpdateWebPImagePolicies(policies map[int64]*WebPImagePolicy) {
|
||||
webPPolicyLocker.Lock()
|
||||
defer webPPolicyLocker.Unlock()
|
||||
this.WebPImagePolicies = policies
|
||||
}
|
||||
|
||||
// FindUAMPolicyWithClusterId 使用集群ID查找UAM策略
|
||||
func (this *NodeConfig) FindUAMPolicyWithClusterId(clusterId int64) *UAMPolicy {
|
||||
uamPolicyLocker.RLock()
|
||||
@@ -766,6 +818,27 @@ func (this *NodeConfig) FindHTTPPagesPolicyWithClusterId(clusterId int64) *HTTPP
|
||||
return this.HTTPPagesPolicies[clusterId]
|
||||
}
|
||||
|
||||
// UpdatePlans 更新套餐
|
||||
func (this *NodeConfig) UpdatePlans(planMap map[int64]*serverconfigs.PlanConfig) {
|
||||
plansLocker.Lock()
|
||||
this.Plans = planMap
|
||||
plansLocker.Unlock()
|
||||
}
|
||||
|
||||
// FindAllPlans 查找所有套餐
|
||||
func (this *NodeConfig) FindAllPlans() map[int64]*serverconfigs.PlanConfig {
|
||||
plansLocker.RLock()
|
||||
defer plansLocker.RUnlock()
|
||||
return this.Plans
|
||||
}
|
||||
|
||||
// 查找单个套餐
|
||||
func (this *NodeConfig) FindPlan(planId int64) *serverconfigs.PlanConfig {
|
||||
plansLocker.RLock()
|
||||
defer plansLocker.RUnlock()
|
||||
return this.Plans[planId]
|
||||
}
|
||||
|
||||
// SecretHash 对Id和Secret的Hash计算
|
||||
func (this *NodeConfig) SecretHash() string {
|
||||
return this.secretHash
|
||||
@@ -774,4 +847,4 @@ func (this *NodeConfig) SecretHash() string {
|
||||
// HasConnTimeoutSettings 检查是否有连接超时设置
|
||||
func (this *NodeConfig) HasConnTimeoutSettings() bool {
|
||||
return this.GlobalServerConfig != nil && (this.GlobalServerConfig.Performance.AutoReadTimeout || this.GlobalServerConfig.Performance.AutoWriteTimeout)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ type NodeStatus struct {
|
||||
DiskMaxUsage float64 `json:"diskMaxUsage"`
|
||||
DiskMaxUsagePartition string `json:"diskMaxUsagePartition"`
|
||||
DiskTotal uint64 `json:"diskTotal"`
|
||||
DiskWritingSpeedMB int `json:"diskWritingSpeedMB"` // 硬盘写入速度
|
||||
UpdatedAt int64 `json:"updatedAt"`
|
||||
Timestamp int64 `json:"timestamp"` // 当前节点时间戳
|
||||
Load1m float64 `json:"load1m"`
|
||||
|
||||
@@ -23,6 +23,8 @@ const (
|
||||
NodeValueItemAttackRequests NodeValueItem = "attackRequests" // 攻击请求访问量
|
||||
NodeValueItemDisk NodeValueItem = "disk" // 磁盘
|
||||
NodeValueItemCacheDir NodeValueItem = "cacheDir" // 缓存目录
|
||||
|
||||
NodeValueItemNetworkPackets NodeValueItem = "networkPackets" // 网络数据包统计
|
||||
)
|
||||
|
||||
type nodeValueItemDefinition struct {
|
||||
@@ -36,6 +38,7 @@ type nodeValueItemParamDefinition struct {
|
||||
Code string `json:"code"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
IsPercent bool `json:"isPercent"` // 是否支持百分比
|
||||
}
|
||||
|
||||
var nodeValueItemDefinitions = []*nodeValueItemDefinition{
|
||||
@@ -46,7 +49,8 @@ var nodeValueItemDefinitions = []*nodeValueItemDefinition{
|
||||
{
|
||||
Code: "usage",
|
||||
Name: "使用比例",
|
||||
Description: "一个不超过1的小数",
|
||||
Description: "0到100之间的数字",
|
||||
IsPercent: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -57,7 +61,8 @@ var nodeValueItemDefinitions = []*nodeValueItemDefinition{
|
||||
{
|
||||
Code: "usage",
|
||||
Name: "使用比例",
|
||||
Description: "一个不超过1的小数",
|
||||
Description: "0到100之间的数字",
|
||||
IsPercent: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -68,24 +73,24 @@ var nodeValueItemDefinitions = []*nodeValueItemDefinition{
|
||||
{
|
||||
Code: "load1m",
|
||||
Name: "1分钟负载",
|
||||
Description: "1分钟内的负载",
|
||||
Description: "1分钟内的平均负载",
|
||||
},
|
||||
{
|
||||
Code: "load5m",
|
||||
Name: "5分钟负载",
|
||||
Description: "5分钟内的负载",
|
||||
Description: "5分钟内的平均负载",
|
||||
},
|
||||
{
|
||||
Code: "load15m",
|
||||
Name: "15分钟负载",
|
||||
Description: "15分钟内的负载",
|
||||
Description: "15分钟内的平均负载",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Code: NodeValueItemTrafficIn,
|
||||
Name: "上行流量",
|
||||
Description: "客户端发送到服务器端的流量。",
|
||||
Description: "平均每分钟客户端发送到服务器端的流量。",
|
||||
Params: []*nodeValueItemParamDefinition{
|
||||
{
|
||||
Code: "total",
|
||||
@@ -97,7 +102,7 @@ var nodeValueItemDefinitions = []*nodeValueItemDefinition{
|
||||
{
|
||||
Code: NodeValueItemTrafficOut,
|
||||
Name: "下行流量",
|
||||
Description: "服务器端发送到客户端的流量。",
|
||||
Description: "平均每分钟服务器端发送到客户端的流量。",
|
||||
Params: []*nodeValueItemParamDefinition{
|
||||
{
|
||||
Code: "total",
|
||||
@@ -107,8 +112,9 @@ var nodeValueItemDefinitions = []*nodeValueItemDefinition{
|
||||
},
|
||||
},
|
||||
{
|
||||
Code: NodeValueItemConnections,
|
||||
Name: "连接数",
|
||||
Code: NodeValueItemConnections,
|
||||
Name: "连接数",
|
||||
Description: "平均每分钟连接数",
|
||||
Params: []*nodeValueItemParamDefinition{
|
||||
{
|
||||
Code: "total",
|
||||
@@ -118,8 +124,9 @@ var nodeValueItemDefinitions = []*nodeValueItemDefinition{
|
||||
},
|
||||
},
|
||||
{
|
||||
Code: NodeValueItemRequests,
|
||||
Name: "请求数",
|
||||
Code: NodeValueItemRequests,
|
||||
Name: "请求数",
|
||||
Description: "平均每分钟请求数",
|
||||
Params: []*nodeValueItemParamDefinition{
|
||||
{
|
||||
Code: "total",
|
||||
@@ -129,8 +136,9 @@ var nodeValueItemDefinitions = []*nodeValueItemDefinition{
|
||||
},
|
||||
},
|
||||
{
|
||||
Code: NodeValueItemAttackRequests,
|
||||
Name: "攻击请求数",
|
||||
Code: NodeValueItemAttackRequests,
|
||||
Name: "攻击请求数",
|
||||
Description: "平均每分钟攻击请求数",
|
||||
Params: []*nodeValueItemParamDefinition{
|
||||
{
|
||||
Code: "total",
|
||||
@@ -146,7 +154,26 @@ var nodeValueItemDefinitions = []*nodeValueItemDefinition{
|
||||
{
|
||||
Code: "usage",
|
||||
Name: "使用比例",
|
||||
Description: "一个不超过1的小数",
|
||||
Description: "0到100之间的数字",
|
||||
IsPercent: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Code: NodeValueItemNetworkPackets,
|
||||
Name: "网络数据包",
|
||||
Params: []*nodeValueItemParamDefinition{
|
||||
{
|
||||
Code: "tcpInPPS",
|
||||
Name: "TCP入口包速率(pps)",
|
||||
},
|
||||
{
|
||||
Code: "udpInPPS",
|
||||
Name: "UDP入口包速率(pps)",
|
||||
},
|
||||
{
|
||||
Code: "icmpInPPS",
|
||||
Name: "ICMP入口包速率(pps)",
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -182,6 +209,21 @@ func FindNodeValueItemParamName(nodeCode NodeValueItem, paramCode string) string
|
||||
return ""
|
||||
}
|
||||
|
||||
// CheckNodeValueItemParamIsPercent 判断监控项某个参数是否支持百分比
|
||||
func CheckNodeValueItemParamIsPercent(nodeCode NodeValueItem, paramCode string) bool {
|
||||
for _, def := range nodeValueItemDefinitions {
|
||||
if def.Code == nodeCode {
|
||||
for _, p := range def.Params {
|
||||
if p.Code == paramCode {
|
||||
return p.IsPercent
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// NodeValueRange 值范围
|
||||
type NodeValueRange = string
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
"time"
|
||||
)
|
||||
@@ -26,7 +27,7 @@ func EncryptMap(nodeUniqueId string, nodeSecret string, data maps.Map, timeout i
|
||||
"data": data,
|
||||
})
|
||||
if err != nil {
|
||||
return "", errors.New("marshal data to json failed: " + err.Error())
|
||||
return "", fmt.Errorf("marshal data to json failed: %w", err)
|
||||
}
|
||||
|
||||
var method = &AES256CFBMethod{}
|
||||
@@ -52,7 +53,7 @@ func DecryptMap(nodeUniqueId string, nodeSecret string, encodedString string) (m
|
||||
|
||||
encodedData, err := base64.StdEncoding.DecodeString(encodedString)
|
||||
if err != nil {
|
||||
return nil, errors.New("base64 decode failed: " + err.Error())
|
||||
return nil, fmt.Errorf("base64 decode failed: %w", err)
|
||||
}
|
||||
|
||||
dataJSON, err := method.Decrypt(encodedData)
|
||||
@@ -63,7 +64,7 @@ func DecryptMap(nodeUniqueId string, nodeSecret string, encodedString string) (m
|
||||
var result = maps.Map{}
|
||||
err = json.Unmarshal(dataJSON, &result)
|
||||
if err != nil {
|
||||
return nil, errors.New("unmarshal data failed: " + err.Error())
|
||||
return nil, fmt.Errorf("unmarshal data failed: %w", err)
|
||||
}
|
||||
|
||||
var expiresAt = result.GetInt64("expiresAt")
|
||||
@@ -107,7 +108,7 @@ func DecryptData(nodeUniqueId string, nodeSecret string, encodedString string) (
|
||||
|
||||
encodedData, err := base64.StdEncoding.DecodeString(encodedString)
|
||||
if err != nil {
|
||||
return nil, errors.New("base64 decode failed: " + err.Error())
|
||||
return nil, fmt.Errorf("base64 decode failed: %w", err)
|
||||
}
|
||||
|
||||
return method.Decrypt(encodedData)
|
||||
|
||||
@@ -196,12 +196,14 @@ func (this *HTTPFirewallPolicyDAO) FindHTTPFirewallActionConfigs(ctx context.Con
|
||||
|
||||
switch action.Code {
|
||||
case firewallconfigs.HTTPFirewallActionRecordIP:
|
||||
listId := action.Options.GetInt64("ipListId")
|
||||
var listId = action.Options.GetInt64("ipListId")
|
||||
listResp, err := this.RPC().IPListRPC().FindEnabledIPList(ctx, &pb.FindEnabledIPListRequest{IpListId: listId})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if listResp.IpList != nil {
|
||||
if listId == 0 {
|
||||
action.Options["ipListName"] = "全局黑名单"
|
||||
} else if listResp.IpList != nil {
|
||||
action.Options["ipListName"] = listResp.IpList.Name
|
||||
} else {
|
||||
action.Options["ipListName"] = action.Options.GetString("ipListName") + "(已删除)"
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||
)
|
||||
|
||||
type SettingCode = string
|
||||
|
||||
const (
|
||||
SettingCodeServerGlobalConfig SettingCode = "serverGlobalConfig" // 服务相关全局设置
|
||||
SettingCodeNodeMonitor SettingCode = "nodeMonitor" // 监控节点状态
|
||||
SettingCodeClusterHealthCheck SettingCode = "clusterHealthCheck" // 集群健康检查
|
||||
SettingCodeIPListVersion SettingCode = "ipListVersion" // IP名单的版本号
|
||||
SettingCodeAdminSecurityConfig SettingCode = "adminSecurityConfig" // 管理员安全设置
|
||||
)
|
||||
|
||||
var SharedSysSettingDAO = new(SysSettingDAO)
|
||||
|
||||
type SysSettingDAO struct {
|
||||
BaseDAO
|
||||
}
|
||||
|
||||
// 读取服务全局配置
|
||||
func (this *SysSettingDAO) ReadGlobalConfig(ctx context.Context) (*serverconfigs.GlobalConfig, error) {
|
||||
globalConfigResp, err := this.RPC().SysSettingRPC().ReadSysSetting(ctx, &pb.ReadSysSettingRequest{Code: SettingCodeServerGlobalConfig})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(globalConfigResp.ValueJSON) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
globalConfig := &serverconfigs.GlobalConfig{}
|
||||
err = json.Unmarshal(globalConfigResp.ValueJSON, globalConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return globalConfig, nil
|
||||
}
|
||||
@@ -3,9 +3,10 @@
|
||||
package errors
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@@ -20,13 +21,13 @@ func HumanError(err error, endpoints []string, configFile string) (resultErr err
|
||||
}
|
||||
switch errStatus.Code() {
|
||||
case codes.InvalidArgument:
|
||||
return errors.New("错误的RPC参数:" + err.Error()), false
|
||||
return fmt.Errorf("错误的RPC参数:%w", err), false
|
||||
case codes.DeadlineExceeded:
|
||||
return errors.New("RPC操作超时,请重试:" + err.Error()), false
|
||||
return fmt.Errorf("RPC操作超时,请重试:%w", err), false
|
||||
case codes.Unimplemented:
|
||||
return errors.New("请求的RPC服务或方法不存在,可能是没有升级API节点或者当前节点没有升级:" + err.Error()), false
|
||||
return fmt.Errorf("请求的RPC服务或方法不存在,可能是没有升级API节点或者当前节点没有升级:%w", err), false
|
||||
case codes.Unavailable:
|
||||
return errors.New("RPC当前不可用:<br/>1、请确认当前节点的api.yaml(<em>" + configFile + "</em>)配置中的地址(<em>" + strings.Join(endpoints, ", ") + "</em>)是否已填写正确;<br/>2、请确保API节点已启动,并检查当前节点和API节点之间的网络连接是正常的。<hr/>错误信息:" + err.Error()), true
|
||||
return fmt.Errorf("RPC当前不可用:<br/>1、请确认当前节点的%s(<em>%s</em>)配置中的地址(<em>%s</em>)是否已填写正确;<br/>2、请确保API节点已启动,并检查当前节点和API节点之间的网络连接是正常的。<hr/>错误信息:%w", filepath.Base(configFile), configFile, strings.Join(endpoints, ", "), err), true
|
||||
}
|
||||
|
||||
return err, false
|
||||
|
||||
37
pkg/rpc/jsons/bit_size_capacity.md
Normal file
37
pkg/rpc/jsons/bit_size_capacity.md
Normal file
@@ -0,0 +1,37 @@
|
||||
# 比特位尺寸
|
||||
## 定义
|
||||
~~~json
|
||||
{
|
||||
"count": "数量",
|
||||
"unit": "单位"
|
||||
}
|
||||
~~~
|
||||
|
||||
其中:
|
||||
* `数量` - 必须是一个整数数字
|
||||
* `单位` - 有以下几个值:
|
||||
* `b` - 比特
|
||||
* `kb` - Kb
|
||||
* `mb` - Mb
|
||||
* `gb` - Gb
|
||||
* `tb` - Tb
|
||||
* `pb` - Pb
|
||||
* `eb` - Eb
|
||||
|
||||
## 示例
|
||||
100Mb:
|
||||
~~~
|
||||
{
|
||||
"count": 100,
|
||||
"unit": "mb"
|
||||
}
|
||||
~~~
|
||||
|
||||
|
||||
32Gb:
|
||||
~~~
|
||||
{
|
||||
"count": 32,
|
||||
"unit": "gb"
|
||||
}
|
||||
~~~
|
||||
@@ -11,11 +11,13 @@
|
||||
"purgeIsOn": "是否允许使用Purge方法清理",
|
||||
"purgeKey": "Purge时使用的X-Edge-Purge-Key",
|
||||
"stale": "陈旧缓存使用策略",
|
||||
"key": "主域名配置",
|
||||
"cacheRefs": ["缓存条件1", "缓存条件2", ...]
|
||||
}
|
||||
~~~
|
||||
其中:
|
||||
* `缓存条件` - 参考 {json:http_cache_ref}
|
||||
* `主域名配置` 参考本文“主域名”配置部分
|
||||
|
||||
## 示例
|
||||
### 无缓存条件
|
||||
@@ -90,3 +92,32 @@
|
||||
]
|
||||
}
|
||||
~~~
|
||||
|
||||
|
||||
## 主域名配置
|
||||
~~~json
|
||||
{
|
||||
"isOn": "true|false",
|
||||
"scheme": "https|http",
|
||||
"host": "域名,必须是当前网站已绑定的域名"
|
||||
}
|
||||
~~~
|
||||
|
||||
### 示例
|
||||
#### 不使用主域名
|
||||
~~~json
|
||||
{
|
||||
"isOn": false
|
||||
}
|
||||
~~~
|
||||
|
||||
#### 使用主域名
|
||||
~~~json
|
||||
{
|
||||
"isOn": true,
|
||||
"scheme": "https",
|
||||
"host": "example.com"
|
||||
}
|
||||
~~~
|
||||
|
||||
如果启用主域名,则缓存键值中的域名会被自动换成主域名,清理缓存的时候也需要使用此主域名。
|
||||
@@ -4,7 +4,9 @@
|
||||
{
|
||||
"isPrior": "是否覆盖上级配置",
|
||||
"isOn": "是否启用配置",
|
||||
"firewallPolicyId": "WAF策略ID"
|
||||
"firewallPolicyId": "WAF策略ID",
|
||||
"ignoreGlobalRules": "是否忽略系统定义的全局规则",
|
||||
"defaultCaptchaType": "默认人机识别方式,可以选none(不设置)、default(默认)、oneClick(单击验证)、slide(滑动解锁)、geetest(极验)"
|
||||
}
|
||||
~~~
|
||||
|
||||
@@ -13,6 +15,8 @@
|
||||
{
|
||||
"isPrior": true,
|
||||
"isOn": true,
|
||||
"firewallPolicyId": 123
|
||||
"firewallPolicyId": 123,
|
||||
"ignoreGlobalRules": false,
|
||||
"defaultCaptchaType": "none"
|
||||
}
|
||||
~~~
|
||||
37
pkg/rpc/jsons/size_capacity.md
Normal file
37
pkg/rpc/jsons/size_capacity.md
Normal file
@@ -0,0 +1,37 @@
|
||||
# 容量
|
||||
## 定义
|
||||
~~~json
|
||||
{
|
||||
"count": "数量",
|
||||
"unit": "单位"
|
||||
}
|
||||
~~~
|
||||
|
||||
其中:
|
||||
* `数量` - 必须是一个整数数字
|
||||
* `单位` - 有以下几个值:
|
||||
* `byte` - 字节
|
||||
* `kb` - KB
|
||||
* `mb` - MB
|
||||
* `gb` - GB
|
||||
* `tb` - TB
|
||||
* `pb` - PB
|
||||
* `eb` - EB
|
||||
|
||||
## 示例
|
||||
100MB:
|
||||
~~~
|
||||
{
|
||||
"count": 100,
|
||||
"unit": "mb"
|
||||
}
|
||||
~~~
|
||||
|
||||
|
||||
32GB:
|
||||
~~~
|
||||
{
|
||||
"count": 32,
|
||||
"unit": "gb"
|
||||
}
|
||||
~~~
|
||||
@@ -1,17 +1,12 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.25.0
|
||||
// protoc-gen-go v1.31.0
|
||||
// protoc v3.19.4
|
||||
// source: api_method_stat_service.proto
|
||||
|
||||
package pb
|
||||
|
||||
import (
|
||||
context "context"
|
||||
proto "github.com/golang/protobuf/proto"
|
||||
grpc "google.golang.org/grpc"
|
||||
codes "google.golang.org/grpc/codes"
|
||||
status "google.golang.org/grpc/status"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
@@ -25,10 +20,6 @@ const (
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
// This is a compile-time assertion that a sufficiently up-to-date version
|
||||
// of the legacy proto package is being used.
|
||||
const _ = proto.ProtoPackageIsVersion4
|
||||
|
||||
// 查找某天的统计
|
||||
type FindAPIMethodStatsWithDayRequest struct {
|
||||
state protoimpl.MessageState
|
||||
@@ -308,123 +299,3 @@ func file_api_method_stat_service_proto_init() {
|
||||
file_api_method_stat_service_proto_goTypes = nil
|
||||
file_api_method_stat_service_proto_depIdxs = nil
|
||||
}
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ context.Context
|
||||
var _ grpc.ClientConnInterface
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
const _ = grpc.SupportPackageIsVersion6
|
||||
|
||||
// APIMethodStatServiceClient is the client API for APIMethodStatService service.
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
|
||||
type APIMethodStatServiceClient interface {
|
||||
// 查找某天的统计
|
||||
FindAPIMethodStatsWithDay(ctx context.Context, in *FindAPIMethodStatsWithDayRequest, opts ...grpc.CallOption) (*FindAPIMethodStatsWithDayResponse, error)
|
||||
// 检查是否有统计数据
|
||||
CountAPIMethodStatsWithDay(ctx context.Context, in *CountAPIMethodStatsWithDayRequest, opts ...grpc.CallOption) (*RPCCountResponse, error)
|
||||
}
|
||||
|
||||
type aPIMethodStatServiceClient struct {
|
||||
cc grpc.ClientConnInterface
|
||||
}
|
||||
|
||||
func NewAPIMethodStatServiceClient(cc grpc.ClientConnInterface) APIMethodStatServiceClient {
|
||||
return &aPIMethodStatServiceClient{cc}
|
||||
}
|
||||
|
||||
func (c *aPIMethodStatServiceClient) FindAPIMethodStatsWithDay(ctx context.Context, in *FindAPIMethodStatsWithDayRequest, opts ...grpc.CallOption) (*FindAPIMethodStatsWithDayResponse, error) {
|
||||
out := new(FindAPIMethodStatsWithDayResponse)
|
||||
err := c.cc.Invoke(ctx, "/pb.APIMethodStatService/findAPIMethodStatsWithDay", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *aPIMethodStatServiceClient) CountAPIMethodStatsWithDay(ctx context.Context, in *CountAPIMethodStatsWithDayRequest, opts ...grpc.CallOption) (*RPCCountResponse, error) {
|
||||
out := new(RPCCountResponse)
|
||||
err := c.cc.Invoke(ctx, "/pb.APIMethodStatService/countAPIMethodStatsWithDay", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// APIMethodStatServiceServer is the server API for APIMethodStatService service.
|
||||
type APIMethodStatServiceServer interface {
|
||||
// 查找某天的统计
|
||||
FindAPIMethodStatsWithDay(context.Context, *FindAPIMethodStatsWithDayRequest) (*FindAPIMethodStatsWithDayResponse, error)
|
||||
// 检查是否有统计数据
|
||||
CountAPIMethodStatsWithDay(context.Context, *CountAPIMethodStatsWithDayRequest) (*RPCCountResponse, error)
|
||||
}
|
||||
|
||||
// UnimplementedAPIMethodStatServiceServer can be embedded to have forward compatible implementations.
|
||||
type UnimplementedAPIMethodStatServiceServer struct {
|
||||
}
|
||||
|
||||
func (*UnimplementedAPIMethodStatServiceServer) FindAPIMethodStatsWithDay(context.Context, *FindAPIMethodStatsWithDayRequest) (*FindAPIMethodStatsWithDayResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method FindAPIMethodStatsWithDay not implemented")
|
||||
}
|
||||
func (*UnimplementedAPIMethodStatServiceServer) CountAPIMethodStatsWithDay(context.Context, *CountAPIMethodStatsWithDayRequest) (*RPCCountResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method CountAPIMethodStatsWithDay not implemented")
|
||||
}
|
||||
|
||||
func RegisterAPIMethodStatServiceServer(s *grpc.Server, srv APIMethodStatServiceServer) {
|
||||
s.RegisterService(&_APIMethodStatService_serviceDesc, srv)
|
||||
}
|
||||
|
||||
func _APIMethodStatService_FindAPIMethodStatsWithDay_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(FindAPIMethodStatsWithDayRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(APIMethodStatServiceServer).FindAPIMethodStatsWithDay(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/pb.APIMethodStatService/FindAPIMethodStatsWithDay",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(APIMethodStatServiceServer).FindAPIMethodStatsWithDay(ctx, req.(*FindAPIMethodStatsWithDayRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _APIMethodStatService_CountAPIMethodStatsWithDay_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(CountAPIMethodStatsWithDayRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(APIMethodStatServiceServer).CountAPIMethodStatsWithDay(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/pb.APIMethodStatService/CountAPIMethodStatsWithDay",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(APIMethodStatServiceServer).CountAPIMethodStatsWithDay(ctx, req.(*CountAPIMethodStatsWithDayRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
var _APIMethodStatService_serviceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "pb.APIMethodStatService",
|
||||
HandlerType: (*APIMethodStatServiceServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "findAPIMethodStatsWithDay",
|
||||
Handler: _APIMethodStatService_FindAPIMethodStatsWithDay_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "countAPIMethodStatsWithDay",
|
||||
Handler: _APIMethodStatService_CountAPIMethodStatsWithDay_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "api_method_stat_service.proto",
|
||||
}
|
||||
|
||||
148
pkg/rpc/pb/api_method_stat_service_grpc.pb.go
Normal file
148
pkg/rpc/pb/api_method_stat_service_grpc.pb.go
Normal file
@@ -0,0 +1,148 @@
|
||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||
// versions:
|
||||
// - protoc-gen-go-grpc v1.3.0
|
||||
// - protoc v3.19.4
|
||||
// source: api_method_stat_service.proto
|
||||
|
||||
package pb
|
||||
|
||||
import (
|
||||
context "context"
|
||||
grpc "google.golang.org/grpc"
|
||||
codes "google.golang.org/grpc/codes"
|
||||
status "google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
// Requires gRPC-Go v1.32.0 or later.
|
||||
const _ = grpc.SupportPackageIsVersion7
|
||||
|
||||
const (
|
||||
APIMethodStatService_FindAPIMethodStatsWithDay_FullMethodName = "/pb.APIMethodStatService/findAPIMethodStatsWithDay"
|
||||
APIMethodStatService_CountAPIMethodStatsWithDay_FullMethodName = "/pb.APIMethodStatService/countAPIMethodStatsWithDay"
|
||||
)
|
||||
|
||||
// APIMethodStatServiceClient is the client API for APIMethodStatService service.
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
||||
type APIMethodStatServiceClient interface {
|
||||
// 查找某天的统计
|
||||
FindAPIMethodStatsWithDay(ctx context.Context, in *FindAPIMethodStatsWithDayRequest, opts ...grpc.CallOption) (*FindAPIMethodStatsWithDayResponse, error)
|
||||
// 检查是否有统计数据
|
||||
CountAPIMethodStatsWithDay(ctx context.Context, in *CountAPIMethodStatsWithDayRequest, opts ...grpc.CallOption) (*RPCCountResponse, error)
|
||||
}
|
||||
|
||||
type aPIMethodStatServiceClient struct {
|
||||
cc grpc.ClientConnInterface
|
||||
}
|
||||
|
||||
func NewAPIMethodStatServiceClient(cc grpc.ClientConnInterface) APIMethodStatServiceClient {
|
||||
return &aPIMethodStatServiceClient{cc}
|
||||
}
|
||||
|
||||
func (c *aPIMethodStatServiceClient) FindAPIMethodStatsWithDay(ctx context.Context, in *FindAPIMethodStatsWithDayRequest, opts ...grpc.CallOption) (*FindAPIMethodStatsWithDayResponse, error) {
|
||||
out := new(FindAPIMethodStatsWithDayResponse)
|
||||
err := c.cc.Invoke(ctx, APIMethodStatService_FindAPIMethodStatsWithDay_FullMethodName, in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *aPIMethodStatServiceClient) CountAPIMethodStatsWithDay(ctx context.Context, in *CountAPIMethodStatsWithDayRequest, opts ...grpc.CallOption) (*RPCCountResponse, error) {
|
||||
out := new(RPCCountResponse)
|
||||
err := c.cc.Invoke(ctx, APIMethodStatService_CountAPIMethodStatsWithDay_FullMethodName, in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// APIMethodStatServiceServer is the server API for APIMethodStatService service.
|
||||
// All implementations should embed UnimplementedAPIMethodStatServiceServer
|
||||
// for forward compatibility
|
||||
type APIMethodStatServiceServer interface {
|
||||
// 查找某天的统计
|
||||
FindAPIMethodStatsWithDay(context.Context, *FindAPIMethodStatsWithDayRequest) (*FindAPIMethodStatsWithDayResponse, error)
|
||||
// 检查是否有统计数据
|
||||
CountAPIMethodStatsWithDay(context.Context, *CountAPIMethodStatsWithDayRequest) (*RPCCountResponse, error)
|
||||
}
|
||||
|
||||
// UnimplementedAPIMethodStatServiceServer should be embedded to have forward compatible implementations.
|
||||
type UnimplementedAPIMethodStatServiceServer struct {
|
||||
}
|
||||
|
||||
func (UnimplementedAPIMethodStatServiceServer) FindAPIMethodStatsWithDay(context.Context, *FindAPIMethodStatsWithDayRequest) (*FindAPIMethodStatsWithDayResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method FindAPIMethodStatsWithDay not implemented")
|
||||
}
|
||||
func (UnimplementedAPIMethodStatServiceServer) CountAPIMethodStatsWithDay(context.Context, *CountAPIMethodStatsWithDayRequest) (*RPCCountResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method CountAPIMethodStatsWithDay not implemented")
|
||||
}
|
||||
|
||||
// UnsafeAPIMethodStatServiceServer may be embedded to opt out of forward compatibility for this service.
|
||||
// Use of this interface is not recommended, as added methods to APIMethodStatServiceServer will
|
||||
// result in compilation errors.
|
||||
type UnsafeAPIMethodStatServiceServer interface {
|
||||
mustEmbedUnimplementedAPIMethodStatServiceServer()
|
||||
}
|
||||
|
||||
func RegisterAPIMethodStatServiceServer(s grpc.ServiceRegistrar, srv APIMethodStatServiceServer) {
|
||||
s.RegisterService(&APIMethodStatService_ServiceDesc, srv)
|
||||
}
|
||||
|
||||
func _APIMethodStatService_FindAPIMethodStatsWithDay_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(FindAPIMethodStatsWithDayRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(APIMethodStatServiceServer).FindAPIMethodStatsWithDay(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: APIMethodStatService_FindAPIMethodStatsWithDay_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(APIMethodStatServiceServer).FindAPIMethodStatsWithDay(ctx, req.(*FindAPIMethodStatsWithDayRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _APIMethodStatService_CountAPIMethodStatsWithDay_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(CountAPIMethodStatsWithDayRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(APIMethodStatServiceServer).CountAPIMethodStatsWithDay(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: APIMethodStatService_CountAPIMethodStatsWithDay_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(APIMethodStatServiceServer).CountAPIMethodStatsWithDay(ctx, req.(*CountAPIMethodStatsWithDayRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
// APIMethodStatService_ServiceDesc is the grpc.ServiceDesc for APIMethodStatService service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
var APIMethodStatService_ServiceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "pb.APIMethodStatService",
|
||||
HandlerType: (*APIMethodStatServiceServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "findAPIMethodStatsWithDay",
|
||||
Handler: _APIMethodStatService_FindAPIMethodStatsWithDay_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "countAPIMethodStatsWithDay",
|
||||
Handler: _APIMethodStatService_CountAPIMethodStatsWithDay_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "api_method_stat_service.proto",
|
||||
}
|
||||
@@ -1,13 +1,12 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.25.0
|
||||
// protoc-gen-go v1.31.0
|
||||
// protoc v3.19.4
|
||||
// source: models/model_acme_provider.proto
|
||||
|
||||
package pb
|
||||
|
||||
import (
|
||||
proto "github.com/golang/protobuf/proto"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
@@ -21,10 +20,6 @@ const (
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
// This is a compile-time assertion that a sufficiently up-to-date version
|
||||
// of the legacy proto package is being used.
|
||||
const _ = proto.ProtoPackageIsVersion4
|
||||
|
||||
type ACMEProvider struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.25.0
|
||||
// protoc-gen-go v1.31.0
|
||||
// protoc v3.19.4
|
||||
// source: models/model_acme_provider_account.proto
|
||||
|
||||
package pb
|
||||
|
||||
import (
|
||||
proto "github.com/golang/protobuf/proto"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
@@ -21,10 +20,6 @@ const (
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
// This is a compile-time assertion that a sufficiently up-to-date version
|
||||
// of the legacy proto package is being used.
|
||||
const _ = proto.ProtoPackageIsVersion4
|
||||
|
||||
type ACMEProviderAccount struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.25.0
|
||||
// protoc-gen-go v1.31.0
|
||||
// protoc v3.19.4
|
||||
// source: models/model_acme_task.proto
|
||||
|
||||
package pb
|
||||
|
||||
import (
|
||||
proto "github.com/golang/protobuf/proto"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
@@ -21,10 +20,6 @@ const (
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
// This is a compile-time assertion that a sufficiently up-to-date version
|
||||
// of the legacy proto package is being used.
|
||||
const _ = proto.ProtoPackageIsVersion4
|
||||
|
||||
type ACMETask struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.25.0
|
||||
// protoc-gen-go v1.31.0
|
||||
// protoc v3.19.4
|
||||
// source: models/model_acme_task_log.proto
|
||||
|
||||
package pb
|
||||
|
||||
import (
|
||||
proto "github.com/golang/protobuf/proto"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
@@ -21,10 +20,6 @@ const (
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
// This is a compile-time assertion that a sufficiently up-to-date version
|
||||
// of the legacy proto package is being used.
|
||||
const _ = proto.ProtoPackageIsVersion4
|
||||
|
||||
// ACME任务日志
|
||||
type ACMETaskLog struct {
|
||||
state protoimpl.MessageState
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.25.0
|
||||
// protoc-gen-go v1.31.0
|
||||
// protoc v3.19.4
|
||||
// source: models/model_acme_user.proto
|
||||
|
||||
package pb
|
||||
|
||||
import (
|
||||
proto "github.com/golang/protobuf/proto"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
@@ -21,10 +20,6 @@ const (
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
// This is a compile-time assertion that a sufficiently up-to-date version
|
||||
// of the legacy proto package is being used.
|
||||
const _ = proto.ProtoPackageIsVersion4
|
||||
|
||||
type ACMEUser struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.25.0
|
||||
// protoc-gen-go v1.31.0
|
||||
// protoc v3.19.4
|
||||
// source: models/model_ad_network.proto
|
||||
|
||||
package pb
|
||||
|
||||
import (
|
||||
proto "github.com/golang/protobuf/proto"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
@@ -21,10 +20,6 @@ const (
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
// This is a compile-time assertion that a sufficiently up-to-date version
|
||||
// of the legacy proto package is being used.
|
||||
const _ = proto.ProtoPackageIsVersion4
|
||||
|
||||
// 高防线路
|
||||
type ADNetwork struct {
|
||||
state protoimpl.MessageState
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.25.0
|
||||
// protoc-gen-go v1.31.0
|
||||
// protoc v3.19.4
|
||||
// source: models/model_ad_package.proto
|
||||
|
||||
package pb
|
||||
|
||||
import (
|
||||
proto "github.com/golang/protobuf/proto"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
@@ -21,10 +20,6 @@ const (
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
// This is a compile-time assertion that a sufficiently up-to-date version
|
||||
// of the legacy proto package is being used.
|
||||
const _ = proto.ProtoPackageIsVersion4
|
||||
|
||||
// 高防产品
|
||||
type ADPackage struct {
|
||||
state protoimpl.MessageState
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.25.0
|
||||
// protoc-gen-go v1.31.0
|
||||
// protoc v3.19.4
|
||||
// source: models/model_ad_package_instance.proto
|
||||
|
||||
package pb
|
||||
|
||||
import (
|
||||
proto "github.com/golang/protobuf/proto"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
@@ -21,10 +20,6 @@ const (
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
// This is a compile-time assertion that a sufficiently up-to-date version
|
||||
// of the legacy proto package is being used.
|
||||
const _ = proto.ProtoPackageIsVersion4
|
||||
|
||||
// 高防产品实例
|
||||
type ADPackageInstance struct {
|
||||
state protoimpl.MessageState
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.25.0
|
||||
// protoc-gen-go v1.31.0
|
||||
// protoc v3.19.4
|
||||
// source: models/model_ad_package_period.proto
|
||||
|
||||
package pb
|
||||
|
||||
import (
|
||||
proto "github.com/golang/protobuf/proto"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
@@ -21,10 +20,6 @@ const (
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
// This is a compile-time assertion that a sufficiently up-to-date version
|
||||
// of the legacy proto package is being used.
|
||||
const _ = proto.ProtoPackageIsVersion4
|
||||
|
||||
// 高防实例有效期
|
||||
type ADPackagePeriod struct {
|
||||
state protoimpl.MessageState
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.25.0
|
||||
// protoc-gen-go v1.31.0
|
||||
// protoc v3.19.4
|
||||
// source: models/model_ad_package_price.proto
|
||||
|
||||
package pb
|
||||
|
||||
import (
|
||||
proto "github.com/golang/protobuf/proto"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
@@ -21,10 +20,6 @@ const (
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
// This is a compile-time assertion that a sufficiently up-to-date version
|
||||
// of the legacy proto package is being used.
|
||||
const _ = proto.ProtoPackageIsVersion4
|
||||
|
||||
// 高防产品价格定义
|
||||
type ADPackagePrice struct {
|
||||
state protoimpl.MessageState
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.25.0
|
||||
// protoc-gen-go v1.31.0
|
||||
// protoc v3.19.4
|
||||
// source: models/model_admin.proto
|
||||
|
||||
package pb
|
||||
|
||||
import (
|
||||
proto "github.com/golang/protobuf/proto"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
@@ -21,10 +20,6 @@ const (
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
// This is a compile-time assertion that a sufficiently up-to-date version
|
||||
// of the legacy proto package is being used.
|
||||
const _ = proto.ProtoPackageIsVersion4
|
||||
|
||||
type Admin struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.25.0
|
||||
// protoc-gen-go v1.31.0
|
||||
// protoc v3.19.4
|
||||
// source: models/model_admin_list.proto
|
||||
|
||||
package pb
|
||||
|
||||
import (
|
||||
proto "github.com/golang/protobuf/proto"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
@@ -21,10 +20,6 @@ const (
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
// This is a compile-time assertion that a sufficiently up-to-date version
|
||||
// of the legacy proto package is being used.
|
||||
const _ = proto.ProtoPackageIsVersion4
|
||||
|
||||
type AdminModuleList struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.25.0
|
||||
// protoc-gen-go v1.31.0
|
||||
// protoc v3.19.4
|
||||
// source: models/model_admin_module.proto
|
||||
|
||||
package pb
|
||||
|
||||
import (
|
||||
proto "github.com/golang/protobuf/proto"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
@@ -21,10 +20,6 @@ const (
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
// This is a compile-time assertion that a sufficiently up-to-date version
|
||||
// of the legacy proto package is being used.
|
||||
const _ = proto.ProtoPackageIsVersion4
|
||||
|
||||
type AdminModule struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.25.0
|
||||
// protoc-gen-go v1.31.0
|
||||
// protoc v3.19.4
|
||||
// source: models/model_api_method_stat.proto
|
||||
|
||||
package pb
|
||||
|
||||
import (
|
||||
proto "github.com/golang/protobuf/proto"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
@@ -21,10 +20,6 @@ const (
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
// This is a compile-time assertion that a sufficiently up-to-date version
|
||||
// of the legacy proto package is being used.
|
||||
const _ = proto.ProtoPackageIsVersion4
|
||||
|
||||
type APIMethodStat struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.25.0
|
||||
// protoc-gen-go v1.31.0
|
||||
// protoc v3.19.4
|
||||
// source: models/model_api_node.proto
|
||||
|
||||
package pb
|
||||
|
||||
import (
|
||||
proto "github.com/golang/protobuf/proto"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
@@ -21,10 +20,6 @@ const (
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
// This is a compile-time assertion that a sufficiently up-to-date version
|
||||
// of the legacy proto package is being used.
|
||||
const _ = proto.ProtoPackageIsVersion4
|
||||
|
||||
type APINode struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.25.0
|
||||
// protoc-gen-go v1.31.0
|
||||
// protoc v3.19.4
|
||||
// source: models/model_api_token.proto
|
||||
|
||||
package pb
|
||||
|
||||
import (
|
||||
proto "github.com/golang/protobuf/proto"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
@@ -21,10 +20,6 @@ const (
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
// This is a compile-time assertion that a sufficiently up-to-date version
|
||||
// of the legacy proto package is being used.
|
||||
const _ = proto.ProtoPackageIsVersion4
|
||||
|
||||
// API令牌
|
||||
type APIToken struct {
|
||||
state protoimpl.MessageState
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.25.0
|
||||
// protoc-gen-go v1.31.0
|
||||
// protoc v3.19.4
|
||||
// source: models/model_authority_key.proto
|
||||
|
||||
package pb
|
||||
|
||||
import (
|
||||
proto "github.com/golang/protobuf/proto"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
@@ -21,10 +20,6 @@ const (
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
// This is a compile-time assertion that a sufficiently up-to-date version
|
||||
// of the legacy proto package is being used.
|
||||
const _ = proto.ProtoPackageIsVersion4
|
||||
|
||||
// 版本认证
|
||||
type AuthorityKey struct {
|
||||
state protoimpl.MessageState
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.25.0
|
||||
// protoc-gen-go v1.31.0
|
||||
// protoc v3.19.4
|
||||
// source: models/model_authority_node.proto
|
||||
|
||||
package pb
|
||||
|
||||
import (
|
||||
proto "github.com/golang/protobuf/proto"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
@@ -21,10 +20,6 @@ const (
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
// This is a compile-time assertion that a sufficiently up-to-date version
|
||||
// of the legacy proto package is being used.
|
||||
const _ = proto.ProtoPackageIsVersion4
|
||||
|
||||
type AuthorityNode struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.25.0
|
||||
// protoc-gen-go v1.31.0
|
||||
// protoc v3.19.4
|
||||
// source: models/model_client_agent.proto
|
||||
|
||||
package pb
|
||||
|
||||
import (
|
||||
proto "github.com/golang/protobuf/proto"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
@@ -21,10 +20,6 @@ const (
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
// This is a compile-time assertion that a sufficiently up-to-date version
|
||||
// of the legacy proto package is being used.
|
||||
const _ = proto.ProtoPackageIsVersion4
|
||||
|
||||
type ClientAgent struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user