Compare commits

...

274 Commits

Author SHA1 Message Date
刘祥超
ae7ca4b083 修改copyright 2024-05-17 18:28:59 +08:00
刘祥超
9991981828 用户注册设置增加“强制绑定手机号”选项 2024-05-14 15:48:42 +08:00
刘祥超
4c771697ec 用户列表页增加手机号绑定状态筛选 2024-05-14 15:05:57 +08:00
刘祥超
cbd47f60a1 DNS服务商账号增加“最小TTL”选项 2024-05-12 09:33:35 +08:00
刘祥超
e9bb79487e 实现Ticket登录 2024-05-10 14:28:30 +08:00
刘祥超
47e085c435 WAF区域封禁增加“允许搜索引擎”选项 2024-05-08 17:53:20 +08:00
刘祥超
2128ed9b9c WAF规则集中增加“允许搜索引擎”选项,可以快速允许搜索引擎访问 2024-05-08 16:43:27 +08:00
刘祥超
b2e0a80efd 缓存策略增加“允许读取不完整的Partial Content”选项 2024-05-07 20:04:53 +08:00
刘祥超
baa77a4e7c 实现远程卸载节点功能 2024-05-07 08:40:24 +08:00
刘祥超
5250b00581 WAF增加“请求报头最大长度”参数 2024-05-06 21:07:01 +08:00
刘祥超
0138c3a329 允许管理员调用UserService.LoginUser()借口 2024-05-06 15:06:10 +08:00
刘祥超
8c1f5c47b0 单个网站的5秒盾可以自定义验证有效期 2024-05-06 14:03:35 +08:00
刘祥超
4890a0f70a 网站全局设置中增加“XFF中最多地址数”选项 2024-05-06 14:03:19 +08:00
刘祥超
48e9cc4a46 IP检查也支持灰名单 2024-05-05 20:20:27 +08:00
刘祥超
402e539999 增加IP灰名单,用于仅记录并观察IP 2024-05-05 18:58:40 +08:00
刘祥超
6b56f539e5 增加根据IP名单代号查找IP名单ID的接口 2024-05-05 14:08:04 +08:00
刘祥超
feef801cb9 删除不需要的 ServerTypeUnixProxy 2024-05-05 11:33:19 +08:00
刘祥超
6a8b1c9885 数据看板增加独立IP数量 2024-05-05 11:27:30 +08:00
刘祥超
eb4e70ed25 增加清理老登录SESSION API 2024-05-03 12:09:45 +08:00
刘祥超
8ca6553ac5 自定义页面增加是否“启用系统自定义页面”选项 2024-05-03 09:35:12 +08:00
刘祥超
bd9727cb58 优化代码 2024-05-03 08:42:52 +08:00
刘祥超
799d186f85 变量修饰符增加quote 2024-05-01 19:44:11 +08:00
刘祥超
c3c3261579 缓存策略默认不启用MMAP 2024-05-01 12:51:31 +08:00
刘祥超
97c6776809 可以在集群设置中修改节点最大并发读/写数 2024-04-30 19:08:51 +08:00
刘祥超
4e4acc327d 用户平台界面设置中增加“使用的DNS解析库”选项 2024-04-29 15:16:42 +08:00
刘祥超
f73251f57d 管理平台界面设置中增加“使用的DNS解析库”选项 2024-04-29 15:06:55 +08:00
刘祥超
d9350839f3 更新依赖库 2024-04-21 20:27:38 +08:00
刘祥超
25269adaae 网站全局设置中增加“自动gzip回源”选项 2024-04-18 16:15:53 +08:00
刘祥超
351337fcbc 防盗链功能增加“例外URL“和“限制URL”设置 2024-04-17 15:45:17 +08:00
刘祥超
505b6b6c9e UA名单功能增加“例外URL“和“限制URL”设置 2024-04-17 15:10:36 +08:00
刘祥超
1b6a5001e8 例外和限制URL中增加常见图片、常见音频、常见视频等规则 2024-04-17 14:46:30 +08:00
刘祥超
443a3f3ec3 内容压缩功能增加“例外URL“和“限制URL”设置 2024-04-17 13:55:10 +08:00
刘祥超
e4861c3fa1 删除一直未实现的Unix协议相关内容 2024-04-14 17:15:38 +08:00
刘祥超
8ba8528c98 源站增加快速停用/启用功能 2024-04-14 16:27:35 +08:00
刘祥超
4d0b1c7e0c 简化IP名单中创建IP操作/支持IP以CIDR方式显示 2024-04-13 16:45:56 +08:00
刘祥超
3de4223023 增加网站每日独立IP统计 2024-04-12 18:52:15 +08:00
刘祥超
5f29576049 更新依赖库 2024-04-12 16:48:15 +08:00
刘祥超
4adb8117f8 节点配置中增加集群的密钥 2024-04-11 14:18:52 +08:00
刘祥超
2d304b19b8 优化测试用例 2024-04-09 09:46:13 +08:00
刘祥超
8e605cce67 系统安全设置中增加“仅从自定义报头中获取IP”选项 2024-04-08 11:22:04 +08:00
刘祥超
0d53785620 WAF策略增加JSCookie动作选项 2024-04-07 14:21:29 +08:00
刘祥超
73ee81da78 优化防火墙相关代码 2024-04-06 20:32:48 +08:00
刘祥超
a600fc9cd3 增强IP相关函数 2024-04-06 14:57:18 +08:00
刘祥超
cc0b2fd74f 优化代码 2024-04-06 10:07:47 +08:00
刘祥超
e54cfa7765 更好地支持IPv6 2024-04-06 09:12:17 +08:00
刘祥超
7c5c600e31 集群设置增加自动硬盘TRIM选项 2024-04-04 17:05:09 +08:00
刘祥超
c6f9126ae2 节点上传指标数据时只上传变更的部分 2024-04-03 08:15:32 +08:00
刘祥超
5478e6a956 使用MMAP提升缓存读取性能 2024-03-29 18:31:53 +08:00
刘祥超
3945e94f71 DNS服务商中的密钥数据以掩码方式显示 2024-03-18 10:18:38 +08:00
刘祥超
9cd3618d9b 部分API文档 2024-03-18 09:29:54 +08:00
刘祥超
4389ffb397 集群设置--网站设置中“处理未绑定域名方式”支持跳转到网址 2024-03-16 08:59:37 +08:00
刘祥超
debb72c2d3 智能DNS中国家/地区线路下支持省/州的细分 2024-03-14 20:12:24 +08:00
刘祥超
b314f7e96c 优化“页面优化”功能相关代码 2024-03-14 14:24:22 +08:00
刘祥超
823e519d58 优化代码 2024-03-10 16:25:52 +08:00
刘祥超
5a54390f1d 在缓存任务键值中增加集群信息 2024-03-10 11:24:50 +08:00
刘祥超
704d3af982 增加单体应用初始化标识 2024-01-29 18:56:28 +08:00
刘祥超
96b48f2bbc 增加通过管理员用户名查找管理员信息的API 2024-01-29 18:55:23 +08:00
刘祥超
4a1c9be931 优化IP库加载速度 2024-01-23 10:04:01 +08:00
刘祥超
f0dc9e0577 增加修改节点停用/启用状态API 2024-01-21 17:43:28 +08:00
刘祥超
1cf38864de 查询集群列表API增加ID排序 2024-01-21 16:57:22 +08:00
刘祥超
5f9e7e981c 部分部分API文档 2024-01-21 14:40:07 +08:00
刘祥超
7073467128 WAF允许ALLOW动作增加有效范围 2024-01-20 21:26:21 +08:00
刘祥超
adc4b945e7 WAF策略增加显示页面动作默认设置 2024-01-20 16:18:49 +08:00
刘祥超
12f6a1e3ce 默认不支持${serverAddr}变量 2024-01-20 10:04:51 +08:00
刘祥超
4f89360902 优化HLS相关API角色 2024-01-20 10:03:51 +08:00
刘祥超
d422dc6b85 WAF操作符增加“包含SQL注入-严格模式” 2024-01-16 20:42:13 +08:00
刘祥超
0dc678e38a 配置代码增加多媒体 2024-01-14 21:10:52 +08:00
刘祥超
05de67318b 网站设置增加HLS加密功能(商业版本) 2024-01-14 20:32:30 +08:00
刘祥超
575e916088 套餐增加文件最大上传尺寸设置 2024-01-13 19:32:41 +08:00
刘祥超
489795dba0 字符编码设置增加“强制替换”选项 2024-01-13 16:28:45 +08:00
刘祥超
3e8fc126b8 5秒盾增加匹配条件 2024-01-12 17:13:34 +08:00
刘祥超
64c3d76fb2 添加快捷添加和删除网站源站API 2024-01-12 11:48:47 +08:00
刘祥超
3bd3ef5f78 套餐API增加查找套餐基本信息API 2024-01-11 18:41:17 +08:00
刘祥超
827eeeb506 实现批量删除网站功能 2024-01-11 18:41:04 +08:00
刘祥超
36cf357984 变量表达式支持修饰符 2024-01-11 16:41:08 +08:00
刘祥超
46140bbdb5 套餐可以设置带宽限制 2024-01-11 15:22:37 +08:00
刘祥超
6a671f67bc 增加用户系统门户页、文章相关管理 2024-01-09 10:20:29 +08:00
刘祥超
ea991f5a97 TLS选项中取出SSL3.0(golang已经不再支持) 2024-01-06 20:47:48 +08:00
刘祥超
5bcbf29fc6 WAF操作符增加“包含XSS注入-严格模式” 2024-01-04 14:52:47 +08:00
刘祥超
e70d6bb33b 增加列出IP名单中的IP ID列表的API 2023-12-24 10:51:03 +08:00
刘祥超
8a8803cee9 优化WAF“阻止”动作的文字提示 2023-12-24 10:13:37 +08:00
刘祥超
184fbd384e WAF参数中增加“请求来源” 2023-12-24 10:03:01 +08:00
刘祥超
fc3c607c8d 优化IP库GC性能 2023-12-24 09:24:37 +08:00
刘祥超
1760e8b9c8 增加请求脚本审核机制 2023-12-23 20:55:01 +08:00
刘祥超
deea02b1ab 优化编译脚本 2023-12-23 10:04:37 +08:00
刘祥超
7f0822000c 增加多语言编译说明 2023-12-23 09:59:29 +08:00
刘祥超
6a36625bc2 增加多处英文菜单 2023-12-23 09:42:24 +08:00
刘祥超
eca0b997f8 增加套餐相关API/给套餐相关API添加更多注释 2023-12-21 15:09:28 +08:00
刘祥超
8746107b73 增加若干功能代号 2023-12-20 17:35:07 +08:00
刘祥超
729311f605 增加若干API/增加多个网站功能项 2023-12-20 15:09:09 +08:00
刘祥超
99a2801591 修改套餐菜单名 2023-12-19 16:20:07 +08:00
刘祥超
8a045c77c9 套餐增加Websocket连接数限制 2023-12-19 14:57:03 +08:00
刘祥超
619ae043e2 修复多语言消息无法读取参数的问题 2023-12-19 08:29:41 +08:00
刘祥超
9ee5c896d1 缓存设置中可以设置缓存主域名,用来复用多域名下的缓存 2023-12-13 18:41:24 +08:00
刘祥超
4209969214 增加保存管理员语言选择的API 2023-12-12 22:40:16 +08:00
刘祥超
a59c84ef0d 增加多处英文翻译 2023-12-12 12:11:33 +08:00
刘祥超
988aca8d84 部分菜单实现中英文切换 2023-12-12 11:48:19 +08:00
刘祥超
310875f8ec WebP策略变化时只更新相关配置 2023-12-11 11:08:48 +08:00
刘祥超
615fdc24d8 WebP转换质量转移到WebP策略配置 2023-12-11 10:17:46 +08:00
刘祥超
acd78085fa 增加“修改用户界面设置”语言消息 2023-12-10 11:08:11 +08:00
刘祥超
0d90dde90b 用户系统界面设置增加“自定义客户端IP报头” 2023-12-10 10:59:51 +08:00
刘祥超
3996a051ff 修复一处消息提示参数 2023-12-10 10:59:16 +08:00
刘祥超
dd14b4ab3d 管理系统安全设置增加“自定义客户端IP报头” 2023-12-10 10:46:55 +08:00
刘祥超
e50bcdf181 WAF策略模板将部分拦截动作(block)改为显示网页(page) 2023-12-09 19:25:06 +08:00
刘祥超
a145b799a2 优化WAF规则模板 2023-12-09 18:15:27 +08:00
刘祥超
cad0fd5ff2 WAF规则模板中XSS注入检测规则使用“包含XSS注入”操作符替代以往的正则表达式 2023-12-09 17:02:01 +08:00
刘祥超
57c249b791 将WAF策略模板SQL注入默认动作修改为“显示页面” 2023-12-09 15:54:57 +08:00
刘祥超
7ee1cc9cf4 WAF规则模板中SQL注入规则使用“包含SQL注入”操作符替代以往的正则表达式 2023-12-09 15:28:55 +08:00
刘祥超
605b01db64 WAF检查项增加“所有报头名称” 2023-12-08 15:38:21 +08:00
刘祥超
bbe76743b1 将WAF checkpoint中名称和描述部分的Header改为“报头” 2023-12-08 15:15:46 +08:00
刘祥超
53563f040f 优化WAF checkpoint参数文字提示 2023-12-08 15:09:32 +08:00
刘祥超
9226001362 优化部分WAF操作符文字提示 2023-12-08 10:18:38 +08:00
刘祥超
4270c08ab7 WAF增加“包含XSS注入”操作符 2023-12-08 10:15:29 +08:00
刘祥超
671fd5dcc2 WAF增加“包含SQL注入”操作符 2023-12-07 20:24:55 +08:00
刘祥超
e8a3dfba71 修复一处单词拼写错误 2023-12-07 12:14:21 +08:00
刘祥超
ba41c16123 WAF操作符增加包含任一单词、包含所有单词、不包含任一单词 2023-12-07 11:43:34 +08:00
刘祥超
490a17558c 进一步缩短WAF Request Body检查尺寸 2023-12-05 16:53:43 +08:00
刘祥超
61f7a14428 页面优化增加例外URL和限制URL 2023-11-30 15:49:19 +08:00
刘祥超
a7336fafbf 增加“极验-行为验”验证码集成支持 2023-11-29 16:58:24 +08:00
刘祥超
7dbf5add34 增加API文档注释 2023-11-24 09:06:36 +08:00
刘祥超
7c5c6267d4 节点配置中增加节点IP信息 2023-11-18 12:10:16 +08:00
刘祥超
8fdc98cde9 CA证书也支持IP地址 2023-11-18 10:39:32 +08:00
刘祥超
d4413b8afe SSL证书支持IP地址 2023-11-18 09:50:34 +08:00
刘祥超
826bf7bf7d 发送短信时加入验证码(code)参数 2023-11-17 15:00:11 +08:00
刘祥超
c6e95eda15 实现用户系统手机号码绑定和登录(商业版) 2023-11-17 11:51:02 +08:00
刘祥超
539016c2f6 源站支持404内容自动重试其他源站 2023-11-15 19:06:51 +08:00
刘祥超
92f4ea0dc4 WAF人机识别实现点击验证和滑动解锁验证/单个网站可以设置默认的人机识别方式 2023-11-15 15:12:08 +08:00
刘祥超
d430eebe8c 增加用户列表菜单 2023-11-13 11:53:36 +08:00
刘祥超
30ff3ecde5 自定义页面增加例外URL和限制URL设置 2023-11-13 10:45:23 +08:00
刘祥超
f0b5f6ed76 自定义页面增加“跳转URL”功能 2023-11-10 16:36:14 +08:00
刘祥超
4c7de6bdc2 URL跳转中增加例外域名和仅限域名 2023-11-10 11:05:21 +08:00
刘祥超
412704c9f3 优化节点阈值设置 2023-11-03 11:57:56 +08:00
刘祥超
f264426099 优化商业版验证 2023-11-02 17:20:16 +08:00
刘祥超
03a6e9ccb9 访问日志存储策略增加“停止默认数据库存储”选项 2023-10-30 19:03:48 +08:00
刘祥超
9b899dff74 实现网络数据包相关统计(商业版本) 2023-10-26 17:17:48 +08:00
刘祥超
5bfd5de90d 删除指标统计项目中的“请求协议Proto“(因为和HTTP协议一样) 2023-10-25 20:56:04 +08:00
刘祥超
2177f97bdb WAF记录IP动作中IP名单如果为空时,默认为全局黑名单 2023-10-15 09:34:33 +08:00
刘祥超
5340e5ad52 取消反向代理中默认自动50x尝试 2023-10-15 09:02:48 +08:00
刘祥超
06a3db911c 增加修改消息任务状态API 2023-10-14 18:16:13 +08:00
刘祥超
a7ae7ea2db 优化消息通知相关代码 2023-10-14 17:15:52 +08:00
刘祥超
f949e31c0f 优化消息发送API 2023-10-12 20:11:34 +08:00
刘祥超
d0e1dfe1af 支持批量复制WAF设置 2023-10-09 19:52:44 +08:00
刘祥超
083ccfed7d 申请证书任务列表区分管理员和用户 2023-10-09 16:18:40 +08:00
刘祥超
347bbe1b96 证书列表区分管理员和用户证书 2023-10-09 15:54:11 +08:00
刘祥超
16cf11b366 完善API文档 2023-10-09 08:45:44 +08:00
刘祥超
01e211560d WAF策略中默认不启用SynFlood检测 2023-10-08 16:01:50 +08:00
刘祥超
96ce664202 集群设置中增加“自动调节系统参数”选项 2023-10-08 16:01:21 +08:00
刘祥超
2b8191001b 将全局设置的TCP相关设置移到“集群设置--网站设置”中 2023-09-18 16:55:30 +08:00
刘祥超
6799f3f9ae 将全局的通用设置--域名审核设置移到“集群设置--网站设置”中 2023-09-18 16:09:46 +08:00
刘祥超
55e2c38cd8 访客IP设置中支持多个请求报头 2023-09-17 19:14:28 +08:00
刘祥超
534d8e471d 全局网站设置中增加Ln请求调度方法 2023-09-17 18:37:08 +08:00
刘祥超
3c81bd6d5d 优化访客IP地址设置 2023-09-07 18:01:58 +08:00
刘祥超
f2d087a6ce 套餐增加请求数(日/月)限制 2023-09-07 11:46:20 +08:00
刘祥超
2497a81e09 重新实现套餐相关功能 2023-09-06 16:31:14 +08:00
刘祥超
972b487db8 爬虫规则中将php改为php\b,避免屏蔽某些安卓WebView 2023-08-30 10:13:16 +08:00
刘祥超
170e6ebfb8 增加API注释 2023-08-29 14:22:53 +08:00
刘祥超
9e80750309 网站设置增加是否支持${serverAddr}选项 2023-08-25 15:31:13 +08:00
刘祥超
f056a9c5bd IP库增加多个辅助查询函数 2023-08-24 12:21:26 +08:00
刘祥超
6a42827ebd 增加检查中国特殊区域的函数 2023-08-24 11:50:47 +08:00
刘祥超
2d25c385fa 改进若干API注释 2023-08-21 15:54:44 +08:00
刘祥超
8a6c20db01 反向代理增加是否重试50X选项,默认为启用 2023-08-20 15:49:49 +08:00
刘祥超
22d00a6c92 WAF增加通配符匹配/不匹配操作符 2023-08-13 10:37:31 +08:00
刘祥超
51f8fd0f31 WAF操作符元数据中增加数据类型选项,以便于优化交互界面 2023-08-13 10:01:24 +08:00
刘祥超
15708ec1bb 编译proto文件时捕捉错误提示 2023-08-12 20:48:53 +08:00
刘祥超
b6667fc323 在README.md中增加多语言配置langs说明 2023-08-12 20:33:50 +08:00
刘祥超
43cf3b57dd 优化API错误相关提示 2023-08-12 20:33:28 +08:00
刘祥超
58dcab31ae 调整WAF通配符顺序 2023-08-12 08:16:54 +08:00
刘祥超
712a9397a1 优化错误处理相关代码 2023-08-11 16:14:47 +08:00
刘祥超
fe00446003 优化错误提示相关代码 2023-08-11 15:26:59 +08:00
刘祥超
c098732e51 静态分发增加例外URL、限制URL、排除隐藏文件等选项 2023-08-10 11:27:00 +08:00
刘祥超
5c1a9fb8ff WAF策略可以自定义默认的区域/省份封禁提示 2023-08-10 10:30:05 +08:00
刘祥超
4b52a9703b 修复proto文件不能编译的问题 2023-08-10 10:29:43 +08:00
刘祥超
1aebbc8e39 减少默认的WAF检查尺寸 2023-08-09 17:56:15 +08:00
刘祥超
9df5a409e6 Update .golangci.yaml 2023-08-09 08:11:47 +08:00
刘祥超
c9bb7fb8a5 添加golangci-lint配置 2023-08-08 18:50:12 +08:00
刘祥超
6a2803187e 优化代码 2023-08-08 15:12:28 +08:00
刘祥超
3c5c961cd5 使用最新的protoc-gen-go和protoc-gen-go-grpc插件编译proto文件 2023-08-07 10:26:22 +08:00
刘祥超
be5c6b12bb 增加脚本使用指南 2023-08-07 09:46:10 +08:00
刘祥超
e6af6b6575 使用最新的protoc-gen-go和protoc-gen-go-grpc插件 2023-08-06 23:36:50 +08:00
刘祥超
65be70d015 增加一些API注释 2023-08-06 19:33:45 +08:00
刘祥超
117c89ff62 缓存策略增加“缓存磁盘最小空余空间”选项 2023-08-06 18:07:33 +08:00
刘祥超
6d8156b10b 缓存策略增加预热超时时间设置(默认20分钟) 2023-08-06 17:06:39 +08:00
刘祥超
9cc9c4e2b3 增加PROXY Protocol版本号校验 2023-08-06 09:55:16 +08:00
刘祥超
7271046cb3 将一些比较耗时的WAF规则分组设为默认不开启 2023-08-02 17:14:24 +08:00
刘祥超
2a67b2b2d6 修复一处编译错误 2023-08-02 17:02:55 +08:00
刘祥超
31de0d5112 WAF策略增加“最多检查内容尺寸“选项 2023-08-02 17:00:40 +08:00
刘祥超
e80ea8a0e2 节点状态中加入磁盘预估写入速度 2023-08-02 14:48:42 +08:00
刘祥超
c08d7c48f2 缓存条件增加“强制Range回源选项” 2023-07-31 17:31:58 +08:00
刘祥超
e44e54fbf4 缓存条件增加是否允许异步读取源站选项 2023-07-31 15:47:24 +08:00
刘祥超
4a11ecb7b4 修复一处编译问题 2023-07-25 14:08:26 +08:00
刘祥超
5c8dff120a 增加 DefaultTCPLinger 值 2023-07-25 09:35:28 +08:00
刘祥超
df148bf027 删除TOA相关不需要的内容 2023-07-24 15:33:30 +08:00
刘祥超
d5bb623339 优化TOA相关API 2023-07-24 09:56:49 +08:00
刘祥超
58ec21d676 优化HTTP报头策略是否为空的判断 2023-07-22 15:00:15 +08:00
刘祥超
279e4025fd 默认自动检查版本更新 2023-07-20 09:37:47 +08:00
刘祥超
bedb18dd71 修复无法读取鉴权方法列表的问题 2023-07-17 09:32:39 +08:00
刘祥超
102b5859b3 5秒盾增加QPS限制选项 2023-07-14 11:01:14 +08:00
刘祥超
8426bf21be WAF-区域封禁增加提示内容设置 2023-07-14 11:01:01 +08:00
刘祥超
04d4895b7b 集群设置--网站设置增加“服务器旗标”设置 2023-07-12 17:39:26 +08:00
刘祥超
a328f75d89 生成IP库的时候自动指定省略的城市名 2023-07-12 15:34:40 +08:00
刘祥超
a9b28d55c1 增加页面优化相关API、配置、消息代号 2023-07-11 19:47:05 +08:00
刘祥超
fd4aff5ab5 增加是否在手机浏览器上也支持HTTP/3的选项 2023-07-09 16:17:03 +08:00
刘祥超
8639bd213e 增加部分API注释 2023-07-09 10:15:33 +08:00
刘祥超
1c192050c7 缓存策略移除“容纳Key数量”选项 2023-07-08 18:51:10 +08:00
刘祥超
83f5166d76 网站列表增加QPS和攻击QPS信息 2023-07-07 18:51:41 +08:00
刘祥超
05cd622456 优化WAF区域/省份封禁:增加仅允许、增加中国香港澳台、内地等特殊区域 2023-07-07 09:51:30 +08:00
刘祥超
64bac81b56 初始化访客IP配置时去除首尾可能的空格 2023-07-07 08:31:17 +08:00
刘祥超
f3cc573a2c 增加部分多语言代号 2023-07-06 10:56:08 +08:00
刘祥超
6d28a67fd4 官网URL放入到多语言消息中 2023-07-05 20:21:41 +08:00
刘祥超
1151eb6c92 优化硬盘空间不足的提示 2023-07-05 16:42:56 +08:00
刘祥超
ceceda22a6 “集群设置 -- 网站设置”增加“允许记录访问日志”选项 2023-07-05 15:29:04 +08:00
刘祥超
916cd0bf67 增加部分消息代号 2023-07-04 20:29:33 +08:00
刘祥超
28458d9cfc 优化代码 2023-07-03 17:12:00 +08:00
刘祥超
0b2e9fa864 优化全局设置的超时设置 2023-07-03 16:21:52 +08:00
刘祥超
ea35ad2dac 修改部分文字 2023-07-03 15:36:59 +08:00
刘祥超
c66adf989c 增加清空节点同步任务、清空DNS同步任务API 2023-07-02 17:29:41 +08:00
刘祥超
81af1caa6c 优化OSS相关代码 2023-07-02 11:04:59 +08:00
刘祥超
52ed467580 增加API注释 2023-07-01 19:27:49 +08:00
刘祥超
705ffcd087 增加部分数据清理周期设置 2023-07-01 17:55:10 +08:00
刘祥超
04d8a1db33 查找当前API节点版本中增加角色 2023-07-01 15:10:07 +08:00
刘祥超
1ef1a7d49e 优化代码 2023-06-30 19:02:31 +08:00
刘祥超
a720ea0373 优化代码 2023-06-30 19:00:53 +08:00
刘祥超
fd9849c9ff 部分中文转换为多语言代号 2023-06-30 18:09:43 +08:00
刘祥超
141dd89f6f 部分中文转换为多语言代号 2023-06-28 19:06:16 +08:00
刘祥超
9db82b0bea 部分中文转换为多语言代号 2023-06-28 16:19:05 +08:00
刘祥超
bd57d35d63 添加多语言最基础代码 2023-06-28 09:12:13 +08:00
刘祥超
4853363765 源站支持HTTP/2 2023-06-23 11:42:51 +08:00
刘祥超
d9233713e4 补充API注释 2023-06-21 08:45:06 +08:00
刘祥超
7f8dd70c9b 增加简化版的创建TCP网站API 2023-06-18 17:14:29 +08:00
刘祥超
1748637c31 增加简化版的创建HTTP网站API 2023-06-18 16:19:52 +08:00
刘祥超
90c06c4175 把“服务”改成“网站” 2023-06-18 10:57:07 +08:00
刘祥超
fe9bc332c1 增加API注释 2023-06-17 21:05:03 +08:00
刘祥超
f436763c8d 默认不启用性能优化 2023-06-17 19:19:40 +08:00
刘祥超
6bf017ee22 完善API注释 2023-06-16 18:27:16 +08:00
刘祥超
70bc6e7d8e 缓存条件类型增加“URL通配符” 2023-06-16 11:34:59 +08:00
刘祥超
e42b13f278 用户设置中增加登录状态下检查客户端区域的选项 2023-06-16 10:59:30 +08:00
刘祥超
cd545b25c9 80/443端口的源站自动修正HTTP和HTTPS协议,防止有些小白用户不知道HTTP和HTTPS的区别 2023-06-16 08:47:47 +08:00
刘祥超
574b264a37 缓存条件增加"强制返回区间内容"选项 2023-06-15 15:14:25 +08:00
刘祥超
12abb714e0 优化OSS源站相关代码 2023-06-13 15:44:43 +08:00
刘祥超
8bef580c2e 智能DNS实现DoH功能 2023-06-11 17:57:41 +08:00
刘祥超
b08064c1de 初步实现对象存储源站 2023-06-07 17:26:34 +08:00
刘祥超
555673b87d 允许在集群设置 -- “网站设置” 中设置节点IP访问显示的内容 2023-06-05 19:27:05 +08:00
刘祥超
e9145ec22c 网站全局设置增加“强制Ln请求“选项 2023-06-05 17:05:49 +08:00
刘祥超
ffd261b285 改进智能DNS验证相关API 2023-06-05 12:34:51 +08:00
刘祥超
2ff4c67e57 增加一处测试用例 2023-06-02 14:58:08 +08:00
刘祥超
1e1e6e7e81 查找HTTP3端口时只计算已经启用的 2023-06-01 19:42:40 +08:00
刘祥超
71e03f5e07 初步实现HTTP3 2023-06-01 17:48:01 +08:00
刘祥超
6a1a2640d3 Update rpc.json 2023-05-28 19:26:18 +08:00
刘祥超
be32bff7db 提供用户某日刷新/预热缓存数量查询API 2023-05-28 18:00:42 +08:00
刘祥超
afd9e3134d WAF增加“跳转”动作 2023-05-28 17:45:39 +08:00
刘祥超
a9dd5e3ba3 URL跳转精准匹配/匹配前缀支持URL查询参数 2023-05-27 21:00:34 +08:00
刘祥超
5caafcb99a 增加读取节点数配额接口 2023-05-27 15:30:05 +08:00
刘祥超
f34633f22a WAF国家/地区封禁、省份封禁增加例外URL、限制URL 2023-05-25 12:02:25 +08:00
刘祥超
2966240a5c 网站全局设置中增加“自动匹配证书”选项 2023-05-25 11:00:25 +08:00
刘祥超
05255c18d8 智能调度动作可以排序 2023-05-24 15:38:37 +08:00
刘祥超
a74a751a50 删除不需要的文件 2023-05-24 15:06:22 +08:00
刘祥超
c24fa291bd 改进流量相关的智能调度过期时间设置 2023-05-24 15:04:07 +08:00
刘祥超
e33f98f869 优化代码 2023-05-23 19:51:28 +08:00
刘祥超
e3ada6da81 实现集群CC防护策略设置 2023-05-23 19:16:09 +08:00
刘祥超
47c0ade078 实现集群自定义页面 2023-05-22 17:30:08 +08:00
刘祥超
2af8e6c7f8 HTTP Header中支持设置非标Header 2023-05-19 19:52:22 +08:00
刘祥超
e909d4c59a 优化代码 2023-05-19 16:44:02 +08:00
刘祥超
ee744d6c70 HTTP Header - CORS跨域设置增加多个选项 2023-05-19 16:33:13 +08:00
刘祥超
dbea336fee 增加复制节点动作API 2023-05-19 11:12:09 +08:00
刘祥超
5961d955d7 实现基础的智能调度 2023-05-17 18:42:35 +08:00
刘祥超
529a98e694 域名解析功能实现健康检查 2023-05-03 17:09:36 +08:00
刘祥超
48aeffba7e 防盗链增加”同时检查Origin选项“ 2023-05-02 17:05:56 +08:00
刘祥超
a7ac768709 优化编译脚本 2023-04-25 10:26:34 +08:00
刘祥超
ca8226fe9d 远程升级API节点时自动上传边缘节点安装文件 2023-04-23 19:43:01 +08:00
刘祥超
a6395b34a3 5秒盾“加入IP白名单”默认为true 2023-04-23 16:04:59 +08:00
刘祥超
97f56c7bb1 创建ACME用户、ACME任务时可以指定平台用户 2023-04-23 15:01:10 +08:00
刘祥超
c0856d3b46 安全设置中增加“检查客户端指纹”、“检查客户端区域”选项 2023-04-19 18:21:44 +08:00
刘祥超
4e80f62837 IP库查询增加更多信息 2023-04-19 18:20:34 +08:00
刘祥超
753552d4a4 修复证书数据可能获取不到的问题 2023-04-10 09:13:05 +08:00
1024 changed files with 99116 additions and 65592 deletions

