diff --git a/internal/web/actions/default/servers/server/settings/locations/userAgent/index.go b/internal/web/actions/default/servers/server/settings/locations/userAgent/index.go index 494079ac..b579b020 100644 --- a/internal/web/actions/default/servers/server/settings/locations/userAgent/index.go +++ b/internal/web/actions/default/servers/server/settings/locations/userAgent/index.go @@ -1,6 +1,6 @@ // Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved. -package useragent +package userAgent import ( "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" diff --git a/internal/web/actions/default/servers/server/settings/locations/userAgent/init.go b/internal/web/actions/default/servers/server/settings/locations/userAgent/init.go index debd17be..a1097802 100644 --- a/internal/web/actions/default/servers/server/settings/locations/userAgent/init.go +++ b/internal/web/actions/default/servers/server/settings/locations/userAgent/init.go @@ -1,4 +1,4 @@ -package useragent +package userAgent import ( "github.com/TeaOSLab/EdgeAdmin/internal/configloaders" diff --git a/internal/web/actions/default/servers/server/settings/userAgent/index.go b/internal/web/actions/default/servers/server/settings/userAgent/index.go index 0a82053a..15cac26c 100644 --- a/internal/web/actions/default/servers/server/settings/userAgent/index.go +++ b/internal/web/actions/default/servers/server/settings/userAgent/index.go @@ -1,6 +1,6 @@ // Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved. -package useragent +package userAgent import ( "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" diff --git a/internal/web/actions/default/servers/server/settings/userAgent/init.go b/internal/web/actions/default/servers/server/settings/userAgent/init.go index ba0a1f13..ec783a5b 100644 --- a/internal/web/actions/default/servers/server/settings/userAgent/init.go +++ b/internal/web/actions/default/servers/server/settings/userAgent/init.go @@ -1,4 +1,4 @@ -package useragent +package userAgent import ( "github.com/TeaOSLab/EdgeAdmin/internal/configloaders" diff --git a/internal/web/import.go b/internal/web/import.go index 7d24606a..88acef41 100644 --- a/internal/web/import.go +++ b/internal/web/import.go @@ -103,7 +103,7 @@ import ( _ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/server/settings/tls" _ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/server/settings/udp" _ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/server/settings/unix" - _ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/server/settings/useragent" + _ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/server/settings/userAgent" _ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/server/settings/waf" _ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/server/settings/web" _ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/server/settings/webp" diff --git a/web/public/js/components.js b/web/public/js/components.js index 72028fef..56f1a56f 100644 --- a/web/public/js/components.js +++ b/web/public/js/components.js @@ -2235,7 +2235,18 @@ Vue.component("traffic-map-box",{props:["v-stats","v-is-attack"],mounted:functio 删除 -`}),Vue.component("http-firewall-policy-selector",{props:["v-http-firewall-policy"],mounted:function(){let t=this;Tea.action("/servers/components/waf/count").post().success(function(e){t.count=e.data.count})},data:function(){return{count:0,firewallPolicy:this.vHttpFirewallPolicy}},methods:{remove:function(){this.firewallPolicy=null},select:function(){let t=this;teaweb.popup("/servers/components/waf/selectPopup",{callback:function(e){t.firewallPolicy=e.data.firewallPolicy}})},create:function(){let t=this;teaweb.popup("/servers/components/waf/createPopup",{height:"26em",callback:function(e){t.firewallPolicy=e.data.firewallPolicy}})}},template:`
+`}),Vue.component("http-cors-header-config-box",{props:["value"],data:function(){let e=this.value;return{config:e=null==e?{isOn:!1,allowMethods:[],allowOrigin:"",allowCredentials:!0,exposeHeaders:[],maxAge:0,requestHeaders:[],requestMethod:""}:e}},template:`
+ + + + + + +
启用CORS自适应跨域 + +
+
+
`}),Vue.component("http-firewall-policy-selector",{props:["v-http-firewall-policy"],mounted:function(){let t=this;Tea.action("/servers/components/waf/count").post().success(function(e){t.count=e.data.count})},data:function(){return{count:0,firewallPolicy:this.vHttpFirewallPolicy}},methods:{remove:function(){this.firewallPolicy=null},select:function(){let t=this;teaweb.popup("/servers/components/waf/selectPopup",{callback:function(e){t.firewallPolicy=e.data.firewallPolicy}})},create:function(){let t=this;teaweb.popup("/servers/components/waf/createPopup",{height:"26em",callback:function(e){t.firewallPolicy=e.data.firewallPolicy}})}},template:`
{{firewallPolicy.name}}     @@ -2976,7 +2987,7 @@ example2.com
-
`}),Vue.component("http-header-policy-box",{props:["v-request-header-policy","v-request-header-ref","v-response-header-policy","v-response-header-ref","v-params","v-is-location","v-is-group","v-has-group-request-config","v-has-group-response-config","v-group-setting-url"],data:function(){let e="response";"#request"==window.location.hash&&(e="request");let t=this.vRequestHeaderRef,i=(null==t&&(t={isPrior:!1,isOn:!0,headerPolicyId:0}),this.vResponseHeaderRef),n=(null==i&&(i={isPrior:!1,isOn:!0,headerPolicyId:0}),[]),s=[];var o=this.vRequestHeaderPolicy;null!=o&&(null!=o.setHeaders&&(n=o.setHeaders),null!=o.deleteHeaders&&(s=o.deleteHeaders));let a=[],l=[];o=this.vResponseHeaderPolicy;return null!=o&&(null!=o.setHeaders&&(a=o.setHeaders),null!=o.deleteHeaders&&(l=o.deleteHeaders)),{type:e,typeName:"request"==e?"请求":"响应",requestHeaderRef:t,responseHeaderRef:i,requestSettingHeaders:n,requestDeletingHeaders:s,responseSettingHeaders:a,responseDeletingHeaders:l}},methods:{selectType:function(e){this.type=e,window.location.hash="#"+e,window.location.reload()},addSettingHeader:function(e){teaweb.popup("/servers/server/settings/headers/createSetPopup?"+this.vParams+"&headerPolicyId="+e+"&type="+this.type,{callback:function(){teaweb.successRefresh("保存成功")}})},addDeletingHeader:function(e,t){teaweb.popup("/servers/server/settings/headers/createDeletePopup?"+this.vParams+"&headerPolicyId="+e+"&type="+t,{callback:function(){teaweb.successRefresh("保存成功")}})},updateSettingPopup:function(e,t){teaweb.popup("/servers/server/settings/headers/updateSetPopup?"+this.vParams+"&headerPolicyId="+e+"&headerId="+t+"&type="+this.type,{callback:function(){teaweb.successRefresh("保存成功")}})},deleteDeletingHeader:function(e,t){teaweb.confirm("确定要删除'"+t+"'吗?",function(){Tea.action("/servers/server/settings/headers/deleteDeletingHeader").params({headerPolicyId:e,headerName:t}).post().refresh()})},deleteHeader:function(e,t,i){teaweb.confirm("确定要删除此Header吗?",function(){this.$post("/servers/server/settings/headers/delete").params({headerPolicyId:e,type:t,headerId:i}).refresh()})}},template:`
+
`}),Vue.component("http-header-policy-box",{props:["v-request-header-policy","v-request-header-ref","v-response-header-policy","v-response-header-ref","v-params","v-is-location","v-is-group","v-has-group-request-config","v-has-group-response-config","v-group-setting-url"],data:function(){let e="response";"#request"==window.location.hash&&(e="request");let t=this.vRequestHeaderRef,i=(null==t&&(t={isPrior:!1,isOn:!0,headerPolicyId:0}),this.vResponseHeaderRef),n=(null==i&&(i={isPrior:!1,isOn:!0,headerPolicyId:0}),[]),s=[];var o=this.vRequestHeaderPolicy;null!=o&&(null!=o.setHeaders&&(n=o.setHeaders),null!=o.deleteHeaders&&(s=o.deleteHeaders));let a=[],l=[];o=this.vResponseHeaderPolicy;null!=o&&(null!=o.setHeaders&&(a=o.setHeaders),null!=o.deleteHeaders&&(l=o.deleteHeaders));let c={isOn:!1};return null!=o.cors&&(c=o.cors),{type:e,typeName:"request"==e?"请求":"响应",requestHeaderRef:t,responseHeaderRef:i,requestSettingHeaders:n,requestDeletingHeaders:s,responseSettingHeaders:a,responseDeletingHeaders:l,responseCORS:c}},methods:{selectType:function(e){this.type=e,window.location.hash="#"+e,window.location.reload()},addSettingHeader:function(e){teaweb.popup("/servers/server/settings/headers/createSetPopup?"+this.vParams+"&headerPolicyId="+e+"&type="+this.type,{callback:function(){teaweb.successRefresh("保存成功")}})},addDeletingHeader:function(e,t){teaweb.popup("/servers/server/settings/headers/createDeletePopup?"+this.vParams+"&headerPolicyId="+e+"&type="+t,{callback:function(){teaweb.successRefresh("保存成功")}})},updateSettingPopup:function(e,t){teaweb.popup("/servers/server/settings/headers/updateSetPopup?"+this.vParams+"&headerPolicyId="+e+"&headerId="+t+"&type="+this.type,{callback:function(){teaweb.successRefresh("保存成功")}})},deleteDeletingHeader:function(e,t){teaweb.confirm("确定要删除'"+t+"'吗?",function(){Tea.action("/servers/server/settings/headers/deleteDeletingHeader").params({headerPolicyId:e,headerName:t}).post().refresh()})},deleteHeader:function(e,t,i){teaweb.confirm("确定要删除此Header吗?",function(){this.$post("/servers/server/settings/headers/delete").params({headerPolicyId:e,type:t,headerId:i}).refresh()})},updateCORS:function(e){teaweb.popup("/servers/server/settings/headers/updateCORSPopup?"+this.vParams+"&headerPolicyId="+e+"&type="+this.type,{callback:function(){teaweb.successRefresh("保存成功")}})}},template:`
-

