From d466b74e01a4da819e2326485f93504599159661 Mon Sep 17 00:00:00 2001 From: GoEdgeLab Date: Mon, 12 Jun 2023 11:16:56 +0800 Subject: [PATCH] commit components.js --- web/public/js/components.js | 129 ++++++++++++------ web/public/js/components.src.js | 231 ++++++++++++++++++++++++++------ 2 files changed, 272 insertions(+), 88 deletions(-) diff --git a/web/public/js/components.js b/web/public/js/components.js index 55c2f054..41295ba0 100644 --- a/web/public/js/components.js +++ b/web/public/js/components.js @@ -1846,12 +1846,13 @@ Vue.component("traffic-map-box",{props:["v-stats","v-is-attack"],mounted:functio
`}),Vue.component("http-cache-ref-box",{props:["v-cache-ref","v-is-reverse"],mounted:function(){this.$refs.variablesDescriber.update(this.ref.key),null!=this.ref.simpleCond?(this.condType=this.ref.simpleCond.type,this.changeCondType(this.ref.simpleCond.type,!0),this.condCategory="simple"):null!=this.ref.conds&&null!=this.ref.conds.groups&&(this.condCategory="complex"),this.changeCondCategory(this.condCategory)},data:function(){let e=this.vCacheRef;null==(e=null==e?{isOn:!0,cachePolicyId:0,key:"${scheme}://${host}${requestPath}${isArgs}${args}",life:{count:2,unit:"hour"},status:[200],maxSize:{count:32,unit:"mb"},minSize:{count:0,unit:"kb"},skipCacheControlValues:["private","no-cache","no-store"],skipSetCookie:!0,enableRequestCachePragma:!1,conds:null,simpleCond:null,allowChunkedEncoding:!0,allowPartialContent:!0,enableIfNoneMatch:!1,enableIfModifiedSince:!1,isReverse:this.vIsReverse,methods:[],expiresTime:{isPrior:!1,isOn:!1,overwrite:!0,autoCalculate:!0,duration:{count:-1,unit:"hour"}}}:e).key&&(e.key=""),null==e.methods&&(e.methods=[]),null==e.life&&(e.life={count:2,unit:"hour"}),null==e.maxSize&&(e.maxSize={count:32,unit:"mb"}),null==e.minSize&&(e.minSize={count:0,unit:"kb"});var t=window.REQUEST_COND_COMPONENTS.$find(function(e,t){return"url-extension"==t.type});return{ref:e,keyIgnoreArgs:"string"==typeof e.key&&e.key.indexOf("${args}")<0,moreOptionsVisible:!1,condCategory:"simple",condType:"url-extension",condComponent:t,condIsCaseInsensitive:null==e.simpleCond||e.simpleCond.isCaseInsensitive,components:window.REQUEST_COND_COMPONENTS}},watch:{keyIgnoreArgs:function(e){"string"==typeof this.ref.key&&(e?this.ref.key=this.ref.key.replace("${isArgs}${args}",""):(this.ref.key.indexOf("${isArgs}")<0&&(this.ref.key=this.ref.key+"${isArgs}"),this.ref.key.indexOf("${args}")<0&&(this.ref.key=this.ref.key+"${args}")))}},methods:{changeOptionsVisible:function(e){this.moreOptionsVisible=e},changeLife:function(e){this.ref.life=e},changeMaxSize:function(e){this.ref.maxSize=e},changeMinSize:function(e){this.ref.minSize=e},changeConds:function(e){this.ref.conds=e,this.ref.simpleCond=null},changeStatusList:function(e){let t=[];e.forEach(function(e){e=parseInt(e);isNaN(e)||e<100||999 - 条件类型 * + 条件类型 * @@ -1892,19 +1893,19 @@ Vue.component("traffic-map-box",{props:["v-stats","v-is-attack"],mounted:functio - 缓存Key * - - -

用来区分不同缓存内容的唯一Key。

- - - - 忽略URI参数 + 忽略URI参数

选中后,表示缓存Key中不包含URI参数(即问号(?))后面的内容。

+ + 缓存Key * + + +

用来区分不同缓存内容的唯一Key。

+ + @@ -2234,8 +2235,8 @@ Vue.component("traffic-map-box",{props:["v-stats","v-is-attack"],mounted:functio
-

缓存条件

- +

缓存条件   [添加]

+
`});let defaultGeneralHeaders=["Cache-Control","Connection","Date","Pragma","Trailer","Transfer-Encoding","Upgrade","Via","Warning"];Vue.component("http-cond-general-header-length",{props:["v-checkpoint"],data:function(){let e=null,t=null;var i;null!=window.parent.UPDATING_RULE&&(null!=(i=window.parent.UPDATING_RULE.checkpointOptions).headers&&Array.$isArray(i.headers)&&(e=i.headers),null!=i.length&&(t=i.length)),null==e&&(e=defaultGeneralHeaders),null==t&&(t=128);let n=this;return setTimeout(function(){n.change()},100),{headers:e,length:t}},watch:{length:function(e){let t=parseInt(e);(t=isNaN(t)?0:t)<0&&(t=0),this.length=t,this.change()}},methods:{change:function(){this.vCheckpoint.options=[{code:"headers",value:this.headers},{code:"length",value:this.length}]}},template:`
@@ -2402,7 +2403,7 @@ Vue.component("traffic-map-box",{props:["v-stats","v-is-attack"],mounted:functio

所有条件匹配顺序为从上到下,可以拖动左侧的排序。服务设置的优先级比全局缓存策略设置的优先级要高。

-     +添加不缓存条件 +     +添加不缓存条件
`}),Vue.component("origin-list-box",{props:["v-primary-origins","v-backup-origins","v-server-type","v-params"],data:function(){return{primaryOrigins:this.vPrimaryOrigins,backupOrigins:this.vBackupOrigins}},methods:{createPrimaryOrigin:function(){teaweb.popup("/servers/server/settings/origins/addPopup?originType=primary&"+this.vParams,{width:"45em",height:"27em",callback:function(e){teaweb.success("保存成功",function(){window.location.reload()})}})},createBackupOrigin:function(){teaweb.popup("/servers/server/settings/origins/addPopup?originType=backup&"+this.vParams,{width:"45em",height:"27em",callback:function(e){teaweb.success("保存成功",function(){window.location.reload()})}})},updateOrigin:function(e,t){teaweb.popup("/servers/server/settings/origins/updatePopup?originType="+t+"&"+this.vParams+"&originId="+e,{width:"45em",height:"27em",callback:function(e){teaweb.success("保存成功",function(){window.location.reload()})}})},deleteOrigin:function(e,t){let i=this;teaweb.confirm("确定要删除此源站吗?",function(){Tea.action("/servers/server/settings/origins/delete?"+i.vParams+"&originId="+e+"&originType="+t).post().success(function(){teaweb.success("删除成功",function(){window.location.reload()})})})}},template:`
@@ -2423,28 +2424,31 @@ Vue.component("traffic-map-box",{props:["v-stats","v-is-attack"],mounted:functio 操作 - - - {{origin.addr}}   -
- {{origin.name}} - 证书 - 主机名: {{origin.host}} - 端口跟随 - - 匹配: {{domain}} - 匹配: 所有域名 -
- - {{origin.weight}} - - - - - 修改   - 删除 - - + + + + {{origin.addr}}   +
+ 对象存储 + {{origin.name}} + 证书 + 主机名: {{origin.host}} + 端口跟随 + + 匹配: {{domain}} + 匹配: 所有域名 +
+ + {{origin.weight}} + + + + + 修改   + 删除 + + + `}),Vue.component("http-cors-header-config-box",{props:["value"],data:function(){let e=this.value,t=(null==(e=null==e?{isOn:!1,allowMethods:[],allowOrigin:"",allowCredentials:!0,exposeHeaders:[],maxAge:0,requestHeaders:[],requestMethod:"",optionsMethodOnly:!1}:e).allowMethods&&(e.allowMethods=[]),null==e.exposeHeaders&&(e.exposeHeaders=[]),e.maxAge.toString());return"0"==t&&(t=""),{config:e,maxAgeSecondsString:t,moreOptionsVisible:!1}},watch:{maxAgeSecondsString:function(e){let t=parseInt(e);isNaN(t)&&(t=0),this.config.maxAge=t}},methods:{changeMoreOptions:function(e){this.moreOptionsVisible=e},addDefaultAllowMethods:function(){let t=this;["PUT","GET","POST","DELETE","HEAD","OPTIONS","PATCH"].forEach(function(e){t.config.allowMethods.$contains(e)||t.config.allowMethods.push(e)})}},template:`
@@ -3332,7 +3336,7 @@ example2.com
- 由于已经在当前服务分组中进行了对应的配置,在这里的配置将不会生效。 + 由于已经在当前网站分组中进行了对应的配置,在这里的配置将不会生效。

设置请求Header   [添加新Header]

@@ -3405,7 +3409,7 @@ example2.com
- 由于已经在当前服务分组中进行了对应的配置,在这里的配置将不会生效。 + 由于已经在当前网站分组中进行了对应的配置,在这里的配置将不会生效。

设置响应Header   [添加新Header]

@@ -4791,6 +4795,10 @@ example2.com

检查URL路径是为/,不需要带域名。

+
`}),Vue.component("http-cond-url-all",{props:["v-cond"],data:function(){let e={isRequest:!0,param:"${requestPath}",operator:"prefix",value:"/",isCaseInsensitive:!1};return null!=this.vCond&&"string"==typeof this.vCond.value&&(e.value=this.vCond.value),{cond:e}},methods:{changeCaseInsensitive:function(e){this.cond.isCaseInsensitive=e}},template:`
+ + +

支持全站所有URL。

`}),Vue.component("http-cond-url-eq",{props:["v-cond"],mounted:function(){this.$refs.valueInput.focus()},data:function(){let e={isRequest:!0,param:"${requestPath}",operator:"eq",value:"",isCaseInsensitive:!1};return null!=this.vCond&&"string"==typeof this.vCond.value&&(e.value=this.vCond.value),{cond:e}},methods:{changeCaseInsensitive:function(e){this.cond.isCaseInsensitive=e}},template:`
@@ -5494,7 +5502,7 @@ example2.com
`}),Vue.component("api-node-selector",{props:[],data:function(){return{}},template:`
暂未实现 -
`}),Vue.component("api-node-addresses-box",{props:["v-addrs","v-name"],data:function(){let e=this.vAddrs;return{addrs:e=null==e?[]:e}},methods:{addAddr:function(){let t=this;teaweb.popup("/api/node/createAddrPopup",{height:"16em",callback:function(e){t.addrs.push(e.data.addr)}})},updateAddr:function(t,e){let i=this;window.UPDATING_ADDR=e,teaweb.popup("/api/node/updateAddrPopup?addressId=",{callback:function(e){Vue.set(i.addrs,t,e.data.addr)}})},removeAddr:function(e){this.addrs.$remove(e)}},template:`
+
`}),Vue.component("api-node-addresses-box",{props:["v-addrs","v-name"],data:function(){let e=this.vAddrs;return{addrs:e=null==e?[]:e}},methods:{addAddr:function(){let t=this;teaweb.popup("/settings/api/node/createAddrPopup",{height:"16em",callback:function(e){t.addrs.push(e.data.addr)}})},updateAddr:function(t,e){let i=this;window.UPDATING_ADDR=e,teaweb.popup("/settings/api/node/updateAddrPopup?addressId=",{callback:function(e){Vue.set(i.addrs,t,e.data.addr)}})},removeAddr:function(e){this.addrs.$remove(e)}},template:`
@@ -5992,7 +6000,7 @@ example2.com
-
`}),Vue.component("node-schedule-conds-box",{props:["value","v-params","v-operators"],mounted:function(){this.formatConds(this.condsConfig.conds),this.$forceUpdate()},data:function(){let e=this.value,t=(null==(e=null==e?{conds:[],connector:"and"}:e).conds&&(e.conds=[]),{}),i=(this.vParams.forEach(function(e){t[e.code]=e}),{});return this.vOperators.forEach(function(e){i[e.code]=e.name}),{condsConfig:e,params:this.vParams,paramMap:t,operatorMap:i,operator:"",isAdding:!1,paramCode:"",param:null,valueBandwidth:{count:100,unit:"mb"},valueTraffic:{count:1,unit:"gb"},valueCPU:80,valueMemory:90,valueLoad:20}},watch:{paramCode:function(i){0==i.length?this.param=null:this.param=this.params.$find(function(e,t){return t.code==i}),this.$emit("changeparam",this.param)}},methods:{add:function(){this.isAdding=!0},confirm:function(){if(null==this.param)teaweb.warn("请选择参数");else if(null!=this.param.operators&&0 +
`}),Vue.component("node-schedule-conds-box",{props:["value","v-params","v-operators"],mounted:function(){this.formatConds(this.condsConfig.conds),this.$forceUpdate()},data:function(){let e=this.value,t=(null==(e=null==e?{conds:[],connector:"and"}:e).conds&&(e.conds=[]),{}),i=(this.vParams.forEach(function(e){t[e.code]=e}),{});return this.vOperators.forEach(function(e){i[e.code]=e.name}),{condsConfig:e,params:this.vParams,paramMap:t,operatorMap:i,operator:"",isAdding:!1,paramCode:"",param:null,valueBandwidth:{count:100,unit:"mb"},valueTraffic:{count:1,unit:"gb"},valueCPU:80,valueMemory:90,valueLoad:20,valueRate:0}},watch:{paramCode:function(i){0==i.length?this.param=null:this.param=this.params.$find(function(e,t){return t.code==i}),this.$emit("changeparam",this.param)}},methods:{add:function(){this.isAdding=!0},confirm:function(){if(null==this.param)teaweb.warn("请选择参数");else if(null!=this.param.operators&&0 @@ -6084,7 +6092,15 @@ example2.com
- + +
+ + +
+
+ + /秒 +
@@ -6362,7 +6378,7 @@ example2.com

{{levels[levelCode - 1].description}}

-
`}),Vue.component("node-schedule-conds-viewer",{props:["value","v-params","v-operators"],mounted:function(){this.formatConds(this.condsConfig.conds),this.$forceUpdate()},data:function(){let t={},i=(this.vParams.forEach(function(e){t[e.code]=e}),{});return this.vOperators.forEach(function(e){i[e.code]=e.name}),{condsConfig:this.value,paramMap:t,operatorMap:i}},methods:{formatConds:function(e){let t=this;e.forEach(function(e){switch(t.paramMap[e.param].valueType){case"bandwidth":return void(e.valueFormat=e.value.count+e.value.unit[0].toUpperCase()+e.value.unit.substring(1)+"ps");case"traffic":return void(e.valueFormat=e.value.count+e.value.unit.toUpperCase());case"cpu":case"memory":return void(e.valueFormat=e.value+"%");case"load":return void(e.valueFormat=e.value)}})}},template:`
+
`}),Vue.component("node-schedule-conds-viewer",{props:["value","v-params","v-operators"],mounted:function(){this.formatConds(this.condsConfig.conds),this.$forceUpdate()},data:function(){let t={},i=(this.vParams.forEach(function(e){t[e.code]=e}),{});return this.vOperators.forEach(function(e){i[e.code]=e.name}),{condsConfig:this.value,paramMap:t,operatorMap:i}},methods:{formatConds:function(e){let t=this;e.forEach(function(e){switch(t.paramMap[e.param].valueType){case"bandwidth":return void(e.valueFormat=e.value.count+e.value.unit[0].toUpperCase()+e.value.unit.substring(1)+"ps");case"traffic":return void(e.valueFormat=e.value.count+e.value.unit.toUpperCase());case"cpu":case"memory":return void(e.valueFormat=e.value+"%");case"load":return void(e.valueFormat=e.value);case"rate":return void(e.valueFormat=e.value+"/秒")}})}},template:`
{{paramMap[cond.param].name}} @@ -6427,6 +6443,31 @@ example2.com
+
`}),Vue.component("dns-resolvers-config-box",{props:["value","name"],data:function(){let e=this.value,t=(null==e&&(e=[]),this.name);return{formName:t=null!=t&&0!=t.length?t:"dnsResolversJSON",resolvers:e,host:"",isAdding:!1}},methods:{add:function(){this.isAdding=!0;let e=this;setTimeout(function(){e.$refs.hostRef.focus()})},confirm:function(){var e=this.host.trim();if(0==e.length){let e=this;void setTimeout(function(){e.$refs.hostRef.focus()})}else this.resolvers.push({host:e,port:0,protocol:""}),this.cancel()},cancel:function(){this.isAdding=!1,this.host="",this.port=0,this.protocol=""},remove:function(e){this.resolvers.$remove(e)}},template:`
+ +
+
+ {{resolver.protocol}}{{resolver.host}}:{{resolver.port}} +   + +
+
+ +
+
+
+ +
+
+ +   +
+
+
+ +
+ +
`}),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:`
@@ -6494,4 +6535,4 @@ example2.com
[选择已有认证]     [添加新认证]
-
`}),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"}]; +
`}),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:"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 6a2f6ba7..2e133691 100755 --- a/web/public/js/components.src.js +++ b/web/public/js/components.src.js @@ -5204,12 +5204,13 @@ Vue.component("http-cache-ref-box", { }, template: ` - 条件类型 * + 条件类型 * @@ -5250,19 +5251,19 @@ Vue.component("http-cache-ref-box", { - 缓存Key * - - -

用来区分不同缓存内容的唯一Key。

- - - - 忽略URI参数 + 忽略URI参数

选中后,表示缓存Key中不包含URI参数(即问号(?))后面的内容。

+ + 缓存Key * + + +

用来区分不同缓存内容的唯一Key。

+ + @@ -6265,8 +6266,8 @@ Vue.component("http-cache-config-box", {
-

缓存条件

- +

缓存条件   [添加]

+
` @@ -6978,7 +6979,7 @@ Vue.component("http-cache-refs-config-box", {

所有条件匹配顺序为从上到下,可以拖动左侧的排序。服务设置的优先级比全局缓存策略设置的优先级要高。

-     +添加不缓存条件 +     +添加不缓存条件
` @@ -7085,28 +7086,31 @@ Vue.component("origin-list-table", { 操作 - - - {{origin.addr}}   -
- {{origin.name}} - 证书 - 主机名: {{origin.host}} - 端口跟随 - - 匹配: {{domain}} - 匹配: 所有域名 -
- - {{origin.weight}} - - - - - 修改   - 删除 - - + + + + {{origin.addr}}   +
+ 对象存储 + {{origin.name}} + 证书 + 主机名: {{origin.host}} + 端口跟随 + + 匹配: {{domain}} + 匹配: 所有域名 +
+ + {{origin.weight}} + + + + + 修改   + 删除 + + + ` }) @@ -9626,7 +9630,7 @@ Vue.component("http-header-policy-box", {
- 由于已经在当前服务分组中进行了对应的配置,在这里的配置将不会生效。 + 由于已经在当前网站分组中进行了对应的配置,在这里的配置将不会生效。

设置请求Header   [添加新Header]

@@ -9699,7 +9703,7 @@ Vue.component("http-header-policy-box", {
- 由于已经在当前服务分组中进行了对应的配置,在这里的配置将不会生效。 + 由于已经在当前网站分组中进行了对应的配置,在这里的配置将不会生效。

设置响应Header   [添加新Header]

@@ -13478,6 +13482,36 @@ Vue.component("http-cond-url-eq-index", {
` }) +// 全站 +Vue.component("http-cond-url-all", { + props: ["v-cond"], + data: function () { + let cond = { + isRequest: true, + param: "${requestPath}", + operator: "prefix", + value: "/", + isCaseInsensitive: false + } + if (this.vCond != null && typeof this.vCond.value == "string") { + cond.value = this.vCond.value + } + return { + cond: cond + } + }, + methods: { + changeCaseInsensitive: function (isCaseInsensitive) { + this.cond.isCaseInsensitive = isCaseInsensitive + } + }, + template: `
+ + +

支持全站所有URL。

+
` +}) + // URL精准匹配 Vue.component("http-cond-url-eq", { props: ["v-cond"], @@ -15346,7 +15380,7 @@ Vue.component("api-node-addresses-box", { // 添加IP地址 addAddr: function () { let that = this; - teaweb.popup("/api/node/createAddrPopup", { + teaweb.popup("/settings/api/node/createAddrPopup", { height: "16em", callback: function (resp) { that.addrs.push(resp.data.addr); @@ -15358,7 +15392,7 @@ Vue.component("api-node-addresses-box", { updateAddr: function (index, addr) { let that = this; window.UPDATING_ADDR = addr - teaweb.popup("/api/node/updateAddrPopup?addressId=", { + teaweb.popup("/settings/api/node/updateAddrPopup?addressId=", { callback: function (resp) { Vue.set(that.addrs, index, resp.data.addr); } @@ -18626,7 +18660,8 @@ Vue.component("node-schedule-conds-box", { }, valueCPU: 80, valueMemory: 90, - valueLoad: 20 + valueLoad: 20, + valueRate: 0 } }, watch: { @@ -18732,6 +18767,16 @@ Vue.component("node-schedule-conds-box", { } value = load break + case "rate": + let rate = parseInt(this.valueRate.toString()) + if (isNaN(rate)) { + rate = 0 + } + if (rate < 0) { + rate = 0 + } + value = rate + break } this.condsConfig.conds.push({ @@ -18770,6 +18815,9 @@ Vue.component("node-schedule-conds-box", { case "load": cond.valueFormat = cond.value return + case "rate": + cond.valueFormat = cond.value + "/秒" + return } }) } @@ -18866,7 +18914,15 @@ Vue.component("node-schedule-conds-box", {
- + +
+ + +
+
+ + /秒 +
@@ -19767,6 +19823,9 @@ Vue.component("node-schedule-conds-viewer", { case "load": cond.valueFormat = cond.value return + case "rate": + cond.valueFormat = cond.value + "/秒" + return } }) } @@ -20024,6 +20083,90 @@ Vue.component("dns-resolver-config-box", {
` }) +Vue.component("dns-resolvers-config-box", { + props: ["value", "name"], + data: function () { + let resolvers = this.value + if (resolvers == null) { + resolvers = [] + } + + let name = this.name + if (name == null || name.length == 0) { + name = "dnsResolversJSON" + } + + return { + formName: name, + resolvers: resolvers, + + host: "", + + isAdding: false + } + }, + methods: { + add: function () { + this.isAdding = true + let that = this + setTimeout(function () { + that.$refs.hostRef.focus() + }) + }, + confirm: function () { + let host = this.host.trim() + if (host.length == 0) { + let that = this + setTimeout(function () { + that.$refs.hostRef.focus() + }) + return + } + this.resolvers.push({ + host: host, + port: 0, // TODO + protocol: "" // TODO + }) + this.cancel() + }, + cancel: function () { + this.isAdding = false + this.host = "" + this.port = 0 + this.protocol = "" + }, + remove: function (index) { + this.resolvers.$remove(index) + } + }, + template: `
+ +
+
+ {{resolver.protocol}}{{resolver.host}}:{{resolver.port}} +   + +
+
+ +
+
+
+ +
+
+ +   +
+
+
+ +
+ +
+
` +}) + Vue.component("ad-instance-objects-box", { props: ["v-objects", "v-user-id"], mounted: function () { @@ -20277,7 +20420,7 @@ Vue.component("grant-selector", {
` }) -window.REQUEST_COND_COMPONENTS = [{"type":"url-extension","name":"URL扩展名","description":"根据URL中的文件路径扩展名进行过滤","component":"http-cond-url-extension","paramsTitle":"扩展名列表","isRequest":true,"caseInsensitive":false},{"type":"url-eq-index","name":"首页","description":"检查URL路径是为\"/\"","component":"http-cond-url-eq-index","paramsTitle":"URL完整路径","isRequest":true,"caseInsensitive":false},{"type":"url-prefix","name":"URL前缀","description":"根据URL中的文件路径前缀进行过滤","component":"http-cond-url-prefix","paramsTitle":"URL前缀","isRequest":true,"caseInsensitive":true},{"type":"url-eq","name":"URL完整路径","description":"检查URL中的文件路径是否一致","component":"http-cond-url-eq","paramsTitle":"URL完整路径","isRequest":true,"caseInsensitive":true},{"type":"url-regexp","name":"URL正则匹配","description":"使用正则表达式检查URL中的文件路径是否一致","component":"http-cond-url-regexp","paramsTitle":"正则表达式","isRequest":true,"caseInsensitive":true},{"type":"user-agent-regexp","name":"User-Agent正则匹配","description":"使用正则表达式检查User-Agent中是否含有某些浏览器和系统标识","component":"http-cond-user-agent-regexp","paramsTitle":"正则表达式","isRequest":true,"caseInsensitive":true},{"type":"params","name":"参数匹配","description":"根据参数值进行匹配","component":"http-cond-params","paramsTitle":"参数配置","isRequest":true,"caseInsensitive":false},{"type":"url-not-extension","name":"排除:URL扩展名","description":"根据URL中的文件路径扩展名进行过滤","component":"http-cond-url-not-extension","paramsTitle":"扩展名列表","isRequest":true,"caseInsensitive":false},{"type":"url-not-prefix","name":"排除:URL前缀","description":"根据URL中的文件路径前缀进行过滤","component":"http-cond-url-not-prefix","paramsTitle":"URL前缀","isRequest":true,"caseInsensitive":true},{"type":"url-not-eq","name":"排除:URL完整路径","description":"检查URL中的文件路径是否一致","component":"http-cond-url-not-eq","paramsTitle":"URL完整路径","isRequest":true,"caseInsensitive":true},{"type":"url-not-regexp","name":"排除:URL正则匹配","description":"使用正则表达式检查URL中的文件路径是否一致,如果一致,则不匹配","component":"http-cond-url-not-regexp","paramsTitle":"正则表达式","isRequest":true,"caseInsensitive":true},{"type":"user-agent-not-regexp","name":"排除:User-Agent正则匹配","description":"使用正则表达式检查User-Agent中是否含有某些浏览器和系统标识,如果含有,则不匹配","component":"http-cond-user-agent-not-regexp","paramsTitle":"正则表达式","isRequest":true,"caseInsensitive":true},{"type":"mime-type","name":"内容MimeType","description":"根据服务器返回的内容的MimeType进行过滤。注意:当用于缓存条件时,此条件需要结合别的请求条件使用。","component":"http-cond-mime-type","paramsTitle":"MimeType列表","isRequest":false,"caseInsensitive":false}] +window.REQUEST_COND_COMPONENTS = [{"type":"url-extension","name":"文件扩展名","description":"根据URL中的文件路径扩展名进行过滤","component":"http-cond-url-extension","paramsTitle":"扩展名列表","isRequest":true,"caseInsensitive":false},{"type":"url-eq-index","name":"首页","description":"检查URL路径是为\"/\"","component":"http-cond-url-eq-index","paramsTitle":"URL完整路径","isRequest":true,"caseInsensitive":false},{"type":"url-all","name":"全站","description":"全站所有URL","component":"http-cond-url-all","paramsTitle":"URL完整路径","isRequest":true,"caseInsensitive":false},{"type":"url-prefix","name":"URL前缀","description":"根据URL中的文件路径前缀进行过滤","component":"http-cond-url-prefix","paramsTitle":"URL前缀","isRequest":true,"caseInsensitive":true},{"type":"url-eq","name":"URL完整路径","description":"检查URL中的文件路径是否一致","component":"http-cond-url-eq","paramsTitle":"URL完整路径","isRequest":true,"caseInsensitive":true},{"type":"url-regexp","name":"URL正则匹配","description":"使用正则表达式检查URL中的文件路径是否一致","component":"http-cond-url-regexp","paramsTitle":"正则表达式","isRequest":true,"caseInsensitive":true},{"type":"user-agent-regexp","name":"User-Agent正则匹配","description":"使用正则表达式检查User-Agent中是否含有某些浏览器和系统标识","component":"http-cond-user-agent-regexp","paramsTitle":"正则表达式","isRequest":true,"caseInsensitive":true},{"type":"params","name":"参数匹配","description":"根据参数值进行匹配","component":"http-cond-params","paramsTitle":"参数配置","isRequest":true,"caseInsensitive":false},{"type":"url-not-extension","name":"排除:URL扩展名","description":"根据URL中的文件路径扩展名进行过滤","component":"http-cond-url-not-extension","paramsTitle":"扩展名列表","isRequest":true,"caseInsensitive":false},{"type":"url-not-prefix","name":"排除:URL前缀","description":"根据URL中的文件路径前缀进行过滤","component":"http-cond-url-not-prefix","paramsTitle":"URL前缀","isRequest":true,"caseInsensitive":true},{"type":"url-not-eq","name":"排除:URL完整路径","description":"检查URL中的文件路径是否一致","component":"http-cond-url-not-eq","paramsTitle":"URL完整路径","isRequest":true,"caseInsensitive":true},{"type":"url-not-regexp","name":"排除:URL正则匹配","description":"使用正则表达式检查URL中的文件路径是否一致,如果一致,则不匹配","component":"http-cond-url-not-regexp","paramsTitle":"正则表达式","isRequest":true,"caseInsensitive":true},{"type":"user-agent-not-regexp","name":"排除:User-Agent正则匹配","description":"使用正则表达式检查User-Agent中是否含有某些浏览器和系统标识,如果含有,则不匹配","component":"http-cond-user-agent-not-regexp","paramsTitle":"正则表达式","isRequest":true,"caseInsensitive":true},{"type":"mime-type","name":"内容MimeType","description":"根据服务器返回的内容的MimeType进行过滤。注意:当用于缓存条件时,此条件需要结合别的请求条件使用。","component":"http-cond-mime-type","paramsTitle":"MimeType列表","isRequest":false,"caseInsensitive":false}] 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"}]