3
.gitignore vendored
View File

@@ -1,2 +1,3 @@
*_plus.go
*_plus_test.go
*_plus_test.go
*_plus.json

75
.golangci.yaml Normal file
View 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

View File

@@ -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库

View File

@@ -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` 文件。

4
build/build-messages.sh Executable file
View File

@@ -0,0 +1,4 @@
#!/usr/bin/env bash
ROOT=$(dirname "$0")
/usr/local/bin/go run "${ROOT}"/../cmd/langs/main.go generate

View File

@@ -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
RESULT=`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"

File diff suppressed because it is too large Load Diff

465
cmd/langs/main.go Normal file
View File

@@ -0,0 +1,465 @@
// Copyright 2023 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
package main
import (
"bytes"
"encoding/json"
"fmt"
"github.com/TeaOSLab/EdgeCommon/pkg/langs"
"github.com/iwind/TeaGo/Tea"
_ "github.com/iwind/TeaGo/bootstrap"
"github.com/iwind/TeaGo/lists"
"github.com/iwind/TeaGo/types"
"go/format"
"os"
"path/filepath"
"regexp"
"sort"
"strconv"
"strings"
)
func main() {
var args = os.Args
if len(args) >= 2 {
switch args[1] {
case "generate":
// generate go codes from json files
runGenerate()
case "search":
// search hans from dir path
runSearch()
}
} else {
fmt.Println("Usage: langs [generate|search]")
}
}
func runGenerate() {
var rootDir = filepath.Clean(Tea.Root + "/../pkg/langs/protos")
dir, err := os.Open(rootDir)
if err != nil {
fmt.Println("[ERROR]read dir failed: " + err.Error())
return
}
defer func() {
_ = dir.Close()
}()
files, err := dir.Readdir(0)
if err != nil {
fmt.Println("[ERROR]read dir failed: " + err.Error())
return
}
var dirRegexp = regexp.MustCompile(`^[a-z]+-[a-z]+$`)
var jsonFileNameRegexp = regexp.MustCompile(`^([a-zA-Z0-9]+)(_([a-zA-Z0-9]+))*\.json$`)
var messageCodeRegexp = regexp.MustCompile(`^[a-zA-Z0-9_]+$`)
var jsonCommentRegexp = regexp.MustCompile(`//\s+.+`)
var messageCodes = []string{}
var langMaps = map[string]*langs.Lang{} // lang => *langs.Lang
var defaultLang = langs.DefaultManager().DefaultLang()
const maxMessageCodeLen = 128
for _, file := range files {
var dirName = file.Name()
if !file.IsDir() || !dirRegexp.MatchString(dirName) {
continue
}
var langCode = dirName
var isBaseLang = langCode == defaultLang
var processOk = func() bool {
jsonFiles, err := filepath.Glob(rootDir + "/" + dirName + "/*.json")
if err != nil {
fmt.Println("[ERROR]list json files failed: " + err.Error())
return false
}
for _, jsonFile := range jsonFiles {
var jsonFileName = filepath.Base(jsonFile)
if len(jsonFileName) == 0 || !jsonFileNameRegexp.MatchString(jsonFileName) {
continue
}
var module = strings.TrimSuffix(jsonFileName, ".json")
data, err := os.ReadFile(jsonFile)
if err != nil {
fmt.Println("[ERROR]read json file '" + jsonFile + "' failed: " + err.Error())
return false
}
// remove comments in json
data = jsonCommentRegexp.ReplaceAll(data, []byte{})
var m = map[string]string{} // code => value
err = json.Unmarshal(data, &m)
if err != nil {
fmt.Println("[ERROR]decode json file '" + jsonFile + "' failed: " + err.Error())
return false
}
var newM = map[string]string{}
for code, value := range m {
if !messageCodeRegexp.MatchString(code) {
fmt.Println("[ERROR]invalid message code '" + code + "'")
return false
}
var fullCode = module + "@" + code
if len(fullCode) > maxMessageCodeLen {
fmt.Println("[ERROR]message code '" + fullCode + "' too long, max length: " + types.String(maxMessageCodeLen))
return false
}
if isBaseLang {
messageCodes = append(messageCodes, fullCode)
}
newM[fullCode] = value
}
finalLang, ok := langMaps[langCode]
if !ok {
finalLang = langs.NewLang(langCode)
langMaps[langCode] = finalLang
}
for code, value := range newM {
if finalLang.Has(langs.MessageCode(code)) {
fmt.Println("[ERROR]message code '" + code + "' duplicated")
return false
}
finalLang.Set(langs.MessageCode(code), value)
}
}
return true
}()
if !processOk {
return
}
}
// compile
for langCode, lang := range langMaps {
err = lang.Compile()
if err != nil {
fmt.Println("[ERROR]compile '" + langCode + "' failed: " + err.Error())
return
}
}
// check message codes
fmt.Println("checking message codes ...")
var defaultMessageMap = map[langs.MessageCode]string{}
for langCode, messageLang := range langMaps {
if langCode == defaultLang { // only check lang not equal to 'en-us'
defaultMessageMap = messageLang.GetAll()
continue
}
for messageCode := range messageLang.GetAll() {
if !lists.ContainsString(messageCodes, messageCode.String()) {
fmt.Println("[ERROR]message code '" + messageCode.String() + "' in lang '" + langCode + "' not exist in default lang file ('" + defaultLang + "')")
return
}
}
}
fmt.Println("found '" + types.String(len(messageCodes)) + "' message codes")
// generate codes/codes.go
sort.Strings(messageCodes)
var codesSource = `
// generated by run 'langs generate'
package codes
import(
"github.com/TeaOSLab/EdgeCommon/pkg/langs"
)
const (
`
for index, messageCode := range messageCodes {
// add comment to message code
comment, _, _ := strings.Cut(defaultMessageMap[langs.MessageCode(messageCode)], "\n")
codesSource += upperWords(messageCode) + " langs.MessageCode = " + strconv.Quote(messageCode) + " // " + comment
// add NL
if index != len(messageCodes)-1 {
codesSource += "\n"
}
}
codesSource += `
)
`
formattedCodesSource, err := format.Source([]byte(codesSource))
if err != nil {
fmt.Println("[ERROR]format 'codes.go' failed: " + err.Error())
return
}
fmt.Println("generating 'codes/codes.go' ...")
err = os.WriteFile(Tea.Root+"/../pkg/langs/codes/codes.go", formattedCodesSource, 0666)
if err != nil {
fmt.Println("[ERROR]write to 'codes.go' failed: " + err.Error())
return
}
// generate messages_LANG.go
for langCode, messageLang := range langMaps {
var langFile = strings.ReplaceAll("messages/messages_"+langCode+".go", "-", "_")
fmt.Println("generating '" + langFile + "' ...")
var source = `
// generated by run 'langs generate'
package messages
import(
"github.com/TeaOSLab/EdgeCommon/pkg/langs"
)
func init() {
langs.Load("` + langCode + `", map[langs.MessageCode]string{
`
for _, code := range messageCodes {
var value = messageLang.Get(langs.MessageCode(code))
source += strconv.Quote(code) + ": " + strconv.Quote(value) + ",\n"
}
source += `
})
}
`
formattedSource, err := format.Source([]byte(source))
if err != nil {
fmt.Println("[ERROR]format '" + langFile + "' failed: " + err.Error())
return
}
err = os.WriteFile(Tea.Root+"/../pkg/langs/"+langFile, formattedSource, 0666)
if err != nil {
fmt.Println("[ERROR]write file '" + langFile + "' failed: " + err.Error())
return
}
}
// generate language javascript files for EdgeAdmin and EdgeUser (commercial versions)
for lang, messageLang := range langMaps {
if lang != defaultLang {
// TODO merge messageMap with default message map
}
for _, component := range []string{"EdgeAdmin", "EdgeUser"} {
fmt.Println("generating '" + lang + ".js' for " + component + " ...")
var targetFile = filepath.Clean(Tea.Root + "/../../" + component + "/web/public/js/langs/" + lang + ".js")
var targetDir = filepath.Dir(targetFile)
dirStat, _ := os.Stat(targetDir)
if dirStat != nil {
var prefix = ""
switch component {
case "EdgeAdmin":
prefix = "admin_"
case "EdgeUser":
prefix = "user_"
}
if len(prefix) == 0 {
continue
}
var filteredMessages = map[langs.MessageCode]string{}
for code, value := range messageLang.GetAll() {
if strings.HasPrefix(code.String(), prefix) && strings.Contains(code.String(), "@ui_") /** must contains 'ui' **/ {
filteredMessages[code] = value
}
}
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'
window.LANG_MESSAGES = `+string(messageMapJSON)+";\n"), 0666)
if err != nil {
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
}
}
}
}
}
fmt.Println("success")
}
func upperWords(s string) string {
var pieces = strings.Split(s, "@")
for pieceIndex, piece := range pieces {
var words = strings.Split(piece, "_")
for index, word := range words {
words[index] = upperWord(word)
}
pieces[pieceIndex] = strings.Join(words, "")
}
return strings.Join(pieces, "_")
}
func upperWord(word string) string {
var l = len(word)
if l == 0 {
return ""
}
if l == 1 {
return strings.ToUpper(word)
}
// special words
switch word {
case "api", "http", "https", "tcp", "tls", "ssl", "udp", "ip", "dns", "ns",
"waf", "acme", "ssh", "toa", "http2", "http3", "uam", "cc",
"db", "isp", "sni", "ui", "soa", "ocsp", "en", "zh", "ad", "tsig",
"rpc", "dao":
return strings.ToUpper(word)
case "ipv6":
return "IPv6"
case "ddos":
return "DDoS"
case "webp":
return "WebP"
case "doh":
return "DoH"
}
return strings.ToUpper(word[:1]) + word[1:]
}
func runSearch() {
if len(os.Args) < 3 {
fmt.Println("Usage: langs search DIR")
return
}
var dir = os.Args[2]
stat, err := os.Stat(dir)
if err != nil {
fmt.Println("[ERROR]could not find dir '" + dir + "': " + err.Error())
return
}
if !stat.IsDir() {
fmt.Println("[ERROR]could not find dir '" + dir + "'")
return
}
fmt.Println("searching '" + dir + "' ...")
var ext = ".go"
var resultFiles = []string{}
for _, pattern := range []string{
"*" + ext,
strings.Repeat("*/", 1) + "*" + ext,
strings.Repeat("*/", 2) + "*" + ext,
strings.Repeat("*/", 3) + "*" + ext,
strings.Repeat("*/", 4) + "*" + ext,
strings.Repeat("*/", 5) + "*" + ext,
strings.Repeat("*/", 6) + "*" + ext,
strings.Repeat("*/", 7) + "*" + ext,
strings.Repeat("*/", 8) + "*" + ext,
strings.Repeat("*/", 9) + "*" + ext,
strings.Repeat("*/", 10) + "*" + ext,
} {
goFiles, err := filepath.Glob(dir + "/" + pattern)
if err != nil {
fmt.Println("[ERROR]search error: " + err.Error())
return
}
resultFiles = append(resultFiles, goFiles...)
}
if len(resultFiles) == 0 {
fmt.Println("no files found in the dir")
return
}
if err != nil {
fmt.Println("[ERROR]search dir '" + dir + "' failed: " + err.Error())
return
}
var hansRegexp = regexp.MustCompile(`\p{Han}+`)
var countMatches = 0
for _, goFile := range resultFiles {
if strings.HasSuffix(goFile, "_test.go") ||
strings.HasSuffix(goFile, "_plus_test.go") ||
strings.Contains(goFile, "/messages/messages_") {
continue
}
data, err := os.ReadFile(goFile)
if err != nil {
fmt.Println("[ERROR]read file '" + goFile + "' failed: " + err.Error())
return
}
var matches = hansRegexp.FindAllSubmatchIndex(data, -1)
if len(matches) > 0 {
for _, match := range matches {
// ignore comment
switch ext {
case ".go":
if checkIsInGoComment(data, match[0]) {
continue
}
}
countMatches++
fmt.Printf("%s %s\n", goFile+":"+types.String(bytes.Count(data[:match[0]], []byte{'\n'})+1), string(data[match[0]:match[1]]))
}
}
}
fmt.Println(countMatches, "matches")
}
func checkIsInGoComment(data []byte, start int) bool {
if start <= 1 {
return false
}
for {
start--
if start <= 1 || data[start] == '\n' {
return false
}
// 'SPACE //'
if data[start] == '/' && data[start-1] == '/' {
return true
}
// '/** SOMETHING **/'
if data[start] == '*' && data[start-1] == '/' {
return true
}
}
}

View File

@@ -1,4 +1,4 @@
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
// Copyright 2022 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
package main

21
go.mod
View File

@@ -1,18 +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-20220304043459-0dd944a5b475
golang.org/x/net v0.8.0
google.golang.org/grpc v1.45.0
google.golang.org/protobuf v1.27.1
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
github.com/iwind/TeaGo v0.0.0-20230623080147-cd1e53b4915f
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 (
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
github.com/golang/protobuf v1.5.3 // indirect
github.com/kr/text v0.2.0 // 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
)

231
go.sum
View File

@@ -1,209 +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=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/DataDog/sketches-go v0.0.0-20190923095040-43f19ad77ff7/go.mod h1:Q5DbzQ+3AkgGwymQO7aZFNP7ns2lZKGtvRBzRXfdi60=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM=
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/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/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgryski/go-rendezvous v0.0.0-20200624174652-8d2f3be8b2d9/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
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.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-redis/redis/v8 v8.0.0-beta.7/go.mod h1:FGJAWDWFht1sQ4qxyJHZZbVyvnVcKQN0E3u5/5lRz+g=
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
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/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
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/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
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/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/iwind/TeaGo v0.0.0-20220304043459-0dd944a5b475 h1:EseyfFaQOjWanGiby9KMw7PjDBMg/95tLDgIw/ns0Cw=
github.com/iwind/TeaGo v0.0.0-20220304043459-0dd944a5b475/go.mod h1:HRHK0zoC/og3c9/hKosD9yYVMTnnzm3PgXUdhRYHaLc=
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
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/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/opentracing/opentracing-go v1.1.1-0.20190913142402-a7454ce5950e/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
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/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
go.opentelemetry.io/otel v0.7.0/go.mod h1:aZMyHG5TqDOXEgH2tyLiXSUKly1jT3yqE9PmrzIeCdo=
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-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
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/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20200513190911-00229845015e/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
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/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
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-20180906233101-161cd47e91fd/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-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
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.2.0 h1:sZfSu1wtKLGlWI4ZZayP0ck9Y73K1ynO6gqzTdBVdPU=
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
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-20180909124046-d0be0721c37e/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-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/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.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A=
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
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.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
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.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
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/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
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-20191009194640-548a555dbc03/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
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.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
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/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
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.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/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=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@@ -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 {

View File

@@ -1,27 +1,14 @@
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
// Copyright 2021 GoEdge CDN goedge.cdn@gmail.com. All rights reserved.
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")))
@@ -39,3 +26,7 @@ func TestIPVersion(t *testing.T) {
a.IsTrue(configutils.IPVersion(net.ParseIP("::1")) == 6)
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")))
}

View File

@@ -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
}
}

View File

@@ -1,21 +1,31 @@
package configutils
import (
"crypto/sha1"
"crypto/sha256"
"encoding/base64"
"fmt"
stringutil "github.com/iwind/TeaGo/utils/string"
"net/url"
"regexp"
"strconv"
"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 +56,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 +72,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))
}
@@ -66,6 +84,18 @@ func ParseVariables(source string, replacer func(varName string) (value string))
return builder.String()
}
func ParseVariablesError(source string, replacer func(varName string) (value string, err error)) (string, error) {
var resultErr error
var result = ParseVariables(source, func(varName string) (value string) {
replacedValue, err := replacer(varName)
if err != nil {
resultErr = err
}
return replacedValue
})
return result, resultErr
}
// ParseVariablesFromHolders 从占位中分析变量
func ParseVariablesFromHolders(holders VariableHolders, replacer func(varName string) (value string)) string {
// no variables
@@ -74,11 +104,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))
}
@@ -88,12 +122,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) {
@@ -109,3 +155,39 @@ 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)
case "quote":
value = strconv.Quote(value)
}
}
return value
}

View File

@@ -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,151 @@ 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 + "}"
}))
// quote
t.Log("quote(abc)", "=>", configutils.ParseVariables("${var|quote}", func(varName string) (value string) {
switch varName {
case "var":
return "abc"
}
return "${" + varName + "}"
}))
t.Log("quote(\"ABC\"123)", "=>", configutils.ParseVariables("${var|quote}", func(varName string) (value string) {
switch varName {
case "var":
return "\"ABC\"123"
}
return "${" + varName + "}"
}))
t.Log("quote('ABC'123)", "=>", configutils.ParseVariables("${var|quote}", func(varName string) (value string) {
switch varName {
case "var":
return "'ABC'123"
}
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 +162,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 +170,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 +181,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 +191,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 +199,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 +207,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"
})
}

View File

@@ -0,0 +1,29 @@
// Copyright 2023 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
package dnsconfigs
import (
"github.com/TeaOSLab/EdgeCommon/pkg/configutils"
"github.com/iwind/TeaGo/types"
)
type DNSResolver struct {
Host string `json:"host"`
Port int `json:"port"`
Protocol string `json:"protocol"`
}
func (this *DNSResolver) Addr() string {
var port = this.Port
if port <= 0 {
// 暂时不支持DoH
// 实际应用中只支持udp
switch this.Protocol {
case "tls":
port = 853
default:
port = 53
}
}
return configutils.QuoteIP(this.Host) + ":" + types.String(port)
}

View File

@@ -1,4 +1,4 @@
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
// Copyright 2021 GoEdge CDN goedge.cdn@gmail.com. All rights reserved.
package dnsconfigs

View File

@@ -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,
}
}

View File

@@ -1 +1,2 @@
*-plus.db
*-plus.db
internal-ip-library-test.db

View File

@@ -1,4 +1,4 @@
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
// Copyright 2022 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
package iplibrary
@@ -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
}

View File

@@ -1,4 +1,4 @@
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
// Copyright 2022 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
package iplibrary_test
@@ -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)
}

View File

@@ -1,4 +1,4 @@
// Copyright 2023 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
// Copyright 2023 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
package iplibrary

View File

@@ -1,4 +1,4 @@
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
// Copyright 2022 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
package iplibrary
@@ -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

View File

@@ -1,4 +1,4 @@
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
// Copyright 2022 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
package iplibrary

View File

@@ -1,3 +1,3 @@
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
// Copyright 2022 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
package iplibrary_test

View File

@@ -1,4 +1,4 @@
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
// Copyright 2022 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
package iplibrary

View File

@@ -1,4 +1,4 @@
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
// Copyright 2022 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
package iplibrary

View File

@@ -1,4 +1,4 @@
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
// Copyright 2022 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
package iplibrary

View File

@@ -1,4 +1,4 @@
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
// Copyright 2022 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
package iplibrary_test

View File

@@ -1,4 +1,4 @@
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
// Copyright 2022 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
package iplibrary_test

View File

@@ -1,14 +1,17 @@
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
// Copyright 2022 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
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()
}

View File

@@ -1,19 +1,21 @@
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
// Copyright 2022 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
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
}

View File

@@ -1,4 +1,4 @@
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
// Copyright 2022 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
package iplibrary_test
@@ -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)
}

View 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()
}

View File

@@ -1,4 +1,4 @@
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
// Copyright 2022 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
package iplibrary
@@ -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
}

View File

@@ -1,4 +1,4 @@
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
// Copyright 2022 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
package iplibrary_test
@@ -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
View File

@@ -0,0 +1,360 @@
// Copyright 2022 GoEdge CDN goedge.cdn@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
}

View File

@@ -1,4 +1,4 @@
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
// Copyright 2022 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
package iplibrary
@@ -70,6 +70,11 @@ func (this *Template) Extract(text string, emptyValues []string) (values map[str
}
}
// 自动修复省略的城市名
if len(values["city"]) == 0 && len(values["province"]) > 0 && len(values["town"]) > 0 {
values["city"] = values["province"]
}
ok = true
return
}

View File

@@ -1,4 +1,4 @@
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
// Copyright 2022 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
package iplibrary_test

View File

@@ -1,9 +1,10 @@
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
// Copyright 2022 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
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
}

View File

@@ -1,4 +1,4 @@
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
// Copyright 2022 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
package iplibrary_test

View File

@@ -1,4 +1,4 @@
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
// Copyright 2022 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
package iplibrary

View File

@@ -1,44 +1,21 @@
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
// Copyright 2022 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
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()
}

View File

@@ -1,4 +1,4 @@
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
// Copyright 2022 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
package iplibrary
@@ -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

View File

@@ -1,4 +1,4 @@
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
// Copyright 2022 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
package iplibrary_test
@@ -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)
}

View 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
View File

@@ -0,0 +1,190 @@
// Copyright 2022 GoEdge CDN goedge.cdn@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)
}

View File

@@ -1,16 +1,18 @@
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
// Copyright 2022 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
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
View 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
View 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
View 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
View 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")
}
}

733
pkg/langs/codes/codes.go Normal file
View File

@@ -0,0 +1,733 @@
// generated by run 'langs generate'
package codes
import (
"github.com/TeaOSLab/EdgeCommon/pkg/langs"
)
const (
ACMEProviderAccount_LogCreateACMEProviderAccount langs.MessageCode = "acme_provider_account@log_create_acme_provider_account" // 创建ACME服务商账号 %d
ACMEProviderAccount_LogDeleteACMEProviderAccount langs.MessageCode = "acme_provider_account@log_delete_acme_provider_account" // 删除ACME服务商账号 %d
ACMEProviderAccount_LogUpdateACMEProviderAccount langs.MessageCode = "acme_provider_account@log_update_acme_provider_account" // 修改ACME服务商账号 %d
ACMETask_LogCreateACMETask langs.MessageCode = "acme_task@log_create_acme_task" // 创建证书申请任务 %d
ACMETask_LogDeleteACMETask langs.MessageCode = "acme_task@log_delete_acme_task" // 删除证书申请任务 %d
ACMETask_LogRunACMETask langs.MessageCode = "acme_task@log_run_acme_task" // 执行ACME任务 %d
ACMETask_LogUpdateACMETask langs.MessageCode = "acme_task@log_update_acme_task" // 修改证书申请任务 %d
ACMEUser_LogCreateACMEUser langs.MessageCode = "acme_user@log_create_acme_user" // 创建ACME用户 %d
ACMEUser_LogDeleteACMEUser langs.MessageCode = "acme_user@log_delete_acme_user" // 删除ACME用户 %d
ACMEUser_LogUpdateACMEUser langs.MessageCode = "acme_user@log_update_acme_user" // 修改ACME用户 %d
ADNetwork_LogCreateADNetwork langs.MessageCode = "ad_network@log_create_ad_network" // 创建高防IP线路 %d
ADNetwork_LogDeleteADNetwork langs.MessageCode = "ad_network@log_delete_ad_network" // 删除高防IP线路
ADNetwork_LogUpdateADNetwork langs.MessageCode = "ad_network@log_update_ad_network" // 修改高防IP线路 %d
ADPackage_LogCreateADPackage langs.MessageCode = "ad_package@log_create_ad_package" // 创建高防产品 %d
ADPackage_LogDeleteADPackage langs.MessageCode = "ad_package@log_delete_ad_package" // 删除高防产品 %d
ADPackage_LogUpdateADPackage langs.MessageCode = "ad_package@log_update_ad_package" // 修改高防产品 %d
ADPackageInstance_LogCreateADPackageInstance langs.MessageCode = "ad_package_instance@log_create_ad_package_instance" // 创建高防实例 %d
ADPackageInstance_LogDeleteADPackageInstance langs.MessageCode = "ad_package_instance@log_delete_ad_package_instance" // 删除高防实例 %d
ADPackageInstance_LogUpdateADPackageInstance langs.MessageCode = "ad_package_instance@log_update_ad_package_instance" // 修改高防实例 %d
ADPackagePeriod_LogCreateADPackagePeriod langs.MessageCode = "ad_package_period@log_create_ad_package_period" // 创建高防IP实例有效期 %d
ADPackagePeriod_LogDeleteADPackagePeriod langs.MessageCode = "ad_package_period@log_delete_ad_package_period" // 删除高防IP实例有效期选项 %d
ADPackagePeriod_LogUpdateADPackagePeriod langs.MessageCode = "ad_package_period@log_update_ad_package_period" // 修改高防IP实例有效期选项 %d
ADPackagePrice_LogCreateADPackagePrice langs.MessageCode = "ad_package_price@log_create_ad_package_price" // 为用户 %d 创建高防实例:%d有效期%d数量%d
ADPackagePrice_LogUpdateADPackagePrice langs.MessageCode = "ad_package_price@log_update_ad_package_price" // 修改高防产品 %d 有效期 %d 的价格
Admin_LogCreateAdmin langs.MessageCode = "admin@log_create_admin" // 创建系统用户 %d
Admin_LogDeleteAdmin langs.MessageCode = "admin@log_delete_admin" // 删除系统用户 %d
Admin_LogUpdateAdmin langs.MessageCode = "admin@log_update_admin" // 修改系统用户 %d
AdminCommon_Canceled langs.MessageCode = "admin_common@canceled" // 已取消
AdminCommon_LogSystemError langs.MessageCode = "admin_common@log_system_error" // 系统发生错误:%s
AdminCommon_MenuSettingBasic langs.MessageCode = "admin_common@menu_setting_basic" // 基础设置
AdminCommon_MenuSettingCache langs.MessageCode = "admin_common@menu_setting_cache" // 缓存设置
AdminCommon_MenuSettingCachePolicy langs.MessageCode = "admin_common@menu_setting_cache_policy" // 缓存策略
AdminCommon_MenuSettingDDoSProtection langs.MessageCode = "admin_common@menu_setting_ddos_protection" // DDoS防护
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> &nbsp; &nbsp; <a href="https://goedge.cn/docs/APINode/QA.md" target="_blank">[调整数据库binlog设置]</a>
AdminDashboard_UIDNS langs.MessageCode = "admin_dashboard@ui_dns" // DNS
AdminDashboard_UIEvents langs.MessageCode = "admin_dashboard@ui_events" // 事件
AdminDashboard_UIOverview langs.MessageCode = "admin_dashboard@ui_overview" // 概况
AdminDashboard_UIUser langs.MessageCode = "admin_dashboard@ui_user" // 用户
AdminDashboard_UIWAF langs.MessageCode = "admin_dashboard@ui_waf" // WAF
AdminLogin_LogFailed langs.MessageCode = "admin_login@log_failed" // 登录失败,用户名:%s
AdminLogin_LogOtpVerifiedSuccess langs.MessageCode = "admin_login@log_otp_verified_success" // 成功通过OTP验证登录系统
AdminLogin_LogSuccess langs.MessageCode = "admin_login@log_success" // 成功登录系统,用户名:%s
AdminLogin_LogSystemError langs.MessageCode = "admin_login@log_system_error" // 登录时发生系统错误:%s
AdminLogin_LogUpdateLogin langs.MessageCode = "admin_login@log_update_login" // 修改登录设置
AdminMenu_AdminRecipients langs.MessageCode = "admin_menu@admin_recipients" // 通知媒介
AdminMenu_Admins langs.MessageCode = "admin_menu@admins" // 系统用户
AdminMenu_Dashboard langs.MessageCode = "admin_menu@dashboard" // 数据看板
AdminMenu_DNS langs.MessageCode = "admin_menu@dns" // 域名解析
AdminMenu_DNSClusters langs.MessageCode = "admin_menu@dns_clusters" // 集群列表
AdminMenu_DNSIssues langs.MessageCode = "admin_menu@dns_issues" // 问题修复
AdminMenu_DNSProviders langs.MessageCode = "admin_menu@dns_providers" // DNS服务商
AdminMenu_Finance langs.MessageCode = "admin_menu@finance" // 财务管理
AdminMenu_FinanceAccounts langs.MessageCode = "admin_menu@finance_accounts" // 用户账户
AdminMenu_FinanceBills langs.MessageCode = "admin_menu@finance_bills" // 费用账单
AdminMenu_FinanceFee langs.MessageCode = "admin_menu@finance_fee" // 计费设置
AdminMenu_FinanceIncome langs.MessageCode = "admin_menu@finance_income" // 统计报表
AdminMenu_FinanceLogs langs.MessageCode = "admin_menu@finance_logs" // 收支明细
AdminMenu_FinanceOrders langs.MessageCode = "admin_menu@finance_orders" // 订单管理
AdminMenu_FinancePackages langs.MessageCode = "admin_menu@finance_packages" // 流量包
AdminMenu_Logs langs.MessageCode = "admin_menu@logs" // 日志审计
AdminMenu_NodeAntiDDoSProducts langs.MessageCode = "admin_menu@node_anti_ddos_products" // 高防IP
AdminMenu_NodeClusters langs.MessageCode = "admin_menu@node_clusters" // 集群列表
AdminMenu_NodeDistributedMonitors langs.MessageCode = "admin_menu@node_distributed_monitors" // 区域监控
AdminMenu_NodeIPList langs.MessageCode = "admin_menu@node_ip_list" // 节点IP
AdminMenu_NodeLogs langs.MessageCode = "admin_menu@node_logs" // 节点日志
AdminMenu_NodeRegions langs.MessageCode = "admin_menu@node_regions" // 区域设置
AdminMenu_NodeSSHGrants langs.MessageCode = "admin_menu@node_ssh_grants" // 节点SSH
AdminMenu_Nodes langs.MessageCode = "admin_menu@nodes" // 边缘节点
AdminMenu_NS langs.MessageCode = "admin_menu@ns" // 智能DNS
AdminMenu_NSAccessLogs langs.MessageCode = "admin_menu@ns_access_logs" // 访问日志
AdminMenu_NSClusters langs.MessageCode = "admin_menu@ns_clusters" // 集群管理
AdminMenu_NSDomainBatchOperations langs.MessageCode = "admin_menu@ns_domain_batch_operations" // 批量操作
AdminMenu_NSDomainGroups langs.MessageCode = "admin_menu@ns_domain_groups" // 域名分组
AdminMenu_NSDomains langs.MessageCode = "admin_menu@ns_domains" // 域名管理
AdminMenu_NSNodeLogs langs.MessageCode = "admin_menu@ns_node_logs" // 运行日志
AdminMenu_NSPlans langs.MessageCode = "admin_menu@ns_plans" // 套餐设置
AdminMenu_NSResolveTest langs.MessageCode = "admin_menu@ns_resolve_test" // 解析测试
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" // 日志策略
AdminMenu_ServerAccessLogs langs.MessageCode = "admin_menu@server_access_logs" // 访问日志
AdminMenu_ServerCachePolicies langs.MessageCode = "admin_menu@server_cache_policies" // 缓存策略
AdminMenu_ServerCerts langs.MessageCode = "admin_menu@server_certs" // 证书管理
AdminMenu_ServerGlobalSettings langs.MessageCode = "admin_menu@server_global_settings" // 通用设置
AdminMenu_ServerGroups langs.MessageCode = "admin_menu@server_groups" // 网站分组
AdminMenu_ServerIPLists langs.MessageCode = "admin_menu@server_ip_lists" // IP名单
AdminMenu_ServerMetrics langs.MessageCode = "admin_menu@server_metrics" // 统计指标
AdminMenu_ServerPurgeFetchCaches langs.MessageCode = "admin_menu@server_purge_fetch_caches" // 刷新预热
AdminMenu_ServerScripts langs.MessageCode = "admin_menu@server_scripts" // 脚本库
AdminMenu_ServerTrafficStats langs.MessageCode = "admin_menu@server_traffic_stats" // 用量统计
AdminMenu_ServerWAFPolicies langs.MessageCode = "admin_menu@server_waf_policies" // WAF策略
AdminMenu_Servers langs.MessageCode = "admin_menu@servers" // 网站列表
AdminMenu_SettingAdvancedSettings langs.MessageCode = "admin_menu@setting_advanced_settings" // 高级设置
AdminMenu_SettingAuthority langs.MessageCode = "admin_menu@setting_authority" // 商业版本
AdminMenu_SettingBasicSettings langs.MessageCode = "admin_menu@setting_basic_settings" // 基础设置
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" // 修改个人资料
AdminSecurity_LogUpdateSecuritySettings langs.MessageCode = "admin_security@log_update_security_settings" // 修改管理界面安全设置
AdminServer_LogUpdateServerHTTPSettings langs.MessageCode = "admin_server@log_update_server_http_settings" // 修改管理界面的HTTP设置
AdminServer_LogUpdateServerHTTPSSettings langs.MessageCode = "admin_server@log_update_server_https_settings" // 修改管理界面的HTTPS设置
AdminSetting_TabAccessLogDatabases langs.MessageCode = "admin_setting@tab_access_log_databases" // 日志数据库
AdminSetting_TabAdminSecuritySettings langs.MessageCode = "admin_setting@tab_admin_security_settings" // 安全设置
AdminSetting_TabAdminServer langs.MessageCode = "admin_setting@tab_admin_server" // Web服务
AdminSetting_TabAdminUI langs.MessageCode = "admin_setting@tab_admin_ui" // 管理界面设置
AdminSetting_TabAPINodes langs.MessageCode = "admin_setting@tab_api_nodes" // API节点
AdminSetting_TabAuthority langs.MessageCode = "admin_setting@tab_authority" // 商业版认证
AdminSetting_TabBackup langs.MessageCode = "admin_setting@tab_backup" // 备份
AdminSetting_TabClientBrowsers langs.MessageCode = "admin_setting@tab_client_browsers" // 浏览器库
AdminSetting_TabClientOperationSystems langs.MessageCode = "admin_setting@tab_client_operation_systems" // 操作系统库
AdminSetting_TabDatabase langs.MessageCode = "admin_setting@tab_database" // 数据库
AdminSetting_TabIPLibrary langs.MessageCode = "admin_setting@tab_ip_library" // IP库
AdminSetting_TabLogin langs.MessageCode = "admin_setting@tab_login" // 登录设置
AdminSetting_TabMonitorNodes langs.MessageCode = "admin_setting@tab_monitor_nodes" // 监控节点
AdminSetting_TabProfile langs.MessageCode = "admin_setting@tab_profile" // 个人资料
AdminSetting_TabTransfer langs.MessageCode = "admin_setting@tab_transfer" // 迁移
AdminSetting_TabUpdates langs.MessageCode = "admin_setting@tab_updates" // 检查更新
AdminSetting_TabUserNodes langs.MessageCode = "admin_setting@tab_user_nodes" // 用户节点
AdminSetting_TabUserUI langs.MessageCode = "admin_setting@tab_user_ui" // 用户界面设置
AdminUI_DefaultProductName langs.MessageCode = "admin_ui@default_product_name" // GoEdge
AdminUI_DefaultSystemName langs.MessageCode = "admin_ui@default_system_name" // GoEdge管理员系统
AdminUI_LogUpdateUISettings langs.MessageCode = "admin_ui@log_update_ui_settings" // 修改管理界面设置
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
ClientBrowser_LogCreateBrowser langs.MessageCode = "client_browser@log_create_browser" // 创建浏览器信息 %s
ClientBrowser_LogUpdateClientBrowser langs.MessageCode = "client_browser@log_update_client_browser" // 修改浏览器信息 %d
ClientSystem_LogCreateSystem langs.MessageCode = "client_system@log_create_system" // 创建操作系统信息 %s
ClientSystem_LogUpdateClientSystem langs.MessageCode = "client_system@log_update_client_system" // 修改操作系统信息 %d
Database_LogDeleteTable langs.MessageCode = "database@log_delete_table" // 删除数据表 %s
Database_LogTruncateTable langs.MessageCode = "database@log_truncate_table" // 清空数据表 %s 数据
Database_LogUpdateAPINodeDatabaseConfig langs.MessageCode = "database@log_update_api_node_database_config" // 修改API节点数据库设置
Database_LogUpdateCleanDays langs.MessageCode = "database@log_update_clean_days" // 修改数据库自动清理设置
DBNode_LogCreateDBNode langs.MessageCode = "db_node@log_create_db_node" // 创建数据库节点 %d
DBNode_LogDeleteDBNode langs.MessageCode = "db_node@log_delete_db_node" // 删除数据库节点 %d
DBNode_LogDeleteTable langs.MessageCode = "db_node@log_delete_table" // 删除数据库节点 %d 数据表 %s
DBNode_LogTruncateTable langs.MessageCode = "db_node@log_truncate_table" // 清空数据库节点 %d 数据表 %s 数据
DBNode_LogUpdateDBNode langs.MessageCode = "db_node@log_update_db_node" // 修改数据库节点 %d
DBNode_TabNodes langs.MessageCode = "db_node@tab_nodes" // 数据库节点
DDoSProtection_LogUpdateClusterDDoSProtection langs.MessageCode = "ddos_protection@log_update_cluster_ddos_protection" // 修改集群 %d 的DDOS防护设置
DDoSProtection_LogUpdateNodeDDoSProtection langs.MessageCode = "ddos_protection@log_update_node_ddos_protection" // 修改节点 %d 的DDOS防护设置
DNS_LogCreateDomain langs.MessageCode = "dns@log_create_domain" // 添加管理域名到DNS服务商 %d
DNS_LogDeleteDomain langs.MessageCode = "dns@log_delete_domain" // 从DNS服务商中删除域名 %d
DNS_LogRecoverDomain langs.MessageCode = "dns@log_recover_domain" // 从DNS服务商中恢复域名 %d
DNS_LogSyncCluster langs.MessageCode = "dns@log_sync_cluster" // 同步集群 %d 的DNS设置
DNS_LogSyncDomain langs.MessageCode = "dns@log_sync_domain" // 同步DNS域名数据 %d
DNS_LogUpdateClusterDNS langs.MessageCode = "dns@log_update_cluster_dns" // 修改集群 %d DNS设置
DNS_LogUpdateDomain langs.MessageCode = "dns@log_update_domain" // 修改DNS服务商域名 %d
DNS_LogUpdateNodeDNS langs.MessageCode = "dns@log_update_node_dns" // 修改节点 %d 的DNS设置
DNSProvider_LogCreateDNSProvider langs.MessageCode = "dns_provider@log_create_dns_provider" // 创建DNS服务商 %d
DNSProvider_LogDeleteDNSProvider langs.MessageCode = "dns_provider@log_delete_dns_provider" // 删除DNS服务商 %d
DNSProvider_LogUpdateDNSProvider langs.MessageCode = "dns_provider@log_update_dns_provider" // 修改DNS服务商 %d
DNSTask_LogDeleteAllDNSTasks langs.MessageCode = "dns_task@log_delete_all_dns_tasks" // 删除所有DNS同步任务
DNSTask_LogDeleteDNSTask langs.MessageCode = "dns_task@log_delete_dns_task" // 删除DNS同步任务 %d
Finance_LogBillGenerateManually langs.MessageCode = "finance@log_bill_generate_manually" // 手动生成上个月 %s 账单
Finance_LogUpdateUserOrderConfig langs.MessageCode = "finance@log_update_user_order_config" // 修改订单设置
FinanceFee_LogUpdateFeeSetting langs.MessageCode = "finance_fee@log_update_fee_setting" // 修改默认计费方式
HTTPAccessLogPolicy_LogCreateHTTPAccessLogPolicy langs.MessageCode = "http_access_log_policy@log_create_http_access_log_policy" // 创建访问日志策略 %d
HTTPAccessLogPolicy_LogDeleteHTTPAccessLogPolicy langs.MessageCode = "http_access_log_policy@log_delete_http_access_log_policy" // 删除访问日志策略 %d
HTTPAccessLogPolicy_LogTestHTTPAccessLogPolicy langs.MessageCode = "http_access_log_policy@log_test_http_access_log_policy" // 测试向访问日志策略 %d 写入数据
HTTPAccessLogPolicy_LogUpdateHTTPAccessLogPolicy langs.MessageCode = "http_access_log_policy@log_update_http_access_log_policy" // 修改访问日志策略 %d
HTTPAuthPolicy_LogCreateHTTPAuthPolicy langs.MessageCode = "http_auth_policy@log_create_http_auth_policy" // 创建HTTP鉴权 %d
HTTPAuthPolicy_LogUpdateHTTPAuthPolicy langs.MessageCode = "http_auth_policy@log_update_http_auth_policy" // 修改HTTP鉴权 %d
HTTPCacheTask_LogCreateHTTPCacheTaskFetch langs.MessageCode = "http_cache_task@log_create_http_cache_task_fetch" // 批量预热缓存Key
HTTPCacheTask_LogCreateHTTPCacheTaskPurge langs.MessageCode = "http_cache_task@log_create_http_cache_task_purge" // 批量刷新缓存Key
HTTPCacheTask_LogDeleteHTTPCacheTask langs.MessageCode = "http_cache_task@log_delete_http_cache_task" // 删除缓存任务 %d
HTTPCacheTask_LogResetHTTPCacheTask langs.MessageCode = "http_cache_task@log_reset_http_cache_task" // 重置缓存任务 %d 状态
HTTPFastcgi_LogCreateHTTPFastcgi langs.MessageCode = "http_fastcgi@log_create_http_fastcgi" // 创建Fastcgi %d
HTTPFastcgi_LogUpdateHTTPFastcgi langs.MessageCode = "http_fastcgi@log_update_http_fastcgi" // 修改Fastcgi %d
HTTPLocation_LogCreateHTTPLocation langs.MessageCode = "http_location@log_create_http_location" // 创建路由规则:%s
HTTPLocation_LogUpdateHTTPLocation langs.MessageCode = "http_location@log_update_http_location" // 修改路由规则 %d 设置
HTTPRewriteRule_LogCreateRewriteRule langs.MessageCode = "http_rewrite_rule@log_create_rewrite_rule" // 在Web %d 中创建重写规则 %d
HTTPRewriteRule_LogDeleteRewriteRule langs.MessageCode = "http_rewrite_rule@log_delete_rewrite_rule" // 从Web %d 中删除重写规则 %d
HTTPRewriteRule_LogSortRewriteRules langs.MessageCode = "http_rewrite_rule@log_sort_rewrite_rules" // 对Web %d 中的重写规则进行排序
HTTPRewriteRule_LogUpdateRewriteRule langs.MessageCode = "http_rewrite_rule@log_update_rewrite_rule" // 修改Web %d 中的重写规则 %d
IPItem_LogCreateIPItem langs.MessageCode = "ip_item@log_create_ip_item" // 在名单 %d 中创建IP %d
IPItem_LogDeleteIPItem langs.MessageCode = "ip_item@log_delete_ip_item" // 从IP名单 %d 中删除IP %d
IPItem_LogReadAllIPItems langs.MessageCode = "ip_item@log_read_all_ip_items" // 将所有IP名单置为已读
IPItem_LogUpdateIPItem langs.MessageCode = "ip_item@log_update_ip_item" // 修改IP名单中的IP %d
IPLibrary_LogFinishIPLibrary langs.MessageCode = "ip_library@log_finish_ip_library" // 完成IP库%d 制作
IPLibraryArtifact_LogCancelIPLibraryArtifact langs.MessageCode = "ip_library_artifact@log_cancel_ip_library_artifact" // 取消使用IP库 %d
IPLibraryArtifact_LogDeleteIPLibraryArtifact langs.MessageCode = "ip_library_artifact@log_delete_ip_library_artifact" // 删除IP库 %d
IPLibraryArtifact_LogUseIPLibraryArtifact langs.MessageCode = "ip_library_artifact@log_use_ip_library_artifact" // 使用IP库 %d
IPLibraryFile_LogDeleteIPLibraryFile langs.MessageCode = "ip_library_file@log_delete_ip_library_file" // 删除IP库文件 %d
IPLibraryFile_LogGenerateIPLibraryFile langs.MessageCode = "ip_library_file@log_generate_ip_library_file" // 重新生成IP库 %d 文件
IPLibraryFile_LogUploadIPLibraryFile langs.MessageCode = "ip_library_file@log_upload_ip_library_file" // 上传IP库 %d
IPList_LogBindIPListWAFPolicy langs.MessageCode = "ip_list@log_bind_ip_list_waf_policy" // 绑定IP名单 %d 到WAF策略 %d
IPList_LogCreateIPItemsBatch langs.MessageCode = "ip_list@log_create_ip_items_batch" // 在IP名单 %d 中批量添加IP
IPList_LogCreateIPList langs.MessageCode = "ip_list@log_create_ip_list" // 创建IP名单 %d
IPList_LogDeleteIPBatch langs.MessageCode = "ip_list@log_delete_ip_batch" // 批量删除IP名单中的IP%s
IPList_LogDeleteIPList langs.MessageCode = "ip_list@log_delete_ip_list" // 删除IP名单 %d
IPList_LogExportIPList langs.MessageCode = "ip_list@log_export_ip_list" // 导出IP名单 %d
IPList_LogImportIPList langs.MessageCode = "ip_list@log_import_ip_list" // 导入IP名单 %d
IPList_LogUnbindIPListWAFPolicy langs.MessageCode = "ip_list@log_unbind_ip_list_waf_policy" // 解除绑定IP名单 %d WAF策略 %d
IPList_LogUpdateIPList langs.MessageCode = "ip_list@log_update_ip_list" // 修改IP名单 %d
Level_Error langs.MessageCode = "level@error" // 错误
Level_Info langs.MessageCode = "level@info" // 信息
Level_Warn langs.MessageCode = "level@warn" // 警告
Log_LogCleanAllLogs langs.MessageCode = "log@log_clean_all_logs" // 清除全部日志
Log_LogCleanLogsDaysBefore langs.MessageCode = "log@log_clean_logs_days_before" // 清除 %d 以前的日志
Log_LogDeleteLog langs.MessageCode = "log@log_delete_log" // 删除单个操作日志 %d
Log_LogUpdateSettings langs.MessageCode = "log@log_update_settings" // 修改日志相关配置
Log_TagAccessLog langs.MessageCode = "log@tag_access_log" // 访问日志
Log_TagListener langs.MessageCode = "log@tag_listener" // 端口监听
Log_TagScript langs.MessageCode = "log@tag_script" // 脚本
Log_TagWAF langs.MessageCode = "log@tag_waf" // WAF
Message_LogReadAll langs.MessageCode = "message@log_read_all" // 将所有消息置为已读
Message_LogReadMessages langs.MessageCode = "message@log_read_messages" // 将一组消息置为已读
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
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
MetricItem_LogAddMetricItemToCluster langs.MessageCode = "metric_item@log_add_metric_item_to_cluster" // 添加指标 %d 到集群 %d
MetricItem_LogCreateMetricItem langs.MessageCode = "metric_item@log_create_metric_item" // 创建统计指标 %d
MetricItem_LogDeleteMetricItem langs.MessageCode = "metric_item@log_delete_metric_item" // 删除统计指标
MetricItem_LogDeleteMetricItemFromCluster langs.MessageCode = "metric_item@log_delete_metric_item_from_cluster" // 从集群 %d 中移除指标 %d
MetricItem_LogUpdateMetricItem langs.MessageCode = "metric_item@log_update_metric_item" // 修改统计指标 %d
MonitorNode_LogCreateMonitorNode langs.MessageCode = "monitor_node@log_create_monitor_node" // 创建监控节点 %d
MonitorNode_LogDeleteMonitorNode langs.MessageCode = "monitor_node@log_delete_monitor_node" // 删除监控节点 %d
MonitorNode_LogUpdateMonitorNode langs.MessageCode = "monitor_node@log_update_monitor_node" // 修改监控节点 %d
Node_LogCreateNode langs.MessageCode = "node@log_create_node" // 创建节点 %d
Node_LogCreateNodeBatch langs.MessageCode = "node@log_create_node_batch" // 批量创建节点
Node_LogDeleteNodeFromCluster langs.MessageCode = "node@log_delete_node_from_cluster" // 从集群 %d 中删除节点 %d
Node_LogInstallNode langs.MessageCode = "node@log_install_node" // 安装节点 %d
Node_LogInstallNodeRemotely langs.MessageCode = "node@log_install_node_remotely" // 远程安装节点 %d
Node_LogStartNodeRemotely langs.MessageCode = "node@log_start_node_remotely" // 远程启动节点 %d
Node_LogStopNodeRemotely langs.MessageCode = "node@log_stop_node_remotely" // 远程停止节点 %d
Node_LogUninstallNodeRemotely langs.MessageCode = "node@log_uninstall_node_remotely" // 远程卸载节点 %d
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 调度动作到集群
NodeAction_LogCopyNodeActionsToGroup langs.MessageCode = "node_action@log_copy_node_actions_to_group" // 复制节点 %d 调度动作到分组
NodeAction_LogCreateNodeAction langs.MessageCode = "node_action@log_create_node_action" // 创建动作 %d
NodeAction_LogDeleteNodeAction langs.MessageCode = "node_action@log_delete_node_action" // 删除节点动作 %d
NodeAction_LogSortNodeActions langs.MessageCode = "node_action@log_sort_node_actions" // 修改节点 %d 动作排序
NodeAction_LogUpdateNodeAction langs.MessageCode = "node_action@log_update_node_action" // 修改节点动作 %d
NodeCache_LogUpdateNodeCacheSettings langs.MessageCode = "node_cache@log_update_node_cache_settings" // 修改节点 %d 缓存设置
NodeCluster_LogCreateCluster langs.MessageCode = "node_cluster@log_create_cluster" // 创建节点集群:%d
NodeCluster_LogDeleteCluster langs.MessageCode = "node_cluster@log_delete_cluster" // 删除集群 %d
NodeCluster_LogPinCluster langs.MessageCode = "node_cluster@log_pin_cluster" // 置顶集群 %d
NodeCluster_LogRunClusterHealthCheck langs.MessageCode = "node_cluster@log_run_cluster_health_check" // 执行集群健康检查设置 %d
NodeCluster_LogUnpinCluster langs.MessageCode = "node_cluster@log_unpin_cluster" // 取消置顶集群 %d
NodeCluster_LogUpdateClusterBasicSettings langs.MessageCode = "node_cluster@log_update_cluster_basic_settings" // 修改集群基础设置 %d
NodeCluster_LogUpdateClusterHealthCheck langs.MessageCode = "node_cluster@log_update_cluster_health_check" // 修改集群健康检查设置 %d
NodeClusterMenu_SettingBasic langs.MessageCode = "node_cluster_menu@setting_basic" // 基础设置
NodeClusterMenu_SettingCachePolicy langs.MessageCode = "node_cluster_menu@setting_cache_policy" // 缓存策略
NodeClusterMenu_SettingCC langs.MessageCode = "node_cluster_menu@setting_cc" // CC防护
NodeClusterMenu_SettingDDoSProtection langs.MessageCode = "node_cluster_menu@setting_ddos_protection" // DDoS防护
NodeClusterMenu_SettingDNS langs.MessageCode = "node_cluster_menu@setting_dns" // DNS设置
NodeClusterMenu_SettingHealthCheck langs.MessageCode = "node_cluster_menu@setting_health_check" // 健康检查
NodeClusterMenu_SettingHTTP3 langs.MessageCode = "node_cluster_menu@setting_http3" // HTTP/3
NodeClusterMenu_SettingMetrics langs.MessageCode = "node_cluster_menu@setting_metrics" // 统计指标
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" // 阈值设置
NodeClusterMenu_SettingTOA langs.MessageCode = "node_cluster_menu@setting_toa" // TOA设置
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_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" // 节点列表
NodeClusterMenu_TabClusterSettings langs.MessageCode = "node_cluster_menu@tab_cluster_settings" // 集群设置
NodeDNS_LogUpdateNodeDNS langs.MessageCode = "node_dns@log_update_node_dns" // 修改节点 %d DNS设置
NodeGrant_LogCreateSSHGrant langs.MessageCode = "node_grant@log_create_ssh_grant" // 创建SSH认证 %d
NodeGrant_LogDeleteSSHGrant langs.MessageCode = "node_grant@log_delete_ssh_grant" // 删除SSH认证 %d
NodeGrant_LogUpdateSSHGrant langs.MessageCode = "node_grant@log_update_ssh_grant" // 修改SSH认证 %d
NodeGrant_MethodPrivateKey langs.MessageCode = "node_grant@method_private_key" // 私钥
NodeGrant_MethodUserPassword langs.MessageCode = "node_grant@method_user_password" // 用户名+密码
NodeGroup_LogCreateNodeGroup langs.MessageCode = "node_group@log_create_node_group" // 创建节点分组 %d
NodeGroup_LogDeleteNodeGroup langs.MessageCode = "node_group@log_delete_node_group" // 删除节点分组 %d
NodeGroup_LogSortNodeGroups langs.MessageCode = "node_group@log_sort_node_groups" // 修改节点分组排序
NodeGroup_LogUpdateNodeGroup langs.MessageCode = "node_group@log_update_node_group" // 修改节点分组 %d
NodeIPAddress_LogDeleteNodeIPAddress langs.MessageCode = "node_ip_address@log_delete_node_ip_address" // 删除IP地址 %d
NodeIPAddress_LogDownNodeIPAddress langs.MessageCode = "node_ip_address@log_down_node_ip_address" // 手动设置IP地址 %d 下线
NodeIPAddress_LogRestoreNodeIPAddress langs.MessageCode = "node_ip_address@log_restore_node_ip_address" // 取消IP地址 %d 的备用IP
NodeIPAddress_LogUpNodeIPAddress langs.MessageCode = "node_ip_address@log_up_node_ip_address" // 手动设置IP地址 %d 上线
NodeLog_LogDeleteNodeLogsBatch langs.MessageCode = "node_log@log_delete_node_logs_batch" // 批量删除节点运行日志
NodeLog_LogFixAllLogs langs.MessageCode = "node_log@log_fix_all_logs" // 设置所有日志为已修复
NodeLog_LogFixNodeLogs langs.MessageCode = "node_log@log_fix_node_logs" // 设置日志 %s 为已修复
NodeMenu_CreateMultipleNodes langs.MessageCode = "node_menu@create_multiple_nodes" // 批量创建
NodeMenu_CreateSingleNode langs.MessageCode = "node_menu@create_single_node" // 单个创建
NodeMenu_InstallAutoRegister langs.MessageCode = "node_menu@install_auto_register" // 自动注册
NodeMenu_InstallManually langs.MessageCode = "node_menu@install_manually" // 手动安装
NodeMenu_InstallRemote langs.MessageCode = "node_menu@install_remote" // 远程安装(%d)
NodeMenu_InstallRemoteUpgrade langs.MessageCode = "node_menu@install_remote_upgrade" // 远程升级(%d)
NodeMenu_SettingBasic langs.MessageCode = "node_menu@setting_basic" // 基础设置
NodeMenu_SettingCache langs.MessageCode = "node_menu@setting_cache" // 缓存设置
NodeMenu_SettingDDoSProtection langs.MessageCode = "node_menu@setting_ddos_protection" // DDoS防护
NodeMenu_SettingDNS langs.MessageCode = "node_menu@setting_dns" // DNS设置
NodeMenu_SettingSchedule langs.MessageCode = "node_menu@setting_schedule" // 智能调度
NodeMenu_SettingSSH langs.MessageCode = "node_menu@setting_ssh" // SSH设置
NodeMenu_SettingSystem langs.MessageCode = "node_menu@setting_system" // 系统设置
NodeMenu_SettingThresholds langs.MessageCode = "node_menu@setting_thresholds" // 阈值设置
NodePriceItem_LogCreateNodePriceItemBandwidth langs.MessageCode = "node_price_item@log_create_node_price_item_bandwidth" // 创建带宽价格项目 %d
NodePriceItem_LogCreateNodePriceItemTraffic langs.MessageCode = "node_price_item@log_create_node_price_item_traffic" // 创建流量价格项目 %d
NodePriceItem_LogDeleteNodePriceItem langs.MessageCode = "node_price_item@log_delete_node_price_item" // 删除流量价格项目 %d
NodePriceItem_LogUpdateNodePriceItemBandwidth langs.MessageCode = "node_price_item@log_update_node_price_item_bandwidth" // 修改带宽价格项目 %d
NodePriceItem_LogUpdateNodePriceItemTraffic langs.MessageCode = "node_price_item@log_update_node_price_item_traffic" // 修改流量价格项目 %d
NodeRegion_LogCreateNodeRegion langs.MessageCode = "node_region@log_create_node_region" // 创建节点区域 %d
NodeRegion_LogDeleteNodeRegion langs.MessageCode = "node_region@log_delete_node_region" // 删除节点区域 %d
NodeRegion_LogMoveNodeBetweenRegions langs.MessageCode = "node_region@log_move_node_between_regions" // 修改节点 %d 区域到 %d
NodeRegion_LogSortNodeRegions langs.MessageCode = "node_region@log_sort_node_regions" // 修改节点区域排序
NodeRegion_LogUpdateNodeRegion langs.MessageCode = "node_region@log_update_node_region" // 修改节点区域 %d
NodeRegionPrice_LogUpdateNodeRegionPrice langs.MessageCode = "node_region_price@log_update_node_region_price" // 修改区域 %d - 价格项 %d 的价格
NodeSchedule_LogResetNodeActionStatus langs.MessageCode = "node_schedule@log_reset_node_action_status" // 重置节点 %d 动作状态
NodeSchedule_LogUpdateNodeScheduleBasic langs.MessageCode = "node_schedule@log_update_node_schedule_basic" // 修改节点调度基本信息
NodeSSH_LogUpdateNodeSSH langs.MessageCode = "node_ssh@log_update_node_ssh" // 修改节点 %d SSH配置
NodeSystem_LogUpdateNodeSystemSettings langs.MessageCode = "node_system@log_update_node_system_settings" // 修改节点 %d 系统信息
NodeSystemd_LogUpdateClusterSystemdSettings langs.MessageCode = "node_systemd@log_update_cluster_systemd_settings" // 修改集群 %d 的系统服务设置
NodeTask_LogDeleteAllNodeTasks langs.MessageCode = "node_task@log_delete_all_node_tasks" // 删除所有节点同步任务
NodeTask_LogDeleteNodeTask langs.MessageCode = "node_task@log_delete_node_task" // 删除同步任务 %d
NodeTask_LogDeleteNodeTasksBatch langs.MessageCode = "node_task@log_delete_node_tasks_batch" // 批量删除节点同步任务
NodeThreshold_LogCreateNodeThreshold langs.MessageCode = "node_threshold@log_create_node_threshold" // 创建节点阈值 %d
NodeThreshold_LogDeleteNodeThreshold langs.MessageCode = "node_threshold@log_delete_node_threshold" // 删除阈值 %d
NodeThreshold_LogUpdateNodeThreshold langs.MessageCode = "node_threshold@log_update_node_threshold" // 修改节点阈值 %d
NodeTOA_LogUpdateClusterTOA langs.MessageCode = "node_toa@log_update_cluster_toa" // 修改集群 %d 的TOA设置
NS_LogCreateNSDomainsBatch langs.MessageCode = "ns@log_create_ns_domains_batch" // 批量添加域名
NS_LogCreateNSRecordsBatch langs.MessageCode = "ns@log_create_ns_records_batch" // 批量添加解析
NS_LogDeleteNSDomainsBatch langs.MessageCode = "ns@log_delete_ns_domains_batch" // 批量删除域名,用户 %d
NS_LogDeleteNSRecordsBatch langs.MessageCode = "ns@log_delete_ns_records_batch" // 批量删除域名记录
NS_LogDisableNSRecordsBatch langs.MessageCode = "ns@log_disable_ns_records_batch" // 批量停用域名记录
NS_LogEnableNSRecordsBatch langs.MessageCode = "ns@log_enable_ns_records_batch" // 批量启用域名记录
NS_LogImportRecordsBatch langs.MessageCode = "ns@log_import_records_batch" // 批量导入记录
NS_LogUpdateNSRecordsBatch langs.MessageCode = "ns@log_update_ns_records_batch" // 批量修改域名记录
NS_LogUpdateNSUserConfig langs.MessageCode = "ns@log_update_ns_user_config" // 修改NS全局设置--用户相关设置
NS_SettingAccessLogs langs.MessageCode = "ns@setting_access_logs" // 访问日志设置
NS_SettingUser langs.MessageCode = "ns@setting_user" // 用户设置
NSCluster_LogCreateNSCluster langs.MessageCode = "ns_cluster@log_create_ns_cluster" // 创建域名服务集群 %d
NSCluster_LogDeleteNSCluster langs.MessageCode = "ns_cluster@log_delete_ns_cluster" // 删除域名服务集群 %d
NSCluster_LogUpdateNSClusterSettingsAccessLog langs.MessageCode = "ns_cluster@log_update_ns_cluster_settings_access_log" // 修改域名服务集群 %d 访问日志配置
NSCluster_LogUpdateNSClusterSettingsAnswer langs.MessageCode = "ns_cluster@log_update_ns_cluster_settings_answer" // 修改NS集群 %d 应答模式设置
NSCluster_LogUpdateNSClusterSettingsBasic langs.MessageCode = "ns_cluster@log_update_ns_cluster_settings_basic" // 修改域名服务集群基本信息 %d
NSCluster_LogUpdateNSClusterSettingsDDoSProtection langs.MessageCode = "ns_cluster@log_update_ns_cluster_settings_ddos_protection" // 修改NS集群 %d 的DDOS防护设置
NSCluster_LogUpdateNSClusterSettingsDoH langs.MessageCode = "ns_cluster@log_update_ns_cluster_settings_doh" // 修改NS集群 %d DoH设置
NSCluster_LogUpdateNSClusterSettingsRecursion langs.MessageCode = "ns_cluster@log_update_ns_cluster_settings_recursion" // 修改DNS集群 %d 的递归DNS设置
NSCluster_LogUpdateNSClusterSettingsSOA langs.MessageCode = "ns_cluster@log_update_ns_cluster_settings_soa" // 修改NS集群 %d SOA配置
NSCluster_LogUpdateNSClusterSettingsTCP langs.MessageCode = "ns_cluster@log_update_ns_cluster_settings_tcp" // 修理NS集群 %d TCP设置
NSCluster_LogUpdateNSClusterSettingsTLS langs.MessageCode = "ns_cluster@log_update_ns_cluster_settings_tls" // 修改NS集群 %d TLS设置
NSCluster_LogUpdateNSClusterSettingsUDP langs.MessageCode = "ns_cluster@log_update_ns_cluster_settings_udp" // 修改NS集群 %d UDP设置
NSCluster_MenuAccessLogs langs.MessageCode = "ns_cluster@menu_access_logs" // 访问日志
NSCluster_MenuAnswerSetting langs.MessageCode = "ns_cluster@menu_answer_setting" // 应答模式
NSCluster_MenuBasic langs.MessageCode = "ns_cluster@menu_basic" // 基础设置
NSCluster_MenuDDoSProtection langs.MessageCode = "ns_cluster@menu_ddos_protection" // DDoS防护
NSCluster_MenuDNSRecursion langs.MessageCode = "ns_cluster@menu_dns_recursion" // 递归DNS
NSCluster_MenuDoH langs.MessageCode = "ns_cluster@menu_doh" // DoH
NSCluster_MenuSOA langs.MessageCode = "ns_cluster@menu_soa" // SOA
NSCluster_MenuTCP langs.MessageCode = "ns_cluster@menu_tcp" // TCP
NSCluster_MenuTLS langs.MessageCode = "ns_cluster@menu_tls" // TLS
NSCluster_MenuUDP langs.MessageCode = "ns_cluster@menu_udp" // UDP
NSCluster_TabDelete langs.MessageCode = "ns_cluster@tab_delete" // 删除集群
NSCluster_TabNodes langs.MessageCode = "ns_cluster@tab_nodes" // 节点列表
NSCluster_TabSetting langs.MessageCode = "ns_cluster@tab_setting" // 集群设置
NSDomain_LogCreateNSDomain langs.MessageCode = "ns_domain@log_create_ns_domain" // 创建域名 %d
NSDomain_LogCreateNSDomainsBatch langs.MessageCode = "ns_domain@log_create_ns_domains_batch" // 批量添加域名
NSDomain_LogDeleteNSDomain langs.MessageCode = "ns_domain@log_delete_ns_domain" // 删除域名 %d
NSDomain_LogUpdateNSDomain langs.MessageCode = "ns_domain@log_update_ns_domain" // 修改域名 %d
NSDomain_LogUpdateNSDomainHealthCheck langs.MessageCode = "ns_domain@log_update_ns_domain_health_check" // 修改域名 %d 健康检查设置
NSDomain_LogUpdateNSDomainStatus langs.MessageCode = "ns_domain@log_update_ns_domain_status" // 修改域名 %d 状态为 %s
NSDomain_LogUpdateNSDomainTSIG langs.MessageCode = "ns_domain@log_update_ns_domain_tsig" // 修改域名 %d 的TSIG配置
NSDomain_LogValidateNSDomains langs.MessageCode = "ns_domain@log_validate_ns_domains" // 批量验证域名
NSDomainGroup_LogCreateNSDomainGroup langs.MessageCode = "ns_domain_group@log_create_ns_domain_group" // 创建域名分组 %d
NSDomainGroup_LogDeleteNSDomainGroup langs.MessageCode = "ns_domain_group@log_delete_ns_domain_group" // 删除域名分组 %d
NSDomainGroup_LogUpdateNSDomainGroup langs.MessageCode = "ns_domain_group@log_update_ns_domain_group" // 修改域名分组 %d
NSKey_LogCreateNSKey langs.MessageCode = "ns_key@log_create_ns_key" // 创建DNS密钥 %d
NSKey_LogDeleteNSKey langs.MessageCode = "ns_key@log_delete_ns_key" // 删除DNS密钥 %d
NSKey_LogUpdateNSKey langs.MessageCode = "ns_key@log_update_ns_key" // 修改DNS密钥 %d
NSNode_LogCreateNSNode langs.MessageCode = "ns_node@log_create_ns_node" // 创建域名服务节点 %d
NSNode_LogDeleteNSNode langs.MessageCode = "ns_node@log_delete_ns_node" // 删除域名服务节点 %d
NSNode_LogInstallNSNodeRemotely langs.MessageCode = "ns_node@log_install_ns_node_remotely" // 安装节点 %d
NSNode_LogStartNSNodeRemotely langs.MessageCode = "ns_node@log_start_ns_node_remotely" // 远程启动节点 %d
NSNode_LogStopNSNodeRemotely langs.MessageCode = "ns_node@log_stop_ns_node_remotely" // 远程停止节点 %d
NSNode_LogUpdateNSNode langs.MessageCode = "ns_node@log_update_ns_node" // 修改节点 %d
NSNode_LogUpdateNSNodeInstallationStatus langs.MessageCode = "ns_node@log_update_ns_node_installation_status" // 修改节点安装状态 %d
NSNodeSSH_LogUpdateNSNodeSSH langs.MessageCode = "ns_node_ssh@log_update_ns_node_ssh" // 修改节点 %d SSH配置
NSPlan_LogCreateNSPlan langs.MessageCode = "ns_plan@log_create_ns_plan" // 创建套餐 %d
NSPlan_LogDeleteNSPlan langs.MessageCode = "ns_plan@log_delete_ns_plan" // 删除套餐 %d
NSPlan_LogSortNSPlans langs.MessageCode = "ns_plan@log_sort_ns_plans" // 套餐排序
NSPlan_LogUpdateNSPlan langs.MessageCode = "ns_plan@log_update_ns_plan" // 修改套餐 %d
NSRecord_LogCreateNSRecord langs.MessageCode = "ns_record@log_create_ns_record" // 创建域名记录 %d
NSRecord_LogCreateNSRecordsBatch langs.MessageCode = "ns_record@log_create_ns_records_batch" // 批量创建域名记录
NSRecord_LogDeleteNSRecord langs.MessageCode = "ns_record@log_delete_ns_record" // 删除域名记录 %d
NSRecord_LogUpNSRecord langs.MessageCode = "ns_record@log_up_ns_record" // 手动设置DNS记录 %d 为上线状态
NSRecord_LogUpdateNSRecord langs.MessageCode = "ns_record@log_update_ns_record" // 修改域名记录 %d
NSRecord_LogUpdateNSRecordHealthCheck langs.MessageCode = "ns_record@log_update_ns_record_health_check" // 修改记录 %d 的健康检查
NSRoute_LogCreateNSRoute langs.MessageCode = "ns_route@log_create_ns_route" // 创建域名服务线路 %d
NSRoute_LogDeleteNSRoute langs.MessageCode = "ns_route@log_delete_ns_route" // 删除域名服务线路 %d
NSRoute_LogSortNSRoutes langs.MessageCode = "ns_route@log_sort_ns_routes" // 对线路进行排序
NSRoute_LogUpdateNSRoute langs.MessageCode = "ns_route@log_update_ns_route" // 修改域名线路 %d
NSRouteCategory_LogCreateNSRouteCategory langs.MessageCode = "ns_route_category@log_create_ns_route_category" // 创建NS线路分类 %d
NSRouteCategory_LogDeleteNSRouteCategory langs.MessageCode = "ns_route_category@log_delete_ns_route_category" // 删除NS线路分类 %d
NSRouteCategory_LogSortNSRouteCategories langs.MessageCode = "ns_route_category@log_sort_ns_route_categories" // 对NS线路分类进行排序
NSRouteCategory_LogUpdateNSRouteCategory langs.MessageCode = "ns_route_category@log_update_ns_route_category" // 修改NS线路分类 %d
NSUserPlan_LogCreateNSUserPlan langs.MessageCode = "ns_user_plan@log_create_ns_user_plan" // 为用户 %d 创建DNS套餐 %d
NSUserPlan_LogDeleteNSUserPlan langs.MessageCode = "ns_user_plan@log_delete_ns_user_plan" // 删除用户套餐 %d
NSUserPlan_LogUpdateNSUserPlan langs.MessageCode = "ns_user_plan@log_update_ns_user_plan" // 修改用户DNS套餐 %d
OrderMethod_LogCreateOrderMethod langs.MessageCode = "order_method@log_create_order_method" // 创建支付方式 %d
OrderMethod_LogDeleteOrderMethod langs.MessageCode = "order_method@log_delete_order_method" // 删除支付方式 %d
OrderMethod_LogUpdateOrderMethod langs.MessageCode = "order_method@log_update_order_method" // 修改支付方式 %d
Plan_LogCreatePlan langs.MessageCode = "plan@log_create_plan" // 创建套餐 %d
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
RegionCountry_LogUpdateRegionCountryCustom langs.MessageCode = "region_country@log_update_region_country_custom" // 定制国家/地区 %d 信息
RegionCountry_RegionChina langs.MessageCode = "region_country@region_china" // 中国
RegionCountry_RegionChinaHk langs.MessageCode = "region_country@region_china_hk" // 中国香港
RegionCountry_RegionChinaMainland langs.MessageCode = "region_country@region_china_mainland" // 中国内地
RegionCountry_RegionChinaMo langs.MessageCode = "region_country@region_china_mo" // 中国澳门
RegionCountry_RegionChinaTw langs.MessageCode = "region_country@region_china_tw" // 中国台湾
RegionCountry_RegionGreaterChina langs.MessageCode = "region_country@region_greater_china" // 中国全境
RegionProvider_LogAddRegionProviderCode langs.MessageCode = "region_provider@log_add_region_provider_code" // 添加ISP服务商 %d 别名 %s
RegionProvider_LogUpdateRegionProviderCustom langs.MessageCode = "region_provider@log_update_region_provider_custom" // 定制ISP %d 信息
RegionProvince_LogAddRegionProvinceCode langs.MessageCode = "region_province@log_add_region_province_code" // 添加省份/州 %d 别名 %s
RegionProvince_LogUpdateRegionProvinceCustom langs.MessageCode = "region_province@log_update_region_province_custom" // 定制省份 %d 信息
RegionTown_LogAddRegionTownCode langs.MessageCode = "region_town@log_add_region_town_code" // 添加区/县 %d 别名 %s
RegionTown_LogUpdateRegionTownCustom langs.MessageCode = "region_town@log_update_region_town_custom" // 定制县级 %d 信息
ReportNode_LogCreateReportNode langs.MessageCode = "report_node@log_create_report_node" // 创建监控终端 %d
ReportNode_LogDeleteReportNode langs.MessageCode = "report_node@log_delete_report_node" // 删除监控终端 %d
ReportNode_LogUpdateReportNode langs.MessageCode = "report_node@log_update_report_node" // 修改监控终端 %d
ReportNodeGroup_LogCreateReportNodeGroup langs.MessageCode = "report_node_group@log_create_report_node_group" // 创建监控节点分组 %d
ReportNodeGroup_LogDeleteReportNodeGroup langs.MessageCode = "report_node_group@log_delete_report_node_group" // 删除监控节点分组 %d
ReportNodeGroup_LogUpdateReportNodeGroup langs.MessageCode = "report_node_group@log_update_report_node_group" // 修改监控节点分组 %d
ReverseProxy_LogUpdateReverseProxyScheduling langs.MessageCode = "reverse_proxy@log_update_reverse_proxy_scheduling" // 修改反向代理 %d 负载均衡算法
Script_LogCreateScript langs.MessageCode = "script@log_create_script" // 创建脚本 %d
Script_LogDeleteScript langs.MessageCode = "script@log_delete_script" // 删除脚本 %d
Script_LogPublishScripts langs.MessageCode = "script@log_publish_scripts" // 发布脚本库到边缘节点
Script_LogUpdateScript langs.MessageCode = "script@log_update_script" // 修改脚本 %d
Server_CopySettingCurrentCluster langs.MessageCode = "server@copy_setting_current_cluster" // 当前集群:%s
Server_CopySettingCurrentGroup langs.MessageCode = "server@copy_setting_current_group" // 当前分组:%s
Server_CopySettingCurrentUser langs.MessageCode = "server@copy_setting_current_user" // 当前用户:%s
Server_CopySettingSelectCluster langs.MessageCode = "server@copy_setting_select_cluster" // 选择集群
Server_CopySettingSelectGroup langs.MessageCode = "server@copy_setting_select_group" // 选择分组
Server_CopySettingSelectServer langs.MessageCode = "server@copy_setting_select_server" // 选择网站
Server_CopySettingSelectUser langs.MessageCode = "server@copy_setting_select_user" // 选择用户
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 域名审核
Server_LogUpdateGlobalSettings langs.MessageCode = "server@log_update_global_settings" // 保存网站全局配置
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" // 修改网站 %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" // 今天
Server_MenuDashboard langs.MessageCode = "server@menu_dashboard" // 看板
Server_MenuSettingAccessLog langs.MessageCode = "server@menu_setting_access_log" // 访问日志
Server_MenuSettingAuth langs.MessageCode = "server@menu_setting_auth" // 访问鉴权
Server_MenuSettingBasic langs.MessageCode = "server@menu_setting_basic" // 基本信息
Server_MenuSettingCache langs.MessageCode = "server@menu_setting_cache" // 缓存
Server_MenuSettingCC langs.MessageCode = "server@menu_setting_cc" // CC防护
Server_MenuSettingCharset langs.MessageCode = "server@menu_setting_charset" // 字符编码
Server_MenuSettingClientIP langs.MessageCode = "server@menu_setting_client_ip" // 访客IP地址
Server_MenuSettingCompression langs.MessageCode = "server@menu_setting_compression" // 内容压缩
Server_MenuSettingDelete langs.MessageCode = "server@menu_setting_delete" // 删除
Server_MenuSettingDNS langs.MessageCode = "server@menu_setting_dns" // DNS
Server_MenuSettingDomains langs.MessageCode = "server@menu_setting_domains" // 域名
Server_MenuSettingFastcgi langs.MessageCode = "server@menu_setting_fastcgi" // Fastcgi
Server_MenuSettingGroup langs.MessageCode = "server@menu_setting_group" // 分组
Server_MenuSettingHTTP langs.MessageCode = "server@menu_setting_http" // HTTP
Server_MenuSettingHTTPHeaders langs.MessageCode = "server@menu_setting_http_headers" // HTTP报头
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" // 其他设置
Server_MenuSettingPages langs.MessageCode = "server@menu_setting_pages" // 自定义页面
Server_MenuSettingPlan langs.MessageCode = "server@menu_setting_plan" // 套餐
Server_MenuSettingRedirects langs.MessageCode = "server@menu_setting_redirects" // URL跳转
Server_MenuSettingReferers langs.MessageCode = "server@menu_setting_referers" // 防盗链
Server_MenuSettingRequestLimit langs.MessageCode = "server@menu_setting_request_limit" // 请求限制
Server_MenuSettingRewriteRules langs.MessageCode = "server@menu_setting_rewrite_rules" // 重写规则
Server_MenuSettingRoot langs.MessageCode = "server@menu_setting_root" // 静态分发
Server_MenuSettingScripts langs.MessageCode = "server@menu_setting_scripts" // 边缘脚本
Server_MenuSettingStat langs.MessageCode = "server@menu_setting_stat" // 统计
Server_MenuSettingTCP langs.MessageCode = "server@menu_setting_tcp" // TCP
Server_MenuSettingTCPProxy langs.MessageCode = "server@menu_setting_tcp_proxy" // TCP代理
Server_MenuSettingTLS langs.MessageCode = "server@menu_setting_tls" // TLS
Server_MenuSettingTrafficLimit langs.MessageCode = "server@menu_setting_traffic_limit" // 流量限制
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_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
Server_MenuSettingWebsocket langs.MessageCode = "server@menu_setting_websocket" // Websocket
Server_MenuStatClients langs.MessageCode = "server@menu_stat_clients" // 终端
Server_MenuStatProviders langs.MessageCode = "server@menu_stat_providers" // 运营商
Server_MenuStatRegions langs.MessageCode = "server@menu_stat_regions" // 地域分布
Server_MenuStatTraffic langs.MessageCode = "server@menu_stat_traffic" // 流量统计
Server_MenuStatWAF langs.MessageCode = "server@menu_stat_waf" // WAF
Server_ServerNamesLogUpdateServerNames langs.MessageCode = "server@server_names_log_update_server_names" // 修改网站 %d 域名
Server_TabAccessLogs langs.MessageCode = "server@tab_access_logs" // 日志
Server_TabDashboard langs.MessageCode = "server@tab_dashboard" // 看板
Server_TabDelete langs.MessageCode = "server@tab_delete" // 删除
Server_TabServerList langs.MessageCode = "server@tab_server_list" // 网站列表
Server_TabSettings langs.MessageCode = "server@tab_settings" // 设置
Server_TabStat langs.MessageCode = "server@tab_stat" // 统计
ServerAccessLog_LogUpdateAccessLogSetting langs.MessageCode = "server_access_log@log_update_access_log_setting" // 修改Web %d 的访问日志设置
ServerAuth_LogUpdateHTTPAuthSettings langs.MessageCode = "server_auth@log_update_http_auth_settings" // 修改Web %d 的鉴权设置
ServerCache_LogFetchCaches langs.MessageCode = "server_cache@log_fetch_caches" // 预热网站 %d 缓存
ServerCache_LogPurgeCaches langs.MessageCode = "server_cache@log_purge_caches" // 删除网站 %d 缓存
ServerCache_LogUpdateCacheSettings langs.MessageCode = "server_cache@log_update_cache_settings" // 修改Web %d 的缓存设置
ServerCache_LogUpdateClusterCachePolicy langs.MessageCode = "server_cache@log_update_cluster_cache_policy" // 设置集群 %d 的缓存策略为 %d
ServerCachePolicy_LogCleanAll langs.MessageCode = "server_cache_policy@log_clean_all" // 清除缓存,缓存策略:%d
ServerCachePolicy_LogCreateCachePolicy langs.MessageCode = "server_cache_policy@log_create_cache_policy" // 创建缓存策略:%d
ServerCachePolicy_LogDeleteCachePolicy langs.MessageCode = "server_cache_policy@log_delete_cache_policy" // 删除缓存策略:%d
ServerCachePolicy_LogFetchCaches langs.MessageCode = "server_cache_policy@log_fetch_caches" // 预热缓存,缓存策略:%d
ServerCachePolicy_LogPurgeCaches langs.MessageCode = "server_cache_policy@log_purge_caches" // 删除缓存,缓存策略:%d
ServerCachePolicy_LogStatCaches langs.MessageCode = "server_cache_policy@log_stat_caches" // 统计缓存,缓存策略:%d
ServerCachePolicy_LogTestReading langs.MessageCode = "server_cache_policy@log_test_reading" // 测试读取,缓存策略:%d
ServerCachePolicy_LogTestWriting langs.MessageCode = "server_cache_policy@log_test_writing" // 测试写入,缓存策略:%d
ServerCachePolicy_LogUpdateCachePolicy langs.MessageCode = "server_cache_policy@log_update_cache_policy" // 修改缓存策略:%d
ServerCC_LogUpdateCCSettings langs.MessageCode = "server_cc@log_update_cc_settings" // 修改Web %d CC防护配置
ServerCC_LogUpdateClusterHTTPCCPolicy langs.MessageCode = "server_cc@log_update_cluster_http_cc_policy" // 修改集群 %d 的HTTP CC策略设置
ServerCharset_LogUpdateCharsetSetting langs.MessageCode = "server_charset@log_update_charset_setting" // 修改Web %d 的字符集设置
ServerCommon_LogUpdateCommonSettings langs.MessageCode = "server_common@log_update_common_settings" // 修改网站Web %d 设置的其他设置
ServerCompression_LogUpdateCompressionSettings langs.MessageCode = "server_compression@log_update_compression_settings" // 修改Web %d 的压缩设置
ServerDNS_LogRegenerateDNSName langs.MessageCode = "server_dns@log_regenerate_dns_name" // 重新生成网站 %d 的CNAME
ServerDNS_LogUpdateDNSName langs.MessageCode = "server_dns@log_update_dns_name" // 修改网站 %d CNAME为 %s
ServerDNS_LogUpdateDNSSettings langs.MessageCode = "server_dns@log_update_dns_settings" // 修改网站 %d 的DNS设置
ServerFastcgi_LogUpdateHTTPFastcgi langs.MessageCode = "server_fastcgi@log_update_http_fastcgi" // 修改Web %d 的Fastcgi设置
ServerGlobalSetting_LogUpdateClusterGlobalServerConfig langs.MessageCode = "server_global_setting@log_update_cluster_global_server_config" // 修改集群 %d 全局配置
ServerGroup_LogCreateServerGroup langs.MessageCode = "server_group@log_create_server_group" // 创建网站分组 %d
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
ServerHTTPHeader_LogCreateNonStandardHeader langs.MessageCode = "server_http_header@log_create_non_standard_header" // 添加非标的报头 HeaderPolicyId: %d, Name: %s
ServerHTTPHeader_LogCreateSettingRequestHeader langs.MessageCode = "server_http_header@log_create_setting_request_header" // 添加自定义请求报头HeaderPolicyId:%d, Name:%s, Value:%s
ServerHTTPHeader_LogCreateSettingResponseHeader langs.MessageCode = "server_http_header@log_create_setting_response_header" // 添加自定义响应报头HeaderPolicyId:%d, Name:%s, Value:%s
ServerHTTPHeader_LogDeleteDeletingHeader langs.MessageCode = "server_http_header@log_delete_deleting_header" // 删除需要删除的报头HeaderPolicyId:%d, HeaderName:%s
ServerHTTPHeader_LogDeleteHeader langs.MessageCode = "server_http_header@log_delete_header" // 删除报头HeaderPolicyId:%d, HeaderId:%d
ServerHTTPHeader_LogDeleteNonStandardHeader langs.MessageCode = "server_http_header@log_delete_non_standard_header" // 删除需要非标的报头HeaderPolicyId:%d, HeaderName:%s
ServerHTTPHeader_LogUpdateHTTPHeaders langs.MessageCode = "server_http_header@log_update_http_headers" // 修改Web %d 的报头设置
ServerHTTPHeader_LogUpdateSettingHeader langs.MessageCode = "server_http_header@log_update_setting_header" // 修改设置报头HeaderId:%d, Name:%s, Value:%s
ServerHTTPS_LogUpdateHTTPSSettings langs.MessageCode = "server_https@log_update_https_settings" // 修改网站 %d 的HTTPS设置
ServerOptimization_LogUpdateOptimizationSettings langs.MessageCode = "server_optimization@log_update_optimization_settings" // 修改Web %d 的页面优化设置
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
ServerPage_LogUpdatePages langs.MessageCode = "server_page@log_update_pages" // 修改Web %d 的自定义页面设置
ServerRedirect_LogUpdateRedirects langs.MessageCode = "server_redirect@log_update_redirects" // 修改Web %d 的跳转设置
ServerReferer_LogUpdateReferers langs.MessageCode = "server_referer@log_update_referers" // 修改Web %d 防盗链设置
ServerRequestLimit_LogUpdateRequestLimitSettings langs.MessageCode = "server_request_limit@log_update_request_limit_settings" // 修改Web %d 请求限制
ServerReverseProxy_LogUpdateLocationReverseProxySettings langs.MessageCode = "server_reverse_proxy@log_update_location_reverse_proxy_settings" // 修改路由规则 %d 的反向代理设置
ServerReverseProxy_LogUpdateServerGroupReverseProxySettings langs.MessageCode = "server_reverse_proxy@log_update_server_group_reverse_proxy_settings" // 修改分组 %d 的反向代理设置
ServerReverseProxy_LogUpdateServerReverseProxySettings langs.MessageCode = "server_reverse_proxy@log_update_server_reverse_proxy_settings" // 修改网站 %d 的反向代理设置
ServerRoot_LogUpdateRoot langs.MessageCode = "server_root@log_update_root" // 修改Web %d 静态分发设置
ServerScript_LogUpdateScripts langs.MessageCode = "server_script@log_update_scripts" // 修改Web %d 边缘脚本
ServerStat_LogUpdateStatSettings langs.MessageCode = "server_stat@log_update_stat_settings" // 修改Web %d 的统计设置
ServerTCP_LogUpdateTCPSettings langs.MessageCode = "server_tcp@log_update_tcp_settings" // 修改网站 %d TCP设置
ServerTLS_LogUpdateTLSSettings langs.MessageCode = "server_tls@log_update_tls_settings" // 修改网站 %d TLS设置
ServerTrafficLimit_LogUpdateTrafficLimitSettings langs.MessageCode = "server_traffic_limit@log_update_traffic_limit_settings" // 修改网站 %d 流量限制
ServerTrafficStat_AllServers langs.MessageCode = "server_traffic_stat@all_servers" // 全部网站(%d
ServerUAM_LogUpdateClusterUAMPolicy langs.MessageCode = "server_uam@log_update_cluster_uam_policy" // 修改集群 %d 的UAM设置
ServerUAM_LogUpdateServerUAMSettings langs.MessageCode = "server_uam@log_update_server_uam_settings" // 修改网站 %d 全站防护模式
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设置
SSLCert_LogDeleteSSLCert langs.MessageCode = "ssl_cert@log_delete_ssl_cert" // 删除SSL证书 %d
SSLCert_LogDownloadSSLCert langs.MessageCode = "ssl_cert@log_download_ssl_cert" // 下载SSL证书 %d
SSLCert_LogDownloadSSLCertKey langs.MessageCode = "ssl_cert@log_download_ssl_cert_key" // 下载SSL密钥 %d
SSLCert_LogDownloadSSLCertZip langs.MessageCode = "ssl_cert@log_download_ssl_cert_zip" // 下载SSL证书压缩包 %d
SSLCert_LogOCSPIgnoreOCSPStatus langs.MessageCode = "ssl_cert@log_ocsp_ignore_ocsp_status" // 忽略一组证书的OCSP状态
SSLCert_LogOCSPResetAllOCSPStatus langs.MessageCode = "ssl_cert@log_ocsp_reset_all_ocsp_status" // 忽略所有证书的OCSP状态
SSLCert_LogOCSPResetOCSPStatus langs.MessageCode = "ssl_cert@log_ocsp_reset_ocsp_status" // 重置一组证书的OCSP状态
SSLCert_LogUpdateSSLCert langs.MessageCode = "ssl_cert@log_update_ssl_cert" // 修改SSL证书 %d
SSLCert_LogUploadSSLCert langs.MessageCode = "ssl_cert@log_upload_ssl_cert" // 上传SSL证书 %d
SSLCert_LogUploadSSLCertBatch langs.MessageCode = "ssl_cert@log_upload_ssl_cert_batch" // 批量上传证书
SSLCert_MenuApply langs.MessageCode = "ssl_cert@menu_apply" // 申请证书
SSLCert_MenuCerts langs.MessageCode = "ssl_cert@menu_certs" // 证书
SSLCert_MenuOCSP langs.MessageCode = "ssl_cert@menu_ocsp" // OCSP日志
System_HomePage langs.MessageCode = "system@home_page" // https://goedge.cn
TicketCategory_LogCreateTicketCategory langs.MessageCode = "ticket_category@log_create_ticket_category" // 添加工单分类 %d
TicketCategory_LogDeleteTicketCategory langs.MessageCode = "ticket_category@log_delete_ticket_category" // 删除工单分类 %d
TicketCategory_LogUpdateTicketCategory langs.MessageCode = "ticket_category@log_update_ticket_category" // 修改分类 %d
TrafficPackage_LogCreateTrafficPackage langs.MessageCode = "traffic_package@log_create_traffic_package" // 创建流量包 %d
TrafficPackage_LogDeleteTrafficPackage langs.MessageCode = "traffic_package@log_delete_traffic_package" // 删除流量包 %d
TrafficPackage_LogUpdateTrafficPackage langs.MessageCode = "traffic_package@log_update_traffic_package" // 修改流量包 %d
TrafficPackagePeriod_LogCreateTrafficPackagePeriod langs.MessageCode = "traffic_package_period@log_create_traffic_package_period" // 创建流量包有效期 %d
TrafficPackagePeriod_LogDeleteTrafficPackagePeriod langs.MessageCode = "traffic_package_period@log_delete_traffic_package_period" // 删除流量包有效期选项 %d
TrafficPackagePeriod_LogUpdateTrafficPackagePeriod langs.MessageCode = "traffic_package_period@log_update_traffic_package_period" // 修改流量包有效期选项 %d
TrafficPackagePrice_LogUpdateTrafficPackagePrice langs.MessageCode = "traffic_package_price@log_update_traffic_package_price" // 修改流量包 %d 区域 %d x 有效期 %d 的价格
User_LogCreateUser langs.MessageCode = "user@log_create_user" // 创建用户 %d
User_LogDeleteUser langs.MessageCode = "user@log_delete_user" // 删除用户 %d
User_LogUpdateUser langs.MessageCode = "user@log_update_user" // 修改用户 %d
User_LogUpdateUserEmailSettings langs.MessageCode = "user@log_update_user_email_settings" // 修改用户邮件设置
User_LogUpdateUserFeatures langs.MessageCode = "user@log_update_user_features" // 设置用户 %d 的功能列表
User_LogUpdateUserGlobalSettings langs.MessageCode = "user@log_update_user_global_settings" // 修改用户设置
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
UserAccessKey_LogUpdateUserAccessKeyIsOn langs.MessageCode = "user_access_key@log_update_user_access_key_is_on" // 设置AccessKey %d 启用状态
UserAccount_LogUpdateUserAccount langs.MessageCode = "user_account@log_update_user_account" // 操作用户账户 %d: %s
UserADInstance_LogDeleteUserADInstance langs.MessageCode = "user_ad_instance@log_delete_user_ad_instance" // 删除用户高防实例 %d
UserADInstance_LogRenewUserADInstance langs.MessageCode = "user_ad_instance@log_renew_user_ad_instance" // 为用户高防实例 %d 续期
UserADInstance_LogUpdateUserADInstanceObjects langs.MessageCode = "user_ad_instance@log_update_user_ad_instance_objects" // 修改用户高防实例 %d 防护对象
UserBill_LogPayUserBill langs.MessageCode = "user_bill@log_pay_user_bill" // 支付账单 %d
UserCommon_Canceled langs.MessageCode = "user_common@canceled" // 已取消
UserCommon_LogSystemError langs.MessageCode = "user_common@log_system_error" // 系统发生错误:%s
UserCommon_ServerError langs.MessageCode = "user_common@server_error" // 服务器出了点小问题,请联系技术人员处理。
UserCommon_System langs.MessageCode = "user_common@system" // 系统
UserIdentity_LogCancelUserIdentity langs.MessageCode = "user_identity@log_cancel_user_identity" // 取消身份认证审核
UserIdentity_LogRejectUserIdentity langs.MessageCode = "user_identity@log_reject_user_identity" // 驳回用户 %d 的实名认证
UserIdentity_LogResetUserIdentity langs.MessageCode = "user_identity@log_reset_user_identity" // 重置用户 %d 的实名认证
UserIdentity_LogSubmitUserIdentity langs.MessageCode = "user_identity@log_submit_user_identity" // 提交身份认证审核
UserIdentity_LogUpdateUserIdentityEnterprise langs.MessageCode = "user_identity@log_update_user_identity_enterprise" // 修改/上传企业实名认证信息
UserIdentity_LogUpdateUserIdentityIndividual langs.MessageCode = "user_identity@log_update_user_identity_individual" // 修改/上传个人实名认证信息
UserIdentity_LogVerifyUserIdentity langs.MessageCode = "user_identity@log_verify_user_identity" // 通过用户 %d 的实名认证
UserLogin_LogUpdateLogin langs.MessageCode = "user_login@log_update_login" // 修改登录设置
UserNode_LogCreateUserNode langs.MessageCode = "user_node@log_create_user_node" // 创建用户节点 %d
UserNode_LogDeleteUserNode langs.MessageCode = "user_node@log_delete_user_node" // 删除用户节点 %d
UserNode_LogUpdateUserNode langs.MessageCode = "user_node@log_update_user_node" // 修改用户节点 %d
UserOrder_LogFinishUserOrder langs.MessageCode = "user_order@log_finish_user_order" // 设置订单 %s 为完成支付
UserPlan_LogBindUserPlanToServer langs.MessageCode = "user_plan@log_bind_user_plan_to_server" // 修改网站 %d 绑定的套餐为 %d
UserPlan_LogBuyUserPlan langs.MessageCode = "user_plan@log_buy_user_plan" // 为用户 %d 购买套餐 %d
UserPlan_LogCancelUserPlanFromServer langs.MessageCode = "user_plan@log_cancel_user_plan_from_server" // 取消网站 %d 绑定的套餐
UserPlan_LogDeleteUserPlan langs.MessageCode = "user_plan@log_delete_user_plan" // 删除用户已购套餐 %d
UserPlan_LogRenewUserPlan langs.MessageCode = "user_plan@log_renew_user_plan" // 续费已购套餐 %d
UserTicket_LogCreateUserTicket langs.MessageCode = "user_ticket@log_create_user_ticket" // 创建工单 %d
UserTicketLog_LogReplyTicket langs.MessageCode = "user_ticket_log@log_reply_ticket" // 回复工单 %d
UserTrafficPackage_LogCreateUserTrafficPackage langs.MessageCode = "user_traffic_package@log_create_user_traffic_package" // 为用户 %d 创建流量包:%d区域%d有效期%d数量%d
UserTrafficPackage_LogDeleteUserTrafficPackage langs.MessageCode = "user_traffic_package@log_delete_user_traffic_package" // 删除用户流量包 %d
WAF_ConnectorAnd langs.MessageCode = "waf@connector_and" // 和(AND)
WAF_ConnectorAndDescription langs.MessageCode = "waf@connector_and_description" // 所有规则都满足才视为匹配
WAF_ConnectorOr langs.MessageCode = "waf@connector_or" // 或(OR)
WAF_ConnectorOrDescription langs.MessageCode = "waf@connector_or_description" // 任一规则满足了就视为匹配
WAF_LogDeleteIPFromWAFPolicy langs.MessageCode = "waf@log_delete_ip_from_waf_policy" // 从WAF策略 %d 名单中删除IP %d
WAF_LogUpdateForbiddenCountries langs.MessageCode = "waf@log_update_forbidden_countries" // WAF策略 %d 设置禁止访问的国家和地区
WAF_LogUpdateForbiddenProvinces langs.MessageCode = "waf@log_update_forbidden_provinces" // WAF策略 %d 设置禁止访问的省份
WAF_LogUpdateIPFromWAFPolicy langs.MessageCode = "waf@log_update_ip_from_waf_policy" // 修改WAF策略 %d 名单中的IP %d
WAFAction_LogCreateWAFAction langs.MessageCode = "waf_action@log_create_waf_action" // 创建集群 %d 的WAF动作
WAFAction_LogDeleteWAFAction langs.MessageCode = "waf_action@log_delete_waf_action" // 删除WAF动作 %d
WAFAction_LogUpdateWAFAction langs.MessageCode = "waf_action@log_update_waf_action" // 修改WAF动作 %d
WAFPolicy_LogCreateWAFPolicy langs.MessageCode = "waf_policy@log_create_waf_policy" // 创建WAF策略 %d
WAFPolicy_LogDeleteWAFPolicy langs.MessageCode = "waf_policy@log_delete_waf_policy" // 删除WAF策略 %d
WAFPolicy_LogExportWAFPolicy langs.MessageCode = "waf_policy@log_export_waf_policy" // 导出WAF策略 %d
WAFPolicy_LogImportWAFPolicy langs.MessageCode = "waf_policy@log_import_waf_policy" // 从文件中导入规则到WAF策略 %d
WAFPolicy_LogUpdateClusterWAFPolicy langs.MessageCode = "waf_policy@log_update_cluster_waf_policy" // 设置集群 %d 的WAF策略为 %d
WAFPolicy_LogUpdateWAFPolicy langs.MessageCode = "waf_policy@log_update_waf_policy" // 修改WAF策略 %d 基本信息
WAFPolicy_LogUpgradeWAFPolicy langs.MessageCode = "waf_policy@log_upgrade_waf_policy" // 升级WAF %d 内置规则
WAFRuleGroup_LogCreateRuleGroup langs.MessageCode = "waf_rule_group@log_create_rule_group" // 创建规则分组 %d名称%s
WAFRuleGroup_LogDeleteRuleGroup langs.MessageCode = "waf_rule_group@log_delete_rule_group" // 删除WAF策略 %d 的规则分组 %d
WAFRuleGroup_LogSortRuleGroups langs.MessageCode = "waf_rule_group@log_sort_rule_groups" // 修改WAF策略 %d 中的规则分组中的排序
WAFRuleGroup_LogUpdateRuleGroup langs.MessageCode = "waf_rule_group@log_update_rule_group" // 修改WAF规则分组 %d 基本信息
WAFRuleGroup_LogUpdateRuleGroupIsOn langs.MessageCode = "waf_rule_group@log_update_rule_group_is_on" // 设置WAF规则分组 %d 开启状态
WAFRuleSet_LogDeleteRuleSet langs.MessageCode = "waf_rule_set@log_delete_rule_set" // 删除WAF规则分组 %d 中的规则集 %d
WAFRuleSet_LogSortRuleSets langs.MessageCode = "waf_rule_set@log_sort_rule_sets" // 修改WAF规则分组 %d 中的规则集排序
WAFRuleSet_LogUpdateRuleSet langs.MessageCode = "waf_rule_set@log_update_rule_set" // 修改WAF规则集 %d 基本信息
WAFRuleSet_LogUpdateRuleSetIsOn langs.MessageCode = "waf_rule_set@log_update_rule_set_is_on" // 修改WAF规则集 %d 开启状态
)

84
pkg/langs/lang.go Normal file
View File

@@ -0,0 +1,84 @@
// Copyright 2023 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
package langs
import (
"errors"
"fmt"
"github.com/TeaOSLab/EdgeCommon/pkg/configutils"
"strings"
)
const varPrefix = "lang."
type LangCode = string
type Lang struct {
code string
messageMap map[MessageCode]string // message code => message text
}
func NewLang(code string) *Lang {
return &Lang{
code: code,
messageMap: map[MessageCode]string{},
}
}
func (this *Lang) Set(messageCode MessageCode, messageText string) {
this.messageMap[messageCode] = messageText
}
func (this *Lang) Has(messageCode MessageCode) bool {
_, ok := this.messageMap[messageCode]
return ok
}
// Get 读取单条消息
// get single message with message code
func (this *Lang) Get(messageCode MessageCode) string {
return this.messageMap[messageCode]
}
// GetAll 读取所有消息
// get all messages
func (this *Lang) GetAll() map[MessageCode]string {
return this.messageMap
}
// Compile variable to literal strings
func (this *Lang) Compile() error {
for code, oldMessage := range this.messageMap {
message, err := this.get(code, 0)
if err != nil {
return fmt.Errorf("compile '%s': '%s' failed: %w", string(code), oldMessage, err)
}
this.messageMap[code] = message
}
return nil
}
func (this *Lang) get(messageCode MessageCode, loopIndex int) (string, error) {
if loopIndex >= 8 /** max recurse **/ {
return "", errors.New("too many recurse")
}
loopIndex++
message, ok := this.messageMap[messageCode]
if len(message) == 0 {
if !ok && loopIndex > 1 {
// recover as variable
return "${" + varPrefix + string(messageCode) + "}", errors.New("can not find message for code '" + string(messageCode) + "'")
}
return "", nil
}
return configutils.ParseVariablesError(message, func(varName string) (value string, err error) {
if !strings.HasPrefix(varName, varPrefix) {
return "${" + varName + "}", nil
}
return this.get(MessageCode(varName[len(varPrefix):]), loopIndex)
})
}

110
pkg/langs/manager.go Normal file
View File

@@ -0,0 +1,110 @@
// Copyright 2023 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
package langs
import (
"fmt"
"strings"
)
var defaultManager = NewManager()
type Manager struct {
langMap map[string]*Lang // lang code => *Lang, lang code must be in lowercase
defaultLangCode string
}
func NewManager() *Manager {
return &Manager{
langMap: map[string]*Lang{},
defaultLangCode: "zh-cn",
}
}
func DefaultManager() *Manager {
return defaultManager
}
func (this *Manager) AddLang(code string) *Lang {
var lang = NewLang(code)
this.langMap[code] = lang
return lang
}
func (this *Manager) HasLang(code string) bool {
_, ok := this.langMap[code]
return ok
}
func (this *Manager) GetLang(code string) (lang *Lang, ok bool) {
lang, ok = this.langMap[code]
return
}
func (this *Manager) MatchLang(code string) (matchedCode string) {
// lookup exact match
code = strings.ToLower(code)
_, ok := this.langMap[code]
if ok {
return code
}
// lookup language family, such as en-us, en
if strings.Contains(code, "-") {
code, _, _ = strings.Cut(code, "-")
}
for rawCode := range this.langMap {
if strings.HasPrefix(rawCode, code+"-") { // en-us vs en
return rawCode
}
}
return this.DefaultLang()
}
func (this *Manager) SetDefaultLang(code string) {
this.defaultLangCode = code
}
func (this *Manager) DefaultLang() string {
if len(this.defaultLangCode) > 0 {
return this.defaultLangCode
}
return "zh-cn"
}
// GetMessage
// message: name: %s, age: %d, salary: %.2f
func (this *Manager) GetMessage(langCode string, messageCode MessageCode, args ...any) string {
var lang = this.langMap[langCode]
if lang == nil && len(this.defaultLangCode) > 0 {
lang = this.langMap[this.defaultLangCode]
}
if lang == nil {
return ""
}
var message = lang.Get(messageCode)
if len(message) == 0 {
// try to get message from default lang
if lang.code != this.defaultLangCode {
var defaultLang = this.langMap[this.defaultLangCode]
if defaultLang != nil {
message = defaultLang.Get(messageCode)
if len(args) == 0 {
return message
}
return fmt.Sprintf(message, args...)
}
}
return ""
}
if len(args) == 0 {
return message
}
return fmt.Sprintf(message, args...)
}

43
pkg/langs/manager_test.go Normal file
View File

@@ -0,0 +1,43 @@
// Copyright 2023 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
package langs_test
import (
"github.com/TeaOSLab/EdgeCommon/pkg/langs"
"testing"
)
func TestManager_GetMessage(t *testing.T) {
var manager = langs.NewManager()
var lang = manager.AddLang("en-US")
lang.Set("user_description", "user: %s, age: %d")
t.Log(manager.GetMessage("en-US", "user_description", "Lily", 23))
t.Log(manager.GetMessage("zh-CN", "user_description", "Lucy", 23)) // use 'en-US' as fallback language
}
func TestManager_GetMessage2(t *testing.T) {
var manager = langs.NewManager()
manager.SetDefaultLang("zh-CN")
var lang = manager.AddLang("en-US")
lang.Set("user_description", "user: %s, age: %d")
t.Log(manager.GetMessage("en-US", "user_description", "Lily", 23))
t.Log(manager.GetMessage("zh-CN", "user_description", "Lucy", 23)) // should be empty
}
func TestManager_MatchLang(t *testing.T) {
var manager = langs.NewManager()
manager.AddLang("en-us")
manager.AddLang("en")
manager.AddLang("zh-cn")
manager.AddLang("zh-hk")
//manager.AddLang("zh-tw")
for _, code := range []string{
"en",
"en-us",
"zh-cn",
"zh-tw",
} {
t.Log(code, "=>", manager.MatchLang(code))
}
}

13
pkg/langs/message.go Normal file
View File

@@ -0,0 +1,13 @@
// Copyright 2023 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
package langs
type MessageCode string
func (this MessageCode) For(langCode LangCode, args ...any) string {
return Message(langCode, this, args...)
}
func (this MessageCode) String() string {
return string(this)
}

14
pkg/langs/message_test.go Normal file
View File

@@ -0,0 +1,14 @@
// Copyright 2023 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
package langs
import "testing"
func TestMessageCode_For(t *testing.T) {
defaultManager.AddLang("en-us").
Set("name", "Lily")
var messageCode MessageCode = "name"
t.Log(messageCode.String(), string(messageCode))
t.Log(messageCode.For("en-us"))
}

View File

@@ -0,0 +1,735 @@
// 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> &nbsp; &nbsp; <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_uninstall_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": "",
})
}

View File

@@ -0,0 +1,735 @@
// generated by run 'langs generate'
package messages
import (
"github.com/TeaOSLab/EdgeCommon/pkg/langs"
)
func init() {
langs.Load("zh-cn", map[langs.MessageCode]string{
"acme_provider_account@log_create_acme_provider_account": "创建ACME服务商账号 %d",
"acme_provider_account@log_delete_acme_provider_account": "删除ACME服务商账号 %d",
"acme_provider_account@log_update_acme_provider_account": "修改ACME服务商账号 %d",
"acme_task@log_create_acme_task": "创建证书申请任务 %d",
"acme_task@log_delete_acme_task": "删除证书申请任务 %d",
"acme_task@log_run_acme_task": "执行ACME任务 %d",
"acme_task@log_update_acme_task": "修改证书申请任务 %d",
"acme_user@log_create_acme_user": "创建ACME用户 %d",
"acme_user@log_delete_acme_user": "删除ACME用户 %d",
"acme_user@log_update_acme_user": "修改ACME用户 %d",
"ad_network@log_create_ad_network": "创建高防IP线路 %d",
"ad_network@log_delete_ad_network": "删除高防IP线路",
"ad_network@log_update_ad_network": "修改高防IP线路 %d",
"ad_package@log_create_ad_package": "创建高防产品 %d",
"ad_package@log_delete_ad_package": "删除高防产品 %d",
"ad_package@log_update_ad_package": "修改高防产品 %d",
"ad_package_instance@log_create_ad_package_instance": "创建高防实例 %d",
"ad_package_instance@log_delete_ad_package_instance": "删除高防实例 %d",
"ad_package_instance@log_update_ad_package_instance": "修改高防实例 %d",
"ad_package_period@log_create_ad_package_period": "创建高防IP实例有效期 %d",
"ad_package_period@log_delete_ad_package_period": "删除高防IP实例有效期选项 %d",
"ad_package_period@log_update_ad_package_period": "修改高防IP实例有效期选项 %d",
"ad_package_price@log_create_ad_package_price": "为用户 %d 创建高防实例:%d有效期%d数量%d",
"ad_package_price@log_update_ad_package_price": "修改高防产品 %d 有效期 %d 的价格",
"admin@log_create_admin": "创建系统用户 %d",
"admin@log_delete_admin": "删除系统用户 %d",
"admin@log_update_admin": "修改系统用户 %d",
"admin_common@canceled": "已取消",
"admin_common@log_system_error": "系统发生错误:%s",
"admin_common@menu_setting_basic": "基础设置",
"admin_common@menu_setting_cache": "缓存设置",
"admin_common@menu_setting_cache_policy": "缓存策略",
"admin_common@menu_setting_ddos_protection": "DDoS防护",
"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> &nbsp; &nbsp; <a href=\"https://goedge.cn/docs/APINode/QA.md\" target=\"_blank\">[调整数据库binlog设置]</a>",
"admin_dashboard@ui_dns": "DNS",
"admin_dashboard@ui_events": "事件",
"admin_dashboard@ui_overview": "概况",
"admin_dashboard@ui_user": "用户",
"admin_dashboard@ui_waf": "WAF",
"admin_login@log_failed": "登录失败,用户名:%s",
"admin_login@log_otp_verified_success": "成功通过OTP验证登录系统",
"admin_login@log_success": "成功登录系统,用户名:%s",
"admin_login@log_system_error": "登录时发生系统错误:%s",
"admin_login@log_update_login": "修改登录设置",
"admin_menu@admin_recipients": "通知媒介",
"admin_menu@admins": "系统用户",
"admin_menu@dashboard": "数据看板",
"admin_menu@dns": "域名解析",
"admin_menu@dns_clusters": "集群列表",
"admin_menu@dns_issues": "问题修复",
"admin_menu@dns_providers": "DNS服务商",
"admin_menu@finance": "财务管理",
"admin_menu@finance_accounts": "用户账户",
"admin_menu@finance_bills": "费用账单",
"admin_menu@finance_fee": "计费设置",
"admin_menu@finance_income": "统计报表",
"admin_menu@finance_logs": "收支明细",
"admin_menu@finance_orders": "订单管理",
"admin_menu@finance_packages": "流量包",
"admin_menu@logs": "日志审计",
"admin_menu@node_anti_ddos_products": "高防IP",
"admin_menu@node_clusters": "集群列表",
"admin_menu@node_distributed_monitors": "区域监控",
"admin_menu@node_ip_list": "节点IP",
"admin_menu@node_logs": "节点日志",
"admin_menu@node_regions": "区域设置",
"admin_menu@node_ssh_grants": "节点SSH",
"admin_menu@nodes": "边缘节点",
"admin_menu@ns": "智能DNS",
"admin_menu@ns_access_logs": "访问日志",
"admin_menu@ns_clusters": "集群管理",
"admin_menu@ns_domain_batch_operations": "批量操作",
"admin_menu@ns_domain_groups": "域名分组",
"admin_menu@ns_domains": "域名管理",
"admin_menu@ns_node_logs": "运行日志",
"admin_menu@ns_plans": "套餐设置",
"admin_menu@ns_resolve_test": "解析测试",
"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": "日志策略",
"admin_menu@server_access_logs": "访问日志",
"admin_menu@server_cache_policies": "缓存策略",
"admin_menu@server_certs": "证书管理",
"admin_menu@server_global_settings": "通用设置",
"admin_menu@server_groups": "网站分组",
"admin_menu@server_ip_lists": "IP名单",
"admin_menu@server_metrics": "统计指标",
"admin_menu@server_purge_fetch_caches": "刷新预热",
"admin_menu@server_scripts": "脚本库",
"admin_menu@server_traffic_stats": "用量统计",
"admin_menu@server_waf_policies": "WAF策略",
"admin_menu@servers": "网站列表",
"admin_menu@setting_advanced_settings": "高级设置",
"admin_menu@setting_authority": "商业版本",
"admin_menu@setting_basic_settings": "基础设置",
"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": "修改个人资料",
"admin_security@log_update_security_settings": "修改管理界面安全设置",
"admin_server@log_update_server_http_settings": "修改管理界面的HTTP设置",
"admin_server@log_update_server_https_settings": "修改管理界面的HTTPS设置",
"admin_setting@tab_access_log_databases": "日志数据库",
"admin_setting@tab_admin_security_settings": "安全设置",
"admin_setting@tab_admin_server": "Web服务",
"admin_setting@tab_admin_ui": "管理界面设置",
"admin_setting@tab_api_nodes": "API节点",
"admin_setting@tab_authority": "商业版认证",
"admin_setting@tab_backup": "备份",
"admin_setting@tab_client_browsers": "浏览器库",
"admin_setting@tab_client_operation_systems": "操作系统库",
"admin_setting@tab_database": "数据库",
"admin_setting@tab_ip_library": "IP库",
"admin_setting@tab_login": "登录设置",
"admin_setting@tab_monitor_nodes": "监控节点",
"admin_setting@tab_profile": "个人资料",
"admin_setting@tab_transfer": "迁移",
"admin_setting@tab_updates": "检查更新",
"admin_setting@tab_user_nodes": "用户节点",
"admin_setting@tab_user_ui": "用户界面设置",
"admin_ui@default_product_name": "GoEdge",
"admin_ui@default_system_name": "GoEdge管理员系统",
"admin_ui@log_update_ui_settings": "修改管理界面设置",
"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",
"client_browser@log_create_browser": "创建浏览器信息 %s",
"client_browser@log_update_client_browser": "修改浏览器信息 %d",
"client_system@log_create_system": "创建操作系统信息 %s",
"client_system@log_update_client_system": "修改操作系统信息 %d",
"database@log_delete_table": "删除数据表 %s",
"database@log_truncate_table": "清空数据表 %s 数据",
"database@log_update_api_node_database_config": "修改API节点数据库设置",
"database@log_update_clean_days": "修改数据库自动清理设置",
"db_node@log_create_db_node": "创建数据库节点 %d",
"db_node@log_delete_db_node": "删除数据库节点 %d",
"db_node@log_delete_table": "删除数据库节点 %d 数据表 %s",
"db_node@log_truncate_table": "清空数据库节点 %d 数据表 %s 数据",
"db_node@log_update_db_node": "修改数据库节点 %d",
"db_node@tab_nodes": "数据库节点",
"ddos_protection@log_update_cluster_ddos_protection": "修改集群 %d 的DDOS防护设置",
"ddos_protection@log_update_node_ddos_protection": "修改节点 %d 的DDOS防护设置",
"dns@log_create_domain": "添加管理域名到DNS服务商 %d",
"dns@log_delete_domain": "从DNS服务商中删除域名 %d",
"dns@log_recover_domain": "从DNS服务商中恢复域名 %d",
"dns@log_sync_cluster": "同步集群 %d 的DNS设置",
"dns@log_sync_domain": "同步DNS域名数据 %d",
"dns@log_update_cluster_dns": "修改集群 %d DNS设置",
"dns@log_update_domain": "修改DNS服务商域名 %d",
"dns@log_update_node_dns": "修改节点 %d 的DNS设置",
"dns_provider@log_create_dns_provider": "创建DNS服务商 %d",
"dns_provider@log_delete_dns_provider": "删除DNS服务商 %d",
"dns_provider@log_update_dns_provider": "修改DNS服务商 %d",
"dns_task@log_delete_all_dns_tasks": "删除所有DNS同步任务",
"dns_task@log_delete_dns_task": "删除DNS同步任务 %d",
"finance@log_bill_generate_manually": "手动生成上个月 %s 账单",
"finance@log_update_user_order_config": "修改订单设置",
"finance_fee@log_update_fee_setting": "修改默认计费方式",
"http_access_log_policy@log_create_http_access_log_policy": "创建访问日志策略 %d",
"http_access_log_policy@log_delete_http_access_log_policy": "删除访问日志策略 %d",
"http_access_log_policy@log_test_http_access_log_policy": "测试向访问日志策略 %d 写入数据",
"http_access_log_policy@log_update_http_access_log_policy": "修改访问日志策略 %d",
"http_auth_policy@log_create_http_auth_policy": "创建HTTP鉴权 %d",
"http_auth_policy@log_update_http_auth_policy": "修改HTTP鉴权 %d",
"http_cache_task@log_create_http_cache_task_fetch": "批量预热缓存Key",
"http_cache_task@log_create_http_cache_task_purge": "批量刷新缓存Key",
"http_cache_task@log_delete_http_cache_task": "删除缓存任务 %d",
"http_cache_task@log_reset_http_cache_task": "重置缓存任务 %d 状态",
"http_fastcgi@log_create_http_fastcgi": "创建Fastcgi %d",
"http_fastcgi@log_update_http_fastcgi": "修改Fastcgi %d",
"http_location@log_create_http_location": "创建路由规则:%s",
"http_location@log_update_http_location": "修改路由规则 %d 设置",
"http_rewrite_rule@log_create_rewrite_rule": "在Web %d 中创建重写规则 %d",
"http_rewrite_rule@log_delete_rewrite_rule": "从Web %d 中删除重写规则 %d",
"http_rewrite_rule@log_sort_rewrite_rules": "对Web %d 中的重写规则进行排序",
"http_rewrite_rule@log_update_rewrite_rule": "修改Web %d 中的重写规则 %d",
"ip_item@log_create_ip_item": "在名单 %d 中创建IP %d",
"ip_item@log_delete_ip_item": "从IP名单 %d 中删除IP %d",
"ip_item@log_read_all_ip_items": "将所有IP名单置为已读",
"ip_item@log_update_ip_item": "修改IP名单中的IP %d",
"ip_library@log_finish_ip_library": "完成IP库%d 制作",
"ip_library_artifact@log_cancel_ip_library_artifact": "取消使用IP库 %d",
"ip_library_artifact@log_delete_ip_library_artifact": "删除IP库 %d",
"ip_library_artifact@log_use_ip_library_artifact": "使用IP库 %d",
"ip_library_file@log_delete_ip_library_file": "删除IP库文件 %d",
"ip_library_file@log_generate_ip_library_file": "重新生成IP库 %d 文件",
"ip_library_file@log_upload_ip_library_file": "上传IP库 %d",
"ip_list@log_bind_ip_list_waf_policy": "绑定IP名单 %d 到WAF策略 %d",
"ip_list@log_create_ip_items_batch": "在IP名单 %d 中批量添加IP",
"ip_list@log_create_ip_list": "创建IP名单 %d",
"ip_list@log_delete_ip_batch": "批量删除IP名单中的IP%s",
"ip_list@log_delete_ip_list": "删除IP名单 %d",
"ip_list@log_export_ip_list": "导出IP名单 %d",
"ip_list@log_import_ip_list": "导入IP名单 %d",
"ip_list@log_unbind_ip_list_waf_policy": "解除绑定IP名单 %d WAF策略 %d",
"ip_list@log_update_ip_list": "修改IP名单 %d",
"level@error": "错误",
"level@info": "信息",
"level@warn": "警告",
"log@log_clean_all_logs": "清除全部日志",
"log@log_clean_logs_days_before": "清除 %d 以前的日志",
"log@log_delete_log": "删除单个操作日志 %d",
"log@log_update_settings": "修改日志相关配置",
"log@tag_access_log": "访问日志",
"log@tag_listener": "端口监听",
"log@tag_script": "脚本",
"log@tag_waf": "WAF",
"message@log_read_all": "将所有消息置为已读",
"message@log_read_messages": "将一组消息置为已读",
"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_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",
"metric_item@log_add_metric_item_to_cluster": "添加指标 %d 到集群 %d",
"metric_item@log_create_metric_item": "创建统计指标 %d",
"metric_item@log_delete_metric_item": "删除统计指标",
"metric_item@log_delete_metric_item_from_cluster": "从集群 %d 中移除指标 %d",
"metric_item@log_update_metric_item": "修改统计指标 %d",
"monitor_node@log_create_monitor_node": "创建监控节点 %d",
"monitor_node@log_delete_monitor_node": "删除监控节点 %d",
"monitor_node@log_update_monitor_node": "修改监控节点 %d",
"node@log_create_node": "创建节点 %d",
"node@log_create_node_batch": "批量创建节点",
"node@log_delete_node_from_cluster": "从集群 %d 中删除节点 %d",
"node@log_install_node": "安装节点 %d",
"node@log_install_node_remotely": "远程安装节点 %d",
"node@log_start_node_remotely": "远程启动节点 %d",
"node@log_stop_node_remotely": "远程停止节点 %d",
"node@log_uninstall_node_remotely": "远程卸载节点 %d",
"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 调度动作到集群",
"node_action@log_copy_node_actions_to_group": "复制节点 %d 调度动作到分组",
"node_action@log_create_node_action": "创建动作 %d",
"node_action@log_delete_node_action": "删除节点动作 %d",
"node_action@log_sort_node_actions": "修改节点 %d 动作排序",
"node_action@log_update_node_action": "修改节点动作 %d",
"node_cache@log_update_node_cache_settings": "修改节点 %d 缓存设置",
"node_cluster@log_create_cluster": "创建节点集群:%d",
"node_cluster@log_delete_cluster": "删除集群 %d",
"node_cluster@log_pin_cluster": "置顶集群 %d",
"node_cluster@log_run_cluster_health_check": "执行集群健康检查设置 %d",
"node_cluster@log_unpin_cluster": "取消置顶集群 %d",
"node_cluster@log_update_cluster_basic_settings": "修改集群基础设置 %d",
"node_cluster@log_update_cluster_health_check": "修改集群健康检查设置 %d",
"node_cluster_menu@setting_basic": "基础设置",
"node_cluster_menu@setting_cache_policy": "缓存策略",
"node_cluster_menu@setting_cc": "CC防护",
"node_cluster_menu@setting_ddos_protection": "DDoS防护",
"node_cluster_menu@setting_dns": "DNS设置",
"node_cluster_menu@setting_health_check": "健康检查",
"node_cluster_menu@setting_http3": "HTTP/3",
"node_cluster_menu@setting_metrics": "统计指标",
"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": "阈值设置",
"node_cluster_menu@setting_toa": "TOA设置",
"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@tab_cluster_dashboard": "集群看板",
"node_cluster_menu@tab_cluster_delete": "删除集群",
"node_cluster_menu@tab_cluster_nodes": "节点列表",
"node_cluster_menu@tab_cluster_settings": "集群设置",
"node_dns@log_update_node_dns": "修改节点 %d DNS设置",
"node_grant@log_create_ssh_grant": "创建SSH认证 %d",
"node_grant@log_delete_ssh_grant": "删除SSH认证 %d",
"node_grant@log_update_ssh_grant": "修改SSH认证 %d",
"node_grant@method_private_key": "私钥",
"node_grant@method_user_password": "用户名+密码",
"node_group@log_create_node_group": "创建节点分组 %d",
"node_group@log_delete_node_group": "删除节点分组 %d",
"node_group@log_sort_node_groups": "修改节点分组排序",
"node_group@log_update_node_group": "修改节点分组 %d",
"node_ip_address@log_delete_node_ip_address": "删除IP地址 %d",
"node_ip_address@log_down_node_ip_address": "手动设置IP地址 %d 下线",
"node_ip_address@log_restore_node_ip_address": "取消IP地址 %d 的备用IP",
"node_ip_address@log_up_node_ip_address": "手动设置IP地址 %d 上线",
"node_log@log_delete_node_logs_batch": "批量删除节点运行日志",
"node_log@log_fix_all_logs": "设置所有日志为已修复",
"node_log@log_fix_node_logs": "设置日志 %s 为已修复",
"node_menu@create_multiple_nodes": "批量创建",
"node_menu@create_single_node": "单个创建",
"node_menu@install_auto_register": "自动注册",
"node_menu@install_manually": "手动安装",
"node_menu@install_remote": "远程安装(%d)",
"node_menu@install_remote_upgrade": "远程升级(%d)",
"node_menu@setting_basic": "基础设置",
"node_menu@setting_cache": "缓存设置",
"node_menu@setting_ddos_protection": "DDoS防护",
"node_menu@setting_dns": "DNS设置",
"node_menu@setting_schedule": "智能调度",
"node_menu@setting_ssh": "SSH设置",
"node_menu@setting_system": "系统设置",
"node_menu@setting_thresholds": "阈值设置",
"node_price_item@log_create_node_price_item_bandwidth": "创建带宽价格项目 %d",
"node_price_item@log_create_node_price_item_traffic": "创建流量价格项目 %d",
"node_price_item@log_delete_node_price_item": "删除流量价格项目 %d",
"node_price_item@log_update_node_price_item_bandwidth": "修改带宽价格项目 %d",
"node_price_item@log_update_node_price_item_traffic": "修改流量价格项目 %d",
"node_region@log_create_node_region": "创建节点区域 %d",
"node_region@log_delete_node_region": "删除节点区域 %d",
"node_region@log_move_node_between_regions": "修改节点 %d 区域到 %d",
"node_region@log_sort_node_regions": "修改节点区域排序",
"node_region@log_update_node_region": "修改节点区域 %d",
"node_region_price@log_update_node_region_price": "修改区域 %d - 价格项 %d 的价格",
"node_schedule@log_reset_node_action_status": "重置节点 %d 动作状态",
"node_schedule@log_update_node_schedule_basic": "修改节点调度基本信息",
"node_ssh@log_update_node_ssh": "修改节点 %d SSH配置",
"node_system@log_update_node_system_settings": "修改节点 %d 系统信息",
"node_systemd@log_update_cluster_systemd_settings": "修改集群 %d 的系统服务设置",
"node_task@log_delete_all_node_tasks": "删除所有节点同步任务",
"node_task@log_delete_node_task": "删除同步任务 %d",
"node_task@log_delete_node_tasks_batch": "批量删除节点同步任务",
"node_threshold@log_create_node_threshold": "创建节点阈值 %d",
"node_threshold@log_delete_node_threshold": "删除阈值 %d",
"node_threshold@log_update_node_threshold": "修改节点阈值 %d",
"node_toa@log_update_cluster_toa": "修改集群 %d 的TOA设置",
"ns@log_create_ns_domains_batch": "批量添加域名",
"ns@log_create_ns_records_batch": "批量添加解析",
"ns@log_delete_ns_domains_batch": "批量删除域名,用户 %d",
"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全局设置--用户相关设置",
"ns@setting_access_logs": "访问日志设置",
"ns@setting_user": "用户设置",
"ns_cluster@log_create_ns_cluster": "创建域名服务集群 %d",
"ns_cluster@log_delete_ns_cluster": "删除域名服务集群 %d",
"ns_cluster@log_update_ns_cluster_settings_access_log": "修改域名服务集群 %d 访问日志配置",
"ns_cluster@log_update_ns_cluster_settings_answer": "修改NS集群 %d 应答模式设置",
"ns_cluster@log_update_ns_cluster_settings_basic": "修改域名服务集群基本信息 %d",
"ns_cluster@log_update_ns_cluster_settings_ddos_protection": "修改NS集群 %d 的DDOS防护设置",
"ns_cluster@log_update_ns_cluster_settings_doh": "修改NS集群 %d DoH设置",
"ns_cluster@log_update_ns_cluster_settings_recursion": "修改DNS集群 %d 的递归DNS设置",
"ns_cluster@log_update_ns_cluster_settings_soa": "修改NS集群 %d SOA配置",
"ns_cluster@log_update_ns_cluster_settings_tcp": "修理NS集群 %d TCP设置",
"ns_cluster@log_update_ns_cluster_settings_tls": "修改NS集群 %d TLS设置",
"ns_cluster@log_update_ns_cluster_settings_udp": "修改NS集群 %d UDP设置",
"ns_cluster@menu_access_logs": "访问日志",
"ns_cluster@menu_answer_setting": "应答模式",
"ns_cluster@menu_basic": "基础设置",
"ns_cluster@menu_ddos_protection": "DDoS防护",
"ns_cluster@menu_dns_recursion": "递归DNS",
"ns_cluster@menu_doh": "DoH",
"ns_cluster@menu_soa": "SOA",
"ns_cluster@menu_tcp": "TCP",
"ns_cluster@menu_tls": "TLS",
"ns_cluster@menu_udp": "UDP",
"ns_cluster@tab_delete": "删除集群",
"ns_cluster@tab_nodes": "节点列表",
"ns_cluster@tab_setting": "集群设置",
"ns_domain@log_create_ns_domain": "创建域名 %d",
"ns_domain@log_create_ns_domains_batch": "批量添加域名",
"ns_domain@log_delete_ns_domain": "删除域名 %d",
"ns_domain@log_update_ns_domain": "修改域名 %d",
"ns_domain@log_update_ns_domain_health_check": "修改域名 %d 健康检查设置",
"ns_domain@log_update_ns_domain_status": "修改域名 %d 状态为 %s",
"ns_domain@log_update_ns_domain_tsig": "修改域名 %d 的TSIG配置",
"ns_domain@log_validate_ns_domains": "批量验证域名",
"ns_domain_group@log_create_ns_domain_group": "创建域名分组 %d",
"ns_domain_group@log_delete_ns_domain_group": "删除域名分组 %d",
"ns_domain_group@log_update_ns_domain_group": "修改域名分组 %d",
"ns_key@log_create_ns_key": "创建DNS密钥 %d",
"ns_key@log_delete_ns_key": "删除DNS密钥 %d",
"ns_key@log_update_ns_key": "修改DNS密钥 %d",
"ns_node@log_create_ns_node": "创建域名服务节点 %d",
"ns_node@log_delete_ns_node": "删除域名服务节点 %d",
"ns_node@log_install_ns_node_remotely": "安装节点 %d",
"ns_node@log_start_ns_node_remotely": "远程启动节点 %d",
"ns_node@log_stop_ns_node_remotely": "远程停止节点 %d",
"ns_node@log_update_ns_node": "修改节点 %d",
"ns_node@log_update_ns_node_installation_status": "修改节点安装状态 %d",
"ns_node_ssh@log_update_ns_node_ssh": "修改节点 %d SSH配置",
"ns_plan@log_create_ns_plan": "创建套餐 %d",
"ns_plan@log_delete_ns_plan": "删除套餐 %d",
"ns_plan@log_sort_ns_plans": "套餐排序",
"ns_plan@log_update_ns_plan": "修改套餐 %d",
"ns_record@log_create_ns_record": "创建域名记录 %d",
"ns_record@log_create_ns_records_batch": "批量创建域名记录",
"ns_record@log_delete_ns_record": "删除域名记录 %d",
"ns_record@log_up_ns_record": "手动设置DNS记录 %d 为上线状态",
"ns_record@log_update_ns_record": "修改域名记录 %d",
"ns_record@log_update_ns_record_health_check": "修改记录 %d 的健康检查",
"ns_route@log_create_ns_route": "创建域名服务线路 %d",
"ns_route@log_delete_ns_route": "删除域名服务线路 %d",
"ns_route@log_sort_ns_routes": "对线路进行排序",
"ns_route@log_update_ns_route": "修改域名线路 %d",
"ns_route_category@log_create_ns_route_category": "创建NS线路分类 %d",
"ns_route_category@log_delete_ns_route_category": "删除NS线路分类 %d",
"ns_route_category@log_sort_ns_route_categories": "对NS线路分类进行排序",
"ns_route_category@log_update_ns_route_category": "修改NS线路分类 %d",
"ns_user_plan@log_create_ns_user_plan": "为用户 %d 创建DNS套餐 %d",
"ns_user_plan@log_delete_ns_user_plan": "删除用户套餐 %d",
"ns_user_plan@log_update_ns_user_plan": "修改用户DNS套餐 %d",
"order_method@log_create_order_method": "创建支付方式 %d",
"order_method@log_delete_order_method": "删除支付方式 %d",
"order_method@log_update_order_method": "修改支付方式 %d",
"plan@log_create_plan": "创建套餐 %d",
"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",
"region_country@log_update_region_country_custom": "定制国家/地区 %d 信息",
"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": "添加ISP服务商 %d 别名 %s",
"region_provider@log_update_region_provider_custom": "定制ISP %d 信息",
"region_province@log_add_region_province_code": "添加省份/州 %d 别名 %s",
"region_province@log_update_region_province_custom": "定制省份 %d 信息",
"region_town@log_add_region_town_code": "添加区/县 %d 别名 %s",
"region_town@log_update_region_town_custom": "定制县级 %d 信息",
"report_node@log_create_report_node": "创建监控终端 %d",
"report_node@log_delete_report_node": "删除监控终端 %d",
"report_node@log_update_report_node": "修改监控终端 %d",
"report_node_group@log_create_report_node_group": "创建监控节点分组 %d",
"report_node_group@log_delete_report_node_group": "删除监控节点分组 %d",
"report_node_group@log_update_report_node_group": "修改监控节点分组 %d",
"reverse_proxy@log_update_reverse_proxy_scheduling": "修改反向代理 %d 负载均衡算法",
"script@log_create_script": "创建脚本 %d",
"script@log_delete_script": "删除脚本 %d",
"script@log_publish_scripts": "发布脚本库到边缘节点",
"script@log_update_script": "修改脚本 %d",
"server@copy_setting_current_cluster": "当前集群:%s",
"server@copy_setting_current_group": "当前分组:%s",
"server@copy_setting_current_user": "当前用户:%s",
"server@copy_setting_select_cluster": "选择集群",
"server@copy_setting_select_group": "选择分组",
"server@copy_setting_select_server": "选择网站",
"server@copy_setting_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": "历史",
"server@menu_accesslog_realtime": "实时",
"server@menu_accesslog_today": "今天",
"server@menu_dashboard": "看板",
"server@menu_setting_access_log": "访问日志",
"server@menu_setting_auth": "访问鉴权",
"server@menu_setting_basic": "基本信息",
"server@menu_setting_cache": "缓存",
"server@menu_setting_cc": "CC防护",
"server@menu_setting_charset": "字符编码",
"server@menu_setting_client_ip": "访客IP地址",
"server@menu_setting_compression": "内容压缩",
"server@menu_setting_delete": "删除",
"server@menu_setting_dns": "DNS",
"server@menu_setting_domains": "域名",
"server@menu_setting_fastcgi": "Fastcgi",
"server@menu_setting_group": "分组",
"server@menu_setting_http": "HTTP",
"server@menu_setting_http_headers": "HTTP报头",
"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": "其他设置",
"server@menu_setting_pages": "自定义页面",
"server@menu_setting_plan": "套餐",
"server@menu_setting_redirects": "URL跳转",
"server@menu_setting_referers": "防盗链",
"server@menu_setting_request_limit": "请求限制",
"server@menu_setting_rewrite_rules": "重写规则",
"server@menu_setting_root": "静态分发",
"server@menu_setting_scripts": "边缘脚本",
"server@menu_setting_stat": "统计",
"server@menu_setting_tcp": "TCP",
"server@menu_setting_tcp_proxy": "TCP代理",
"server@menu_setting_tls": "TLS",
"server@menu_setting_traffic_limit": "流量限制",
"server@menu_setting_uam": "5秒盾",
"server@menu_setting_udp": "UDP",
"server@menu_setting_udp_proxy": "UDP代理",
"server@menu_setting_user_agents": "UA名单",
"server@menu_setting_waf": "WAF",
"server@menu_setting_webp": "WebP",
"server@menu_setting_websocket": "Websocket",
"server@menu_stat_clients": "终端",
"server@menu_stat_providers": "运营商",
"server@menu_stat_regions": "地域分布",
"server@menu_stat_traffic": "流量统计",
"server@menu_stat_waf": "WAF",
"server@server_names_log_update_server_names": "修改网站 %d 域名",
"server@tab_access_logs": "日志",
"server@tab_dashboard": "看板",
"server@tab_delete": "删除",
"server@tab_server_list": "网站列表",
"server@tab_settings": "设置",
"server@tab_stat": "统计",
"server_access_log@log_update_access_log_setting": "修改Web %d 的访问日志设置",
"server_auth@log_update_http_auth_settings": "修改Web %d 的鉴权设置",
"server_cache@log_fetch_caches": "预热网站 %d 缓存",
"server_cache@log_purge_caches": "删除网站 %d 缓存",
"server_cache@log_update_cache_settings": "修改Web %d 的缓存设置",
"server_cache@log_update_cluster_cache_policy": "设置集群 %d 的缓存策略为 %d",
"server_cache_policy@log_clean_all": "清除缓存,缓存策略:%d",
"server_cache_policy@log_create_cache_policy": "创建缓存策略:%d",
"server_cache_policy@log_delete_cache_policy": "删除缓存策略:%d",
"server_cache_policy@log_fetch_caches": "预热缓存,缓存策略:%d",
"server_cache_policy@log_purge_caches": "删除缓存,缓存策略:%d",
"server_cache_policy@log_stat_caches": "统计缓存,缓存策略:%d",
"server_cache_policy@log_test_reading": "测试读取,缓存策略:%d",
"server_cache_policy@log_test_writing": "测试写入,缓存策略:%d",
"server_cache_policy@log_update_cache_policy": "修改缓存策略:%d",
"server_cc@log_update_cc_settings": "修改Web %d CC防护配置",
"server_cc@log_update_cluster_http_cc_policy": "修改集群 %d 的HTTP CC策略设置",
"server_charset@log_update_charset_setting": "修改Web %d 的字符集设置",
"server_common@log_update_common_settings": "修改网站Web %d 设置的其他设置",
"server_compression@log_update_compression_settings": "修改Web %d 的压缩设置",
"server_dns@log_regenerate_dns_name": "重新生成网站 %d 的CNAME",
"server_dns@log_update_dns_name": "修改网站 %d CNAME为 %s",
"server_dns@log_update_dns_settings": "修改网站 %d 的DNS设置",
"server_fastcgi@log_update_http_fastcgi": "修改Web %d 的Fastcgi设置",
"server_global_setting@log_update_cluster_global_server_config": "修改集群 %d 全局配置",
"server_group@log_create_server_group": "创建网站分组 %d",
"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",
"server_http_header@log_create_non_standard_header": "添加非标的报头 HeaderPolicyId: %d, Name: %s",
"server_http_header@log_create_setting_request_header": "添加自定义请求报头HeaderPolicyId:%d, Name:%s, Value:%s",
"server_http_header@log_create_setting_response_header": "添加自定义响应报头HeaderPolicyId:%d, Name:%s, Value:%s",
"server_http_header@log_delete_deleting_header": "删除需要删除的报头HeaderPolicyId:%d, HeaderName:%s",
"server_http_header@log_delete_header": "删除报头HeaderPolicyId:%d, HeaderId:%d",
"server_http_header@log_delete_non_standard_header": "删除需要非标的报头HeaderPolicyId:%d, HeaderName:%s",
"server_http_header@log_update_http_headers": "修改Web %d 的报头设置",
"server_http_header@log_update_setting_header": "修改设置报头HeaderId:%d, Name:%s, Value:%s",
"server_https@log_update_https_settings": "修改网站 %d 的HTTPS设置",
"server_optimization@log_update_optimization_settings": "修改Web %d 的页面优化设置",
"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",
"server_page@log_update_pages": "修改Web %d 的自定义页面设置",
"server_redirect@log_update_redirects": "修改Web %d 的跳转设置",
"server_referer@log_update_referers": "修改Web %d 防盗链设置",
"server_request_limit@log_update_request_limit_settings": "修改Web %d 请求限制",
"server_reverse_proxy@log_update_location_reverse_proxy_settings": "修改路由规则 %d 的反向代理设置",
"server_reverse_proxy@log_update_server_group_reverse_proxy_settings": "修改分组 %d 的反向代理设置",
"server_reverse_proxy@log_update_server_reverse_proxy_settings": "修改网站 %d 的反向代理设置",
"server_root@log_update_root": "修改Web %d 静态分发设置",
"server_script@log_update_scripts": "修改Web %d 边缘脚本",
"server_stat@log_update_stat_settings": "修改Web %d 的统计设置",
"server_tcp@log_update_tcp_settings": "修改网站 %d TCP设置",
"server_tls@log_update_tls_settings": "修改网站 %d TLS设置",
"server_traffic_limit@log_update_traffic_limit_settings": "修改网站 %d 流量限制",
"server_traffic_stat@all_servers": "全部网站(%d",
"server_uam@log_update_cluster_uam_policy": "修改集群 %d 的UAM设置",
"server_uam@log_update_server_uam_settings": "修改网站 %d 全站防护模式",
"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设置",
"ssl_cert@log_delete_ssl_cert": "删除SSL证书 %d",
"ssl_cert@log_download_ssl_cert": "下载SSL证书 %d",
"ssl_cert@log_download_ssl_cert_key": "下载SSL密钥 %d",
"ssl_cert@log_download_ssl_cert_zip": "下载SSL证书压缩包 %d",
"ssl_cert@log_ocsp_ignore_ocsp_status": "忽略一组证书的OCSP状态",
"ssl_cert@log_ocsp_reset_all_ocsp_status": "忽略所有证书的OCSP状态",
"ssl_cert@log_ocsp_reset_ocsp_status": "重置一组证书的OCSP状态",
"ssl_cert@log_update_ssl_cert": "修改SSL证书 %d",
"ssl_cert@log_upload_ssl_cert": "上传SSL证书 %d",
"ssl_cert@log_upload_ssl_cert_batch": "批量上传证书",
"ssl_cert@menu_apply": "申请证书",
"ssl_cert@menu_certs": "证书",
"ssl_cert@menu_ocsp": "OCSP日志",
"system@home_page": "https://goedge.cn",
"ticket_category@log_create_ticket_category": "添加工单分类 %d",
"ticket_category@log_delete_ticket_category": "删除工单分类 %d",
"ticket_category@log_update_ticket_category": "修改分类 %d",
"traffic_package@log_create_traffic_package": "创建流量包 %d",
"traffic_package@log_delete_traffic_package": "删除流量包 %d",
"traffic_package@log_update_traffic_package": "修改流量包 %d",
"traffic_package_period@log_create_traffic_package_period": "创建流量包有效期 %d",
"traffic_package_period@log_delete_traffic_package_period": "删除流量包有效期选项 %d",
"traffic_package_period@log_update_traffic_package_period": "修改流量包有效期选项 %d",
"traffic_package_price@log_update_traffic_package_price": "修改流量包 %d 区域 %d x 有效期 %d 的价格",
"user@log_create_user": "创建用户 %d",
"user@log_delete_user": "删除用户 %d",
"user@log_update_user": "修改用户 %d",
"user@log_update_user_email_settings": "修改用户邮件设置",
"user@log_update_user_features": "设置用户 %d 的功能列表",
"user@log_update_user_global_settings": "修改用户设置",
"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",
"user_access_key@log_update_user_access_key_is_on": "设置AccessKey %d 启用状态",
"user_account@log_update_user_account": "操作用户账户 %d: %s",
"user_ad_instance@log_delete_user_ad_instance": "删除用户高防实例 %d",
"user_ad_instance@log_renew_user_ad_instance": "为用户高防实例 %d 续期",
"user_ad_instance@log_update_user_ad_instance_objects": "修改用户高防实例 %d 防护对象",
"user_bill@log_pay_user_bill": "支付账单 %d",
"user_common@canceled": "已取消",
"user_common@log_system_error": "系统发生错误:%s",
"user_common@server_error": "服务器出了点小问题,请联系技术人员处理。",
"user_common@system": "系统",
"user_identity@log_cancel_user_identity": "取消身份认证审核",
"user_identity@log_reject_user_identity": "驳回用户 %d 的实名认证",
"user_identity@log_reset_user_identity": "重置用户 %d 的实名认证",
"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": "通过用户 %d 的实名认证",
"user_login@log_update_login": "修改登录设置",
"user_node@log_create_user_node": "创建用户节点 %d",
"user_node@log_delete_user_node": "删除用户节点 %d",
"user_node@log_update_user_node": "修改用户节点 %d",
"user_order@log_finish_user_order": "设置订单 %s 为完成支付",
"user_plan@log_bind_user_plan_to_server": "修改网站 %d 绑定的套餐为 %d",
"user_plan@log_buy_user_plan": "为用户 %d 购买套餐 %d",
"user_plan@log_cancel_user_plan_from_server": "取消网站 %d 绑定的套餐",
"user_plan@log_delete_user_plan": "删除用户已购套餐 %d",
"user_plan@log_renew_user_plan": "续费已购套餐 %d",
"user_ticket@log_create_user_ticket": "创建工单 %d",
"user_ticket_log@log_reply_ticket": "回复工单 %d",
"user_traffic_package@log_create_user_traffic_package": "为用户 %d 创建流量包:%d区域%d有效期%d数量%d",
"user_traffic_package@log_delete_user_traffic_package": "删除用户流量包 %d",
"waf@connector_and": "和(AND)",
"waf@connector_and_description": "所有规则都满足才视为匹配",
"waf@connector_or": "或(OR)",
"waf@connector_or_description": "任一规则满足了就视为匹配",
"waf@log_delete_ip_from_waf_policy": "从WAF策略 %d 名单中删除IP %d",
"waf@log_update_forbidden_countries": "WAF策略 %d 设置禁止访问的国家和地区",
"waf@log_update_forbidden_provinces": "WAF策略 %d 设置禁止访问的省份",
"waf@log_update_ip_from_waf_policy": "修改WAF策略 %d 名单中的IP %d",
"waf_action@log_create_waf_action": "创建集群 %d 的WAF动作",
"waf_action@log_delete_waf_action": "删除WAF动作 %d",
"waf_action@log_update_waf_action": "修改WAF动作 %d",
"waf_policy@log_create_waf_policy": "创建WAF策略 %d",
"waf_policy@log_delete_waf_policy": "删除WAF策略 %d",
"waf_policy@log_export_waf_policy": "导出WAF策略 %d",
"waf_policy@log_import_waf_policy": "从文件中导入规则到WAF策略 %d",
"waf_policy@log_update_cluster_waf_policy": "设置集群 %d 的WAF策略为 %d",
"waf_policy@log_update_waf_policy": "修改WAF策略 %d 基本信息",
"waf_policy@log_upgrade_waf_policy": "升级WAF %d 内置规则",
"waf_rule_group@log_create_rule_group": "创建规则分组 %d名称%s",
"waf_rule_group@log_delete_rule_group": "删除WAF策略 %d 的规则分组 %d",
"waf_rule_group@log_sort_rule_groups": "修改WAF策略 %d 中的规则分组中的排序",
"waf_rule_group@log_update_rule_group": "修改WAF规则分组 %d 基本信息",
"waf_rule_group@log_update_rule_group_is_on": "设置WAF规则分组 %d 开启状态",
"waf_rule_set@log_delete_rule_set": "删除WAF规则分组 %d 中的规则集 %d",
"waf_rule_set@log_sort_rule_sets": "修改WAF规则分组 %d 中的规则集排序",
"waf_rule_set@log_update_rule_set": "修改WAF规则集 %d 基本信息",
"waf_rule_set@log_update_rule_set_is_on": "修改WAF规则集 %d 开启状态",
})
}

View 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
~~~

View 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"
}

View 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> &nbsp; &nbsp; <a href=\"${lang.system@home_page}/docs/APINode/QA.md\" target=\"_blank\">[调整数据库binlog设置]</a>"
}

View 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"
}

View 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"
}

View 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"
}

View 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"
}

View 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 启用状态"
}

View File

@@ -0,0 +1,3 @@
{
"home_page": "https://goedge.cn"
}

View File

@@ -0,0 +1,5 @@
{
"log_create_acme_provider_account": "创建ACME服务商账号 %d",
"log_delete_acme_provider_account": "删除ACME服务商账号 %d",
"log_update_acme_provider_account": "修改ACME服务商账号 %d"
}

View File

@@ -0,0 +1,6 @@
{
"log_create_acme_task": "创建证书申请任务 %d",
"log_update_acme_task": "修改证书申请任务 %d",
"log_delete_acme_task": "删除证书申请任务 %d",
"log_run_acme_task": "执行ACME任务 %d"
}

View File

@@ -0,0 +1,5 @@
{
"log_create_acme_user": "创建ACME用户 %d",
"log_delete_acme_user": "删除ACME用户 %d",
"log_update_acme_user": "修改ACME用户 %d"
}

View File

@@ -0,0 +1,5 @@
{
"log_delete_ad_network": "删除高防IP线路",
"log_update_ad_network": "修改高防IP线路 %d",
"log_create_ad_network": "创建高防IP线路 %d"
}

View File

@@ -0,0 +1,5 @@
{
"log_create_ad_package": "创建高防产品 %d",
"log_delete_ad_package": "删除高防产品 %d",
"log_update_ad_package": "修改高防产品 %d"
}

View File

@@ -0,0 +1,5 @@
{
"log_delete_ad_package_instance": "删除高防实例 %d",
"log_update_ad_package_instance": "修改高防实例 %d",
"log_create_ad_package_instance": "创建高防实例 %d"
}

View File

@@ -0,0 +1,5 @@
{
"log_create_ad_package_period": "创建高防IP实例有效期 %d",
"log_delete_ad_package_period": "删除高防IP实例有效期选项 %d",
"log_update_ad_package_period": "修改高防IP实例有效期选项 %d"
}

View File

@@ -0,0 +1,4 @@
{
"log_create_ad_package_price": "为用户 %d 创建高防实例:%d有效期%d数量%d",
"log_update_ad_package_price": "修改高防产品 %d 有效期 %d 的价格"
}

View File

@@ -0,0 +1,5 @@
{
"log_create_admin": "创建系统用户 %d",
"log_delete_admin": "删除系统用户 %d",
"log_update_admin": "修改系统用户 %d"
}

View File

@@ -0,0 +1,19 @@
{
"menu_setting_basic": "基础设置",
"menu_setting_dns": "DNS设置",
"menu_setting_health_check": "健康检查",
"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": "系统",
"canceled": "已取消",
"server_error": "服务器出了点小问题,请联系技术人员处理。",
"log_system_error": "系统发生错误:%s"
}

View File

@@ -0,0 +1,9 @@
{
"ui_overview": "概况",
"ui_waf": "WAF",
"ui_dns": "DNS",
"ui_user": "用户",
"ui_events": "事件",
"disk_usage_warning": "当前服务器磁盘空间不足,请立即扩充容量,文件路径:%s已使用%dG已使用比例%.2f%%,仅剩余空间:%.2f%%。<br/>如果是因为本机数据库数据过多,你可以:<a href=\"/settings/database/clean\">[清理访问日志]</a> &nbsp; &nbsp; <a href=\"${lang.system@home_page}/docs/APINode/QA.md\" target=\"_blank\">[调整数据库binlog设置]</a>"
}

View File

@@ -0,0 +1,8 @@
{
"log_system_error": "登录时发生系统错误:%s",
"log_failed": "登录失败,用户名:%s",
"log_success": "成功登录系统,用户名:%s",
"log_otp_verified_success": "成功通过OTP验证登录系统",
"log_update_login": "修改登录设置"
}

View File

@@ -0,0 +1,74 @@
{
"dashboard": "数据看板",
"servers": "网站列表",
"server_access_logs": "访问日志",
"server_groups": "网站分组",
"server_certs": "证书管理",
"server_traffic_stats": "用量统计",
"server_cache_policies": "缓存策略",
"server_purge_fetch_caches": "刷新预热",
"server_waf_policies": "WAF策略",
"server_ip_lists": "IP名单",
"server_access_log_policies": "日志策略",
"server_metrics": "统计指标",
"server_scripts": "脚本库",
"user_scripts": "用户脚本",
"server_global_settings": "通用设置",
"nodes": "边缘节点",
"node_clusters": "集群列表",
"node_logs": "节点日志",
"node_ip_list": "节点IP",
"node_regions": "区域设置",
"node_ssh_grants": "节点SSH",
"node_distributed_monitors": "区域监控",
"node_anti_ddos_products": "高防IP",
"dns": "域名解析",
"dns_clusters": "集群列表",
"dns_providers": "DNS服务商",
"dns_issues": "问题修复",
"ns": "智能DNS",
"ns_domains": "域名管理",
"ns_domain_groups": "域名分组",
"ns_domain_batch_operations": "批量操作",
"ns_clusters": "集群管理",
"ns_routes": "线路管理",
"ns_settings": "全局配置",
"ns_user_plans": "用户套餐",
"ns_plans": "套餐设置",
"ns_access_logs": "访问日志",
"ns_node_logs": "运行日志",
"ns_resolve_test": "解析测试",
"users": "平台用户",
"user_list": "用户列表",
"user_settings": "用户设置",
"finance": "财务管理",
"finance_bills": "费用账单",
"finance_accounts": "用户账户",
"finance_logs": "收支明细",
"finance_orders": "订单管理",
"finance_income": "统计报表",
"finance_fee": "计费设置",
"finance_packages": "流量包",
"plans": "套餐管理",
"plan_list": "套餐列表",
"plan_user_plans": "已购套餐",
"tickets": "工单系统",
"ticket_category": "分类",
"admins": "系统用户",
"admin_recipients": "通知媒介",
"logs": "日志审计",
"settings": "系统设置",
"setting_basic_settings": "基础设置",
"setting_advanced_settings": "高级设置",
"setting_authority": "商业版本"
}

View File

@@ -0,0 +1,3 @@
{
"log_update_profile": "修改个人资料"
}

View File

@@ -0,0 +1,3 @@
{
"log_update_security_settings": "修改管理界面安全设置"
}

View File

@@ -0,0 +1,4 @@
{
"log_update_server_http_settings": "修改管理界面的HTTP设置",
"log_update_server_https_settings": "修改管理界面的HTTPS设置"
}

View File

@@ -0,0 +1,20 @@
{
"tab_admin_server": "Web服务",
"tab_admin_ui": "管理界面设置",
"tab_user_ui": "用户界面设置",
"tab_admin_security_settings": "安全设置",
"tab_updates": "检查更新",
"tab_profile": "个人资料",
"tab_login": "登录设置",
"tab_database": "数据库",
"tab_api_nodes": "API节点",
"tab_user_nodes": "用户节点",
"tab_monitor_nodes": "监控节点",
"tab_ip_library": "IP库",
"tab_client_operation_systems": "操作系统库",
"tab_client_browsers": "浏览器库",
"tab_authority": "商业版认证",
"tab_access_log_databases": "日志数据库",
"tab_transfer": "迁移",
"tab_backup": "备份"
}

View File

@@ -0,0 +1,6 @@
{
"default_product_name": "GoEdge",
"default_system_name": "GoEdge管理员系统",
"log_update_ui_settings": "修改管理界面设置"
}

View File

@@ -0,0 +1,5 @@
{
"log_ignore_version": "忽略升级版本 %s",
"log_reset_ignore_version": "重置忽略升级版本",
"log_update_check_settings": "修改检查更新设置"
}

View File

@@ -0,0 +1,3 @@
{
"log_update_ui_settings": "修改用户界面设置"
}

View File

@@ -0,0 +1,5 @@
{
"log_create_api_node": "创建API节点 %d",
"log_update_api_node": "修改API节点 %d",
"log_delete_api_node": "删除API节点 %d"
}

View File

@@ -0,0 +1,4 @@
{
"log_update_client_browser": "修改浏览器信息 %d",
"log_create_browser": "创建浏览器信息 %s"
}

View File

@@ -0,0 +1,4 @@
{
"log_update_client_system": "修改操作系统信息 %d",
"log_create_system": "创建操作系统信息 %s"
}

View File

@@ -0,0 +1,6 @@
{
"log_update_clean_days": "修改数据库自动清理设置",
"log_delete_table": "删除数据表 %s",
"log_truncate_table": "清空数据表 %s 数据",
"log_update_api_node_database_config": "修改API节点数据库设置"
}

View File

@@ -0,0 +1,9 @@
{
"tab_nodes": "数据库节点",
"log_create_db_node": "创建数据库节点 %d",
"log_delete_db_node": "删除数据库节点 %d",
"log_update_db_node": "修改数据库节点 %d",
"log_delete_table": "删除数据库节点 %d 数据表 %s",
"log_truncate_table": "清空数据库节点 %d 数据表 %s 数据"
}

View File

@@ -0,0 +1,4 @@
{
"log_update_cluster_ddos_protection": "修改集群 %d 的DDOS防护设置",
"log_update_node_ddos_protection": "修改节点 %d 的DDOS防护设置"
}

View File

@@ -0,0 +1,10 @@
{
"log_update_cluster_dns": "修改集群 %d DNS设置",
"log_sync_domain": "同步DNS域名数据 %d",
"log_sync_cluster": "同步集群 %d 的DNS设置",
"log_create_domain": "添加管理域名到DNS服务商 %d",
"log_delete_domain": "从DNS服务商中删除域名 %d",
"log_recover_domain": "从DNS服务商中恢复域名 %d",
"log_update_domain": "修改DNS服务商域名 %d",
"log_update_node_dns": "修改节点 %d 的DNS设置"
}

View File

@@ -0,0 +1,5 @@
{
"log_create_dns_provider": "创建DNS服务商 %d",
"log_delete_dns_provider": "删除DNS服务商 %d",
"log_update_dns_provider": "修改DNS服务商 %d"
}

View File

@@ -0,0 +1,4 @@
{
"log_delete_dns_task": "删除DNS同步任务 %d",
"log_delete_all_dns_tasks": "删除所有DNS同步任务"
}

View File

@@ -0,0 +1,4 @@
{
"log_bill_generate_manually": "手动生成上个月 %s 账单",
"log_update_user_order_config": "修改订单设置"
}

Some files were not shown because too many files have changed in this diff Show More