设置请求Header [添加新Header]

+

设置请求Header [添加新Header]

暂时还没有Header。

@@ -3011,35 +3022,39 @@ example2.com - - - - - + + + + + + +
操作
- {{header.name}} -
- {{code}} - {{method}} - {{domain}} - 附加 - 跳转禁用 - 替换 -
-
{{header.value}}修改   删除
+ {{header.name}} +
+ {{code}} + {{method}} + {{domain}} + 附加 + 跳转禁用 + 替换 +
+
{{header.value}}修改   删除
-

删除请求Header

+

删除请求Header

这里可以设置需要从请求中删除的Header。

- - + + + +
需要删除的Header -
-
{{headerName}}
-
-
- -
需要删除的Header +
+
{{headerName}}
+
+
+ +
@@ -3059,7 +3074,7 @@ example2.com 由于已经在当前服务分组中进行了对应的配置,在这里的配置将不会生效。
-

设置响应Header [添加新Header]

+

设置响应Header [添加新Header]

将会覆盖已有的同名Header。

暂时还没有Header。

@@ -3070,37 +3085,52 @@ example2.com - - - - - + + + + + + +
操作
- {{header.name}} -
- {{code}} - {{method}} - {{domain}} - 附加 - 跳转禁用 - 替换 -
-
{{header.value}}修改   删除
+ {{header.name}} +
+ {{code}} + {{method}} + {{domain}} + 附加 + 跳转禁用 + 替换 +
+
{{header.value}}修改   删除
-

