diff --git a/web/public/js/components.js b/web/public/js/components.js index 41e691f1..8c95ea4a 100644 --- a/web/public/js/components.js +++ b/web/public/js/components.js @@ -1095,6 +1095,7 @@ Vue.component("traffic-map-box",{props:["v-stats","v-is-attack"],mounted:functio 带宽百分位:{{config.percentile}}th没有设置   |   基础带宽价格:{{config.base}}元/Mbps没有设置   |   阶梯价格:{{config.ranges.length}}段没有设置   |  支持区域带宽计费 +  |  使用平均带宽算法
修改
@@ -1134,6 +1135,17 @@ 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;通常平均带宽算法要比峰值带宽要少很多。修改此选项会同时影响到用量统计图表。

+ + `}),Vue.component("plan-traffic-ranges",{props:["value"],data:function(){let e=this.value;return{ranges:e=null==e?[]:e,isAdding:!1,minGB:"",minGBUnit:"gb",maxGB:"",maxGBUnit:"gb",pricePerGB:"",totalPrice:"",addingRange:{minGB:0,maxGB:0,pricePerGB:0,totalPrice:0}}},methods:{add:function(){this.isAdding=!this.isAdding;let e=this;setTimeout(function(){e.$refs.minGB.focus()})},cancelAdding:function(){this.isAdding=!1},confirm:function(){this.addingRange.minGB<0?teaweb.warn("流量下限需要大于0"):this.addingRange.maxGB<0?teaweb.warn("流量上限需要大于0"):this.addingRange.pricePerGB<=0&&this.addingRange.totalPrice<=0?teaweb.warn("请设置单位价格或者总价格"):(this.isAdding=!1,this.minGB="",this.maxGB="",this.pricePerGB="",this.totalPrice="",this.ranges.push(this.addingRange),this.ranges.$sort(function(e,t){return e.minGB @@ -1511,7 +1523,7 @@ Vue.component("traffic-map-box",{props:["v-stats","v-is-attack"],mounted:functio | {{paramFilter.code}} - {{operatorName(rule.operator)}} + {{operatorName(rule.operator)}} {{rule.value}} [空] @@ -1687,7 +1699,10 @@ Vue.component("traffic-map-box",{props:["v-stats","v-is-attack"],mounted:functio {{condComponent.paramsTitle}} * - + + + +
@@ -1920,31 +1935,42 @@ 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{firewall:e=null==e?{isPrior:!1,isOn:!1,firewallPolicyId:0}: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;return{firewall:e=null==e?{isPrior:!1,isOn:!1,firewallPolicyId:0,ignoreGlobalRules:!1}:e,moreOptionsVisible:!1}},methods:{changeOptionsVisible:function(e){this.moreOptionsVisible=e}},template:`
+ + + + + + +
全局WAF策略 +
{{vFirewallPolicy.name}}   [{{vFirewallPolicy.modeInfo.name}}]  +

当前服务所在集群的设置。

+
+ 当前集群没有设置WAF策略,当前配置无法生效。 +
+ - - - - + + + + + + +
WAF策略 -
{{vFirewallPolicy.name}}   [{{vFirewallPolicy.modeInfo.name}}]  -

使用当前服务所在集群的设置。

-
- 当前集群没有设置WAF策略,当前配置无法生效。 -
启用WAF -
- - -
+

启用WAF之后,各项WAF设置才会生效。

不使用全局规则 + +

选中后,表示不使用系统全局WAF策略中定义的规则。

+
`}),Vue.component("metric-chart",{props:["v-chart","v-stats","v-item"],mounted:function(){this.load()},data:function(){let e=this.vStats;var t;0<(e=null==e?[]:e).length&&((t=e.$sum(function(e,t){return t.value}))"+n.valueTypeName+": "+i+"
占比:"+t+"%"}},series:[{name:name,type:"pie",data:t,areaStyle:{},color:["#9DD3E8","#B2DB9E","#F39494","#FBD88A","#879BD7"]}]})},renderTimeBar:function(e){this.stats.$sort(function(e,t){return e.time"+a.valueTypeName+":"+i+"
占比:"+t+"%"}},yAxis:{axisLabel:{formatter:function(e){return e+i.unit}}},grid:{left:40,top:10,right:20,bottom:n},series:[{name:name,type:"bar",data:t.map(function(e){return e/i.divider}),itemStyle:{color:teaweb.DefaultChartColor},areaStyle:{},barWidth:"20em"}]}),null!=this.item.keys&&this.item.keys.$contains("${remoteAddr}")){let i=this;e.on("click",function(e){var t=i.item.keys.$indexesOf("${remoteAddr}")[0],e=i.stats[e.dataIndex].keys[t];teaweb.popup("/servers/ipbox?ip="+e,{width:"50em",height:"30em"})})}},renderTable:function(e){let n=` @@ -2138,7 +2164,7 @@ Vue.component("traffic-map-box",{props:["v-stats","v-is-attack"],mounted:functio 分表{{p.code+1}}       |
-`}),Vue.component("http-cache-refs-config-box",{props:["v-cache-refs","v-cache-config","v-cache-policy-id","v-web-id"],mounted:function(){let n=this;sortTable(function(e){let i=[];e.forEach(function(t){n.refs.forEach(function(e){e.id==t&&i.push(e)})}),n.updateRefs(i),n.change()})},data:function(){let e=this.vCacheRefs,t=(null==e&&(e=[]),0);return e.forEach(function(e){t++,e.id=t}),{refs:e,id:t}},methods:{addRef:function(e){window.UPDATING_CACHE_REF=null;let t=window.innerHeight,s=(500 +`}),Vue.component("http-cache-refs-config-box",{props:["v-cache-refs","v-cache-config","v-cache-policy-id","v-web-id"],mounted:function(){let n=this;sortTable(function(e){let i=[];e.forEach(function(t){n.refs.forEach(function(e){e.id==t&&i.push(e)})}),n.updateRefs(i),n.change()})},data:function(){let e=this.vCacheRefs,t=(null==e&&(e=[]),0);return e.forEach(function(e){t++,e.id=t}),{refs:e,id:t}},methods:{addRef:function(e){window.UPDATING_CACHE_REF=null;let t=window.innerHeight,s=(500
@@ -2433,7 +2459,7 @@ Vue.component("traffic-map-box",{props:["v-stats","v-is-attack"],mounted:functio
`}),Vue.component("firewall-syn-flood-config-viewer",{props:["v-syn-flood-config"],data:function(){let e=this.vSynFloodConfig;return{config:e=null==e?{isOn:!1,minAttempts:10,timeoutSeconds:600,ignoreLocal:!0}:e}},template:`
- 已启用 / 空连接次数:{{config.minAttempts}}次/分钟 / 封禁时间:{{config.timeoutSeconds}}秒 / 忽略局域网访问 + 已启用 / 空连接次数:{{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:`
@@ -2485,7 +2511,7 @@ example2.com
-
`}),Vue.component("http-referers-config-box",{props:["v-referers-config","v-is-location","v-is-group"],data:function(){let e=this.vReferersConfig;return null==(e=null==e?{isPrior:!1,isOn:!1,allowEmpty:!0,allowSameDomain:!0,allowDomains:[],denyDomains:[]}:e).allowDomains&&(e.allowDomains=[]),null==e.denyDomains&&(e.denyDomains=[]),{config:e}},methods:{isOn:function(){return(!this.vIsLocation&&!this.vIsGroup||this.config.isPrior)&&this.config.isOn},changeAllowDomains:function(e){},changeDenyDomains:function(e){}},template:`
+
`}),Vue.component("http-referers-config-box",{props:["v-referers-config","v-is-location","v-is-group"],data:function(){let e=this.vReferersConfig;return null==(e=null==e?{isPrior:!1,isOn:!1,allowEmpty:!0,allowSameDomain:!0,allowDomains:[],denyDomains:[]}:e).allowDomains&&(e.allowDomains=[]),null==e.denyDomains&&(e.denyDomains=[]),{config:e}},methods:{isOn:function(){return(!this.vIsLocation&&!this.vIsGroup||this.config.isPrior)&&this.config.isOn},changeAllowDomains:function(e){"object"==typeof e&&(this.config.allowDomains=e,this.$forceUpdate())},changeDenyDomains:function(e){"object"==typeof e&&(this.config.denyDomains=e,this.$forceUpdate())}},template:`
@@ -2637,14 +2663,14 @@ example2.com

403 Forbidden

Request ID: \${requestId}.
-`;return{id:t,actions:this.vActions,configs:e,isAdding:!1,editingIndex:-1,action:null,actionCode:"",actionOptions:{},ipListLevels:[],blockTimeout:"",blockScope:"global",captchaLife:"",captchaMaxFails:"",captchaFailBlockTimeout:"",get302Life:"",post307Life:"",recordIPType:"black",recordIPLevel:"critical",recordIPTimeout:"",recordIPListId:0,recordIPListName:"",tagTags:[],pageStatus:403,pageBody:i,defaultPageBody:i,goGroupName:"",goGroupId:0,goGroup:null,goSetId:0,goSetName:"",jsCookieLife:"",jsCookieMaxFails:"",jsCookieFailBlockTimeout:""}},watch:{actionCode:function(i){this.action=this.actions.$find(function(e,t){return t.code==i}),this.actionOptions={}},blockTimeout:function(e){e=parseInt(e),isNaN(e)?this.actionOptions.timeout=0:this.actionOptions.timeout=e},blockScope:function(e){this.actionOptions.scope=e},captchaLife:function(e){e=parseInt(e),isNaN(e)?this.actionOptions.life=0:this.actionOptions.life=e},captchaMaxFails:function(e){e=parseInt(e),isNaN(e)?this.actionOptions.maxFails=0:this.actionOptions.maxFails=e},captchaFailBlockTimeout:function(e){e=parseInt(e),isNaN(e)?this.actionOptions.failBlockTimeout=0:this.actionOptions.failBlockTimeout=e},get302Life:function(e){e=parseInt(e),isNaN(e)?this.actionOptions.life=0:this.actionOptions.life=e},post307Life:function(e){e=parseInt(e),isNaN(e)?this.actionOptions.life=0:this.actionOptions.life=e},recordIPType:function(e){this.recordIPListId=0},recordIPTimeout:function(e){e=parseInt(e),isNaN(e)?this.actionOptions.timeout=0:this.actionOptions.timeout=e},goGroupId:function(i){var e=this.vFirewallPolicy.inbound.groups.$find(function(e,t){return t.id==i});this.goGroup=e,this.goGroupName=null==e?"":e.name,this.goSetId=0,this.goSetName=""},goSetId:function(i){var e;null!=this.goGroup&&(null==(e=this.goGroup.sets.$find(function(e,t){return t.id==i}))?(this.goSetId=0,this.goSetName=""):this.goSetName=e.name)},jsCookieLife:function(e){e=parseInt(e),isNaN(e)?this.actionOptions.life=0:this.actionOptions.life=e},jsCookieMaxFails:function(e){e=parseInt(e),isNaN(e)?this.actionOptions.maxFails=0:this.actionOptions.maxFails=e},jsCookieFailBlockTimeout:function(e){e=parseInt(e),isNaN(e)?this.actionOptions.failBlockTimeout=0:this.actionOptions.failBlockTimeout=e}},methods:{add:function(){this.action=null,this.actionCode="block",this.isAdding=!0,this.actionOptions={},this.blockTimeout="",this.blockScope="global",this.captchaLife="",this.captchaMaxFails="",this.captchaFailBlockTimeout="",this.jsCookieLife="",this.jsCookieMaxFails="",this.jsCookieFailBlockTimeout="",this.get302Life="",this.post307Life="",this.recordIPLevel="critical",this.recordIPType="black",this.recordIPTimeout="",this.recordIPListId=0,this.recordIPListName="",this.tagTags=[],this.pageStatus=403,this.pageBody=this.defaultPageBody,this.goGroupName="",this.goGroupId=0,this.goGroup=null,this.goSetId=0,this.goSetName="";let i=this;this.action=this.vActions.$find(function(e,t){return t.code==i.actionCode}),this.scroll()},remove:function(e){this.isAdding=!1,this.editingIndex=-1,this.configs.$remove(e)},update:function(e,i){if(this.isAdding&&this.editingIndex==e)this.cancel();else{switch(this.add(),this.isAdding=!0,this.editingIndex=e,this.actionCode=i.code,i.code){case"block":this.blockTimeout="",(null!=i.options.timeout||0 +`;return{id:t,actions:this.vActions,configs:e,isAdding:!1,editingIndex:-1,action:null,actionCode:"",actionOptions:{},ipListLevels:[],blockTimeout:"",blockTimeoutMax:"",blockScope:"global",captchaLife:"",captchaMaxFails:"",captchaFailBlockTimeout:"",get302Life:"",post307Life:"",recordIPType:"black",recordIPLevel:"critical",recordIPTimeout:"",recordIPListId:0,recordIPListName:"",tagTags:[],pageStatus:403,pageBody:i,defaultPageBody:i,goGroupName:"",goGroupId:0,goGroup:null,goSetId:0,goSetName:"",jsCookieLife:"",jsCookieMaxFails:"",jsCookieFailBlockTimeout:""}},watch:{actionCode:function(i){this.action=this.actions.$find(function(e,t){return t.code==i}),this.actionOptions={}},blockTimeout:function(e){e=parseInt(e),isNaN(e)?this.actionOptions.timeout=0:this.actionOptions.timeout=e},blockTimeoutMax:function(e){e=parseInt(e),isNaN(e)?this.actionOptions.timeoutMax=0:this.actionOptions.timeoutMax=e},blockScope:function(e){this.actionOptions.scope=e},captchaLife:function(e){e=parseInt(e),isNaN(e)?this.actionOptions.life=0:this.actionOptions.life=e},captchaMaxFails:function(e){e=parseInt(e),isNaN(e)?this.actionOptions.maxFails=0:this.actionOptions.maxFails=e},captchaFailBlockTimeout:function(e){e=parseInt(e),isNaN(e)?this.actionOptions.failBlockTimeout=0:this.actionOptions.failBlockTimeout=e},get302Life:function(e){e=parseInt(e),isNaN(e)?this.actionOptions.life=0:this.actionOptions.life=e},post307Life:function(e){e=parseInt(e),isNaN(e)?this.actionOptions.life=0:this.actionOptions.life=e},recordIPType:function(e){this.recordIPListId=0},recordIPTimeout:function(e){e=parseInt(e),isNaN(e)?this.actionOptions.timeout=0:this.actionOptions.timeout=e},goGroupId:function(i){var e=this.vFirewallPolicy.inbound.groups.$find(function(e,t){return t.id==i});this.goGroup=e,this.goGroupName=null==e?"":e.name,this.goSetId=0,this.goSetName=""},goSetId:function(i){var e;null!=this.goGroup&&(null==(e=this.goGroup.sets.$find(function(e,t){return t.id==i}))?(this.goSetId=0,this.goSetName=""):this.goSetName=e.name)},jsCookieLife:function(e){e=parseInt(e),isNaN(e)?this.actionOptions.life=0:this.actionOptions.life=e},jsCookieMaxFails:function(e){e=parseInt(e),isNaN(e)?this.actionOptions.maxFails=0:this.actionOptions.maxFails=e},jsCookieFailBlockTimeout:function(e){e=parseInt(e),isNaN(e)?this.actionOptions.failBlockTimeout=0:this.actionOptions.failBlockTimeout=e}},methods:{add:function(){this.action=null,this.actionCode="block",this.isAdding=!0,this.actionOptions={},this.blockTimeout="",this.blockTimeoutMax="",this.blockScope="global",this.captchaLife="",this.captchaMaxFails="",this.captchaFailBlockTimeout="",this.jsCookieLife="",this.jsCookieMaxFails="",this.jsCookieFailBlockTimeout="",this.get302Life="",this.post307Life="",this.recordIPLevel="critical",this.recordIPType="black",this.recordIPTimeout="",this.recordIPListId=0,this.recordIPListName="",this.tagTags=[],this.pageStatus=403,this.pageBody=this.defaultPageBody,this.goGroupName="",this.goGroupId=0,this.goGroup=null,this.goSetId=0,this.goSetName="";let i=this;this.action=this.vActions.$find(function(e,t){return t.code==i.actionCode}),this.scroll()},remove:function(e){this.isAdding=!1,this.editingIndex=-1,this.configs.$remove(e)},update:function(e,i){if(this.isAdding&&this.editingIndex==e)this.cancel();else{switch(this.add(),this.isAdding=!0,this.editingIndex=e,this.actionCode=i.code,i.code){case"block":this.blockTimeout="",this.blockTimeoutMax="",(null!=i.options.timeout||0
{{config.name}} ({{config.code.toUpperCase()}}) - :有效期{{config.options.timeout}}秒 + :封禁时长{{config.options.timeout}}-{{config.options.timeoutMax}} :有效期{{config.options.life}}秒 @@ -2703,7 +2729,18 @@ example2.com
- + + + + + - + @@ -3479,7 +3515,7 @@ example2.com `});var punycode=new function(){this.utf16={decode:function(e){for(var t,i,n=[],s=0,o=e.length;s>>10&1023|55296)),t=56320|1023&t),i.push(String.fromCharCode(t))}return i.join("")}};var b=2147483647;function y(e,t){return e+22+75*(e<26)-((0!=t)<<5)}function x(e,t,i){var n;for(e=i?Math.floor(e/700):e>>1,e+=Math.floor(e/t),n=0;455= 0x80");d.push(e.charCodeAt(n))}for(s=0Math.floor((b-m)/a))throw RangeError("punycode_overflow(1)");if(m+=r*a,r<(r=l<=v?1:v+26<=l?26:l-v))break;if(a>Math.floor(b/(36-r)))throw RangeError("punycode_overflow(2)");a*=36-r}if(v=x(m-o,i=d.length+1,0===o),Math.floor(m/i)>b-h)throw RangeError("punycode_overflow(3)");h+=Math.floor(m/i),m%=i,t&&p.splice(m,0,e.charCodeAt(s-1)-65<26),d.splice(m,0,h),m++}if(t)for(m=0,c=d.length;mMath.floor((b-v)/(i+1)))throw RangeError("punycode_overflow (1)");for(v+=(s-m)*(i+1),m=s,g=0;gb)return Error("punycode_overflow(2)");if(c==m){for(o=v,a=36;!(o<(l=a<=f?1:f+26<=a?26:a-f));a+=36)h.push(String.fromCharCode(y(l+(o-l)%(36-l),0))),o=Math.floor((o-l)/(36-l));h.push(String.fromCharCode(y(o,t&&r[g]?1:0))),f=x(v,i+1,i==n),v=0,++i}}++v,++m}return h.join("")},this.ToASCII=function(e){for(var t=e.split("."),i=[],n=0;n 默认设置
- 状态码:{{options.statusCode}} / 提示内容:[{{options.body.length}}字符][无] / 超时时间:{{options.timeout}}秒 + 状态码:{{options.statusCode}} / 提示内容:[{{options.body.length}}字符][无] / 超时时间:{{options.timeout}}秒 / 最大封禁时长:{{options.timeoutMax}}秒
`}),Vue.component("http-access-log-config-box",{props:["v-access-log-config","v-fields","v-default-field-codes","v-is-location","v-is-group"],data:function(){let t=this,i=(setTimeout(function(){t.changeFields()},100),{isPrior:!1,isOn:!1,fields:[1,2,6,7],status1:!0,status2:!0,status3:!0,status4:!0,status5:!0,firewallOnly:!1,enableClientClosed:!1});return null!=this.vAccessLogConfig&&(i=this.vAccessLogConfig),this.vFields.forEach(function(e){null==t.vAccessLogConfig?e.isChecked=t.vDefaultFieldCodes.$contains(e.code):e.isChecked=i.fields.$contains(e.code)}),{accessLog:i,hasRequestBodyField:this.vFields.$contains(8),showAdvancedOptions:!1}},methods:{changeFields:function(){this.accessLog.fields=this.vFields.filter(function(e){return e.isChecked}).map(function(e){return e.code}),this.hasRequestBodyField=this.accessLog.fields.$contains(8)},changeAdvanced:function(e){this.showAdvancedOptions=e}},template:`
@@ -4201,9 +4237,11 @@ example2.com
封锁时间封禁范围 + +

只封禁用户对当前网站服务的访问,其他服务不受影响。

+

封禁用户对所有网站服务的访问。

+
封禁时长
@@ -2712,14 +2749,13 @@ example2.com
封锁范围最大封禁时长 - -

只封锁用户对当前网站服务的访问,其他服务不受影响。

-

封锁用户对所有网站服务的访问。

+
+ + +
+

选填项。如果同时填写了封禁时长和最大封禁时长,则会在两者之间随机选择一个数字作为最终的封禁时长。

-
`}),Vue.component("http-firewall-block-options",{props:["v-block-options"],data:function(){return{blockOptions:this.vBlockOptions,statusCode:this.vBlockOptions.statusCode,timeout:this.vBlockOptions.timeout,isEditing:!1}},watch:{statusCode:function(e){e=parseInt(e);isNaN(e)?this.blockOptions.statusCode=403:this.blockOptions.statusCode=e},timeout:function(e){e=parseInt(e);isNaN(e)?this.blockOptions.timeout=0:this.blockOptions.timeout=e}},methods:{edit:function(){this.isEditing=!this.isEditing}},template:`
+
`}),Vue.component("http-firewall-block-options",{props:["v-block-options"],data:function(){return{blockOptions:this.vBlockOptions,statusCode:this.vBlockOptions.statusCode,timeout:this.vBlockOptions.timeout,timeoutMax:this.vBlockOptions.timeoutMax,isEditing:!1}},watch:{statusCode:function(e){e=parseInt(e);isNaN(e)?this.blockOptions.statusCode=403:this.blockOptions.statusCode=e},timeout:function(e){e=parseInt(e);isNaN(e)?this.blockOptions.timeout=0:this.blockOptions.timeout=e},timeoutMax:function(e){e=parseInt(e);isNaN(e)?this.blockOptions.timeoutMax=0:this.blockOptions.timeoutMax=e}},methods:{edit:function(){this.isEditing=!this.isEditing}},template:`
- 状态码:{{statusCode}} / 提示内容:[{{blockOptions.body.length}}字符][无] / 超时时间:{{timeout}}秒 + 状态码:{{statusCode}} / 提示内容:[{{blockOptions.body.length}}字符][无] / 封禁时长:{{timeout}}秒 + / 最大封禁时长:{{timeoutMax}}秒 + @@ -4218,13 +4256,23 @@ example2.com - + + + + +
状态码
超时时间封禁时长
-

触发阻止动作时,封锁客户端IP的时间。

+

触发阻止动作时,封禁客户端IP的时间。

+
最大封禁时长 +
+ + +
+

如果最大封禁时长大于封禁时长({{timeout}}秒),那么表示每次封禁的时候,将会在这两个时长数字之间随机选取一个数字作为最终的封禁时长。

@@ -4257,7 +4305,7 @@ example2.com - | {{paramFilter.code}} {{operatorName(rule.operator)}} + | {{paramFilter.code}} {{operatorName(rule.operator)}} {{rule.value}} [空] @@ -4327,7 +4375,7 @@ example2.com
-
`}),Vue.component("http-cond-url-extension",{props:["v-cond"],data:function(){let e={isRequest:!0,param:"${requestPathExtension}",operator:"in",value:"[]"},t=(null!=this.vCond&&this.vCond.param==e.param&&(e.value=this.vCond.value),[]);try{t=JSON.parse(e.value)}catch(e){}return{cond:e,extensions:t,isAdding:!1,addingExt:""}},watch:{extensions:function(){this.cond.value=JSON.stringify(this.extensions)}},methods:{addExt:function(){if(this.isAdding=!this.isAdding,this.isAdding){let e=this;setTimeout(function(){e.$refs.addingExt.focus()},100)}},cancelAdding:function(){this.isAdding=!1,this.addingExt=""},confirmAdding:function(){0!=this.addingExt.length&&("."!=this.addingExt[0]&&(this.addingExt="."+this.addingExt),this.addingExt=this.addingExt.replace(/\s+/g,"").toLowerCase(),this.extensions.push(this.addingExt),this.cancelAdding())},removeExt:function(e){this.extensions.$remove(e)}},template:`
+
`}),Vue.component("http-cond-url-extension",{props:["v-cond"],data:function(){let e={isRequest:!0,param:"${requestPathLowerExtension}",operator:"in",value:"[]"},t=(null!=this.vCond&&this.vCond.param==e.param&&(e.value=this.vCond.value),[]);try{t=JSON.parse(e.value)}catch(e){}return{cond:e,extensions:t,isAdding:!1,addingExt:""}},watch:{extensions:function(){this.cond.value=JSON.stringify(this.extensions)}},methods:{addExt:function(){if(this.isAdding=!this.isAdding,this.isAdding){let e=this;setTimeout(function(){e.$refs.addingExt.focus()},100)}},cancelAdding:function(){this.isAdding=!1,this.addingExt=""},confirmAdding:function(){0!=this.addingExt.length&&("."!=this.addingExt[0]&&(this.addingExt="."+this.addingExt),this.addingExt=this.addingExt.replace(/\s+/g,"").toLowerCase(),this.extensions.push(this.addingExt),this.cancelAdding())},removeExt:function(e){this.extensions.$remove(e)}},template:`
{{ext}}
@@ -4346,7 +4394,7 @@ example2.com

扩展名需要包含点(.)符号,例如.jpg.png之类。

-
`}),Vue.component("http-cond-url-not-extension",{props:["v-cond"],data:function(){let e={isRequest:!0,param:"${requestPathExtension}",operator:"not in",value:"[]"},t=(null!=this.vCond&&this.vCond.param==e.param&&(e.value=this.vCond.value),[]);try{t=JSON.parse(e.value)}catch(e){}return{cond:e,extensions:t,isAdding:!1,addingExt:""}},watch:{extensions:function(){this.cond.value=JSON.stringify(this.extensions)}},methods:{addExt:function(){if(this.isAdding=!this.isAdding,this.isAdding){let e=this;setTimeout(function(){e.$refs.addingExt.focus()},100)}},cancelAdding:function(){this.isAdding=!1,this.addingExt=""},confirmAdding:function(){0!=this.addingExt.length&&("."!=this.addingExt[0]&&(this.addingExt="."+this.addingExt),this.addingExt=this.addingExt.replace(/\s+/g,"").toLowerCase(),this.extensions.push(this.addingExt),this.cancelAdding())},removeExt:function(e){this.extensions.$remove(e)}},template:`
+
`}),Vue.component("http-cond-url-not-extension",{props:["v-cond"],data:function(){let e={isRequest:!0,param:"${requestPathLowerExtension}",operator:"not in",value:"[]"},t=(null!=this.vCond&&this.vCond.param==e.param&&(e.value=this.vCond.value),[]);try{t=JSON.parse(e.value)}catch(e){}return{cond:e,extensions:t,isAdding:!1,addingExt:""}},watch:{extensions:function(){this.cond.value=JSON.stringify(this.extensions)}},methods:{addExt:function(){if(this.isAdding=!this.isAdding,this.isAdding){let e=this;setTimeout(function(){e.$refs.addingExt.focus()},100)}},cancelAdding:function(){this.isAdding=!1,this.addingExt=""},confirmAdding:function(){0!=this.addingExt.length&&("."!=this.addingExt[0]&&(this.addingExt="."+this.addingExt),this.addingExt=this.addingExt.replace(/\s+/g,"").toLowerCase(),this.extensions.push(this.addingExt),this.cancelAdding())},removeExt:function(e){this.extensions.$remove(e)}},template:`
{{ext}}
@@ -4422,21 +4470,19 @@ example2.com

服务器返回的内容的MimeType,比如text/htmlimage/*等。

`}),Vue.component("http-cond-params",{props:["v-cond"],mounted:function(){let i=this.vCond;if(null!=i)if(this.operator=i.operator,["regexp","not regexp","eq","not","prefix","suffix","contains","not contains","eq ip","gt ip","gte ip","lt ip","lte ip","ip range"].$contains(i.operator))this.stringValue=i.value;else if(["eq int","eq float","gt","gte","lt","lte","mod 10","ip mod 10","mod 100","ip mod 100"].$contains(i.operator))this.numberValue=i.value;else{var e;if(["mod","ip mod"].$contains(i.operator))return e=i.value.split(","),this.modDivValue=e[0],void(1 - 参数值 + 参数值
-
-
- -
-
- -
-
+
+ +
+
+ +

其中可以使用变量,类似于\${requestPath},也可以是多个变量的组合。

@@ -4539,7 +4585,8 @@ example2.com

选中后表示对比时忽略参数值的大小写。

-`}),Vue.component("http-status-box",{props:["v-status-list"],data:function(){let e=this.vStatusList;return{statusList:e=null==e?[]:e,isAdding:!1,addingStatus:""}},methods:{add:function(){this.isAdding=!0;let e=this;setTimeout(function(){e.$refs.addingStatus.focus()},100)},confirm:function(){let e=this;this.addingStatus=this.addingStatus.replace(/\s/g,"").toUpperCase(),0==this.addingStatus.length?teaweb.warn("请输入要添加的状态码",function(){e.$refs.addingStatus.focus()}):this.statusList.$contains(this.addingStatus)?teaweb.warn("此状态码已经存在,无需重复添加",function(){e.$refs.addingStatus.focus()}):this.addingStatus.match(/^\d{3}$/)?(this.statusList.push(parseInt(this.addingStatus,10)),this.cancel()):teaweb.warn("请输入正确的状态码",function(){e.$refs.addingStatus.focus()})},remove:function(e){this.statusList.$remove(e)},cancel:function(){this.isAdding=!1,this.addingStatus=""}},template:`
+ +`}),Vue.component("http-status-box",{props:["v-status-list"],data:function(){let e=this.vStatusList;return{statusList:e=null==e?[]:e,isAdding:!1,addingStatus:""}},methods:{add:function(){this.isAdding=!0;let e=this;setTimeout(function(){e.$refs.addingStatus.focus()},100)},confirm:function(){let e=this;this.addingStatus=this.addingStatus.replace(/\s/g,"").toUpperCase(),0==this.addingStatus.length?teaweb.warn("请输入要添加的状态码",function(){e.$refs.addingStatus.focus()}):this.statusList.$contains(this.addingStatus)?teaweb.warn("此状态码已经存在,无需重复添加",function(){e.$refs.addingStatus.focus()}):this.addingStatus.match(/^\d{3}$/)?(this.statusList.push(parseInt(this.addingStatus,10)),this.cancel()):teaweb.warn("请输入正确的状态码",function(){e.$refs.addingStatus.focus()})},remove:function(e){this.statusList.$remove(e)},cancel:function(){this.isAdding=!1,this.addingStatus=""}},template:`
@@ -4837,7 +4884,7 @@ example2.com - 已启用 / 空连接次数:{{config.minAttempts}}次/分钟 / 封禁时间:{{config.timeoutSeconds}}秒 / 忽略局域网访问 + 已启用 / 空连接次数:{{config.minAttempts}}次/分钟 / 封禁时长:{{config.timeoutSeconds}}秒 / 忽略局域网访问 未启用 @@ -4862,7 +4909,7 @@ example2.com - 封禁时间 + 封禁时长
@@ -5101,7 +5148,7 @@ example2.com 更多选项收起选项 -`}),Vue.component("download-link",{props:["v-element","v-file","v-value"],created:function(){let e=this;setTimeout(function(){e.url=e.composeURL()},1e3)},data:function(){let e=this.vFile;return{file:e=null!=e&&0!=e.length?e:"unknown-file",url:this.composeURL()}},methods:{composeURL:function(){let e="";if(null!=this.vValue)e=this.vValue;else{var t=document.getElementById(this.vElement);if(null==t)return;null==(e=t.innerText)&&(e=t.textContent)}return Tea.url("/ui/download",{file:this.file,text:e})}},template:''}),Vue.component("values-box",{props:["values","v-values","size","maxlength","name","placeholder","v-allow-empty"],data:function(){let e=this.values;return null==e&&(e=[]),{realValues:e=null!=this.vValues&&"object"==typeof this.vValues?this.vValues:e,isUpdating:!1,isAdding:!1,index:0,value:"",isEditing:!1}},methods:{create:function(){this.isAdding=!0;var e=this;setTimeout(function(){e.$refs.value.focus()},200)},update:function(e){this.cancel(),this.isUpdating=!0,this.index=e,this.value=this.realValues[e];var t=this;setTimeout(function(){t.$refs.value.focus()},200)},confirm:function(){(0!=this.value.length||"boolean"==typeof this.vAllowEmpty&&this.vAllowEmpty)&&(this.isUpdating?Vue.set(this.realValues,this.index,this.value):this.realValues.push(this.value),this.cancel(),this.$emit("change",this.realValues))},remove:function(e){this.realValues.$remove(e),this.$emit("change",this.realValues)},cancel:function(){this.isUpdating=!1,this.isAdding=!1,this.value=""},updateAll:function(e){this.realValues=e},addValue:function(e){this.realValues.push(e)},startEditing:function(){this.isEditing=!this.isEditing},allValues:function(){return this.realValues}},template:`
+`}),Vue.component("download-link",{props:["v-element","v-file","v-value"],created:function(){let e=this;setTimeout(function(){e.url=e.composeURL()},1e3)},data:function(){let e=this.vFile;return{file:e=null!=e&&0!=e.length?e:"unknown-file",url:this.composeURL()}},methods:{composeURL:function(){let e="";if(null!=this.vValue)e=this.vValue;else{var t=document.getElementById(this.vElement);if(null==t)return;null==(e=t.innerText)&&(e=t.textContent)}return Tea.url("/ui/download",{file:this.file,text:e})}},template:''}),Vue.component("values-box",{props:["values","v-values","size","maxlength","name","placeholder","v-allow-empty","validator"],data:function(){let e=this.values;return null==e&&(e=[]),{realValues:e=null!=this.vValues&&"object"==typeof this.vValues?this.vValues:e,isUpdating:!1,isAdding:!1,index:0,value:"",isEditing:!1}},methods:{create:function(){this.isAdding=!0;var e=this;setTimeout(function(){e.$refs.value.focus()},200)},update:function(e){this.cancel(),this.isUpdating=!0,this.index=e,this.value=this.realValues[e];var t=this;setTimeout(function(){t.$refs.value.focus()},200)},confirm:function(){if(0!=this.value.length||"boolean"==typeof this.vAllowEmpty&&this.vAllowEmpty){if("function"==typeof this.validator){var t=this.validator.call(this,this.value);if("object"==typeof t&&"boolean"==typeof t.isOk&&!t.isOk){if("string"==typeof t.message){let e=this;teaweb.warn(t.message,function(){e.$refs.value.focus()})}return}}this.isUpdating?Vue.set(this.realValues,this.index,this.value):this.realValues.push(this.value),this.cancel(),this.$emit("change",this.realValues)}},remove:function(e){this.realValues.$remove(e),this.$emit("change",this.realValues)},cancel:function(){this.isUpdating=!1,this.isAdding=!1,this.value=""},updateAll:function(e){this.realValues=e},addValue:function(e){this.realValues.push(e)},startEditing:function(){this.isEditing=!this.isEditing},allValues:function(){return this.realValues}},template:`
{{value}} @@ -5151,7 +5198,11 @@ example2.com

常用时间:  1小时  |  1天  |  3天  |  1周  |  30天 

-
`}),Vue.component("label-on",{props:["v-is-on"],template:'
已启用已停用
'}),Vue.component("code-label",{methods:{click:function(e){this.$emit("click",e)}},template:''}),Vue.component("code-label-plain",{template:''}),Vue.component("tiny-label",{template:''}),Vue.component("tiny-basic-label",{template:''}),Vue.component("micro-basic-label",{template:''}),Vue.component("grey-label",{props:["color"],data:function(){let e="grey";return{labelColor:e=null!=this.color&&0'}),Vue.component("optional-label",{template:'(可选)'}),Vue.component("plus-label",{template:'Plus专属功能。'}),Vue.component("pro-warning-label",{template:'注意:通常不需要修改;如要修改,请在专家指导下进行。'}),Vue.component("first-menu",{props:[],template:' \t\t
\t\t\t \t\t\t
\t\t
'}),Vue.component("more-options-indicator",{props:[],data:function(){return{visible:!1}},methods:{changeVisible:function(){this.visible=!this.visible,null!=Tea.Vue&&(Tea.Vue.moreOptionsVisible=this.visible),this.$emit("change",this.visible),this.$emit("input",this.visible)}},template:'更多选项收起选项 '}),Vue.component("page-size-selector",{data:function(){let t=window.location.search,i=10;if(0 +
`}),Vue.component("label-on",{props:["v-is-on"],template:'
已启用已停用
'}),Vue.component("code-label",{methods:{click:function(e){this.$emit("click",e)}},template:''}),Vue.component("code-label-plain",{template:''}),Vue.component("tiny-label",{template:''}),Vue.component("tiny-basic-label",{template:''}),Vue.component("micro-basic-label",{template:''}),Vue.component("grey-label",{props:["color"],data:function(){let e="grey";return{labelColor:e=null!=this.color&&0'}),Vue.component("optional-label",{template:'(可选)'}),Vue.component("plus-label",{template:'Plus专属功能。'}),Vue.component("pro-warning-label",{template:'注意:通常不需要修改;如要修改,请在专家指导下进行。'}),Vue.component("js-page",{props:["v-max"],data:function(){let e=this.vMax;return{max:e=null==e?0:e,page:1}},methods:{updateMax:function(e){this.max=e},selectPage:function(e){this.page=e,this.$emit("change",e)}},template:`
+
+ {{i}} +
+
`}),Vue.component("first-menu",{props:[],template:' \t\t
\t\t\t \t\t\t
\t\t
'}),Vue.component("more-options-indicator",{props:[],data:function(){return{visible:!1}},methods:{changeVisible:function(){this.visible=!this.visible,null!=Tea.Vue&&(Tea.Vue.moreOptionsVisible=this.visible),this.$emit("change",this.visible),this.$emit("input",this.visible)}},template:'更多选项收起选项 '}),Vue.component("page-size-selector",{data:function(){let t=window.location.search,i=10;if(0 `}),Vue.component("second-menu",{template:' \t\t
\t\t\t \t\t\t
\t\t
'}),Vue.component("loading-message",{template:`
  @@ -5454,6 +5505,18 @@ example2.com
+
`}),Vue.component("node-ip-address-clusters-selector",{props:["vClusters"],mounted:function(){this.checkClusters()},data:function(){let e=this.vClusters;return{clusters:e=null==e?[]:e,hasCheckedCluster:!1,clustersVisible:!1}},methods:{checkClusters:function(){let t=!1;return this.clusters.forEach(function(e){e.isChecked&&(t=!0)}),this.hasCheckedCluster=t},changeCluster:function(e){e.isChecked=!e.isChecked,this.checkClusters()},showClusters:function(){this.clustersVisible=!this.clustersVisible}},template:`
+ 默认用于所有集群   修改 +
+ {{cluster.name}}   修改 +

当前IP仅在所选集群中有效。

+
+
+
+ + {{cluster.name}} + +
`}),Vue.component("node-login-suggest-ports",{data:function(){return{ports:[],availablePorts:[],autoSelected:!1,isLoading:!1}},methods:{reload:function(e){let t=this;this.autoSelected=!1,this.isLoading=!0,Tea.action("/clusters/cluster/suggestLoginPorts").params({host:e}).success(function(e){null!=e.data.availablePorts&&(t.availablePorts=e.data.availablePorts,0 正在检查端口... @@ -5473,7 +5536,7 @@ example2.com -
`}),Vue.component("node-ip-addresses-box",{props:["v-ip-addresses","role"],data:function(){return{ipAddresses:null==this.vIpAddresses?[]:this.vIpAddresses,supportThresholds:"ns"!=this.role}},methods:{addIPAddress:function(){window.UPDATING_NODE_IP_ADDRESS=null;let t=this;teaweb.popup("/nodes/ipAddresses/createPopup?supportThresholds="+(this.supportThresholds?1:0),{callback:function(e){t.ipAddresses.push(e.data.ipAddress)},height:"24em",width:"44em"})},updateIPAddress:function(t,e){window.UPDATING_NODE_IP_ADDRESS=e;let i=this;teaweb.popup("/nodes/ipAddresses/updatePopup?supportThresholds="+(this.supportThresholds?1:0),{callback:function(e){Vue.set(i.ipAddresses,t,e.data.ipAddress)},height:"24em",width:"44em"})},removeIPAddress:function(e){this.ipAddresses.$remove(e)},isIPv6:function(e){return-1 +
`}),Vue.component("node-ip-addresses-box",{props:["v-ip-addresses","role","v-node-id"],data:function(){let e=this.vNodeId;return null==e&&(e=0),{ipAddresses:null==this.vIpAddresses?[]:this.vIpAddresses,supportThresholds:"ns"!=this.role,nodeId:e}},methods:{addIPAddress:function(){window.UPDATING_NODE_IP_ADDRESS=null;let t=this;teaweb.popup("/nodes/ipAddresses/createPopup?nodeId="+this.nodeId+"&supportThresholds="+(this.supportThresholds?1:0),{callback:function(e){t.ipAddresses.push(e.data.ipAddress)},height:"24em",width:"44em"})},updateIPAddress:function(t,e){window.UPDATING_NODE_IP_ADDRESS=teaweb.clone(e);let i=this;teaweb.popup("/nodes/ipAddresses/updatePopup?nodeId="+this.nodeId+"&supportThresholds="+(this.supportThresholds?1:0),{callback:function(e){Vue.set(i.ipAddresses,t,e.data.ipAddress)},height:"24em",width:"44em"})},removeIPAddress:function(e){this.ipAddresses.$remove(e)},isIPv6:function(e){return-1
@@ -5485,6 +5548,11 @@ example2.com [down] [{{address.thresholds.length}}个阈值]   + +   专属集群:[{{cluster.name}}] +   + +
@@ -5800,10 +5868,71 @@ example2.com
+
`}),Vue.component("ad-instance-objects-box",{props:["v-objects","v-user-id"],mounted:function(){this.getUserServers(1)},data:function(){let e=this.vObjects,t=(null==e&&(e=[]),[]);return e.forEach(function(e){t.push(e.code)}),{userId:this.vUserId,objects:e,objectCodes:t,isAdding:!0,servers:[],serversIsLoading:!1}},methods:{add:function(){this.isAdding=!0},cancel:function(){this.isAdding=!1},remove:function(e){let t=this;teaweb.confirm("确定要删除此防护对象吗?",function(){t.objects.$remove(e),t.notifyChange()})},removeObjectCode:function(i){let n=-1;this.objectCodes.forEach(function(e,t){i==e&&(n=t)}),0<=n&&(this.objects.$remove(n),this.notifyChange())},getUserServers:function(i){if(null==Tea.Vue){let e=this;void setTimeout(function(){e.getUserServers(i)},100)}else{let t=this;this.serversIsLoading=!0,Tea.Vue.$post(".userServers").params({userId:this.userId,page:i,pageSize:5}).success(function(e){t.servers=e.data.servers,t.$refs.serverPage.updateMax(e.data.page.max),t.serversIsLoading=!1}).error(function(){t.serversIsLoading=!1})}},changeServerPage:function(e){this.getUserServers(e)},selectServerObject:function(e){this.existObjectCode("server:"+e.id)||(this.objects.push({type:"server",code:"server:"+e.id,id:e.id,name:e.name}),this.notifyChange())},notifyChange:function(){let t=[];this.objects.forEach(function(e){t.push(e.code)}),this.objectCodes=t},existObjectCode:function(t){let i=!1;return this.objects.forEach(function(e){e.code==t&&(i=!0)}),i}},template:`
+ + + +
+
暂时还没有设置任何防护对象。
+
+ + + + + +
已选中防护对象 +
+ 网站服务:{{object.name}} +   +
+
+
+
+
+ + +
+ + + + + + + + + + +
对象类型网站服务
服务列表 + 加载中... +
暂时还没有可选的网站服务。
+ + + + + + + + + + + +
网站服务名称操作
{{server.name}} + 选中 + 取消 +
+ + +
+
+ + +
+ +
`}),Vue.component("grant-selector",{props:["v-grant","v-node-cluster-id","v-ns-cluster-id"],data:function(){return{grantId:null==this.vGrant?0:this.vGrant.id,grant:this.vGrant,nodeClusterId:null!=this.vNodeClusterId?this.vNodeClusterId:0,nsClusterId:null!=this.vNsClusterId?this.vNsClusterId:0}},methods:{select:function(){let t=this;teaweb.popup("/clusters/grants/selectPopup?nodeClusterId="+this.nodeClusterId+"&nsClusterId="+this.nsClusterId,{callback:e=>{t.grantId=e.data.grant.id,0{t.grantId=e.data.grant.id,0{t.grant=e.data.grant,t.notifyUpdate()}})}},remove:function(){this.grant=null,this.grantId=0,this.notifyUpdate()},notifyUpdate:function(){this.$emit("change",this.grant)}},template:`
{{grant.name}}({{grant.methodName}})({{grant.username}})
-
`}),window.REQUEST_COND_COMPONENTS=[{type:"url-extension",name:"URL扩展名",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-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:"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:"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"},{description:"判断参数值解析后的文件是否存在",name:"文件存在",op:"file exist"},{description:"判断参数值解析后的文件是否不存在",name:"文件不存在",op:"file not exist"}],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:"${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:"${host}",description:"通常是请求的域名",icon:""},{name:"请求协议Proto",code:"${proto}",description:"包含版本的HTTP请求协议,类似于HTTP/1.0",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:"gt",description:"使用数值对比大于,对比值需要是一个数字",caseInsensitive:"none"},{name:"数值大于等于",code:"gte",description:"使用数值对比大于等于,对比值需要是一个数字",caseInsensitive:"none"},{name:"数值小于",code:"lt",description:"使用数值对比小于,对比值需要是一个数字",caseInsensitive:"none"},{name:"数值小于等于",code:"lte",description:"使用数值对比小于等于,对比值需要是一个数字",caseInsensitive:"none"},{name:"数值等于",code:"eq",description:"使用数值对比等于,对比值需要是一个数字",caseInsensitive:"none"},{name:"数值不等于",code:"neq",description:"使用数值对比不等于,对比值需要是一个数字",caseInsensitive:"none"},{name:"字符串等于",code:"eq string",description:"使用字符串对比等于",caseInsensitive:"no"},{name:"字符串不等于",code:"neq string",description:"使用字符串对比不等于",caseInsensitive:"no"},{name:"正则匹配",code:"match",description:'使用正则表达式匹配,在头部使用(?i)表示不区分大小写,正则表达式语法 »',caseInsensitive:"yes"},{name:"正则不匹配",code:"not match",description:'使用正则表达式不匹配,在头部使用(?i)表示不区分大小写,正则表达式语法 »',caseInsensitive:"yes"},{name:"包含字符串",code:"contains",description:"包含某个字符串,比如Hello World包含了World",caseInsensitive:"no"},{name:"不包含字符串",code:"not contains",description:"不包含某个字符串,比如Hello字符串中不包含Hi",caseInsensitive:"no"},{name:"包含任一字符串",code:"contains any",description:"包含字符串列表中的任意一个,比如/hello/world包含/hello和/hi中的/hello,每行一个字符串",caseInsensitive:"no"},{name:"包含所有字符串",code:"contains all",description:"包含字符串列表中的所有字符串,比如/hello/world必须包含/hello和/world,每行一个字符串",caseInsensitive:"no"},{name:"包含前缀",code:"prefix",description:"包含字符串前缀部分,比如/hello前缀会匹配/hello, /hello/world等",caseInsensitive:"no"},{name:"包含后缀",code:"suffix",description:"包含字符串后缀部分,比如/hello后缀会匹配/hello, /hi/hello等",caseInsensitive:"no"},{name:"包含二进制数据",code:"contains binary",description:"包含一组二进制数据",caseInsensitive:"no"},{name:"不包含二进制数据",code:"not contains binary",description:"不包含一组二进制数据",caseInsensitive:"no"},{name:"包含索引",code:"has key",description:"对于一组数据拥有某个键值或者索引",caseInsensitive:"no"},{name:"版本号大于",code:"version gt",description:"对比版本号大于",caseInsensitive:"no"},{name:"版本号小于",code:"version lt",description:"对比版本号小于",caseInsensitive:"no"},{name:"版本号范围",code:"version range",description:"判断版本号在某个范围内,格式为version1,version2",caseInsensitive:"no"},{name:"IP等于",code:"eq ip",description:"将参数转换为IP进行对比,只能对比单个IP",caseInsensitive:"none"},{name:"在一组IP中",code:"in ip list",description:"判断参数IP在一组IP内,每行一个IP",caseInsensitive:"none"},{name:"IP大于",code:"gt ip",description:"将参数转换为IP进行对比",caseInsensitive:"none"},{name:"IP大于等于",code:"gte ip",description:"将参数转换为IP进行对比",caseInsensitive:"none"},{name:"IP小于",code:"lt ip",description:"将参数转换为IP进行对比",caseInsensitive:"none"},{name:"IP小于等于",code:"lte ip",description:"将参数转换为IP进行对比",caseInsensitive:"none"},{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"},{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"},{name:"IP取模10",code:"ip mod 10",description:"对IP参数值取模,除数为10,对比值为余数",caseInsensitive:"none"},{name:"IP取模100",code:"ip mod 100",description:"对IP参数值取模,除数为100,对比值为余数",caseInsensitive:"none"},{name:"IP取模",code:"ip mod",description:"对IP参数值取模,对比值格式为:除数,余数,比如10,1",caseInsensitive:"none"}]; +
`}),window.REQUEST_COND_COMPONENTS=[{type:"url-extension",name:"URL扩展名",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-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:"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:"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"},{description:"判断参数值解析后的文件是否存在",name:"文件存在",op:"file exist"},{description:"判断参数值解析后的文件是否不存在",name:"文件不存在",op:"file not exist"}],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:"请求协议Proto",code:"${proto}",description:"包含版本的HTTP请求协议,类似于HTTP/1.0",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:"gt",description:"使用数值对比大于,对比值需要是一个数字",caseInsensitive:"none"},{name:"数值大于等于",code:"gte",description:"使用数值对比大于等于,对比值需要是一个数字",caseInsensitive:"none"},{name:"数值小于",code:"lt",description:"使用数值对比小于,对比值需要是一个数字",caseInsensitive:"none"},{name:"数值小于等于",code:"lte",description:"使用数值对比小于等于,对比值需要是一个数字",caseInsensitive:"none"},{name:"数值等于",code:"eq",description:"使用数值对比等于,对比值需要是一个数字",caseInsensitive:"none"},{name:"数值不等于",code:"neq",description:"使用数值对比不等于,对比值需要是一个数字",caseInsensitive:"none"},{name:"字符串等于",code:"eq string",description:"使用字符串对比等于",caseInsensitive:"no"},{name:"字符串不等于",code:"neq string",description:"使用字符串对比不等于",caseInsensitive:"no"},{name:"正则匹配",code:"match",description:'使用正则表达式匹配,在头部使用(?i)表示不区分大小写,正则表达式语法 »',caseInsensitive:"yes"},{name:"正则不匹配",code:"not match",description:'使用正则表达式不匹配,在头部使用(?i)表示不区分大小写,正则表达式语法 »',caseInsensitive:"yes"},{name:"包含字符串",code:"contains",description:"包含某个字符串,比如Hello World包含了World",caseInsensitive:"no"},{name:"不包含字符串",code:"not contains",description:"不包含某个字符串,比如Hello字符串中不包含Hi",caseInsensitive:"no"},{name:"包含任一字符串",code:"contains any",description:"包含字符串列表中的任意一个,比如/hello/world包含/hello和/hi中的/hello,每行一个字符串",caseInsensitive:"no"},{name:"包含所有字符串",code:"contains all",description:"包含字符串列表中的所有字符串,比如/hello/world必须包含/hello和/world,每行一个字符串",caseInsensitive:"no"},{name:"包含前缀",code:"prefix",description:"包含字符串前缀部分,比如/hello前缀会匹配/hello, /hello/world等",caseInsensitive:"no"},{name:"包含后缀",code:"suffix",description:"包含字符串后缀部分,比如/hello后缀会匹配/hello, /hi/hello等",caseInsensitive:"no"},{name:"包含二进制数据",code:"contains binary",description:"包含一组二进制数据",caseInsensitive:"no"},{name:"不包含二进制数据",code:"not contains binary",description:"不包含一组二进制数据",caseInsensitive:"no"},{name:"包含索引",code:"has key",description:"对于一组数据拥有某个键值或者索引",caseInsensitive:"no"},{name:"版本号大于",code:"version gt",description:"对比版本号大于",caseInsensitive:"no"},{name:"版本号小于",code:"version lt",description:"对比版本号小于",caseInsensitive:"no"},{name:"版本号范围",code:"version range",description:"判断版本号在某个范围内,格式为version1,version2",caseInsensitive:"no"},{name:"IP等于",code:"eq ip",description:"将参数转换为IP进行对比,只能对比单个IP",caseInsensitive:"none"},{name:"在一组IP中",code:"in ip list",description:"判断参数IP在一组IP内,每行一个IP",caseInsensitive:"none"},{name:"IP大于",code:"gt ip",description:"将参数转换为IP进行对比",caseInsensitive:"none"},{name:"IP大于等于",code:"gte ip",description:"将参数转换为IP进行对比",caseInsensitive:"none"},{name:"IP小于",code:"lt ip",description:"将参数转换为IP进行对比",caseInsensitive:"none"},{name:"IP小于等于",code:"lte ip",description:"将参数转换为IP进行对比",caseInsensitive:"none"},{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"},{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"},{name:"IP取模10",code:"ip mod 10",description:"对IP参数值取模,除数为10,对比值为余数",caseInsensitive:"none"},{name:"IP取模100",code:"ip mod 100",description:"对IP参数值取模,除数为100,对比值为余数",caseInsensitive:"none"},{name:"IP取模",code:"ip mod",description:"对IP参数值取模,对比值格式为:除数,余数,比如10,1",caseInsensitive:"none"}]; diff --git a/web/public/js/components.src.js b/web/public/js/components.src.js index 994240bd..eb95baed 100755 --- a/web/public/js/components.src.js +++ b/web/public/js/components.src.js @@ -3177,6 +3177,7 @@ Vue.component("plan-price-bandwidth-config-box", { 带宽百分位:{{config.percentile}}th没有设置   |   基础带宽价格:{{config.base}}元/Mbps没有设置   |   阶梯价格:{{config.ranges.length}}段没有设置   |  支持区域带宽计费 +  |  使用平均带宽算法 @@ -3216,6 +3217,17 @@ Vue.component("plan-price-bandwidth-config-box", {

选中后,表示可以根据节点所在区域设置不同的带宽价格。

+ + 带宽算法 + + +

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

+

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

+ +
` @@ -4239,7 +4251,7 @@ Vue.component("http-firewall-rule-label", { | {{paramFilter.code}} - {{operatorName(rule.operator)}} + {{operatorName(rule.operator)}} {{rule.value}} [空] @@ -4807,7 +4819,10 @@ Vue.component("http-cache-ref-box", { {{condComponent.paramsTitle}} * - + + + +
@@ -5217,39 +5232,57 @@ Vue.component("http-firewall-config-box", { firewall = { isPrior: false, isOn: false, - firewallPolicyId: 0 + firewallPolicyId: 0, + ignoreGlobalRules: false } } return { - firewall: firewall + firewall: firewall, + moreOptionsVisible: false + } + }, + methods: { + changeOptionsVisible: function (v) { + this.moreOptionsVisible = v } }, template: `
+ + + + + + +
全局WAF策略 +
{{vFirewallPolicy.name}}   [{{vFirewallPolicy.modeInfo.name}}]  +

当前服务所在集群的设置。

+
+ 当前集群没有设置WAF策略,当前配置无法生效。 +
+ - - - - + + + + + + +
WAF策略 -
{{vFirewallPolicy.name}}   [{{vFirewallPolicy.modeInfo.name}}]  -

使用当前服务所在集群的设置。

-
- 当前集群没有设置WAF策略,当前配置无法生效。 -
启用WAF -
- - -
+

启用WAF之后,各项WAF设置才会生效。

不使用全局规则 + +

选中后,表示不使用系统全局WAF策略中定义的规则。

+
` @@ -6352,7 +6385,7 @@ Vue.component("http-cache-refs-config-box", { }) }, updateRef: function (index, cacheRef) { - window.UPDATING_CACHE_REF = cacheRef + window.UPDATING_CACHE_REF = teaweb.clone(cacheRef) let height = window.innerHeight if (height > 500) { @@ -7137,7 +7170,7 @@ Vue.component("firewall-syn-flood-config-viewer", { }, template: `
- 已启用 / 空连接次数:{{config.minAttempts}}次/分钟 / 封禁时间:{{config.timeoutSeconds}}秒 / 忽略局域网访问 + 已启用 / 空连接次数:{{config.minAttempts}}次/分钟 / 封禁时长:{{config.timeoutSeconds}}秒 / 忽略局域网访问 未启用
` @@ -7411,8 +7444,16 @@ Vue.component("http-referers-config-box", { return ((!this.vIsLocation && !this.vIsGroup) || this.config.isPrior) && this.config.isOn }, changeAllowDomains: function (domains) { + if (typeof (domains) == "object") { + this.config.allowDomains = domains + this.$forceUpdate() + } }, changeDenyDomains: function (domains) { + if (typeof (domains) == "object") { + this.config.denyDomains = domains + this.$forceUpdate() + } } }, template: `
@@ -7702,6 +7743,7 @@ Vue.component("http-firewall-actions-box", { // 动作参数 blockTimeout: "", + blockTimeoutMax: "", blockScope: "global", captchaLife: "", @@ -7751,6 +7793,14 @@ Vue.component("http-firewall-actions-box", { this.actionOptions["timeout"] = v } }, + blockTimeoutMax: function (v) { + v = parseInt(v) + if (isNaN(v)) { + this.actionOptions["timeoutMax"] = 0 + } else { + this.actionOptions["timeoutMax"] = v + } + }, blockScope: function (v) { this.actionOptions["scope"] = v }, @@ -7866,6 +7916,7 @@ Vue.component("http-firewall-actions-box", { // 动作参数 this.blockTimeout = "" + this.blockTimeoutMax = "" this.blockScope = "global" this.captchaLife = "" @@ -7927,9 +7978,13 @@ Vue.component("http-firewall-actions-box", { switch (config.code) { case "block": this.blockTimeout = "" + this.blockTimeoutMax = "" if (config.options.timeout != null || config.options.timeout > 0) { this.blockTimeout = config.options.timeout.toString() } + if (config.options.timeoutMax != null || config.options.timeoutMax > 0) { + this.blockTimeoutMax = config.options.timeoutMax.toString() + } if (config.options.scope != null && config.options.scope.length > 0) { this.blockScope = config.options.scope } else { @@ -8213,7 +8268,7 @@ Vue.component("http-firewall-actions-box", { {{config.name}} ({{config.code.toUpperCase()}}) - :有效期{{config.options.timeout}}秒 + :封禁时长{{config.options.timeout}}-{{config.options.timeoutMax}} :有效期{{config.options.life}}秒 @@ -8272,7 +8327,18 @@ Vue.component("http-firewall-actions-box", { - 封锁时间 + 封禁范围 + + +

只封禁用户对当前网站服务的访问,其他服务不受影响。

+

封禁用户对所有网站服务的访问。

+ + + + 封禁时长
@@ -8281,14 +8347,13 @@ Vue.component("http-firewall-actions-box", { - 封锁范围 + 最大封禁时长 - -

只封锁用户对当前网站服务的访问,其他服务不受影响。

-

封锁用户对所有网站服务的访问。

+
+ + +
+

选填项。如果同时填写了封禁时长和最大封禁时长,则会在两者之间随机选择一个数字作为最终的封禁时长。

@@ -10152,7 +10217,7 @@ Vue.component("http-firewall-block-options-viewer", { template: `
默认设置
- 状态码:{{options.statusCode}} / 提示内容:[{{options.body.length}}字符][无] / 超时时间:{{options.timeout}}秒 + 状态码:{{options.statusCode}} / 提示内容:[{{options.body.length}}字符][无] / 超时时间:{{options.timeout}}秒 / 最大封禁时长:{{options.timeoutMax}}秒
` @@ -11846,6 +11911,7 @@ Vue.component("http-firewall-block-options", { blockOptions: this.vBlockOptions, statusCode: this.vBlockOptions.statusCode, timeout: this.vBlockOptions.timeout, + timeoutMax: this.vBlockOptions.timeoutMax, isEditing: false } }, @@ -11865,6 +11931,14 @@ Vue.component("http-firewall-block-options", { } else { this.blockOptions.timeout = timeout } + }, + timeoutMax: function (v) { + let timeoutMax = parseInt(v) + if (isNaN(timeoutMax)) { + this.blockOptions.timeoutMax = 0 + } else { + this.blockOptions.timeoutMax = timeoutMax + } } }, methods: { @@ -11874,7 +11948,9 @@ Vue.component("http-firewall-block-options", { }, template: `
- 状态码:{{statusCode}} / 提示内容:[{{blockOptions.body.length}}字符][无] / 超时时间:{{timeout}}秒 + 状态码:{{statusCode}} / 提示内容:[{{blockOptions.body.length}}字符][无] / 封禁时长:{{timeout}}秒 + / 最大封禁时长:{{timeoutMax}}秒 + @@ -11889,13 +11965,23 @@ Vue.component("http-firewall-block-options", { - + + + + +
状态码
超时时间封禁时长
-

触发阻止动作时,封锁客户端IP的时间。

+

触发阻止动作时,封禁客户端IP的时间。

+
最大封禁时长 +
+ + +
+

如果最大封禁时长大于封禁时长({{timeout}}秒),那么表示每次封禁的时候,将会在这两个时长数字之间随机选取一个数字作为最终的封禁时长。

@@ -12059,7 +12145,7 @@ Vue.component("http-firewall-rules-box", { - | {{paramFilter.code}} {{operatorName(rule.operator)}} + | {{paramFilter.code}} {{operatorName(rule.operator)}} {{rule.value}} [空] @@ -12255,7 +12341,7 @@ Vue.component("http-cond-url-extension", { data: function () { let cond = { isRequest: true, - param: "${requestPathExtension}", + param: "${requestPathLowerExtension}", operator: "in", value: "[]" } @@ -12346,7 +12432,7 @@ Vue.component("http-cond-url-not-extension", { data: function () { let cond = { isRequest: true, - param: "${requestPathExtension}", + param: "${requestPathLowerExtension}", operator: "not in", value: "[]" } @@ -12969,21 +13055,19 @@ Vue.component("http-cond-params", { }, template: ` - 参数值 + 参数值
-
-
- -
-
- -
-
+
+ +
+
+ +

其中可以使用变量,类似于\${requestPath},也可以是多个变量的组合。

@@ -13086,7 +13170,8 @@ Vue.component("http-cond-params", {

选中后表示对比时忽略参数值的大小写。

-` + +` }) // 请求方法列表 @@ -13843,7 +13928,7 @@ Vue.component("firewall-syn-flood-config-box", { - 已启用 / 空连接次数:{{config.minAttempts}}次/分钟 / 封禁时间:{{config.timeoutSeconds}}秒 / 忽略局域网访问 + 已启用 / 空连接次数:{{config.minAttempts}}次/分钟 / 封禁时长:{{config.timeoutSeconds}}秒 / 忽略局域网访问 未启用 @@ -13868,7 +13953,7 @@ Vue.component("firewall-syn-flood-config-box", { - 封禁时间 + 封禁时长 ` }) +Vue.component("node-ip-address-clusters-selector", { + props: ["vClusters"], + mounted: function () { + this.checkClusters() + }, + data: function () { + let clusters = this.vClusters + if (clusters == null) { + clusters = [] + } + return { + clusters: clusters, + hasCheckedCluster: false, + clustersVisible: false + } + }, + methods: { + checkClusters: function () { + let that = this + + let b = false + this.clusters.forEach(function (cluster) { + if (cluster.isChecked) { + b = true + } + }) + + this.hasCheckedCluster = b + + return b + }, + changeCluster: function (cluster) { + cluster.isChecked = !cluster.isChecked + this.checkClusters() + }, + showClusters: function () { + this.clustersVisible = !this.clustersVisible + } + }, + template: `
+ 默认用于所有集群   修改 +
+ {{cluster.name}}   修改 +

当前IP仅在所选集群中有效。

+
+
+
+ + {{cluster.name}} + +
+
` +}) + // 节点登录推荐端口 Vue.component("node-login-suggest-ports", { data: function () { @@ -17143,11 +17326,17 @@ Vue.component("node-group-selector", { // 节点IP地址管理(标签形式) Vue.component("node-ip-addresses-box", { - props: ["v-ip-addresses", "role"], + props: ["v-ip-addresses", "role", "v-node-id"], data: function () { + let nodeId = this.vNodeId + if (nodeId == null) { + nodeId = 0 + } + return { ipAddresses: (this.vIpAddresses == null) ? [] : this.vIpAddresses, - supportThresholds: this.role != "ns" + supportThresholds: this.role != "ns", + nodeId: nodeId } }, methods: { @@ -17156,7 +17345,7 @@ Vue.component("node-ip-addresses-box", { window.UPDATING_NODE_IP_ADDRESS = null let that = this; - teaweb.popup("/nodes/ipAddresses/createPopup?supportThresholds=" + (this.supportThresholds ? 1 : 0), { + teaweb.popup("/nodes/ipAddresses/createPopup?nodeId=" + this.nodeId + "&supportThresholds=" + (this.supportThresholds ? 1 : 0), { callback: function (resp) { that.ipAddresses.push(resp.data.ipAddress); }, @@ -17167,10 +17356,10 @@ Vue.component("node-ip-addresses-box", { // 修改地址 updateIPAddress: function (index, address) { - window.UPDATING_NODE_IP_ADDRESS = address + window.UPDATING_NODE_IP_ADDRESS = teaweb.clone(address) let that = this; - teaweb.popup("/nodes/ipAddresses/updatePopup?supportThresholds=" + (this.supportThresholds ? 1 : 0), { + teaweb.popup("/nodes/ipAddresses/updatePopup?nodeId=" + this.nodeId + "&supportThresholds=" + (this.supportThresholds ? 1 : 0), { callback: function (resp) { Vue.set(that.ipAddresses, index, resp.data.ipAddress); }, @@ -17201,6 +17390,11 @@ Vue.component("node-ip-addresses-box", { [down] [{{address.thresholds.length}}个阈值]   + +   专属集群:[{{cluster.name}}] +   + +
@@ -18249,6 +18443,183 @@ Vue.component("dns-resolver-config-box", {
` }) +Vue.component("ad-instance-objects-box", { + props: ["v-objects", "v-user-id"], + mounted: function () { + this.getUserServers(1) + }, + data: function () { + let objects = this.vObjects + if (objects == null) { + objects = [] + } + + let objectCodes = [] + objects.forEach(function (v) { + objectCodes.push(v.code) + }) + + return { + userId: this.vUserId, + objects: objects, + objectCodes: objectCodes, + isAdding: true, + + servers: [], + serversIsLoading: false + } + }, + methods: { + add: function () { + this.isAdding = true + }, + cancel: function () { + this.isAdding = false + }, + remove: function (index) { + let that = this + teaweb.confirm("确定要删除此防护对象吗?", function () { + that.objects.$remove(index) + that.notifyChange() + }) + }, + removeObjectCode: function (objectCode) { + let index = -1 + this.objectCodes.forEach(function (v, k) { + if (objectCode == v) { + index = k + } + }) + if (index >= 0) { + this.objects.$remove(index) + this.notifyChange() + } + }, + getUserServers: function (page) { + if (Tea.Vue == null) { + let that = this + setTimeout(function () { + that.getUserServers(page) + }, 100) + return + } + + let that = this + this.serversIsLoading = true + Tea.Vue.$post(".userServers") + .params({ + userId: this.userId, + page: page, + pageSize: 5 + }) + .success(function (resp) { + that.servers = resp.data.servers + + that.$refs.serverPage.updateMax(resp.data.page.max) + that.serversIsLoading = false + }) + .error(function () { + that.serversIsLoading = false + }) + }, + changeServerPage: function (page) { + this.getUserServers(page) + }, + selectServerObject: function (server) { + if (this.existObjectCode("server:" + server.id)) { + return + } + + this.objects.push({ + "type": "server", + "code": "server:" + server.id, + + "id": server.id, + "name": server.name + }) + this.notifyChange() + }, + notifyChange: function () { + let objectCodes = [] + this.objects.forEach(function (v) { + objectCodes.push(v.code) + }) + this.objectCodes = objectCodes + }, + existObjectCode: function (objectCode) { + let found = false + this.objects.forEach(function (v) { + if (v.code == objectCode) { + found = true + } + }) + return found + } + }, + template: `
+ + + +
+
暂时还没有设置任何防护对象。
+
+ + + + + +
已选中防护对象 +
+ 网站服务:{{object.name}} +   +
+
+
+
+
+ + +
+ + + + + + + + + + +
对象类型网站服务
服务列表 + 加载中... +
暂时还没有可选的网站服务。
+ + + + + + + + + + + +
网站服务名称操作
{{server.name}} + 选中 + 取消 +
+ + +
+
+ + +
+ +
+
` +}) + Vue.component("grant-selector", { props: ["v-grant", "v-node-cluster-id", "v-ns-cluster-id"], data: function () { @@ -18329,9 +18700,9 @@ window.REQUEST_COND_COMPONENTS = [{"type":"url-extension","name":"URL扩展名", window.REQUEST_COND_OPERATORS = [{"description":"判断是否正则表达式匹配","name":"正则表达式匹配","op":"regexp"},{"description":"判断是否正则表达式不匹配","name":"正则表达式不匹配","op":"not regexp"},{"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在某个范围之内,范围格式可以是英文逗号分隔的\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","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"},{"description":"判断参数值解析后的文件是否存在","name":"文件存在","op":"file exist"},{"description":"判断参数值解析后的文件是否不存在","name":"文件不存在","op":"file not exist"}] -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":"${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.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":"${host}","description":"通常是请求的域名","icon":""},{"name":"请求协议Proto","code":"${proto}","description":"包含版本的HTTP请求协议,类似于HTTP/1.0","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.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":"请求协议Proto","code":"${proto}","description":"包含版本的HTTP请求协议,类似于HTTP/1.0","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"}]