diff --git a/internal/utils/numberutils/utils.go b/internal/utils/numberutils/utils.go index d2588969..9650ebfc 100644 --- a/internal/utils/numberutils/utils.go +++ b/internal/utils/numberutils/utils.go @@ -30,17 +30,17 @@ func FormatBytes(bytes int64) string { if bytes < Pow1024(1) { return FormatInt64(bytes) + "B" } else if bytes < Pow1024(2) { - return TrimZeroSuffix(fmt.Sprintf("%.2fKB", float64(bytes)/float64(Pow1024(1)))) + return TrimZeroSuffix(fmt.Sprintf("%.2fKiB", float64(bytes)/float64(Pow1024(1)))) } else if bytes < Pow1024(3) { - return TrimZeroSuffix(fmt.Sprintf("%.2fMB", float64(bytes)/float64(Pow1024(2)))) + return TrimZeroSuffix(fmt.Sprintf("%.2fMiB", float64(bytes)/float64(Pow1024(2)))) } else if bytes < Pow1024(4) { - return TrimZeroSuffix(fmt.Sprintf("%.2fGB", float64(bytes)/float64(Pow1024(3)))) + return TrimZeroSuffix(fmt.Sprintf("%.2fGiB", float64(bytes)/float64(Pow1024(3)))) } else if bytes < Pow1024(5) { - return TrimZeroSuffix(fmt.Sprintf("%.2fTB", float64(bytes)/float64(Pow1024(4)))) + return TrimZeroSuffix(fmt.Sprintf("%.2fTiB", float64(bytes)/float64(Pow1024(4)))) } else if bytes < Pow1024(6) { - return TrimZeroSuffix(fmt.Sprintf("%.2fPB", float64(bytes)/float64(Pow1024(5)))) + return TrimZeroSuffix(fmt.Sprintf("%.2fPiB", float64(bytes)/float64(Pow1024(5)))) } else { - return TrimZeroSuffix(fmt.Sprintf("%.2fEB", float64(bytes)/float64(Pow1024(6)))) + return TrimZeroSuffix(fmt.Sprintf("%.2fEiB", float64(bytes)/float64(Pow1024(6)))) } } diff --git a/web/public/js/components.js b/web/public/js/components.js index 60d94cc6..b1803129 100644 --- a/web/public/js/components.js +++ b/web/public/js/components.js @@ -1044,7 +1044,7 @@ Vue.component("traffic-map-box",{props:["v-stats","v-is-attack"],mounted:functio 按{{plan.bandwidthPrice.percentile}}th带宽计费
- {{range.minMB}} - {{range.maxMB}}MB{{range.totalPrice}}元{{range.pricePerMB}}元/MB + {{range.minMB}} - {{range.maxMB}}MiB{{range.totalPrice}}元{{range.pricePerMB}}元/MiB
@@ -1303,7 +1303,7 @@ Vue.component("traffic-map-box",{props:["v-stats","v-is-attack"],mounted:functio

按在计时时间段内(5分钟)最高带宽峰值计算,比如5分钟内最高的某个时间点带宽为100Mbps,那么就认为此时间段内的峰值带宽为100Mbps。修改此选项会同时影响到用量统计图表。

-

按在计时时间段内(5分钟)平均带宽计算,即此时间段内的总流量除以时间段的秒数,比如5分钟(300秒)内总流量600MB,那么带宽即为600MB * 8bit/300s = 16Mbps;通常平均带宽算法要比峰值带宽要少很多。修改此选项会同时影响到用量统计图表。

+

按在计时时间段内(5分钟)平均带宽计算,即此时间段内的总流量除以时间段的秒数,比如5分钟(300秒)内总流量600MiB,那么带宽即为600MiB * 8bit/300s = 16Mbps;通常平均带宽算法要比峰值带宽要少很多。修改此选项会同时影响到用量统计图表。

@@ -2114,7 +2114,7 @@ Vue.component("traffic-map-box",{props:["v-stats","v-is-attack"],mounted:functio -`}),Vue.component("http-firewall-config-box",{props:["v-firewall-config","v-is-location","v-is-group","v-firewall-policy"],data:function(){let e=this.vFirewallConfig;return null!=(e=null==e?{isPrior:!1,isOn:!1,firewallPolicyId:0,ignoreGlobalRules:!1,defaultCaptchaType:"none"}:e).defaultCaptchaType&&0!=e.defaultCaptchaType.length||(e.defaultCaptchaType="none"),{firewall:e,moreOptionsVisible:!1,execGlobalRules:!e.ignoreGlobalRules,captchaTypes:window.WAF_CAPTCHA_TYPES}},watch:{execGlobalRules:function(e){this.firewall.ignoreGlobalRules=!e}},methods:{changeOptionsVisible:function(e){this.moreOptionsVisible=e}},template:`
+
`}),Vue.component("http-firewall-config-box",{props:["v-firewall-config","v-is-location","v-is-group","v-firewall-policy"],data:function(){let e=this.vFirewallConfig;null!=(e=null==e?{isPrior:!1,isOn:!1,firewallPolicyId:0,ignoreGlobalRules:!1,defaultCaptchaType:"none"}:e).defaultCaptchaType&&0!=e.defaultCaptchaType.length||(e.defaultCaptchaType="none");var t=window.WAF_CAPTCHA_TYPES.$copy();let i=!1;return(i=null!=this.vFirewallPolicy&&null!=this.vFirewallPolicy.captchaAction&&null!=this.vFirewallPolicy.captchaAction.geeTestConfig?this.vFirewallPolicy.captchaAction.geeTestConfig.isOn:i)||"geetest"!=e.defaultCaptchaType||(e.defaultCaptchaType="none"),{firewall:e,moreOptionsVisible:!1,execGlobalRules:!e.ignoreGlobalRules,captchaTypes:t,geeTestIsOn:i}},watch:{execGlobalRules:function(e){this.firewall.ignoreGlobalRules=!e}},methods:{changeOptionsVisible:function(e){this.moreOptionsVisible=e}},template:`
@@ -2147,7 +2147,7 @@ Vue.component("traffic-map-box",{props:["v-stats","v-is-attack"],mounted:functio @@ -4347,7 +4421,7 @@ example2.com {{cert.name}} / {{cert.dnsNames}} / 有效至{{formatTime(cert.timeEndAt)}}   -`}),Vue.component("http-firewall-captcha-options-viewer",{props:["v-captcha-options"],mounted:function(){this.updateSummary()},data:function(){let e=this.vCaptchaOptions;return{options:e=null==e?{life:0,maxFails:0,failBlockTimeout:0,failBlockScopeAll:!1,uiIsOn:!1,uiTitle:"",uiPrompt:"",uiButtonTitle:"",uiShowRequestId:!1,uiCss:"",uiFooter:"",uiBody:"",cookieId:"",lang:""}:e,summary:"",captchaTypes:window.WAF_CAPTCHA_TYPES}},methods:{updateSummary:function(){let e=[],i=(0{{summary}} +`}),Vue.component("http-firewall-captcha-options-viewer",{props:["v-captcha-options"],mounted:function(){this.updateSummary()},data:function(){let e=this.vCaptchaOptions;return{options:e=null==e?{life:0,maxFails:0,failBlockTimeout:0,failBlockScopeAll:!1,uiIsOn:!1,uiTitle:"",uiPrompt:"",uiButtonTitle:"",uiShowRequestId:!1,uiCss:"",uiFooter:"",uiBody:"",cookieId:"",lang:""}:e,summary:"",captchaTypes:window.WAF_CAPTCHA_TYPES}},methods:{updateSummary:function(){let e=[],i=(0{{summary}} `}),Vue.component("reverse-proxy-box",{props:["v-reverse-proxy-ref","v-reverse-proxy-config","v-is-location","v-is-group","v-family"],data:function(){let e=this.vReverseProxyRef,t=(null==e&&(e={isPrior:!1,isOn:!1,reverseProxyId:0}),this.vReverseProxyConfig),i=(null==(t=null==t?{requestPath:"",stripPrefix:"",requestURI:"",requestHost:"",requestHostType:0,requestHostExcludingPort:!1,addHeaders:[],connTimeout:{count:0,unit:"second"},readTimeout:{count:0,unit:"second"},idleTimeout:{count:0,unit:"second"},maxConns:0,maxIdleConns:0,followRedirects:!1,retry50X:!1,retry40X:!1}:t).addHeaders&&(t.addHeaders=[]),null==t.connTimeout&&(t.connTimeout={count:0,unit:"second"}),null==t.readTimeout&&(t.readTimeout={count:0,unit:"second"}),null==t.idleTimeout&&(t.idleTimeout={count:0,unit:"second"}),null==t.proxyProtocol&&Vue.set(t,"proxyProtocol",{isOn:!1,version:1}),[{name:"X-Real-IP",isChecked:!1},{name:"X-Forwarded-For",isChecked:!1},{name:"X-Forwarded-By",isChecked:!1},{name:"X-Forwarded-Host",isChecked:!1},{name:"X-Forwarded-Proto",isChecked:!1}]);return i.forEach(function(e){e.isChecked=t.addHeaders.$contains(e.name)}),{reverseProxyRef:e,reverseProxyConfig:t,advancedVisible:!1,family:this.vFamily,forwardHeaders:i}},watch:{"reverseProxyConfig.requestHostType":function(e){let t=parseInt(e);isNaN(t)&&(t=0),this.reverseProxyConfig.requestHostType=t},"reverseProxyConfig.connTimeout.count":function(e){let t=parseInt(e);(isNaN(t)||t<0)&&(t=0),this.reverseProxyConfig.connTimeout.count=t},"reverseProxyConfig.readTimeout.count":function(e){let t=parseInt(e);(isNaN(t)||t<0)&&(t=0),this.reverseProxyConfig.readTimeout.count=t},"reverseProxyConfig.idleTimeout.count":function(e){let t=parseInt(e);(isNaN(t)||t<0)&&(t=0),this.reverseProxyConfig.idleTimeout.count=t},"reverseProxyConfig.maxConns":function(e){let t=parseInt(e);(isNaN(t)||t<0)&&(t=0),this.reverseProxyConfig.maxConns=t},"reverseProxyConfig.maxIdleConns":function(e){let t=parseInt(e);(isNaN(t)||t<0)&&(t=0),this.reverseProxyConfig.maxIdleConns=t},"reverseProxyConfig.proxyProtocol.version":function(e){let t=parseInt(e);isNaN(t)&&(t=1),this.reverseProxyConfig.proxyProtocol.version=t}},methods:{isOn:function(){return(!this.vIsLocation&&!this.vIsGroup||this.reverseProxyRef.isPrior)&&this.reverseProxyRef.isOn},changeAdvancedVisible:function(e){this.advancedVisible=e},changeAddHeader:function(){this.reverseProxyConfig.addHeaders=this.forwardHeaders.filter(function(e){return e.isChecked}).map(function(e){return e.name})}},template:`
@@ -5354,7 +5428,7 @@ example2.com

使用系统默认的设置。

{{captchaType.description}}

@@ -2546,43 +2546,117 @@ Vue.component("traffic-map-box",{props:["v-stats","v-is-attack"],mounted:functio -`}),Vue.component("http-optimization-config-box",{props:["v-optimization-config","v-is-location","v-is-group"],data:function(){return{config:this.vOptimizationConfig,moreOptionsVisible:!1}},methods:{isOn:function(){return(!this.vIsLocation&&!this.vIsGroup||this.config.isPrior)&&this.config.isOn}},template:`
+
`}),Vue.component("http-optimization-config-box",{props:["v-optimization-config","v-is-location","v-is-group"],data:function(){return{config:this.vOptimizationConfig,htmlMoreOptions:!1,javascriptMoreOptions:!1,cssMoreOptions:!1}},methods:{isOn:function(){return(!this.vIsLocation&&!this.vIsGroup||this.config.isPrior)&&this.config.isOn}},template:`
- - - - - - - - - - - - - - - - +
HTML优化 -
- - -
-

可以自动优化HTML中包含的空白、注释、空标签等。只有文件可以缓存时才会被优化。

-
Javascript优化 -
- - -
-

可以自动缩短Javascript中变量、函数名称等。只有文件可以缓存时才会被优化。

-
CSS优化 -
- - -
-

可以自动去除CSS中包含的空白。只有文件可以缓存时才会被优化。

-
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + +
HTML优化 +
+ + +
+

可以自动优化HTML中包含的空白、注释、空标签等。只有文件可以缓存时才会被优化。

+
HTML例外URL + +

如果填写了例外URL,表示这些URL跳过CC防护不做处理。

+
HTML限制URL + +

如果填写了限制URL,表示只对这些URL进行CC防护处理;如果不填则表示支持所有的URL。

+
+ + + + + + + + + + + + + + + + + + + + + +
Javascript优化 +
+ + +
+

可以自动缩短Javascript中变量、函数名称等。只有文件可以缓存时才会被优化。

+
Javascript例外URL + +

如果填写了例外URL,表示这些URL跳过CC防护不做处理。

+
Javascript限制URL + +

如果填写了限制URL,表示只对这些URL进行CC防护处理;如果不填则表示支持所有的URL。

+
+ + + + + + + + + + + + + + + + + + + + + +
CSS优化 +
+ + +
+

可以自动去除CSS中包含的空白。只有文件可以缓存时才会被优化。

+
CSS例外URL + +

如果填写了例外URL,表示这些URL跳过CC防护不做处理。

+
CSS限制URL + +

如果填写了限制URL,表示只对这些URL进行CC防护处理;如果不填则表示支持所有的URL。

+
+
+
`}),Vue.component("http-websocket-box",{props:["v-websocket-ref","v-websocket-config","v-is-location","v-is-group"],data:function(){let e=this.vWebsocketRef,t=(null==e&&(e={isPrior:!1,isOn:!1,websocketId:0}),this.vWebsocketConfig);return null==t?t={id:0,isOn:!1,handshakeTimeout:{count:30,unit:"second"},allowAllOrigins:!0,allowedOrigins:[],requestSameOrigin:!0,requestOrigin:""}:(null==t.handshakeTimeout&&(t.handshakeTimeout={count:30,unit:"second"}),null==t.allowedOrigins&&(t.allowedOrigins=[])),{websocketRef:e,websocketConfig:t,handshakeTimeoutCountString:t.handshakeTimeout.count.toString(),advancedVisible:!1}},watch:{handshakeTimeoutCountString:function(e){e=parseInt(e);!isNaN(e)&&0<=e?this.websocketConfig.handshakeTimeout.count=e:this.websocketConfig.handshakeTimeout.count=0}},methods:{isOn:function(){return(!this.vIsLocation&&!this.vIsGroup||this.websocketRef.isPrior)&&this.websocketRef.isOn},changeAdvancedVisible:function(e){this.advancedVisible=e},createOrigin:function(){let t=this;teaweb.popup("/servers/server/settings/websocket/createOrigin",{height:"12.5em",callback:function(e){t.websocketConfig.allowedOrigins.push(e.data.origin)}})},removeOrigin:function(e){this.websocketConfig.allowedOrigins.$remove(e)}},template:`
@@ -2819,7 +2893,7 @@ Vue.component("traffic-map-box",{props:["v-stats","v-is-attack"],mounted:functio 已启用 / 空连接次数:{{config.minAttempts}}次/分钟 / 封禁时长:{{config.timeoutSeconds}}秒 / 忽略局域网访问 未启用 -
`}),Vue.component("domains-box",{props:["v-domains","name","v-support-wildcard"],data:function(){let e=this.vDomains,t=(null==e&&(e=[]),"domainsJSON"),i=(null!=this.name&&"string"==typeof this.name&&(t=this.name),!0);return"boolean"==typeof this.vSupportWildcard&&(i=this.vSupportWildcard),{domains:e,mode:"single",batchDomains:"",isAdding:!1,addingDomain:"",isEditing:!1,editingIndex:-1,realName:t,supportWildcard:i}},watch:{vSupportWildcard:function(e){"boolean"==typeof e&&(this.supportWildcard=e)},mode:function(e){let t=this;setTimeout(function(){"single"==e?null!=t.$refs.addingDomain&&t.$refs.addingDomain.focus():"batch"==e&&null!=t.$refs.batchDomains&&t.$refs.batchDomains.focus()},100)}},methods:{add:function(){this.isAdding=!0;let e=this;setTimeout(function(){e.$refs.addingDomain.focus()},100)},confirm:function(){if("batch"==this.mode)this.confirmBatch();else{let t=this;if(this.addingDomain=this.addingDomain.replace(/\s/g,""),0==this.addingDomain.length)teaweb.warn("请输入要添加的域名",function(){t.$refs.addingDomain.focus()});else{if(this.supportWildcard){if("~"==this.addingDomain[0]){var e=this.addingDomain.substring(1);try{new RegExp(e)}catch(e){return void teaweb.warn("正则表达式错误:"+e.message,function(){t.$refs.addingDomain.focus()})}}}else if(/[*~^]/.test(this.addingDomain))return void teaweb.warn("当前只支持添加普通域名,域名中不能含有特殊符号",function(){t.$refs.addingDomain.focus()});this.isEditing&&0<=this.editingIndex?this.domains[this.editingIndex]=this.addingDomain:this.domains.push(this.addingDomain),this.cancel(),this.change()}}},confirmBatch:function(){let e=this.batchDomains.split("\n"),i=[],n=this,s=!1;e.forEach(function(e){if(!s&&0!=e.length){if(n.supportWildcard){if("~"==e){var t=e.substring(1);try{new RegExp(t)}catch(e){return s=!0,void teaweb.warn("正则表达式错误:"+e.message,function(){n.$refs.batchDomains.focus()})}}}else if(/[*~^]/.test(e))return s=!0,void teaweb.warn("当前只支持添加普通域名,域名中不能含有特殊符号",function(){n.$refs.batchDomains.focus()});i.push(e)}}),s||(0==i.length?teaweb.warn("请输入要添加的域名",function(){n.$refs.batchDomains.focus()}):(i.forEach(function(e){n.domains.push(e)}),this.cancel(),this.change()))},edit:function(e){this.addingDomain=this.domains[e],this.isEditing=!0,this.editingIndex=e;let t=this;setTimeout(function(){t.$refs.addingDomain.focus()},50)},remove:function(e){this.domains.$remove(e),this.change()},cancel:function(){this.isAdding=!1,this.mode="single",this.batchDomains="",this.isEditing=!1,this.editingIndex=-1,this.addingDomain=""},change:function(){this.$emit("change",this.domains)}},template:`
+
`}),Vue.component("domains-box",{props:["v-domains","name","v-support-wildcard"],data:function(){let e=this.vDomains,t=(null==e&&(e=[]),"domainsJSON"),i=(null!=this.name&&"string"==typeof this.name&&(t=this.name),!0);return"boolean"==typeof this.vSupportWildcard&&(i=this.vSupportWildcard),{domains:e,mode:"single",batchDomains:"",isAdding:!1,addingDomain:"",isEditing:!1,editingIndex:-1,realName:t,supportWildcard:i}},watch:{vSupportWildcard:function(e){"boolean"==typeof e&&(this.supportWildcard=e)},mode:function(e){let t=this;setTimeout(function(){"single"==e?null!=t.$refs.addingDomain&&t.$refs.addingDomain.focus():"batch"==e&&null!=t.$refs.batchDomains&&t.$refs.batchDomains.focus()},100)}},methods:{add:function(){this.isAdding=!0;let e=this;setTimeout(function(){e.$refs.addingDomain.focus()},100)},confirm:function(){if("batch"==this.mode)this.confirmBatch();else{let t=this;if(this.addingDomain=this.addingDomain.replace(/\s/g,""),0==this.addingDomain.length)teaweb.warn("请输入要添加的域名",function(){t.$refs.addingDomain.focus()});else{if(this.supportWildcard){if("~"==this.addingDomain[0]){var e=this.addingDomain.substring(1);try{new RegExp(e)}catch(e){return void teaweb.warn("正则表达式错误:"+e.message,function(){t.$refs.addingDomain.focus()})}}}else if(/[*~^]/.test(this.addingDomain))return void teaweb.warn("当前只支持添加普通域名,域名中不能含有特殊符号",function(){t.$refs.addingDomain.focus()});if(this.isEditing&&0<=this.editingIndex)this.domains[this.editingIndex]=this.addingDomain;else if(this.addingDomain.match("[,、,;]")){let e=this.addingDomain.split(new RegExp("[,、,;]"));e.forEach(function(e){0
@@ -4117,7 +4191,7 @@ example2.com

在基础信息之外要存储的信息。 - 记录"请求Body"将会显著消耗更多的系统资源,建议仅在调试时启用,最大记录尺寸为2MB。 + 记录"请求Body"将会显著消耗更多的系统资源,建议仅在调试时启用,最大记录尺寸为2MiB。

-
`}),Vue.component("http-firewall-captcha-options",{props:["v-captcha-options"],mounted:function(){this.updateSummary()},data:function(){let e=this.vCaptchaOptions;return(e=null==e?{captchaType:"default",countLetters:0,life:0,maxFails:0,failBlockTimeout:0,failBlockScopeAll:!1,uiIsOn:!1,uiTitle:"",uiPrompt:"",uiButtonTitle:"",uiShowRequestId:!0,uiCss:"",uiFooter:"",uiBody:"",cookieId:"",lang:""}:e).countLetters<=0&&(e.countLetters=6),null!=e.captchaType&&0!=e.captchaType.length||(e.captchaType="default"),{options:e,isEditing:!1,summary:"",uiBodyWarning:"",captchaTypes:window.WAF_CAPTCHA_TYPES}},watch:{"options.countLetters":function(e){let t=parseInt(e,10);isNaN(t)||t<0?t=0:10|\s).+\$\{body}.*<\/form>/s.test(e)?this.uiBodyWarning="页面模板中不能使用
标签包裹${body}变量,否则将导致验证码表单无法提交。":this.uiBodyWarning=""}},methods:{edit:function(){this.isEditing=!this.isEditing},updateSummary:function(){let e=[],i=(0 +`}),Vue.component("http-firewall-captcha-options",{props:["v-captcha-options"],mounted:function(){this.updateSummary()},data:function(){let e=this.vCaptchaOptions;return(e=null==e?{captchaType:"default",countLetters:0,life:0,maxFails:0,failBlockTimeout:0,failBlockScopeAll:!1,uiIsOn:!1,uiTitle:"",uiPrompt:"",uiButtonTitle:"",uiShowRequestId:!0,uiCss:"",uiFooter:"",uiBody:"",cookieId:"",lang:"",geeTestConfig:{isOn:!1,captchaId:"",captchaKey:""}}:e).countLetters<=0&&(e.countLetters=6),null!=e.captchaType&&0!=e.captchaType.length||(e.captchaType="default"),{options:e,isEditing:!1,summary:"",uiBodyWarning:"",captchaTypes:window.WAF_CAPTCHA_TYPES}},watch:{"options.countLetters":function(e){let t=parseInt(e,10);isNaN(t)||t<0?t=0:10|\s).+\$\{body}.*<\/form>/s.test(e)?this.uiBodyWarning="页面模板中不能使用
标签包裹${body}变量,否则将导致验证码表单无法提交。":this.uiBodyWarning=""},"options.geeTestConfig.isOn":function(e){this.updateSummary()}},methods:{edit:function(){this.isEditing=!this.isEditing},updateSummary:function(){let e=[],i=(0 {{summary}}
@@ -5419,7 +5493,6 @@ example2.com 定制UI - @@ -5471,6 +5544,31 @@ example2.com + + + + + + + + + + + + + + + + +
允许用户使用极验 +

选中后,表示允许用户在WAF设置中选择极验。

+
极验-验证ID * + +

在极验控制台--业务管理中获取。

+
极验-验证Key * + +

在极验控制台--业务管理中获取。

+
`}),Vue.component("user-agent-config-box",{props:["v-is-location","v-is-group","value"],data:function(){let e=this.value;return null==(e=null==e?{isPrior:!1,isOn:!1,filters:[]}:e).filters&&(e.filters=[]),{config:e,isAdding:!1,addingFilter:{keywords:[],action:"deny"}}},methods:{isOn:function(){return(!this.vIsLocation&&!this.vIsGroup||this.config.isPrior)&&this.config.isOn},remove:function(e){let t=this;teaweb.confirm("确定要删除此名单吗?",function(){t.config.filters.$remove(e)})},add:function(){this.isAdding=!0},confirm:function(){if("deny"==this.addingFilter.action)this.config.filters.push(this.addingFilter);else{let i=-1;this.config.filters.forEach(function(e,t){"allow"==e.action&&(i=t)}),i<0?this.config.filters.unshift(this.addingFilter):this.config.filters.$insert(i+1,this.addingFilter)}this.cancel()},cancel:function(){this.isAdding=!1,this.addingFilter={keywords:[],action:"deny"}},changeKeywords:function(e){this.addingFilter.keywords=e}},template:`
@@ -6285,12 +6383,12 @@ example2.com
`}),Vue.component("inner-menu",{template:` @@ -6470,11 +6568,11 @@ example2.com
@@ -6947,4 +7045,4 @@ example2.com
[选择已有认证]     [添加新认证]
-`}),window.REQUEST_COND_COMPONENTS=[{type:"url-extension",name:"文件扩展名",description:"根据URL中的文件路径扩展名进行过滤",component:"http-cond-url-extension",paramsTitle:"扩展名列表",isRequest:!0,caseInsensitive:!1},{type:"url-eq-index",name:"首页",description:'检查URL路径是为"/"',component:"http-cond-url-eq-index",paramsTitle:"URL完整路径",isRequest:!0,caseInsensitive:!1},{type:"url-all",name:"全站",description:"全站所有URL",component:"http-cond-url-all",paramsTitle:"URL完整路径",isRequest:!0,caseInsensitive:!1},{type:"url-prefix",name:"URL目录前缀",description:"根据URL中的文件路径前缀进行过滤",component:"http-cond-url-prefix",paramsTitle:"URL目录前缀",isRequest:!0,caseInsensitive:!0},{type:"url-eq",name:"URL完整路径",description:"检查URL中的文件路径是否一致",component:"http-cond-url-eq",paramsTitle:"URL完整路径",isRequest:!0,caseInsensitive:!0},{type:"url-regexp",name:"URL正则匹配",description:"使用正则表达式检查URL中的文件路径是否一致",component:"http-cond-url-regexp",paramsTitle:"正则表达式",isRequest:!0,caseInsensitive:!0},{type:"url-wildcard-match",name:"URL通配符",description:"使用通配符检查URL中的文件路径是否一致",component:"http-cond-url-wildcard-match",paramsTitle:"通配符",isRequest:!0,caseInsensitive:!0},{type:"user-agent-regexp",name:"User-Agent正则匹配",description:"使用正则表达式检查User-Agent中是否含有某些浏览器和系统标识",component:"http-cond-user-agent-regexp",paramsTitle:"正则表达式",isRequest:!0,caseInsensitive:!0},{type:"params",name:"参数匹配",description:"根据参数值进行匹配",component:"http-cond-params",paramsTitle:"参数配置",isRequest:!0,caseInsensitive:!1},{type:"url-not-extension",name:"排除:URL扩展名",description:"根据URL中的文件路径扩展名进行过滤",component:"http-cond-url-not-extension",paramsTitle:"扩展名列表",isRequest:!0,caseInsensitive:!1},{type:"url-not-prefix",name:"排除:URL前缀",description:"根据URL中的文件路径前缀进行过滤",component:"http-cond-url-not-prefix",paramsTitle:"URL前缀",isRequest:!0,caseInsensitive:!0},{type:"url-not-eq",name:"排除:URL完整路径",description:"检查URL中的文件路径是否一致",component:"http-cond-url-not-eq",paramsTitle:"URL完整路径",isRequest:!0,caseInsensitive:!0},{type:"url-not-regexp",name:"排除:URL正则匹配",description:"使用正则表达式检查URL中的文件路径是否一致,如果一致,则不匹配",component:"http-cond-url-not-regexp",paramsTitle:"正则表达式",isRequest:!0,caseInsensitive:!0},{type:"user-agent-not-regexp",name:"排除:User-Agent正则匹配",description:"使用正则表达式检查User-Agent中是否含有某些浏览器和系统标识,如果含有,则不匹配",component:"http-cond-user-agent-not-regexp",paramsTitle:"正则表达式",isRequest:!0,caseInsensitive:!0},{type:"mime-type",name:"内容MimeType",description:"根据服务器返回的内容的MimeType进行过滤。注意:当用于缓存条件时,此条件需要结合别的请求条件使用。",component:"http-cond-mime-type",paramsTitle:"MimeType列表",isRequest:!1,caseInsensitive:!1}],window.REQUEST_COND_OPERATORS=[{description:"判断是否正则表达式匹配",name:"正则表达式匹配",op:"regexp"},{description:"判断是否正则表达式不匹配",name:"正则表达式不匹配",op:"not regexp"},{description:"判断是否和指定的通配符匹配",name:"通配符匹配",op:"wildcard match"},{description:"判断是否和指定的通配符不匹配",name:"通配符不匹配",op:"wildcard not match"},{description:"使用字符串对比参数值是否相等于某个值",name:"字符串等于",op:"eq"},{description:"参数值包含某个前缀",name:"字符串前缀",op:"prefix"},{description:"参数值包含某个后缀",name:"字符串后缀",op:"suffix"},{description:"参数值包含另外一个字符串",name:"字符串包含",op:"contains"},{description:"参数值不包含另外一个字符串",name:"字符串不包含",op:"not contains"},{description:"使用字符串对比参数值是否不相等于某个值",name:"字符串不等于",op:"not"},{description:"判断参数值在某个列表中",name:"在列表中",op:"in"},{description:"判断参数值不在某个列表中",name:"不在列表中",op:"not in"},{description:"判断小写的扩展名(不带点)在某个列表中",name:"扩展名",op:"file ext"},{description:"判断MimeType在某个列表中,支持类似于image/*的语法",name:"MimeType",op:"mime type"},{description:"判断版本号在某个范围内,格式为version1,version2",name:"版本号范围",op:"version range"},{description:"将参数转换为整数数字后进行对比",name:"整数等于",op:"eq int"},{description:"将参数转换为可以有小数的浮点数字进行对比",name:"浮点数等于",op:"eq float"},{description:"将参数转换为数字进行对比",name:"数字大于",op:"gt"},{description:"将参数转换为数字进行对比",name:"数字大于等于",op:"gte"},{description:"将参数转换为数字进行对比",name:"数字小于",op:"lt"},{description:"将参数转换为数字进行对比",name:"数字小于等于",op:"lte"},{description:"对整数参数值取模,除数为10,对比值为余数",name:"整数取模10",op:"mod 10"},{description:"对整数参数值取模,除数为100,对比值为余数",name:"整数取模100",op:"mod 100"},{description:"对整数参数值取模,对比值格式为:除数,余数,比如10,1",name:"整数取模",op:"mod"},{description:"将参数转换为IP进行对比",name:"IP等于",op:"eq ip"},{description:"将参数转换为IP进行对比",name:"IP大于",op:"gt ip"},{description:"将参数转换为IP进行对比",name:"IP大于等于",op:"gte ip"},{description:"将参数转换为IP进行对比",name:"IP小于",op:"lt ip"},{description:"将参数转换为IP进行对比",name:"IP小于等于",op:"lte ip"},{description:"IP在某个范围之内,范围格式可以是英文逗号分隔的开始IP,结束IP,比如192.168.1.100,192.168.2.200,或者CIDR格式的ip/bits,比如192.168.2.1/24",name:"IP范围",op:"ip range"},{description:"对IP参数值取模,除数为10,对比值为余数",name:"IP取模10",op:"ip mod 10"},{description:"对IP参数值取模,除数为100,对比值为余数",name:"IP取模100",op:"ip mod 100"},{description:"对IP参数值取模,对比值格式为:除数,余数,比如10,1",name:"IP取模",op:"ip mod"}],window.REQUEST_VARIABLES=[{code:"${edgeVersion}",description:"",name:"边缘节点版本"},{code:"${remoteAddr}",description:"会依次根据X-Forwarded-For、X-Real-IP、RemoteAddr获取,适合前端有别的反向代理服务时使用,存在伪造的风险",name:"客户端地址(IP)"},{code:"${rawRemoteAddr}",description:"返回直接连接服务的客户端原始IP地址",name:"客户端地址(IP)"},{code:"${remotePort}",description:"",name:"客户端端口"},{code:"${remoteUser}",description:"",name:"客户端用户名"},{code:"${requestURI}",description:"比如/hello?name=lily",name:"请求URI"},{code:"${requestPath}",description:"比如/hello",name:"请求路径(不包括参数)"},{code:"${requestURL}",description:"比如https://example.com/hello?name=lily",name:"完整的请求URL"},{code:"${requestLength}",description:"",name:"请求内容长度"},{code:"${requestMethod}",description:"比如GET、POST",name:"请求方法"},{code:"${requestFilename}",description:"",name:"请求文件路径"},{code:"${requestPathExtension}",description:"请求路径中的文件扩展名,包括点符号,比如.html、.png",name:"请求文件扩展名"},{code:"${requestPathLowerExtension}",description:"请求路径中的文件扩展名,其中大写字母会被自动转换为小写,包括点符号,比如.html、.png",name:"请求文件小写扩展名"},{code:"${scheme}",description:"",name:"请求协议,http或https"},{code:"${proto}","description:":"类似于HTTP/1.0",name:"包含版本的HTTP请求协议"},{code:"${timeISO8601}",description:"比如2018-07-16T23:52:24.839+08:00",name:"ISO 8601格式的时间"},{code:"${timeLocal}",description:"比如17/Jul/2018:09:52:24 +0800",name:"本地时间"},{code:"${msec}",description:"比如1531756823.054",name:"带有毫秒的时间"},{code:"${timestamp}",description:"",name:"unix时间戳,单位为秒"},{code:"${host}",description:"",name:"主机名"},{code:"${cname}",description:"比如38b48e4f.goedge.cn",name:"当前网站的CNAME"},{code:"${serverName}",description:"",name:"接收请求的服务器名"},{code:"${serverPort}",description:"",name:"接收请求的服务器端口"},{code:"${referer}",description:"",name:"请求来源URL"},{code:"${referer.host}",description:"",name:"请求来源URL域名"},{code:"${userAgent}",description:"",name:"客户端信息"},{code:"${contentType}",description:"",name:"请求头部的Content-Type"},{code:"${cookies}",description:"",name:"所有cookie组合字符串"},{code:"${cookie.NAME}",description:"",name:"单个cookie值"},{code:"${isArgs}",description:"如果URL有参数,则值为`?`;否则,则值为空",name:"问号(?)标记"},{code:"${args}",description:"",name:"所有参数组合字符串"},{code:"${arg.NAME}",description:"",name:"单个参数值"},{code:"${headers}",description:"",name:"所有Header信息组合字符串"},{code:"${header.NAME}",description:"",name:"单个Header值"},{code:"${geo.country.name}",description:"",name:"国家/地区名称"},{code:"${geo.country.id}",description:"",name:"国家/地区ID"},{code:"${geo.province.name}",description:"目前只包含中国省份",name:"省份名称"},{code:"${geo.province.id}",description:"目前只包含中国省份",name:"省份ID"},{code:"${geo.city.name}",description:"目前只包含中国城市",name:"城市名称"},{code:"${geo.city.id}",description:"目前只包含中国城市",name:"城市名称"},{code:"${isp.name}",description:"",name:"ISP服务商名称"},{code:"${isp.id}",description:"",name:"ISP服务商ID"},{code:"${browser.os.name}",description:"客户端所在操作系统名称",name:"操作系统名称"},{code:"${browser.os.version}",description:"客户端所在操作系统版本",name:"操作系统版本"},{code:"${browser.name}",description:"客户端浏览器名称",name:"浏览器名称"},{code:"${browser.version}",description:"客户端浏览器版本",name:"浏览器版本"},{code:"${browser.isMobile}",description:"如果客户端是手机,则值为1,否则为0",name:"手机标识"}],window.METRIC_HTTP_KEYS=[{name:"客户端地址(IP)",code:"${remoteAddr}",description:"会依次根据X-Forwarded-For、X-Real-IP、RemoteAddr获取,适用于前端可能有别的反向代理的情形,存在被伪造的可能",icon:""},{name:"直接客户端地址(IP)",code:"${rawRemoteAddr}",description:"返回直接连接服务的客户端原始IP地址",icon:""},{name:"客户端用户名",code:"${remoteUser}",description:"通过基本认证填入的用户名",icon:""},{name:"请求URI",code:"${requestURI}",description:"包含参数,比如/hello?name=lily",icon:""},{name:"请求路径",code:"${requestPath}",description:"不包含参数,比如/hello",icon:""},{name:"完整URL",code:"${requestURL}",description:"比如https://example.com/hello?name=lily",icon:""},{name:"请求方法",code:"${requestMethod}",description:"比如GET、POST等",icon:""},{name:"请求协议Scheme",code:"${scheme}",description:"http或https",icon:""},{name:"文件扩展名",code:"${requestPathExtension}",description:"请求路径中的文件扩展名,包括点符号,比如.html、.png",icon:""},{name:"小写文件扩展名",code:"${requestPathLowerExtension}",description:"请求路径中的文件扩展名小写形式,包括点符号,比如.html、.png",icon:""},{name:"主机名",code:"${host}",description:"通常是请求的域名",icon:""},{name:"HTTP协议",code:"${proto}",description:"包含版本的HTTP请求协议,类似于HTTP/1.0",icon:""},{name:"URL参数值",code:"${arg.NAME}",description:"单个URL参数值",icon:""},{name:"请求来源URL",code:"${referer}",description:"请求来源Referer URL",icon:""},{name:"请求来源URL域名",code:"${referer.host}",description:"请求来源Referer URL域名",icon:""},{name:"Header值",code:"${header.NAME}",description:"单个Header值,比如${header.User-Agent}",icon:""},{name:"Cookie值",code:"${cookie.NAME}",description:"单个cookie值,比如${cookie.sid}",icon:""},{name:"状态码",code:"${status}",description:"",icon:""},{name:"响应的Content-Type值",code:"${response.contentType}",description:"",icon:""}],window.IP_ADDR_THRESHOLD_ITEMS=[{code:"nodeAvgRequests",description:"当前节点在单位时间内接收到的平均请求数。",name:"节点平均请求数",unit:"个"},{code:"nodeAvgTrafficOut",description:"当前节点在单位时间内发送的下行流量。",name:"节点平均下行流量",unit:"M"},{code:"nodeAvgTrafficIn",description:"当前节点在单位时间内接收的上行流量。",name:"节点平均上行流量",unit:"M"},{code:"nodeHealthCheck",description:"当前节点健康检查结果。",name:"节点健康检查结果",unit:""},{code:"connectivity",description:"通过区域监控得到的当前IP地址的连通性数值,取值在0和100之间。",name:"IP连通性",unit:"%"},{code:"groupAvgRequests",description:"当前节点所在分组在单位时间内接收到的平均请求数。",name:"分组平均请求数",unit:"个"},{code:"groupAvgTrafficOut",description:"当前节点所在分组在单位时间内发送的下行流量。",name:"分组平均下行流量",unit:"M"},{code:"groupAvgTrafficIn",description:"当前节点所在分组在单位时间内接收的上行流量。",name:"分组平均上行流量",unit:"M"},{code:"clusterAvgRequests",description:"当前节点所在集群在单位时间内接收到的平均请求数。",name:"集群平均请求数",unit:"个"},{code:"clusterAvgTrafficOut",description:"当前节点所在集群在单位时间内发送的下行流量。",name:"集群平均下行流量",unit:"M"},{code:"clusterAvgTrafficIn",description:"当前节点所在集群在单位时间内接收的上行流量。",name:"集群平均上行流量",unit:"M"}],window.IP_ADDR_THRESHOLD_ACTIONS=[{code:"up",description:"上线当前IP。",name:"上线"},{code:"down",description:"下线当前IP。",name:"下线"},{code:"notify",description:"发送已达到阈值通知。",name:"通知"},{code:"switch",description:"在DNS中记录中将IP切换到指定的备用IP。",name:"切换"},{code:"webHook",description:"调用外部的WebHook。",name:"WebHook"}],window.WAF_RULE_OPERATORS=[{name:"正则匹配",code:"match",description:'使用正则表达式匹配,在头部使用(?i)表示不区分大小写,正则表达式语法 »。',caseInsensitive:"yes",dataType:"regexp"},{name:"正则不匹配",code:"not match",description:'使用正则表达式不匹配,在头部使用(?i)表示不区分大小写,正则表达式语法 »。',caseInsensitive:"yes",dataType:"regexp"},{name:"通配符匹配",code:"wildcard match",description:"判断是否和指定的通配符匹配,可以在对比值中使用星号通配符(*)表示任意字符。",caseInsensitive:"yes",dataType:"wildcard"},{name:"通配符不匹配",code:"wildcard not match",description:"判断是否和指定的通配符不匹配,可以在对比值中使用星号通配符(*)表示任意字符。",caseInsensitive:"yes",dataType:"wildcard"},{name:"字符串等于",code:"eq string",description:"使用字符串对比等于。",caseInsensitive:"no",dataType:"string"},{name:"字符串不等于",code:"neq string",description:"使用字符串对比不等于。",caseInsensitive:"no",dataType:"string"},{name:"包含字符串",code:"contains",description:"包含某个字符串,比如Hello World包含了World。",caseInsensitive:"no",dataType:"string"},{name:"不包含字符串",code:"not contains",description:"不包含某个字符串,比如Hello字符串中不包含Hi。",caseInsensitive:"no",dataType:"string"},{name:"包含任一字符串",code:"contains any",description:"包含字符串列表中的任意一个,比如/hello/world包含/hello和/hi中的/hello,对比值中每行一个字符串。",caseInsensitive:"no",dataType:"strings"},{name:"包含所有字符串",code:"contains all",description:"包含字符串列表中的所有字符串,比如/hello/world必须包含/hello和/world,对比值中每行一个字符串。",caseInsensitive:"no",dataType:"strings"},{name:"包含前缀",code:"prefix",description:"包含字符串前缀部分,比如/hello前缀会匹配/hello, /hello/world等。",caseInsensitive:"no",dataType:"string"},{name:"包含后缀",code:"suffix",description:"包含字符串后缀部分,比如/hello后缀会匹配/hello, /hi/hello等。",caseInsensitive:"no",dataType:"string"},{name:"包含二进制数据",code:"contains binary",description:"包含一组二进制数据。",caseInsensitive:"no",dataType:"string"},{name:"不包含二进制数据",code:"not contains binary",description:"不包含一组二进制数据。",caseInsensitive:"no",dataType:"string"},{name:"数值大于",code:"gt",description:"使用数值对比大于,对比值需要是一个数字。",caseInsensitive:"none",dataType:"number"},{name:"数值大于等于",code:"gte",description:"使用数值对比大于等于,对比值需要是一个数字。",caseInsensitive:"none",dataType:"number"},{name:"数值小于",code:"lt",description:"使用数值对比小于,对比值需要是一个数字。",caseInsensitive:"none",dataType:"number"},{name:"数值小于等于",code:"lte",description:"使用数值对比小于等于,对比值需要是一个数字。",caseInsensitive:"none",dataType:"number"},{name:"数值等于",code:"eq",description:"使用数值对比等于,对比值需要是一个数字。",caseInsensitive:"none",dataType:"number"},{name:"数值不等于",code:"neq",description:"使用数值对比不等于,对比值需要是一个数字。",caseInsensitive:"none",dataType:"number"},{name:"包含索引",code:"has key",description:"对于一组数据拥有某个键值或者索引。",caseInsensitive:"no",dataType:"string|number"},{name:"版本号大于",code:"version gt",description:"对比版本号大于。",caseInsensitive:"none",dataType:"version"},{name:"版本号小于",code:"version lt",description:"对比版本号小于",caseInsensitive:"none",dataType:"version"},{name:"版本号范围",code:"version range",description:"判断版本号在某个范围内,格式为 起始version1,结束version2。",caseInsensitive:"none",dataType:"versionRange"},{name:"IP等于",code:"eq ip",description:"将参数转换为IP进行对比,只能对比单个IP。",caseInsensitive:"none",dataType:"ip"},{name:"在一组IP中",code:"in ip list",description:"判断参数IP在一组IP内,对比值中每行一个IP。",caseInsensitive:"none",dataType:"ips"},{name:"IP大于",code:"gt ip",description:"将参数转换为IP进行对比。",caseInsensitive:"none",dataType:"ip"},{name:"IP大于等于",code:"gte ip",description:"将参数转换为IP进行对比。",caseInsensitive:"none",dataType:"ip"},{name:"IP小于",code:"lt ip",description:"将参数转换为IP进行对比。",caseInsensitive:"none",dataType:"ip"},{name:"IP小于等于",code:"lte ip",description:"将参数转换为IP进行对比。",caseInsensitive:"none",dataType:"ip"},{name:"IP范围",code:"ip range",description:"IP在某个范围之内,范围格式可以是英文逗号分隔的开始IP,结束IP,比如192.168.1.100,192.168.2.200;或者CIDR格式的ip/bits,比如192.168.2.1/24;或者单个IP。可以填写多行,每行一个IP范围。",caseInsensitive:"none",dataType:"ips"},{name:"不在IP范围",code:"not ip range",description:"IP不在某个范围之内,范围格式可以是英文逗号分隔的开始IP,结束IP,比如192.168.1.100,192.168.2.200;或者CIDR格式的ip/bits,比如192.168.2.1/24;或者单个IP。可以填写多行,每行一个IP范围。",caseInsensitive:"none",dataType:"ips"},{name:"IP取模10",code:"ip mod 10",description:"对IP参数值取模,除数为10,对比值为余数。",caseInsensitive:"none",dataType:"number"},{name:"IP取模100",code:"ip mod 100",description:"对IP参数值取模,除数为100,对比值为余数。",caseInsensitive:"none",dataType:"number"},{name:"IP取模",code:"ip mod",description:"对IP参数值取模,对比值格式为:除数,余数,比如10,1。",caseInsensitive:"none",dataType:"number"}],window.WAF_CAPTCHA_TYPES=[{name:"验证码",code:"default",description:"通过输入验证码来验证人机。",icon:""},{name:"点击验证",code:"oneClick",description:"通过点击界面元素来验证人机。",icon:""},{name:"滑动解锁",code:"slide",description:"通过滑动方块解锁来验证人机。",icon:""}]; +`}),window.REQUEST_COND_COMPONENTS=[{type:"url-extension",name:"文件扩展名",description:"根据URL中的文件路径扩展名进行过滤",component:"http-cond-url-extension",paramsTitle:"扩展名列表",isRequest:!0,caseInsensitive:!1},{type:"url-eq-index",name:"首页",description:'检查URL路径是为"/"',component:"http-cond-url-eq-index",paramsTitle:"URL完整路径",isRequest:!0,caseInsensitive:!1},{type:"url-all",name:"全站",description:"全站所有URL",component:"http-cond-url-all",paramsTitle:"URL完整路径",isRequest:!0,caseInsensitive:!1},{type:"url-prefix",name:"URL目录前缀",description:"根据URL中的文件路径前缀进行过滤",component:"http-cond-url-prefix",paramsTitle:"URL目录前缀",isRequest:!0,caseInsensitive:!0},{type:"url-eq",name:"URL完整路径",description:"检查URL中的文件路径是否一致",component:"http-cond-url-eq",paramsTitle:"URL完整路径",isRequest:!0,caseInsensitive:!0},{type:"url-regexp",name:"URL正则匹配",description:"使用正则表达式检查URL中的文件路径是否一致",component:"http-cond-url-regexp",paramsTitle:"正则表达式",isRequest:!0,caseInsensitive:!0},{type:"url-wildcard-match",name:"URL通配符",description:"使用通配符检查URL中的文件路径是否一致",component:"http-cond-url-wildcard-match",paramsTitle:"通配符",isRequest:!0,caseInsensitive:!0},{type:"user-agent-regexp",name:"User-Agent正则匹配",description:"使用正则表达式检查User-Agent中是否含有某些浏览器和系统标识",component:"http-cond-user-agent-regexp",paramsTitle:"正则表达式",isRequest:!0,caseInsensitive:!0},{type:"params",name:"参数匹配",description:"根据参数值进行匹配",component:"http-cond-params",paramsTitle:"参数配置",isRequest:!0,caseInsensitive:!1},{type:"url-not-extension",name:"排除:URL扩展名",description:"根据URL中的文件路径扩展名进行过滤",component:"http-cond-url-not-extension",paramsTitle:"扩展名列表",isRequest:!0,caseInsensitive:!1},{type:"url-not-prefix",name:"排除:URL前缀",description:"根据URL中的文件路径前缀进行过滤",component:"http-cond-url-not-prefix",paramsTitle:"URL前缀",isRequest:!0,caseInsensitive:!0},{type:"url-not-eq",name:"排除:URL完整路径",description:"检查URL中的文件路径是否一致",component:"http-cond-url-not-eq",paramsTitle:"URL完整路径",isRequest:!0,caseInsensitive:!0},{type:"url-not-regexp",name:"排除:URL正则匹配",description:"使用正则表达式检查URL中的文件路径是否一致,如果一致,则不匹配",component:"http-cond-url-not-regexp",paramsTitle:"正则表达式",isRequest:!0,caseInsensitive:!0},{type:"user-agent-not-regexp",name:"排除:User-Agent正则匹配",description:"使用正则表达式检查User-Agent中是否含有某些浏览器和系统标识,如果含有,则不匹配",component:"http-cond-user-agent-not-regexp",paramsTitle:"正则表达式",isRequest:!0,caseInsensitive:!0},{type:"mime-type",name:"内容MimeType",description:"根据服务器返回的内容的MimeType进行过滤。注意:当用于缓存条件时,此条件需要结合别的请求条件使用。",component:"http-cond-mime-type",paramsTitle:"MimeType列表",isRequest:!1,caseInsensitive:!1}],window.REQUEST_COND_OPERATORS=[{description:"判断是否正则表达式匹配",name:"正则表达式匹配",op:"regexp"},{description:"判断是否正则表达式不匹配",name:"正则表达式不匹配",op:"not regexp"},{description:"判断是否和指定的通配符匹配",name:"通配符匹配",op:"wildcard match"},{description:"判断是否和指定的通配符不匹配",name:"通配符不匹配",op:"wildcard not match"},{description:"使用字符串对比参数值是否相等于某个值",name:"字符串等于",op:"eq"},{description:"参数值包含某个前缀",name:"字符串前缀",op:"prefix"},{description:"参数值包含某个后缀",name:"字符串后缀",op:"suffix"},{description:"参数值包含另外一个字符串",name:"字符串包含",op:"contains"},{description:"参数值不包含另外一个字符串",name:"字符串不包含",op:"not contains"},{description:"使用字符串对比参数值是否不相等于某个值",name:"字符串不等于",op:"not"},{description:"判断参数值在某个列表中",name:"在列表中",op:"in"},{description:"判断参数值不在某个列表中",name:"不在列表中",op:"not in"},{description:"判断小写的扩展名(不带点)在某个列表中",name:"扩展名",op:"file ext"},{description:"判断MimeType在某个列表中,支持类似于image/*的语法",name:"MimeType",op:"mime type"},{description:"判断版本号在某个范围内,格式为version1,version2",name:"版本号范围",op:"version range"},{description:"将参数转换为整数数字后进行对比",name:"整数等于",op:"eq int"},{description:"将参数转换为可以有小数的浮点数字进行对比",name:"浮点数等于",op:"eq float"},{description:"将参数转换为数字进行对比",name:"数字大于",op:"gt"},{description:"将参数转换为数字进行对比",name:"数字大于等于",op:"gte"},{description:"将参数转换为数字进行对比",name:"数字小于",op:"lt"},{description:"将参数转换为数字进行对比",name:"数字小于等于",op:"lte"},{description:"对整数参数值取模,除数为10,对比值为余数",name:"整数取模10",op:"mod 10"},{description:"对整数参数值取模,除数为100,对比值为余数",name:"整数取模100",op:"mod 100"},{description:"对整数参数值取模,对比值格式为:除数,余数,比如10,1",name:"整数取模",op:"mod"},{description:"将参数转换为IP进行对比",name:"IP等于",op:"eq ip"},{description:"将参数转换为IP进行对比",name:"IP大于",op:"gt ip"},{description:"将参数转换为IP进行对比",name:"IP大于等于",op:"gte ip"},{description:"将参数转换为IP进行对比",name:"IP小于",op:"lt ip"},{description:"将参数转换为IP进行对比",name:"IP小于等于",op:"lte ip"},{description:"IP在某个范围之内,范围格式可以是英文逗号分隔的开始IP,结束IP,比如192.168.1.100,192.168.2.200,或者CIDR格式的ip/bits,比如192.168.2.1/24",name:"IP范围",op:"ip range"},{description:"对IP参数值取模,除数为10,对比值为余数",name:"IP取模10",op:"ip mod 10"},{description:"对IP参数值取模,除数为100,对比值为余数",name:"IP取模100",op:"ip mod 100"},{description:"对IP参数值取模,对比值格式为:除数,余数,比如10,1",name:"IP取模",op:"ip mod"}],window.REQUEST_VARIABLES=[{code:"${edgeVersion}",description:"",name:"边缘节点版本"},{code:"${remoteAddr}",description:"会依次根据X-Forwarded-For、X-Real-IP、RemoteAddr获取,适合前端有别的反向代理服务时使用,存在伪造的风险",name:"客户端地址(IP)"},{code:"${rawRemoteAddr}",description:"返回直接连接服务的客户端原始IP地址",name:"客户端地址(IP)"},{code:"${remotePort}",description:"",name:"客户端端口"},{code:"${remoteUser}",description:"",name:"客户端用户名"},{code:"${requestURI}",description:"比如/hello?name=lily",name:"请求URI"},{code:"${requestPath}",description:"比如/hello",name:"请求路径(不包括参数)"},{code:"${requestURL}",description:"比如https://example.com/hello?name=lily",name:"完整的请求URL"},{code:"${requestLength}",description:"",name:"请求内容长度"},{code:"${requestMethod}",description:"比如GET、POST",name:"请求方法"},{code:"${requestFilename}",description:"",name:"请求文件路径"},{code:"${requestPathExtension}",description:"请求路径中的文件扩展名,包括点符号,比如.html、.png",name:"请求文件扩展名"},{code:"${requestPathLowerExtension}",description:"请求路径中的文件扩展名,其中大写字母会被自动转换为小写,包括点符号,比如.html、.png",name:"请求文件小写扩展名"},{code:"${scheme}",description:"",name:"请求协议,http或https"},{code:"${proto}","description:":"类似于HTTP/1.0",name:"包含版本的HTTP请求协议"},{code:"${timeISO8601}",description:"比如2018-07-16T23:52:24.839+08:00",name:"ISO 8601格式的时间"},{code:"${timeLocal}",description:"比如17/Jul/2018:09:52:24 +0800",name:"本地时间"},{code:"${msec}",description:"比如1531756823.054",name:"带有毫秒的时间"},{code:"${timestamp}",description:"",name:"unix时间戳,单位为秒"},{code:"${host}",description:"",name:"主机名"},{code:"${cname}",description:"比如38b48e4f.goedge.cn",name:"当前网站的CNAME"},{code:"${serverName}",description:"",name:"接收请求的服务器名"},{code:"${serverPort}",description:"",name:"接收请求的服务器端口"},{code:"${referer}",description:"",name:"请求来源URL"},{code:"${referer.host}",description:"",name:"请求来源URL域名"},{code:"${userAgent}",description:"",name:"客户端信息"},{code:"${contentType}",description:"",name:"请求头部的Content-Type"},{code:"${cookies}",description:"",name:"所有cookie组合字符串"},{code:"${cookie.NAME}",description:"",name:"单个cookie值"},{code:"${isArgs}",description:"如果URL有参数,则值为`?`;否则,则值为空",name:"问号(?)标记"},{code:"${args}",description:"",name:"所有参数组合字符串"},{code:"${arg.NAME}",description:"",name:"单个参数值"},{code:"${headers}",description:"",name:"所有Header信息组合字符串"},{code:"${header.NAME}",description:"",name:"单个Header值"},{code:"${geo.country.name}",description:"",name:"国家/地区名称"},{code:"${geo.country.id}",description:"",name:"国家/地区ID"},{code:"${geo.province.name}",description:"目前只包含中国省份",name:"省份名称"},{code:"${geo.province.id}",description:"目前只包含中国省份",name:"省份ID"},{code:"${geo.city.name}",description:"目前只包含中国城市",name:"城市名称"},{code:"${geo.city.id}",description:"目前只包含中国城市",name:"城市名称"},{code:"${isp.name}",description:"",name:"ISP服务商名称"},{code:"${isp.id}",description:"",name:"ISP服务商ID"},{code:"${browser.os.name}",description:"客户端所在操作系统名称",name:"操作系统名称"},{code:"${browser.os.version}",description:"客户端所在操作系统版本",name:"操作系统版本"},{code:"${browser.name}",description:"客户端浏览器名称",name:"浏览器名称"},{code:"${browser.version}",description:"客户端浏览器版本",name:"浏览器版本"},{code:"${browser.isMobile}",description:"如果客户端是手机,则值为1,否则为0",name:"手机标识"}],window.METRIC_HTTP_KEYS=[{name:"客户端地址(IP)",code:"${remoteAddr}",description:"会依次根据X-Forwarded-For、X-Real-IP、RemoteAddr获取,适用于前端可能有别的反向代理的情形,存在被伪造的可能",icon:""},{name:"直接客户端地址(IP)",code:"${rawRemoteAddr}",description:"返回直接连接服务的客户端原始IP地址",icon:""},{name:"客户端用户名",code:"${remoteUser}",description:"通过基本认证填入的用户名",icon:""},{name:"请求URI",code:"${requestURI}",description:"包含参数,比如/hello?name=lily",icon:""},{name:"请求路径",code:"${requestPath}",description:"不包含参数,比如/hello",icon:""},{name:"完整URL",code:"${requestURL}",description:"比如https://example.com/hello?name=lily",icon:""},{name:"请求方法",code:"${requestMethod}",description:"比如GET、POST等",icon:""},{name:"请求协议Scheme",code:"${scheme}",description:"http或https",icon:""},{name:"文件扩展名",code:"${requestPathExtension}",description:"请求路径中的文件扩展名,包括点符号,比如.html、.png",icon:""},{name:"小写文件扩展名",code:"${requestPathLowerExtension}",description:"请求路径中的文件扩展名小写形式,包括点符号,比如.html、.png",icon:""},{name:"主机名",code:"${host}",description:"通常是请求的域名",icon:""},{name:"HTTP协议",code:"${proto}",description:"包含版本的HTTP请求协议,类似于HTTP/1.0",icon:""},{name:"URL参数值",code:"${arg.NAME}",description:"单个URL参数值",icon:""},{name:"请求来源URL",code:"${referer}",description:"请求来源Referer URL",icon:""},{name:"请求来源URL域名",code:"${referer.host}",description:"请求来源Referer URL域名",icon:""},{name:"Header值",code:"${header.NAME}",description:"单个Header值,比如${header.User-Agent}",icon:""},{name:"Cookie值",code:"${cookie.NAME}",description:"单个cookie值,比如${cookie.sid}",icon:""},{name:"状态码",code:"${status}",description:"",icon:""},{name:"响应的Content-Type值",code:"${response.contentType}",description:"",icon:""}],window.IP_ADDR_THRESHOLD_ITEMS=[{code:"nodeAvgRequests",description:"当前节点在单位时间内接收到的平均请求数。",name:"节点平均请求数",unit:"个"},{code:"nodeAvgTrafficOut",description:"当前节点在单位时间内发送的下行流量。",name:"节点平均下行流量",unit:"M"},{code:"nodeAvgTrafficIn",description:"当前节点在单位时间内接收的上行流量。",name:"节点平均上行流量",unit:"M"},{code:"nodeHealthCheck",description:"当前节点健康检查结果。",name:"节点健康检查结果",unit:""},{code:"connectivity",description:"通过区域监控得到的当前IP地址的连通性数值,取值在0和100之间。",name:"IP连通性",unit:"%"},{code:"groupAvgRequests",description:"当前节点所在分组在单位时间内接收到的平均请求数。",name:"分组平均请求数",unit:"个"},{code:"groupAvgTrafficOut",description:"当前节点所在分组在单位时间内发送的下行流量。",name:"分组平均下行流量",unit:"M"},{code:"groupAvgTrafficIn",description:"当前节点所在分组在单位时间内接收的上行流量。",name:"分组平均上行流量",unit:"M"},{code:"clusterAvgRequests",description:"当前节点所在集群在单位时间内接收到的平均请求数。",name:"集群平均请求数",unit:"个"},{code:"clusterAvgTrafficOut",description:"当前节点所在集群在单位时间内发送的下行流量。",name:"集群平均下行流量",unit:"M"},{code:"clusterAvgTrafficIn",description:"当前节点所在集群在单位时间内接收的上行流量。",name:"集群平均上行流量",unit:"M"}],window.IP_ADDR_THRESHOLD_ACTIONS=[{code:"up",description:"上线当前IP。",name:"上线"},{code:"down",description:"下线当前IP。",name:"下线"},{code:"notify",description:"发送已达到阈值通知。",name:"通知"},{code:"switch",description:"在DNS中记录中将IP切换到指定的备用IP。",name:"切换"},{code:"webHook",description:"调用外部的WebHook。",name:"WebHook"}],window.WAF_RULE_OPERATORS=[{name:"正则匹配",code:"match",description:'使用正则表达式匹配,在头部使用(?i)表示不区分大小写,正则表达式语法 »。',caseInsensitive:"yes",dataType:"regexp"},{name:"正则不匹配",code:"not match",description:'使用正则表达式不匹配,在头部使用(?i)表示不区分大小写,正则表达式语法 »。',caseInsensitive:"yes",dataType:"regexp"},{name:"通配符匹配",code:"wildcard match",description:"判断是否和指定的通配符匹配,可以在对比值中使用星号通配符(*)表示任意字符。",caseInsensitive:"yes",dataType:"wildcard"},{name:"通配符不匹配",code:"wildcard not match",description:"判断是否和指定的通配符不匹配,可以在对比值中使用星号通配符(*)表示任意字符。",caseInsensitive:"yes",dataType:"wildcard"},{name:"字符串等于",code:"eq string",description:"使用字符串对比等于。",caseInsensitive:"no",dataType:"string"},{name:"字符串不等于",code:"neq string",description:"使用字符串对比不等于。",caseInsensitive:"no",dataType:"string"},{name:"包含字符串",code:"contains",description:"包含某个字符串,比如Hello World包含了World。",caseInsensitive:"no",dataType:"string"},{name:"不包含字符串",code:"not contains",description:"不包含某个字符串,比如Hello字符串中不包含Hi。",caseInsensitive:"no",dataType:"string"},{name:"包含任一字符串",code:"contains any",description:"包含字符串列表中的任意一个,比如/hello/world包含/hello和/hi中的/hello,对比值中每行一个字符串。",caseInsensitive:"no",dataType:"strings"},{name:"包含所有字符串",code:"contains all",description:"包含字符串列表中的所有字符串,比如/hello/world必须包含/hello和/world,对比值中每行一个字符串。",caseInsensitive:"no",dataType:"strings"},{name:"包含前缀",code:"prefix",description:"包含字符串前缀部分,比如/hello前缀会匹配/hello, /hello/world等。",caseInsensitive:"no",dataType:"string"},{name:"包含后缀",code:"suffix",description:"包含字符串后缀部分,比如/hello后缀会匹配/hello, /hi/hello等。",caseInsensitive:"no",dataType:"string"},{name:"包含二进制数据",code:"contains binary",description:"包含一组二进制数据。",caseInsensitive:"no",dataType:"string"},{name:"不包含二进制数据",code:"not contains binary",description:"不包含一组二进制数据。",caseInsensitive:"no",dataType:"string"},{name:"数值大于",code:"gt",description:"使用数值对比大于,对比值需要是一个数字。",caseInsensitive:"none",dataType:"number"},{name:"数值大于等于",code:"gte",description:"使用数值对比大于等于,对比值需要是一个数字。",caseInsensitive:"none",dataType:"number"},{name:"数值小于",code:"lt",description:"使用数值对比小于,对比值需要是一个数字。",caseInsensitive:"none",dataType:"number"},{name:"数值小于等于",code:"lte",description:"使用数值对比小于等于,对比值需要是一个数字。",caseInsensitive:"none",dataType:"number"},{name:"数值等于",code:"eq",description:"使用数值对比等于,对比值需要是一个数字。",caseInsensitive:"none",dataType:"number"},{name:"数值不等于",code:"neq",description:"使用数值对比不等于,对比值需要是一个数字。",caseInsensitive:"none",dataType:"number"},{name:"包含索引",code:"has key",description:"对于一组数据拥有某个键值或者索引。",caseInsensitive:"no",dataType:"string|number"},{name:"版本号大于",code:"version gt",description:"对比版本号大于。",caseInsensitive:"none",dataType:"version"},{name:"版本号小于",code:"version lt",description:"对比版本号小于",caseInsensitive:"none",dataType:"version"},{name:"版本号范围",code:"version range",description:"判断版本号在某个范围内,格式为 起始version1,结束version2。",caseInsensitive:"none",dataType:"versionRange"},{name:"IP等于",code:"eq ip",description:"将参数转换为IP进行对比,只能对比单个IP。",caseInsensitive:"none",dataType:"ip"},{name:"在一组IP中",code:"in ip list",description:"判断参数IP在一组IP内,对比值中每行一个IP。",caseInsensitive:"none",dataType:"ips"},{name:"IP大于",code:"gt ip",description:"将参数转换为IP进行对比。",caseInsensitive:"none",dataType:"ip"},{name:"IP大于等于",code:"gte ip",description:"将参数转换为IP进行对比。",caseInsensitive:"none",dataType:"ip"},{name:"IP小于",code:"lt ip",description:"将参数转换为IP进行对比。",caseInsensitive:"none",dataType:"ip"},{name:"IP小于等于",code:"lte ip",description:"将参数转换为IP进行对比。",caseInsensitive:"none",dataType:"ip"},{name:"IP范围",code:"ip range",description:"IP在某个范围之内,范围格式可以是英文逗号分隔的开始IP,结束IP,比如192.168.1.100,192.168.2.200;或者CIDR格式的ip/bits,比如192.168.2.1/24;或者单个IP。可以填写多行,每行一个IP范围。",caseInsensitive:"none",dataType:"ips"},{name:"不在IP范围",code:"not ip range",description:"IP不在某个范围之内,范围格式可以是英文逗号分隔的开始IP,结束IP,比如192.168.1.100,192.168.2.200;或者CIDR格式的ip/bits,比如192.168.2.1/24;或者单个IP。可以填写多行,每行一个IP范围。",caseInsensitive:"none",dataType:"ips"},{name:"IP取模10",code:"ip mod 10",description:"对IP参数值取模,除数为10,对比值为余数。",caseInsensitive:"none",dataType:"number"},{name:"IP取模100",code:"ip mod 100",description:"对IP参数值取模,除数为100,对比值为余数。",caseInsensitive:"none",dataType:"number"},{name:"IP取模",code:"ip mod",description:"对IP参数值取模,对比值格式为:除数,余数,比如10,1。",caseInsensitive:"none",dataType:"number"}],window.WAF_CAPTCHA_TYPES=[{name:"验证码",code:"default",description:"通过输入验证码来验证人机。",icon:""},{name:"点击验证",code:"oneClick",description:"通过点击界面元素来验证人机。",icon:""},{name:"滑动解锁",code:"slide",description:"通过滑动方块解锁来验证人机。",icon:""},{name:"极验-行为验",code:"geetest",description:"使用极验-行为验提供的人机验证方式。",icon:""}]; diff --git a/web/public/js/components.src.js b/web/public/js/components.src.js index 4eed042f..ab304ffb 100755 --- a/web/public/js/components.src.js +++ b/web/public/js/components.src.js @@ -2912,7 +2912,7 @@ Vue.component("plan-price-view", { 按{{plan.bandwidthPrice.percentile}}th带宽计费
- {{range.minMB}} - {{range.maxMB}}MB{{range.totalPrice}}元{{range.pricePerMB}}元/MB + {{range.minMB}} - {{range.maxMB}}MiB{{range.totalPrice}}元{{range.pricePerMB}}元/MiB
@@ -3547,7 +3547,7 @@ Vue.component("plan-price-bandwidth-config-box", {

按在计时时间段内(5分钟)最高带宽峰值计算,比如5分钟内最高的某个时间点带宽为100Mbps,那么就认为此时间段内的峰值带宽为100Mbps。修改此选项会同时影响到用量统计图表。

-

按在计时时间段内(5分钟)平均带宽计算,即此时间段内的总流量除以时间段的秒数,比如5分钟(300秒)内总流量600MB,那么带宽即为600MB * 8bit/300s = 16Mbps;通常平均带宽算法要比峰值带宽要少很多。修改此选项会同时影响到用量统计图表。

+

按在计时时间段内(5分钟)平均带宽计算,即此时间段内的总流量除以时间段的秒数,比如5分钟(300秒)内总流量600MiB,那么带宽即为600MiB * 8bit/300s = 16Mbps;通常平均带宽算法要比峰值带宽要少很多。修改此选项会同时影响到用量统计图表。

@@ -5673,11 +5673,25 @@ Vue.component("http-firewall-config-box", { firewall.defaultCaptchaType = "none" } + let allCaptchaTypes = window.WAF_CAPTCHA_TYPES.$copy() + + // geetest + let geeTestIsOn = false + if (this.vFirewallPolicy != null && this.vFirewallPolicy.captchaAction != null && this.vFirewallPolicy.captchaAction.geeTestConfig != null) { + geeTestIsOn = this.vFirewallPolicy.captchaAction.geeTestConfig.isOn + } + + // 如果没有启用geetest,则还原 + if (!geeTestIsOn && firewall.defaultCaptchaType == "geetest") { + firewall.defaultCaptchaType = "none" + } + return { firewall: firewall, moreOptionsVisible: false, execGlobalRules: !firewall.ignoreGlobalRules, - captchaTypes: window.WAF_CAPTCHA_TYPES + captchaTypes: allCaptchaTypes, + geeTestIsOn: geeTestIsOn } }, watch: { @@ -5723,7 +5737,7 @@ Vue.component("http-firewall-config-box", {

使用系统默认的设置。

{{captchaType.description}}

@@ -7412,7 +7426,9 @@ Vue.component("http-optimization-config-box", { return { config: config, - moreOptionsVisible: false + htmlMoreOptions: false, + javascriptMoreOptions: false, + cssMoreOptions: false } }, methods: { @@ -7422,41 +7438,115 @@ Vue.component("http-optimization-config-box", { }, template: `
- - - - - - - - - - - - - - - - +
HTML优化 -
- - -
-

可以自动优化HTML中包含的空白、注释、空标签等。只有文件可以缓存时才会被优化。

-
Javascript优化 -
- - -
-

可以自动缩短Javascript中变量、函数名称等。只有文件可以缓存时才会被优化。

-
CSS优化 -
- - -
-

可以自动去除CSS中包含的空白。只有文件可以缓存时才会被优化。

-
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + +
HTML优化 +
+ + +
+

可以自动优化HTML中包含的空白、注释、空标签等。只有文件可以缓存时才会被优化。

+
HTML例外URL + +

如果填写了例外URL,表示这些URL跳过CC防护不做处理。

+
HTML限制URL + +

如果填写了限制URL,表示只对这些URL进行CC防护处理;如果不填则表示支持所有的URL。

+
+ + + + + + + + + + + + + + + + + + + + + +
Javascript优化 +
+ + +
+

可以自动缩短Javascript中变量、函数名称等。只有文件可以缓存时才会被优化。

+
Javascript例外URL + +

如果填写了例外URL,表示这些URL跳过CC防护不做处理。

+
Javascript限制URL + +

如果填写了限制URL,表示只对这些URL进行CC防护处理;如果不填则表示支持所有的URL。

+
+ + + + + + + + + + + + + + + + + + + + + +
CSS优化 +
+ + +
+

可以自动去除CSS中包含的空白。只有文件可以缓存时才会被优化。

+
CSS例外URL + +

如果填写了例外URL,表示这些URL跳过CC防护不做处理。

+
CSS限制URL + +

如果填写了限制URL,表示只对这些URL进行CC防护处理;如果不填则表示支持所有的URL。

+
+
+
` }) @@ -8137,7 +8227,17 @@ Vue.component("domains-box", { if (this.isEditing && this.editingIndex >= 0) { this.domains[this.editingIndex] = this.addingDomain } else { - this.domains.push(this.addingDomain) + // 分割逗号(,)、顿号(、) + if (this.addingDomain.match("[,、,;]")) { + let domainList = this.addingDomain.split(new RegExp("[,、,;]")) + domainList.forEach(function (v) { + if (v.length > 0) { + that.domains.push(v) + } + }) + } else { + this.domains.push(this.addingDomain) + } } this.cancel() this.change() @@ -11626,7 +11726,7 @@ Vue.component("http-access-log-config-box", {

在基础信息之外要存储的信息。 - 记录"请求Body"将会显著消耗更多的系统资源,建议仅在调试时启用,最大记录尺寸为2MB。 + 记录"请求Body"将会显著消耗更多的系统资源,建议仅在调试时启用,最大记录尺寸为2MiB。

@@ -12121,6 +12221,11 @@ Vue.component("http-firewall-captcha-options-viewer", { summaryList.push("定制UI") } } + + if (this.options.geeTestConfig.isOn) { + summaryList.push("已配置极验") + } + if (summaryList.length == 0) { this.summary = "默认配置" } else { @@ -15155,7 +15260,12 @@ Vue.component("http-firewall-captcha-options", { uiFooter: "", uiBody: "", cookieId: "", - lang: "" + lang: "", + geeTestConfig: { + isOn: false, + captchaId: "", + captchaKey: "" + } } } if (options.countLetters <= 0) { @@ -15166,6 +15276,7 @@ Vue.component("http-firewall-captcha-options", { options.captchaType = "default" } + return { options: options, isEditing: false, @@ -15225,6 +15336,9 @@ Vue.component("http-firewall-captcha-options", { } else { this.uiBodyWarning = "" } + }, + "options.geeTestConfig.isOn": function (v) { + this.updateSummary() } }, methods: { @@ -15260,6 +15374,10 @@ Vue.component("http-firewall-captcha-options", { } } + if (this.options.geeTestConfig.isOn) { + summaryList.push("已配置极验") + } + if (summaryList.length == 0) { this.summary = "默认配置" } else { @@ -15335,7 +15453,6 @@ Vue.component("http-firewall-captcha-options", { 定制UI - @@ -15387,6 +15504,31 @@ Vue.component("http-firewall-captcha-options", { + + + + + + + + + + + + + + + + +
允许用户使用极验 +

选中后,表示允许用户在WAF设置中选择极验。

+
极验-验证ID * + +

在极验控制台--业务管理中获取。

+
极验-验证Key * + +

在极验控制台--业务管理中获取。

+
` @@ -19216,12 +19358,12 @@ Vue.component("size-capacity-box", {
` @@ -20071,11 +20213,11 @@ Vue.component("node-schedule-conds-box", {
@@ -21628,5 +21770,5 @@ window.IP_ADDR_THRESHOLD_ACTIONS = [{"code":"up","description":"上线当前IP window.WAF_RULE_OPERATORS = [{"name":"正则匹配","code":"match","description":"使用正则表达式匹配,在头部使用(?i)表示不区分大小写,\u003ca href=\"https://goedge.cn/docs/Appendix/Regexp/Index.md\" target=\"_blank\"\u003e正则表达式语法 \u0026raquo;\u003c/a\u003e。","caseInsensitive":"yes","dataType":"regexp"},{"name":"正则不匹配","code":"not match","description":"使用正则表达式不匹配,在头部使用(?i)表示不区分大小写,\u003ca href=\"https://goedge.cn/docs/Appendix/Regexp/Index.md\" target=\"_blank\"\u003e正则表达式语法 \u0026raquo;\u003c/a\u003e。","caseInsensitive":"yes","dataType":"regexp"},{"name":"通配符匹配","code":"wildcard match","description":"判断是否和指定的通配符匹配,可以在对比值中使用星号通配符(*)表示任意字符。","caseInsensitive":"yes","dataType":"wildcard"},{"name":"通配符不匹配","code":"wildcard not match","description":"判断是否和指定的通配符不匹配,可以在对比值中使用星号通配符(*)表示任意字符。","caseInsensitive":"yes","dataType":"wildcard"},{"name":"字符串等于","code":"eq string","description":"使用字符串对比等于。","caseInsensitive":"no","dataType":"string"},{"name":"字符串不等于","code":"neq string","description":"使用字符串对比不等于。","caseInsensitive":"no","dataType":"string"},{"name":"包含字符串","code":"contains","description":"包含某个字符串,比如Hello World包含了World。","caseInsensitive":"no","dataType":"string"},{"name":"不包含字符串","code":"not contains","description":"不包含某个字符串,比如Hello字符串中不包含Hi。","caseInsensitive":"no","dataType":"string"},{"name":"包含任一字符串","code":"contains any","description":"包含字符串列表中的任意一个,比如/hello/world包含/hello和/hi中的/hello,对比值中每行一个字符串。","caseInsensitive":"no","dataType":"strings"},{"name":"包含所有字符串","code":"contains all","description":"包含字符串列表中的所有字符串,比如/hello/world必须包含/hello和/world,对比值中每行一个字符串。","caseInsensitive":"no","dataType":"strings"},{"name":"包含前缀","code":"prefix","description":"包含字符串前缀部分,比如/hello前缀会匹配/hello, /hello/world等。","caseInsensitive":"no","dataType":"string"},{"name":"包含后缀","code":"suffix","description":"包含字符串后缀部分,比如/hello后缀会匹配/hello, /hi/hello等。","caseInsensitive":"no","dataType":"string"},{"name":"包含二进制数据","code":"contains binary","description":"包含一组二进制数据。","caseInsensitive":"no","dataType":"string"},{"name":"不包含二进制数据","code":"not contains binary","description":"不包含一组二进制数据。","caseInsensitive":"no","dataType":"string"},{"name":"数值大于","code":"gt","description":"使用数值对比大于,对比值需要是一个数字。","caseInsensitive":"none","dataType":"number"},{"name":"数值大于等于","code":"gte","description":"使用数值对比大于等于,对比值需要是一个数字。","caseInsensitive":"none","dataType":"number"},{"name":"数值小于","code":"lt","description":"使用数值对比小于,对比值需要是一个数字。","caseInsensitive":"none","dataType":"number"},{"name":"数值小于等于","code":"lte","description":"使用数值对比小于等于,对比值需要是一个数字。","caseInsensitive":"none","dataType":"number"},{"name":"数值等于","code":"eq","description":"使用数值对比等于,对比值需要是一个数字。","caseInsensitive":"none","dataType":"number"},{"name":"数值不等于","code":"neq","description":"使用数值对比不等于,对比值需要是一个数字。","caseInsensitive":"none","dataType":"number"},{"name":"包含索引","code":"has key","description":"对于一组数据拥有某个键值或者索引。","caseInsensitive":"no","dataType":"string|number"},{"name":"版本号大于","code":"version gt","description":"对比版本号大于。","caseInsensitive":"none","dataType":"version"},{"name":"版本号小于","code":"version lt","description":"对比版本号小于","caseInsensitive":"none","dataType":"version"},{"name":"版本号范围","code":"version range","description":"判断版本号在某个范围内,格式为 起始version1,结束version2。","caseInsensitive":"none","dataType":"versionRange"},{"name":"IP等于","code":"eq ip","description":"将参数转换为IP进行对比,只能对比单个IP。","caseInsensitive":"none","dataType":"ip"},{"name":"在一组IP中","code":"in ip list","description":"判断参数IP在一组IP内,对比值中每行一个IP。","caseInsensitive":"none","dataType":"ips"},{"name":"IP大于","code":"gt ip","description":"将参数转换为IP进行对比。","caseInsensitive":"none","dataType":"ip"},{"name":"IP大于等于","code":"gte ip","description":"将参数转换为IP进行对比。","caseInsensitive":"none","dataType":"ip"},{"name":"IP小于","code":"lt ip","description":"将参数转换为IP进行对比。","caseInsensitive":"none","dataType":"ip"},{"name":"IP小于等于","code":"lte ip","description":"将参数转换为IP进行对比。","caseInsensitive":"none","dataType":"ip"},{"name":"IP范围","code":"ip range","description":"IP在某个范围之内,范围格式可以是英文逗号分隔的\u003ccode-label\u003e开始IP,结束IP\u003c/code-label\u003e,比如\u003ccode-label\u003e192.168.1.100,192.168.2.200\u003c/code-label\u003e;或者CIDR格式的ip/bits,比如\u003ccode-label\u003e192.168.2.1/24\u003c/code-label\u003e;或者单个IP。可以填写多行,每行一个IP范围。","caseInsensitive":"none","dataType":"ips"},{"name":"不在IP范围","code":"not ip range","description":"IP不在某个范围之内,范围格式可以是英文逗号分隔的\u003ccode-label\u003e开始IP,结束IP\u003c/code-label\u003e,比如\u003ccode-label\u003e192.168.1.100,192.168.2.200\u003c/code-label\u003e;或者CIDR格式的ip/bits,比如\u003ccode-label\u003e192.168.2.1/24\u003c/code-label\u003e;或者单个IP。可以填写多行,每行一个IP范围。","caseInsensitive":"none","dataType":"ips"},{"name":"IP取模10","code":"ip mod 10","description":"对IP参数值取模,除数为10,对比值为余数。","caseInsensitive":"none","dataType":"number"},{"name":"IP取模100","code":"ip mod 100","description":"对IP参数值取模,除数为100,对比值为余数。","caseInsensitive":"none","dataType":"number"},{"name":"IP取模","code":"ip mod","description":"对IP参数值取模,对比值格式为:除数,余数,比如10,1。","caseInsensitive":"none","dataType":"number"}]; -window.WAF_CAPTCHA_TYPES = [{"name":"验证码","code":"default","description":"通过输入验证码来验证人机。","icon":""},{"name":"点击验证","code":"oneClick","description":"通过点击界面元素来验证人机。","icon":""},{"name":"滑动解锁","code":"slide","description":"通过滑动方块解锁来验证人机。","icon":""}]; +window.WAF_CAPTCHA_TYPES = [{"name":"验证码","code":"default","description":"通过输入验证码来验证人机。","icon":""},{"name":"点击验证","code":"oneClick","description":"通过点击界面元素来验证人机。","icon":""},{"name":"滑动解锁","code":"slide","description":"通过滑动方块解锁来验证人机。","icon":""},{"name":"极验-行为验","code":"geetest","description":"使用极验-行为验提供的人机验证方式。","icon":""}]; diff --git a/web/public/js/components/common/size-capacity-box.js b/web/public/js/components/common/size-capacity-box.js index db123b68..bdc84960 100644 --- a/web/public/js/components/common/size-capacity-box.js +++ b/web/public/js/components/common/size-capacity-box.js @@ -63,12 +63,12 @@ Vue.component("size-capacity-box", {
` diff --git a/web/public/js/components/plans/plan-price-view.js b/web/public/js/components/plans/plan-price-view.js index fc3b2fe9..30eefc48 100644 --- a/web/public/js/components/plans/plan-price-view.js +++ b/web/public/js/components/plans/plan-price-view.js @@ -26,7 +26,7 @@ Vue.component("plan-price-view", { 按{{plan.bandwidthPrice.percentile}}th带宽计费
- {{range.minMB}} - {{range.maxMB}}MB{{range.totalPrice}}元{{range.pricePerMB}}元/MB + {{range.minMB}} - {{range.maxMB}}MiB{{range.totalPrice}}元{{range.pricePerMB}}元/MiB
diff --git a/web/public/js/components/server/http-access-log-config-box.js b/web/public/js/components/server/http-access-log-config-box.js index d5ac287c..372ed801 100644 --- a/web/public/js/components/server/http-access-log-config-box.js +++ b/web/public/js/components/server/http-access-log-config-box.js @@ -85,7 +85,7 @@ Vue.component("http-access-log-config-box", {

在基础信息之外要存储的信息。 - 记录"请求Body"将会显著消耗更多的系统资源,建议仅在调试时启用,最大记录尺寸为2MB。 + 记录"请求Body"将会显著消耗更多的系统资源,建议仅在调试时启用,最大记录尺寸为2MiB。

diff --git a/web/public/js/utils.js b/web/public/js/utils.js index 2033d12d..3aec62c5 100644 --- a/web/public/js/utils.js +++ b/web/public/js/utils.js @@ -124,21 +124,21 @@ window.teaweb = { return bytes + "B"; } if (bytes < Math.pow(1024, 2)) { - return (Math.round(bytes * 100 / Math.pow(1024, 1)) / 100) + "KB"; + return (Math.round(bytes * 100 / Math.pow(1024, 1)) / 100) + "KiB"; } if (bytes < Math.pow(1024, 3)) { - return (Math.round(bytes * 100 / Math.pow(1024, 2)) / 100) + "MB"; + return (Math.round(bytes * 100 / Math.pow(1024, 2)) / 100) + "MiB"; } if (bytes < Math.pow(1024, 4)) { - return (Math.round(bytes * 100 / Math.pow(1024, 3)) / 100) + "GB"; + return (Math.round(bytes * 100 / Math.pow(1024, 3)) / 100) + "GiB"; } if (bytes < Math.pow(1024, 5)) { - return (Math.round(bytes * 100 / Math.pow(1024, 4)) / 100) + "TB"; + return (Math.round(bytes * 100 / Math.pow(1024, 4)) / 100) + "TiB"; } if (bytes < Math.pow(1024, 6)) { - return (Math.round(bytes * 100 / Math.pow(1024, 5)) / 100) + "PB"; + return (Math.round(bytes * 100 / Math.pow(1024, 5)) / 100) + "PiB"; } - return (Math.round(bytes * 100 / Math.pow(1024, 6)) / 100) + "EB"; + return (Math.round(bytes * 100 / Math.pow(1024, 6)) / 100) + "EiB"; }, formatBits: function (bits, decimal) { bits = Math.ceil(bits); diff --git a/web/public/js/utils.min.js b/web/public/js/utils.min.js index 5e1584af..e94e2a36 100644 --- a/web/public/js/utils.min.js +++ b/web/public/js/utils.min.js @@ -1 +1 @@ -window.teaweb={set:function(t,e){localStorage.setItem(t,JSON.stringify(e))},get:function(t){t=localStorage.getItem(t);return null==t||0==t.length?null:JSON.parse(t)},getString:function(t){t=this.get(t);return"string"==typeof t?t:""},getBool:function(t){return Boolean(this.get(t))},remove:function(t){localStorage.removeItem(t)},match:function(t,e){if(null==t)return!1;if(null==e)return!0;if(t=t.trim(),0==(e=e.trim()).length)return!0;if(0==t.length)return!1;for(var n=e.split(/\s+/),o=0;o=Math.pow(1024,6)?(o="E",n=Math.pow(1024,6)):t>=Math.pow(1024,5)?(o="P",n=Math.pow(1024,5)):t>=Math.pow(1024,4)?(o="T",n=Math.pow(1024,4)):t>=Math.pow(1024,3)?(o="G",n=Math.pow(1024,3)):t>=Math.pow(1024,2)?(o="M",n=Math.pow(1024,2)):t>=Math.pow(1024,1)&&(o="K",n=Math.pow(1024,1)),{unit:o,divider:n}},bitsAxis:function(t,e){t=this.bytesAxis(t,e);let n=t.unit;return"B"==n?n="bps":n+="bps",{unit:n,divider:t.divider}},countAxis:function(t,e){t=Math.max.apply(this,t.map(e));let n=1,o="";return 1e9<=t?(o="B",n=1e9):1e6<=t?(o="M",n=1e6):1e3<=t&&(o="K",n=1e3),{unit:o,divider:n,max:t}},splitFormat:function(t){t=t.match(/^([0-9.]+)([a-zA-Z]+)$/);return[parseFloat(t[1]),t[2]]},popup:function(t,e){null!=t&&0',width:n,padding:"0.5em",showConfirmButton:!1,showCloseButton:!0,focusConfirm:!1,onClose:function(t){"function"==typeof e.onClose&&e.onClose.apply(Tea.Vue,arguments)}})},popupSuccess:function(t,e,n){let o={};null!=e&&(o.width=e),null!=n&&(o.height=n),o.callback=function(){teaweb.success("保存成功",function(){teaweb.reload()})},this.popup(t,o)},popupFinish:function(){null!=window.POPUP_CALLBACK&&window.POPUP_CALLBACK.apply(window,arguments)},popupTip:function(t){Swal.fire({html:'
'+t+"
",width:"34em",padding:"4em",showConfirmButton:!1,showCloseButton:!0,focusConfirm:!1})},isPopup:function(){var t=window.location.hash;return null!=t&&t.startsWith("#popup")},closePopup:function(){this.isPopup()&&window.parent.Swal.close()},Swal:function(){return(this.isPopup()?window.parent:window).Swal},hasPopup:function(){return 0{b} : {c}"+u},series:[{name:r,max:l,type:"gauge",radius:"100%",detail:{formatter:"{value}",show:!1,valueAnimation:!0},data:[{value:a,name:r}],pointer:{show:!1},splitLine:{show:!1},axisTick:{show:!1},axisLine:{show:!0,lineStyle:{width:4}},progress:{show:!0,width:4,itemStyle:{color:i}},splitNumber:{show:!1},title:{show:!1},startAngle:270,endAngle:-90}]};null!=s&&e.series.push({name:n,max:l,type:"gauge",radius:"100%",detail:{formatter:"{value}",show:!1,valueAnimation:!0},data:[{value:s,name:n}],pointer:{show:!1},splitLine:{show:!1},axisTick:{show:!1},axisLine:{show:!0,lineStyle:{width:4}},progress:{show:!0,width:4,itemStyle:{color:c,opacity:.3}},splitNumber:{show:!1},title:{show:!1},startAngle:270,endAngle:-90}),t.setOption(e)}},xRotation:function(t,e){t=t.getWidth();let n=0;return e.forEach(function(t){n+=10*t.length}),n<=t?null:[40,-20]},chartMap:{},initChart:function(t,e){"boolean"!=typeof e&&(e=!0);var n=t.getAttribute("id");if(null!=n&&0/g,">")).replace(/"/g,""")},chartColor:function(t){return t="green"==(t="blue"==(t="yellow"==(t="red"==(t=null!=t&&0!=t.length?t:"#5470c6")?"#ee6666":t)?"#fac858":t)?"#5470c6":t)?"#3ba272":t},DefaultChartColor:"#9DD3E8",validateIP:function(n){if("string"!=typeof n)return!1;if(0==n.length)return!1;if(0<=n.indexOf(":")){let t=n.split(":");if(8',document.body.appendChild(t),t.play().then(function(){setTimeout(function(){document.body.removeChild(t)},2e3)}).catch(function(t){console.log(t.message)})},convertSizeCapacityToBytes:function(t){if(null==t)return 0;switch(t.unit){case"byte":return t.count;case"kb":return 1024*t.count;case"mb":return t.count*Math.pow(1024,2);case"gb":return t.count*Math.pow(1024,3);case"tb":return t.count*Math.pow(1024,4);case"pb":return t.count*Math.pow(1024,5);case"eb":return t.count*Math.pow(1024,6)}return 0},compareSizeCapacity:function(t,e){t=this.convertSizeCapacityToBytes(t),e=this.convertSizeCapacityToBytes(e);return t==e?0:e=Math.pow(1024,6)?(o="E",n=Math.pow(1024,6)):t>=Math.pow(1024,5)?(o="P",n=Math.pow(1024,5)):t>=Math.pow(1024,4)?(o="T",n=Math.pow(1024,4)):t>=Math.pow(1024,3)?(o="G",n=Math.pow(1024,3)):t>=Math.pow(1024,2)?(o="M",n=Math.pow(1024,2)):t>=Math.pow(1024,1)&&(o="K",n=Math.pow(1024,1)),{unit:o,divider:n}},bitsAxis:function(t,e){t=this.bytesAxis(t,e);let n=t.unit;return"B"==n?n="bps":n+="bps",{unit:n,divider:t.divider}},countAxis:function(t,e){t=Math.max.apply(this,t.map(e));let n=1,o="";return 1e9<=t?(o="B",n=1e9):1e6<=t?(o="M",n=1e6):1e3<=t&&(o="K",n=1e3),{unit:o,divider:n,max:t}},splitFormat:function(t){t=t.match(/^([0-9.]+)([a-zA-Z]+)$/);return[parseFloat(t[1]),t[2]]},popup:function(t,e){null!=t&&0',width:n,padding:"0.5em",showConfirmButton:!1,showCloseButton:!0,focusConfirm:!1,onClose:function(t){"function"==typeof e.onClose&&e.onClose.apply(Tea.Vue,arguments)}})},popupSuccess:function(t,e,n){let o={};null!=e&&(o.width=e),null!=n&&(o.height=n),o.callback=function(){teaweb.success("保存成功",function(){teaweb.reload()})},this.popup(t,o)},popupFinish:function(){null!=window.POPUP_CALLBACK&&window.POPUP_CALLBACK.apply(window,arguments)},popupTip:function(t){Swal.fire({html:'
'+t+"
",width:"34em",padding:"4em",showConfirmButton:!1,showCloseButton:!0,focusConfirm:!1})},isPopup:function(){var t=window.location.hash;return null!=t&&t.startsWith("#popup")},closePopup:function(){this.isPopup()&&window.parent.Swal.close()},Swal:function(){return(this.isPopup()?window.parent:window).Swal},hasPopup:function(){return 0{b} : {c}"+u},series:[{name:r,max:l,type:"gauge",radius:"100%",detail:{formatter:"{value}",show:!1,valueAnimation:!0},data:[{value:a,name:r}],pointer:{show:!1},splitLine:{show:!1},axisTick:{show:!1},axisLine:{show:!0,lineStyle:{width:4}},progress:{show:!0,width:4,itemStyle:{color:i}},splitNumber:{show:!1},title:{show:!1},startAngle:270,endAngle:-90}]};null!=s&&e.series.push({name:n,max:l,type:"gauge",radius:"100%",detail:{formatter:"{value}",show:!1,valueAnimation:!0},data:[{value:s,name:n}],pointer:{show:!1},splitLine:{show:!1},axisTick:{show:!1},axisLine:{show:!0,lineStyle:{width:4}},progress:{show:!0,width:4,itemStyle:{color:c,opacity:.3}},splitNumber:{show:!1},title:{show:!1},startAngle:270,endAngle:-90}),t.setOption(e)}},xRotation:function(t,e){t=t.getWidth();let n=0;return e.forEach(function(t){n+=10*t.length}),n<=t?null:[40,-20]},chartMap:{},initChart:function(t,e){"boolean"!=typeof e&&(e=!0);var n=t.getAttribute("id");if(null!=n&&0/g,">")).replace(/"/g,""")},chartColor:function(t){return t="green"==(t="blue"==(t="yellow"==(t="red"==(t=null!=t&&0!=t.length?t:"#5470c6")?"#ee6666":t)?"#fac858":t)?"#5470c6":t)?"#3ba272":t},DefaultChartColor:"#9DD3E8",validateIP:function(n){if("string"!=typeof n)return!1;if(0==n.length)return!1;if(0<=n.indexOf(":")){let t=n.split(":");if(8',document.body.appendChild(t),t.play().then(function(){setTimeout(function(){document.body.removeChild(t)},2e3)}).catch(function(t){console.log(t.message)})},convertSizeCapacityToBytes:function(t){if(null==t)return 0;switch(t.unit){case"byte":return t.count;case"kb":return 1024*t.count;case"mb":return t.count*Math.pow(1024,2);case"gb":return t.count*Math.pow(1024,3);case"tb":return t.count*Math.pow(1024,4);case"pb":return t.count*Math.pow(1024,5);case"eb":return t.count*Math.pow(1024,6)}return 0},compareSizeCapacity:function(t,e){t=this.convertSizeCapacityToBytes(t),e=this.convertSizeCapacityToBytes(e);return t==e?0:e磁盘预估写入最大速度 -> {{node.status.diskWritingSpeedMB}} - MB/s 极快 - MB/s 快 - MB/s 一般 + MiB/s 极快 + MiB/s 快 + MiB/s 一般 diff --git a/web/views/@default/servers/components/cache/createPopup.html b/web/views/@default/servers/components/cache/createPopup.html index 81e1ac91..5bb76ec7 100644 --- a/web/views/@default/servers/components/cache/createPopup.html +++ b/web/views/@default/servers/components/cache/createPopup.html @@ -67,7 +67,7 @@ 缓存磁盘最小空余空间 -

缓存磁盘保留的最小空余空间,如果为0表示自动限制(目前默认保留5GB)。

+

缓存磁盘保留的最小空余空间,如果为0表示自动限制(目前默认保留5GiB)。

diff --git a/web/views/@default/servers/components/cache/update.html b/web/views/@default/servers/components/cache/update.html index bf7f17de..2e89576c 100644 --- a/web/views/@default/servers/components/cache/update.html +++ b/web/views/@default/servers/components/cache/update.html @@ -74,7 +74,7 @@ 缓存磁盘最小空余空间 -

缓存磁盘保留的最小空余空间,如果为0表示使用默认(目前默认保留5GB)。

+

缓存磁盘保留的最小空余空间,如果为0表示使用默认(目前默认保留5GiB)。

diff --git a/web/views/@default/users/update.html b/web/views/@default/users/update.html index edf002ce..0161a64f 100644 --- a/web/views/@default/users/update.html +++ b/web/views/@default/users/update.html @@ -89,7 +89,7 @@

按在计时时间段内(5分钟)最高带宽峰值计算,比如5分钟内最高的某个时间点带宽为100Mbps,那么就认为此时间段内的峰值带宽为100Mbps。

-

按在计时时间段内(5分钟)平均带宽计算,即此时间段内的总流量除以时间段的秒数,比如5分钟(300秒)内总流量600MB,那么带宽即为600MB * 8bit/300s = 16Mbps;通常平均带宽算法要比峰值带宽要少很多。

+

按在计时时间段内(5分钟)平均带宽计算,即此时间段内的总流量除以时间段的秒数,比如5分钟(300秒)内总流量600MiB,那么带宽即为600MiB * 8bit/300s = 16Mbps;通常平均带宽算法要比峰值带宽要少很多。