From e0078a42dce7e7643864b074556c09d80d70d1a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E7=A5=A5=E8=B6=85?= Date: Wed, 26 Oct 2022 16:06:50 +0800 Subject: [PATCH] =?UTF-8?q?URL=E8=B7=B3=E8=BD=AC=E4=B8=AD=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E5=9F=9F=E5=90=8D=E8=B7=B3=E8=BD=AC=E3=80=81=E7=AB=AF?= =?UTF-8?q?=E5=8F=A3=E8=B7=B3=E8=BD=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/settings/redirects/createPopup.go | 170 +++++++++++++----- .../server/http-host-redirect-box.js | 47 ++++- .../settings/redirects/createPopup.html | 157 ++++++++++++---- .../server/settings/redirects/createPopup.js | 16 +- 4 files changed, 297 insertions(+), 93 deletions(-) diff --git a/internal/web/actions/default/servers/server/settings/redirects/createPopup.go b/internal/web/actions/default/servers/server/settings/redirects/createPopup.go index 437e6c67..01d7b582 100644 --- a/internal/web/actions/default/servers/server/settings/redirects/createPopup.go +++ b/internal/web/actions/default/servers/server/settings/redirects/createPopup.go @@ -6,9 +6,9 @@ import ( "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs" "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared" "github.com/iwind/TeaGo/actions" - "github.com/iwind/TeaGo/maps" "net/url" "regexp" + "strings" ) type CreatePopupAction struct { @@ -27,6 +27,9 @@ func (this *CreatePopupAction) RunGet(params struct { } func (this *CreatePopupAction) RunPost(params struct { + Type string + + // URL Mode string BeforeURL string AfterURL string @@ -34,51 +37,129 @@ func (this *CreatePopupAction) RunPost(params struct { MatchRegexp bool KeepRequestURI bool KeepArgs bool - Status int - CondsJSON []byte - IsOn bool + + // 域名 + DomainsAll bool + DomainsBeforeJSON []byte + DomainAfter string + DomainAfterScheme string + + // 端口 + PortsAll bool + PortsBefore []string + PortAfter int + PortAfterScheme string + + Status int + CondsJSON []byte + IsOn bool Must *actions.Must CSRF *actionutils.CSRF }) { - params.Must. - Field("beforeURL", params.BeforeURL). - Require("请填写跳转前的URL") + var config = &serverconfigs.HTTPHostRedirectConfig{} + config.Type = params.Type + config.Status = params.Status + config.IsOn = params.IsOn + + switch params.Type { + case serverconfigs.HTTPHostRedirectTypeURL: + params.Must. + Field("beforeURL", params.BeforeURL). + Require("请填写跳转前的URL") + + // 校验格式 + if params.MatchRegexp { + _, err := regexp.Compile(params.BeforeURL) + if err != nil { + this.Fail("跳转前URL正则表达式错误:" + err.Error()) + } + } else { + u, err := url.Parse(params.BeforeURL) + if err != nil { + this.FailField("beforeURL", "请输入正确的跳转前URL") + } + if (u.Scheme != "http" && u.Scheme != "https") || + len(u.Host) == 0 { + this.FailField("beforeURL", "请输入正确的跳转前URL") + } - // 校验格式 - if params.MatchRegexp { - _, err := regexp.Compile(params.BeforeURL) - if err != nil { - this.Fail("跳转前URL正则表达式错误:" + err.Error()) - } - } else { - u, err := url.Parse(params.BeforeURL) - if err != nil { - this.FailField("beforeURL", "请输入正确的跳转前URL") - } - if (u.Scheme != "http" && u.Scheme != "https") || - len(u.Host) == 0 { - this.FailField("beforeURL", "请输入正确的跳转前URL") } - } + params.Must. + Field("afterURL", params.AfterURL). + Require("请填写跳转后URL") - params.Must. - Field("afterURL", params.AfterURL). - Require("请填写跳转后URL") + // 校验格式 + if params.MatchRegexp { + // 正则表达式情况下不做校验 + } else { + u, err := url.Parse(params.AfterURL) + if err != nil { + this.FailField("afterURL", "请输入正确的跳转后URL") + } + if (u.Scheme != "http" && u.Scheme != "https") || + len(u.Host) == 0 { + this.FailField("afterURL", "请输入正确的跳转后URL") + } + } - // 校验格式 - if params.MatchRegexp { - // 正则表达式情况下不做校验 - } else { - u, err := url.Parse(params.AfterURL) - if err != nil { - this.FailField("afterURL", "请输入正确的跳转后URL") + config.Mode = params.Mode + config.BeforeURL = params.BeforeURL + config.AfterURL = params.AfterURL + config.MatchPrefix = params.MatchPrefix + config.MatchRegexp = params.MatchRegexp + config.KeepRequestURI = params.KeepRequestURI + config.KeepArgs = params.KeepArgs + case serverconfigs.HTTPHostRedirectTypeDomain: + config.DomainsAll = params.DomainsAll + var domainsBefore = []string{} + if len(params.DomainsBeforeJSON) > 0 { + err := json.Unmarshal(params.DomainsBeforeJSON, &domainsBefore) + if err != nil { + this.Fail("错误的域名格式:" + err.Error()) + return + } } - if (u.Scheme != "http" && u.Scheme != "https") || - len(u.Host) == 0 { - this.FailField("afterURL", "请输入正确的跳转后URL") + config.DomainsBefore = domainsBefore + if !params.DomainsAll { + if len(domainsBefore) == 0 { + this.Fail("请输入跳转前域名") + return + } } + if len(params.DomainAfter) == 0 { + this.FailField("domainAfter", "请输入跳转后域名") + return + } + config.DomainAfter = params.DomainAfter + config.DomainAfterScheme = params.DomainAfterScheme + case serverconfigs.HTTPHostRedirectTypePort: + config.PortsAll = params.PortsAll + + config.PortsBefore = params.PortsBefore + var portReg = regexp.MustCompile(`^\d+$`) + var portRangeReg = regexp.MustCompile(`^\d+-\d+$`) + if !config.PortsAll { + for _, port := range params.PortsBefore { + port = strings.ReplaceAll(port, " ", "") + if !portReg.MatchString(port) && !portRangeReg.MatchString(port) { + this.Fail("端口号" + port + "填写错误(请输入单个端口号或一个端口范围)") + return + } + } + if len(params.PortsBefore) == 0 { + this.Fail("请输入跳转前端口") + return + } + } + + if params.PortAfter <= 0 { + this.FailField("portAfter", "请输入跳转后端口") + return + } + config.PortAfter = params.PortAfter + config.PortAfterScheme = params.PortAfterScheme } params.Must. @@ -99,19 +180,16 @@ func (this *CreatePopupAction) RunPost(params struct { this.Fail("匹配条件校验失败:" + err.Error()) } } + config.Conds = conds - this.Data["redirect"] = maps.Map{ - "mode": params.Mode, - "status": params.Status, - "beforeURL": params.BeforeURL, - "afterURL": params.AfterURL, - "matchPrefix": params.MatchPrefix, - "matchRegexp": params.MatchRegexp, - "keepRequestURI": params.KeepRequestURI, - "keepArgs": params.KeepArgs, - "conds": conds, - "isOn": params.IsOn, + // 校验配置 + err := config.Init() + if err != nil { + this.Fail("配置校验失败:" + err.Error()) + return } + this.Data["redirect"] = config + this.Success() } diff --git a/web/public/js/components/server/http-host-redirect-box.js b/web/public/js/components/server/http-host-redirect-box.js index 1d6d3456..e90c28e5 100644 --- a/web/public/js/components/server/http-host-redirect-box.js +++ b/web/public/js/components/server/http-host-redirect-box.js @@ -100,10 +100,9 @@ Vue.component("http-host-redirect-box", { - 跳转前URL + 跳转前 - 跳转后URL - 匹配模式 + 跳转后 HTTP状态码 状态 操作 @@ -113,17 +112,47 @@ Vue.component("http-host-redirect-box", { - {{redirect.beforeURL}} +
+ {{redirect.beforeURL}} +
+ URL跳转 + 匹配前缀 + 正则匹配 + 精准匹配 +
+
+
+ 所有域名 + + {{redirect.domainsBefore[0]}} + {{redirect.domainsBefore[0]}}等{{redirect.domainsBefore.length}}个域名 + +
+ 域名跳转 + {{redirect.domainAfterScheme}} +
+
+
+ 所有端口 + + {{redirect.portsBefore.join(", ")}} + {{redirect.portsBefore.slice(0, 5).join(", ")}}等{{redirect.portsBefore.length}}个端口 + +
+ 端口跳转 + {{redirect.portAfterScheme}} +
+
+
- 匹配条件 + 匹配条件
-> - {{redirect.afterURL}} - 匹配前缀 - 正则匹配 - 精准匹配 + {{redirect.afterURL}} + {{redirect.domainAfter}} + {{redirect.portAfter}} {{redirect.status}} diff --git a/web/views/@default/servers/server/settings/redirects/createPopup.html b/web/views/@default/servers/server/settings/redirects/createPopup.html index cb0be022..cf31dbea 100644 --- a/web/views/@default/servers/server/settings/redirects/createPopup.html +++ b/web/views/@default/servers/server/settings/redirects/createPopup.html @@ -10,46 +10,129 @@ - + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - +
跳转前URL *跳转类型 - -

需要填写完整的URL,包括http://或者https://,如果有非默认端口,也需要带上端口号。

-
匹配模式 * - + + + -

精准匹配跳转前的URL,即只有访问完全一样的URL才会跳转。

-

只要访问的URL头部部分包含跳转前URL,即可跳转。

-

可以在跳转前URL中使用正则表达式,然后可以在跳转后URL中使用正则表达式中括号的变量,比如${1}${2}分别表示第一个和第二个括号内的变量值。

-
跳转后URL * - -

需要填写完整的URL,包括http://或者https://,如果有非默认端口,也需要带上端口号。

-
是否保留URL路径参数 - -

选中后,则跳转之后,保留跳转之前的URL路径和参数。

-
是否保留请求参数 - -

选中后,则跳转之后,保留跳转之前的URL上的参数(即问号之后的部分)。

跳转前URL * + +

需要填写完整的URL,包括http://或者https://,如果有非默认端口,也需要带上端口号。

+
匹配模式 * + +

精准匹配跳转前的URL,即只有访问完全一样的URL才会跳转。

+

只要访问的URL头部部分包含跳转前URL,即可跳转。

+

可以在跳转前URL中使用正则表达式,然后可以在跳转后URL中使用正则表达式中括号的变量,比如${1}${2}分别表示第一个和第二个括号内的变量值。

+
跳转后URL * + +

需要填写完整的URL,包括http://或者https://,如果有非默认端口,也需要带上端口号。

+
是否保留URL路径参数 + +

选中后,则跳转之后,保留跳转之前的URL路径和参数。

+
是否保留请求参数 + +

选中后,则跳转之后,保留跳转之前的URL上的参数(即问号之后的部分)。

+
所有域名都跳转 + +

选中后,表示所有域名都会跳转(只要跳转前后域名不同);不选中后可以指定域名跳转。

+
指定跳转前域名 + +
跳转后域名 * + +
跳转后协议 + +

跳转后的URL的协议。

+
所有端口都跳转 + +

选中后,表示所有端口都会跳转(只要跳转前后端口不同);不选中后可以指定端口跳转。

+
指定跳转前端口 + +
跳转后端口 * + +
跳转后协议 + +

跳转后的URL的协议。

+
跳转状态码 @@ -64,7 +147,7 @@
是否启用启用当前跳转
diff --git a/web/views/@default/servers/server/settings/redirects/createPopup.js b/web/views/@default/servers/server/settings/redirects/createPopup.js index fceb441e..4f4868fd 100644 --- a/web/views/@default/servers/server/settings/redirects/createPopup.js +++ b/web/views/@default/servers/server/settings/redirects/createPopup.js @@ -3,8 +3,12 @@ Tea.context(function () { if (window.parent.UPDATING_REDIRECT != null) { this.isCreating = false this.redirect = window.parent.UPDATING_REDIRECT + if (this.redirect.type == null || this.redirect.type.length == 0) { + this.redirect.type = "url" + } } else { this.redirect = { + type: "url", status: 0, beforeURL: "", afterURL: "", @@ -13,7 +17,17 @@ Tea.context(function () { keepRequestURI: false, keepArgs: true, conds: null, - isOn: true + isOn: true, + + domainsAll: false, + domainBefore: [], + domainAfter: "", + domainAfterScheme: "", + + portsAll: false, + portsBefore: [], + portAfter: 0, + portAfterScheme: "" } }