删除响应Header

+

删除响应Header

这里可以设置需要从响应中删除的Header。

- - + + + +
需要删除的Header -
-
{{headerName}}
-
-
- -
需要删除的Header +
+
{{headerName}}
+
+
+ +
-
+ +

其他设置

+ + + + + + +
CORS自适应跨域 + 已启用未启用   [修改] +
+
`}),Vue.component("http-common-config-box",{props:["v-common-config"],data:function(){let e=this.vCommonConfig;return{config:e=null==e?{mergeSlashes:!1}:e}},template:`
@@ -3211,7 +3241,7 @@ example2.com
-
`}),Vue.component("http-compression-config-box",{props:["v-compression-config","v-is-location","v-is-group"],mounted:function(){let e=this;sortLoad(function(){e.initSortableTypes()})},data:function(){let t=this.vCompressionConfig,e=(null==(t=null==t?{isPrior:!1,isOn:!1,useDefaultTypes:!0,types:["brotli","gzip","zstd","deflate"],level:5,decompressData:!1,gzipRef:null,deflateRef:null,brotliRef:null,minLength:{count:0,unit:"kb"},maxLength:{count:0,unit:"kb"},mimeTypes:["text/*","application/javascript","application/json","application/atom+xml","application/rss+xml","application/xhtml+xml","font/*","image/svg+xml"],extensions:[".js",".json",".html",".htm",".xml",".css",".woff2",".txt"],conds:null}:t).types&&(t.types=[]),null==t.mimeTypes&&(t.mimeTypes=[]),null==t.extensions&&(t.extensions=[]),[{name:"Gzip",code:"gzip",isOn:!0},{name:"Deflate",code:"deflate",isOn:!0},{name:"Brotli",code:"brotli",isOn:!0},{name:"ZSTD",code:"zstd",isOn:!0}]),i=[];return t.types.forEach(function(t){e.forEach(function(e){t==e.code&&(e.isOn=!0,i.push(e))})}),e.forEach(function(e){t.types.$contains(e.code)||(e.isOn=!1,i.push(e))}),{config:t,moreOptionsVisible:!1,allTypes:i}},watch:{"config.level":function(e){let t=parseInt(e);isNaN(t)||t<1?t=1:10 +`}),Vue.component("http-compression-config-box",{props:["v-compression-config","v-is-location","v-is-group"],mounted:function(){let e=this;sortLoad(function(){e.initSortableTypes()})},data:function(){let t=this.vCompressionConfig,e=(null==(t=null==t?{isPrior:!1,isOn:!1,useDefaultTypes:!0,types:["brotli","gzip","zstd","deflate"],level:5,decompressData:!1,gzipRef:null,deflateRef:null,brotliRef:null,minLength:{count:1,unit:"kb"},maxLength:{count:32,unit:"mb"},mimeTypes:["text/*","application/javascript","application/json","application/atom+xml","application/rss+xml","application/xhtml+xml","font/*","image/svg+xml"],extensions:[".js",".json",".html",".htm",".xml",".css",".woff2",".txt"],exceptExtensions:[".apk",".ipa"],conds:null,enablePartialContent:!1}:t).types&&(t.types=[]),null==t.mimeTypes&&(t.mimeTypes=[]),null==t.extensions&&(t.extensions=[]),[{name:"Gzip",code:"gzip",isOn:!0},{name:"Deflate",code:"deflate",isOn:!0},{name:"Brotli",code:"brotli",isOn:!0},{name:"ZSTD",code:"zstd",isOn:!0}]),i=[];return t.types.forEach(function(t){e.forEach(function(e){t==e.code&&(e.isOn=!0,i.push(e))})}),e.forEach(function(e){t.types.$contains(e.code)||(e.isOn=!1,i.push(e))}),{config:t,moreOptionsVisible:!1,allTypes:i}},watch:{"config.level":function(e){let t=parseInt(e);isNaN(t)||t<1?t=1:10 @@ -3243,6 +3273,13 @@ example2.com

含有这些扩展名的URL将会被压缩,不区分大小写。

+ + + + + + + +
例外扩展名 + +

含有这些扩展名的URL将不会被压缩,不区分大小写。

+
支持的MimeType @@ -3295,6 +3332,13 @@ example2.com

0表示不限制,内容长度从文件尺寸或Content-Length中获取。

支持Partial
Content
+ +

支持对分区内容(PartialContent)的压缩;除非客户端有特殊要求,一般不需要启用。

+
匹配条件 @@ -4191,8 +4235,8 @@ example2.com {{cond.value}} -`}),Vue.component("http-header-assistant",{props:["v-type","v-value"],mounted:function(){let t=this;Tea.action("/servers/headers/options?type="+this.vType).post().success(function(e){t.allHeaders=e.data.headers})},data:function(){return{allHeaders:[],matchedHeaders:[],selectedHeaderName:""}},watch:{vValue:function(t){t!=this.selectedHeaderName&&(this.selectedHeaderName=""),0==t.length?this.matchedHeaders=[]:this.matchedHeaders=this.allHeaders.filter(function(e){return teaweb.match(e,t)}).slice(0,5)}},methods:{select:function(e){this.$emit("select",e),this.selectedHeaderName=e}},template:` - {{header}} +`}),Vue.component("http-header-assistant",{props:["v-type","v-value"],mounted:function(){let t=this;Tea.action("/servers/headers/options?type="+this.vType).post().success(function(e){t.allHeaders=e.data.headers})},data:function(){return{allHeaders:[],matchedHeaders:[],selectedHeaderName:""}},watch:{vValue:function(t){t!=this.selectedHeaderName&&(this.selectedHeaderName=""),0==t.length?this.matchedHeaders=[]:this.matchedHeaders=this.allHeaders.filter(function(e){return teaweb.match(e,t)}).slice(0,10)}},methods:{select:function(e){this.$emit("select",e),this.selectedHeaderName=e}},template:` + {{header}}     `}),Vue.component("http-firewall-rules-box",{props:["v-rules","v-type"],data:function(){let e=this.vRules;return{rules:e=null==e?[]:e}},methods:{addRule:function(){window.UPDATING_RULE=null;let t=this;teaweb.popup("/servers/components/waf/createRulePopup?type="+this.vType,{height:"30em",callback:function(e){t.rules.push(e.data.rule)}})},updateRule:function(t,e){window.UPDATING_RULE=teaweb.clone(e);let i=this;teaweb.popup("/servers/components/waf/createRulePopup?type="+this.vType,{height:"30em",callback:function(e){Vue.set(i.rules,t,e.data.rule)}})},removeRule:function(e){let t=this;teaweb.confirm("确定要删除此规则吗?",function(){t.rules.$remove(e)})}},template:`
@@ -4713,7 +4757,80 @@ example2.com
-`}),Vue.component("firewall-syn-flood-config-box",{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,isEditing:!1,minAttempts:e.minAttempts,timeoutSeconds:e.timeoutSeconds}},methods:{edit:function(){this.isEditing=!this.isEditing}},watch:{minAttempts:function(e){let t=parseInt(e);(t=isNaN(t)?10:t)<5&&(t=5),this.config.minAttempts=t},timeoutSeconds:function(e){let t=parseInt(e);(t=isNaN(t)?10:t)<60&&(t=60),this.config.timeoutSeconds=t}},template:`
+`}),Vue.component("user-agent-config-box",{props:["v-is-location","v-is-group","value"],data:function(){let e=this.value;return null==(e=null==e?{isPrior:!1,isOn:!1,filters:[]}:e).filters&&(e.filters=[]),{config:e,isAdding:!1,addingFilter:{keywords:[],action:"deny"}}},methods:{isOn:function(){return(!this.vIsLocation&&!this.vIsGroup||this.config.isPrior)&&this.config.isOn},remove:function(e){let t=this;teaweb.confirm("确定要删除此名单吗?",function(){t.config.filters.$remove(e)})},add:function(){this.isAdding=!0},confirm:function(){if("deny"==this.addingFilter.action)this.config.filters.push(this.addingFilter);else{let i=-1;this.config.filters.forEach(function(e,t){"allow"==e.action&&(i=t)}),i<0?this.config.filters.unshift(this.addingFilter):this.config.filters.$insert(i+1,this.addingFilter)}this.cancel()},cancel:function(){this.isAdding=!1,this.addingFilter={keywords:[],action:"deny"}},changeKeywords:function(e){this.addingFilter.keywords=e}},template:`
+ + + + + + + + + + + + + + + +
启用UA名单 +
+ + +
+

选中后表示开启UserAgent名单。

+
UA名单 +
+ + + + + + + + + + + + + + + +
UA关键词动作操作
+ + {{keyword}} + [空] + + + 允许不允许 + 删除
+
+
+ + + + + + + + + +
UA关键词 + +

不区分大小写,比如Chrome;支持*通配符,比如*Firefox*;也支持空的关键词,表示空UserAgent。

+
动作 +
+   +
+
+ +
+
+
+
`}),Vue.component("firewall-syn-flood-config-box",{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,isEditing:!1,minAttempts:e.minAttempts,timeoutSeconds:e.timeoutSeconds}},methods:{edit:function(){this.isEditing=!this.isEditing}},watch:{minAttempts:function(e){let t=parseInt(e);(t=isNaN(t)?10:t)<5&&(t=5),this.config.minAttempts=t},timeoutSeconds:function(e){let t=parseInt(e);(t=isNaN(t)?10:t)<60&&(t=60),this.config.timeoutSeconds=t}},template:`
@@ -4981,14 +5098,19 @@ 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"],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&&(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"],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:`
-
{{value}}
+
+ {{value}} + [空] +
[修改]
-
{{value}} +
+ {{value}} + [空]   diff --git a/web/public/js/components.src.js b/web/public/js/components.src.js index 1d47b77e..6852234b 100755 --- a/web/public/js/components.src.js +++ b/web/public/js/components.src.js @@ -6594,6 +6594,41 @@ Vue.component("origin-list-table", { ` }) +Vue.component("http-cors-header-config-box", { + props: ["value"], + data: function () { + let config = this.value + if (config == null) { + config = { + isOn: false, + allowMethods: [], + allowOrigin: "", + allowCredentials: true, + exposeHeaders: [], + maxAge: 0, + requestHeaders: [], + requestMethod: "" + } + } + + return { + config: config + } + }, + template: `
+ + + + + + +
启用CORS自适应跨域 + +
+
+
` +}) + Vue.component("http-firewall-policy-selector", { props: ["v-http-firewall-policy"], mounted: function () { @@ -8690,6 +8725,13 @@ Vue.component("http-header-policy-box", { } } + let responseCORS = { + isOn: false + } + if (responsePolicy.cors != null) { + responseCORS = responsePolicy.cors + } + return { type: type, typeName: (type == "request") ? "请求" : "响应", @@ -8698,7 +8740,8 @@ Vue.component("http-header-policy-box", { requestSettingHeaders: requestSettingHeaders, requestDeletingHeaders: requestDeletingHeaders, responseSettingHeaders: responseSettingHeaders, - responseDeletingHeaders: responseDeletingHeaders + responseDeletingHeaders: responseDeletingHeaders, + responseCORS: responseCORS } }, methods: { @@ -8750,6 +8793,13 @@ Vue.component("http-header-policy-box", { .refresh() } ) + }, + updateCORS: function (policyId) { + teaweb.popup("/servers/server/settings/headers/updateCORSPopup?" + this.vParams + "&headerPolicyId=" + policyId + "&type=" + this.type, { + callback: function () { + teaweb.successRefresh("保存成功") + } + }) } }, template: `
@@ -8777,7 +8827,7 @@ Vue.component("http-header-policy-box", { 由于已经在当前服务分组中进行了对应的配置,在这里的配置将不会生效。
-

设置请求Header [添加新Header]

+

设置请求Header [添加新Header]

暂时还没有Header。

@@ -8787,35 +8837,39 @@ Vue.component("http-header-policy-box", { - - - - - + + + + + + +
操作
- {{header.name}} -
- {{code}} - {{method}} - {{domain}} - 附加 - 跳转禁用 - 替换 -
-
{{header.value}}修改   删除
+ {{header.name}} +
+ {{code}} + {{method}} + {{domain}} + 附加 + 跳转禁用 + 替换 +
+
{{header.value}}修改   删除
-

删除请求Header

+

删除请求Header

这里可以设置需要从请求中删除的Header。

- - + + + +
需要删除的Header -
-
{{headerName}}
-
-
- -
需要删除的Header +
+
{{headerName}}
+
+
+ +
@@ -8835,7 +8889,7 @@ Vue.component("http-header-policy-box", { 由于已经在当前服务分组中进行了对应的配置,在这里的配置将不会生效。
-

设置响应Header [添加新Header]

+

设置响应Header [添加新Header]

将会覆盖已有的同名Header。

暂时还没有Header。

@@ -8846,37 +8900,52 @@ Vue.component("http-header-policy-box", { - - - - - + + + + + + +
操作
- {{header.name}} -
- {{code}} - {{method}} - {{domain}} - 附加 - 跳转禁用 - 替换 -
-
{{header.value}}修改   删除
+ {{header.name}} +
+ {{code}} + {{method}} + {{domain}} + 附加 + 跳转禁用 + 替换 +
+
{{header.value}}修改   删除
-

删除响应Header

+

删除响应Header

这里可以设置需要从响应中删除的Header。

- - + + + +
需要删除的Header -
-
{{headerName}}
-
-
- -
需要删除的Header +
+
{{headerName}}
+
+
+ +
-
+ +

其他设置

+ + + + + + +
CORS自适应跨域 + 已启用未启用   [修改] +
+
` @@ -9151,11 +9220,13 @@ Vue.component("http-compression-config-box", { gzipRef: null, deflateRef: null, brotliRef: null, - minLength: {count: 0, "unit": "kb"}, - maxLength: {count: 0, "unit": "kb"}, + minLength: {count: 1, "unit": "kb"}, + maxLength: {count: 32, "unit": "mb"}, mimeTypes: ["text/*", "application/javascript", "application/json", "application/atom+xml", "application/rss+xml", "application/xhtml+xml", "font/*", "image/svg+xml"], extensions: [".js", ".json", ".html", ".htm", ".xml", ".css", ".woff2", ".txt"], - conds: null + exceptExtensions: [".apk", ".ipa"], + conds: null, + enablePartialContent: false } } @@ -9239,6 +9310,14 @@ Vue.component("http-compression-config-box", { }) this.config.extensions = values }, + changeExceptExtensions: function (values) { + values.forEach(function (v, k) { + if (v.length > 0 && v[0] != ".") { + values[k] = "." + v + } + }) + this.config.exceptExtensions = values + }, changeMimeTypes: function (values) { this.config.mimeTypes = values }, @@ -9310,6 +9389,13 @@ Vue.component("http-compression-config-box", {

含有这些扩展名的URL将会被压缩,不区分大小写。

+ + 例外扩展名 + + +

含有这些扩展名的URL将不会被压缩,不区分大小写。

+ + 支持的MimeType @@ -9362,6 +9448,13 @@ Vue.component("http-compression-config-box", {

0表示不限制,内容长度从文件尺寸或Content-Length中获取。

+ + 支持Partial
Content + + +

支持对分区内容(PartialContent)的压缩;除非客户端有特殊要求,一般不需要启用。

+ + 匹配条件 @@ -11864,7 +11957,7 @@ Vue.component("http-header-assistant", { } this.matchedHeaders = this.allHeaders.filter(function (header) { return teaweb.match(header, v) - }).slice(0, 5) + }).slice(0, 10) } }, methods: { @@ -11874,7 +11967,7 @@ Vue.component("http-header-assistant", { } }, template: ` - {{header}} + {{header}}     ` }) @@ -13525,6 +13618,149 @@ Vue.component("http-firewall-captcha-options", { ` }) +Vue.component("user-agent-config-box", { + props: ["v-is-location", "v-is-group", "value"], + data: function () { + let config = this.value + if (config == null) { + config = { + isPrior: false, + isOn: false, + filters: [] + } + } + if (config.filters == null) { + config.filters = [] + } + return { + config: config, + isAdding: false, + addingFilter: { + keywords: [], + action: "deny" + } + } + }, + methods: { + isOn: function () { + return ((!this.vIsLocation && !this.vIsGroup) || this.config.isPrior) && this.config.isOn + }, + remove: function (index) { + let that = this + teaweb.confirm("确定要删除此名单吗?", function () { + that.config.filters.$remove(index) + }) + }, + add: function () { + this.isAdding = true + }, + confirm: function () { + if (this.addingFilter.action == "deny") { + this.config.filters.push(this.addingFilter) + } else { + let index = -1 + this.config.filters.forEach(function (filter, filterIndex) { + if (filter.action == "allow") { + index = filterIndex + } + }) + + if (index < 0) { + this.config.filters.unshift(this.addingFilter) + } else { + this.config.filters.$insert(index + 1, this.addingFilter) + } + } + + this.cancel() + }, + cancel: function () { + this.isAdding = false + this.addingFilter = { + keywords: [], + action: "deny" + } + }, + changeKeywords: function (keywords) { + this.addingFilter.keywords = keywords + } + }, + template: `
+ + + + + + + + + + + + + + + +
启用UA名单 +
+ + +
+

选中后表示开启UserAgent名单。

+
UA名单 +
+ + + + + + + + + + + + + + + +
UA关键词动作操作
+ + {{keyword}} + [空] + + + 允许不允许 + 删除
+
+
+ + + + + + + + + +
UA关键词 + +

不区分大小写,比如Chrome;支持*通配符,比如*Firefox*;也支持空的关键词,表示空UserAgent。

+
动作 +
+   +
+
+ +
+
+
+
` +}) + Vue.component("firewall-syn-flood-config-box", { props: ["v-syn-flood-config"], data: function () { @@ -14623,7 +14859,7 @@ Vue.component("download-link", { }) Vue.component("values-box", { - props: ["values", "v-values", "size", "maxlength", "name", "placeholder"], + props: ["values", "v-values", "size", "maxlength", "name", "placeholder", "v-allow-empty"], data: function () { let values = this.values; if (values == null) { @@ -14663,7 +14899,9 @@ Vue.component("values-box", { }, confirm: function () { if (this.value.length == 0) { - return + if (typeof(this.vAllowEmpty) != "boolean" || !this.vAllowEmpty) { + return + } } if (this.isUpdating) { @@ -14699,12 +14937,17 @@ Vue.component("values-box", { }, template: `
-
{{value}}
+
+ {{value}} + [空] +
[修改]
-
{{value}} +
+ {{value}} + [空]