URL跳转中增加域名跳转、端口跳转

This commit is contained in:
GoEdgeLab
2022-10-26 16:06:50 +08:00
parent 4fa1234d4d
commit a5f75a87f2
4 changed files with 297 additions and 93 deletions

View File

@@ -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,6 +37,19 @@ func (this *CreatePopupAction) RunPost(params struct {
MatchRegexp bool
KeepRequestURI bool
KeepArgs bool
// 域名
DomainsAll bool
DomainsBeforeJSON []byte
DomainAfter string
DomainAfterScheme string
// 端口
PortsAll bool
PortsBefore []string
PortAfter int
PortAfterScheme string
Status int
CondsJSON []byte
IsOn bool
@@ -41,6 +57,13 @@ func (this *CreatePopupAction) RunPost(params struct {
Must *actions.Must
CSRF *actionutils.CSRF
}) {
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")
@@ -81,6 +104,64 @@ func (this *CreatePopupAction) RunPost(params struct {
}
}
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
}
}
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.
Field("status", params.Status).
Gte(0, "请选择正确的跳转状态码")
@@ -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()
}

View File

@@ -100,10 +100,9 @@ Vue.component("http-host-redirect-box", {
<thead>
<tr>
<th style="width: 1em"></th>
<th>跳转前URL</th>
<th>跳转前</th>
<th style="width: 1em"></th>
<th>跳转后URL</th>
<th>匹配模式</th>
<th>跳转后</th>
<th>HTTP状态码</th>
<th class="two wide">状态</th>
<th class="two op">操作</th>
@@ -113,17 +112,47 @@ Vue.component("http-host-redirect-box", {
<tr>
<td style="text-align: center;"><i class="icon bars handle grey"></i> </td>
<td>
<div v-if="redirect.type == '' || redirect.type == 'url'">
{{redirect.beforeURL}}
<div style="margin-top: 0.4em">
<grey-label><strong>URL跳转</strong></grey-label>
<grey-label v-if="redirect.matchPrefix">匹配前缀</grey-label>
<grey-label v-if="redirect.matchRegexp">正则匹配</grey-label>
<grey-label v-if="!redirect.matchPrefix && !redirect.matchRegexp">精准匹配</grey-label>
</div>
</div>
<div v-if="redirect.type == 'domain'">
<span v-if="redirect.domainsAll">所有域名</span>
<span v-if="!redirect.domainsAll && redirect.domainsBefore != null">
<span v-if="redirect.domainsBefore.length == 1">{{redirect.domainsBefore[0]}}</span>
<span v-if="redirect.domainsBefore.length > 1">{{redirect.domainsBefore[0]}}等{{redirect.domainsBefore.length}}个域名</span>
</span>
<div style="margin-top: 0.4em">
<grey-label><strong>域名跳转</strong></grey-label>
<grey-label v-if="redirect.domainAfterScheme != null && redirect.domainAfterScheme.length > 0">{{redirect.domainAfterScheme}}</grey-label>
</div>
</div>
<div v-if="redirect.type == 'port'">
<span v-if="redirect.portsAll">所有端口</span>
<span v-if="!redirect.portsAll && redirect.portsBefore != null">
<span v-if="redirect.portsBefore.length <= 5">{{redirect.portsBefore.join(", ")}}</span>
<span v-if="redirect.portsBefore.length > 5">{{redirect.portsBefore.slice(0, 5).join(", ")}}等{{redirect.portsBefore.length}}个端口</span>
</span>
<div style="margin-top: 0.4em">
<grey-label><strong>端口跳转</strong></grey-label>
<grey-label v-if="redirect.portAfterScheme != null && redirect.portAfterScheme.length > 0">{{redirect.portAfterScheme}}</grey-label>
</div>
</div>
<div style="margin-top: 0.5em" v-if="redirect.conds != null && redirect.conds.groups != null && redirect.conds.groups.length > 0">
<span class="ui label text basic tiny">匹配条件</span>
<grey-label>匹配条件</grey-label>
</div>
</td>
<td nowrap="">-&gt;</td>
<td>{{redirect.afterURL}}</td>
<td>
<span v-if="redirect.matchPrefix">匹配前缀</span>
<span v-if="redirect.matchRegexp">正则匹配</span>
<span v-if="!redirect.matchPrefix && !redirect.matchRegexp">精准匹配</span>
<span v-if="redirect.type == '' || redirect.type == 'url'">{{redirect.afterURL}}</span>
<span v-if="redirect.type == 'domain'">{{redirect.domainAfter}}</span>
<span v-if="redirect.type == 'port'">{{redirect.portAfter}}</span>
</td>
<td>
<span v-if="redirect.status > 0">{{redirect.status}}</span>

View File

@@ -10,14 +10,27 @@
<table class="ui table definition selectable">
<tr>
<td class="title">跳转前URL *</td>
<td class="title">跳转类型</td>
<td>
<select class="ui dropdown auto-width" name="type" v-model="redirect.type">
<option value="url">URL跳转</option>
<option value="domain">域名跳转</option>
<option value="port">端口跳转</option>
</select>
</td>
</tr>
<!-- URL跳转 -->
<tbody v-show="redirect.type == 'url'">
<tr>
<td class="color-border">跳转前URL *</td>
<td>
<input type="text" name="beforeURL" placeholder="比如 http://www.url1.com" v-model="redirect.beforeURL" ref="focus"/>
<p class="comment">需要填写完整的URL包括<code-label>http://</code-label>或者<code-label>https://</code-label>,如果有非默认端口,也需要带上端口号。</p>
</td>
</tr>
<tr>
<td>匹配模式 *</td>
<td class="color-border">匹配模式 *</td>
<td>
<select class="ui dropdown auto-width" name="mode" v-model="mode">
<option value="equal">精准匹配</option>
@@ -30,26 +43,96 @@
</td>
</tr>
<tr>
<td>跳转后URL *</td>
<td class="color-border">跳转后URL *</td>
<td>
<input type="text" name="afterURL" placeholder="比如 https://www.url2.cn" v-model="redirect.afterURL"/>
<p class="comment">需要填写完整的URL包括<code-label>http://</code-label>或者<code-label>https://</code-label>,如果有非默认端口,也需要带上端口号。</p>
</td>
</tr>
<tr v-if="mode == 'matchPrefix'">
<td>是否保留URL路径参数</td>
<td class="color-border">是否保留URL路径参数</td>
<td>
<checkbox name="keepRequestURI" value="1" v-model="redirect.keepRequestURI"></checkbox>
<p class="comment">选中后则跳转之后保留跳转之前的URL路径和参数。</p>
</td>
</tr>
<tr v-if="mode == 'equal' || mode == 'matchRegexp'">
<td>是否保留请求参数</td>
<td class="color-border">是否保留请求参数</td>
<td>
<checkbox name="keepArgs" value="1" v-model="redirect.keepArgs"></checkbox>
<p class="comment">选中后则跳转之后保留跳转之前的URL上的参数即问号之后的部分</p>
</td>
</tr>
</tbody>
<!-- 域名跳转 -->
<tbody v-show="redirect.type == 'domain'">
<tr>
<td class="color-border">所有域名都跳转</td>
<td>
<checkbox name="domainsAll" v-model="redirect.domainsAll"></checkbox>
<p class="comment">选中后,表示所有域名都会跳转(只要跳转前后域名不同);不选中后可以指定域名跳转。</p>
</td>
</tr>
<tr v-show="!redirect.domainsAll">
<td class="color-border">指定跳转前域名</td>
<td>
<domains-box name="domainsBeforeJSON" :v-domains="redirect.domainsBefore"></domains-box>
</td>
</tr>
<tr>
<td class="color-border">跳转后域名 *</td>
<td>
<input type="text" name="domainAfter" maxlength="100" v-model="redirect.domainAfter"/>
</td>
</tr>
<tr>
<td class="color-border">跳转后协议</td>
<td>
<select class="ui dropdown auto-width" name="domainAfterScheme" v-model="redirect.domainAfterScheme">
<option value="">保持</option>
<option value="https">HTTPS</option>
<option value="http">HTTP</option>
</select>
<p class="comment">跳转后的URL的协议。</p>
</td>
</tr>
</tbody>
<!-- 端口跳转 -->
<tbody v-show="redirect.type == 'port'">
<tr>
<td class="color-border">所有端口都跳转</td>
<td>
<checkbox name="portsAll" v-model="redirect.portsAll"></checkbox>
<p class="comment">选中后,表示所有端口都会跳转(只要跳转前后端口不同);不选中后可以指定端口跳转。</p>
</td>
</tr>
<tr v-show="!redirect.portsAll">
<td class="color-border">指定跳转前端口</td>
<td>
<values-box placeholder="单个端口 或 端口1-端口2" name="portsBefore" :v-values="redirect.portsBefore"></values-box>
</td>
</tr>
<tr>
<td class="color-border">跳转后端口 *</td>
<td>
<input type="text" name="portAfter" maxlength="5" v-model="redirect.portAfter" style="width: 5em"/>
</td>
</tr>
<tr>
<td class="color-border">跳转后协议</td>
<td>
<select class="ui dropdown auto-width" name="portAfterScheme" v-model="redirect.portAfterScheme">
<option value="">保持</option>
<option value="https">HTTPS</option>
<option value="http">HTTP</option>
</select>
<p class="comment">跳转后的URL的协议。</p>
</td>
</tr>
</tbody>
<tr>
<td>跳转状态码</td>
<td>
@@ -64,7 +147,7 @@
<td><http-request-conds-box :v-conds="redirect.conds" @change="changeConds"></http-request-conds-box></td>
</tr>
<tr>
<td>是否启用</td>
<td>启用当前跳转</td>
<td><checkbox name="isOn" value="1" v-model="redirect.isOn"></checkbox></td>
</tr>
</table>

View File

@@ -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: ""
}
}