mirror of
https://github.com/tobychui/zoraxy.git
synced 2025-11-14 21:04:10 +01:00
Fixed #874
- Added exact match for redirection feature - Added case sensitive check for redirection - Updated version number
This commit is contained in:
@@ -103,6 +103,7 @@ func RegisterRedirectionAPIs(authRouter *auth.RouterDef) {
|
|||||||
authRouter.HandleFunc("/api/redirect/delete", handleDeleteRedirectionRule)
|
authRouter.HandleFunc("/api/redirect/delete", handleDeleteRedirectionRule)
|
||||||
authRouter.HandleFunc("/api/redirect/edit", handleEditRedirectionRule)
|
authRouter.HandleFunc("/api/redirect/edit", handleEditRedirectionRule)
|
||||||
authRouter.HandleFunc("/api/redirect/regex", handleToggleRedirectRegexpSupport)
|
authRouter.HandleFunc("/api/redirect/regex", handleToggleRedirectRegexpSupport)
|
||||||
|
authRouter.HandleFunc("/api/redirect/case_sensitive", handleToggleRedirectCaseSensitivity)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register the APIs for access rules management functions
|
// Register the APIs for access rules management functions
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ import (
|
|||||||
const (
|
const (
|
||||||
/* Build Constants */
|
/* Build Constants */
|
||||||
SYSTEM_NAME = "Zoraxy"
|
SYSTEM_NAME = "Zoraxy"
|
||||||
SYSTEM_VERSION = "3.2.9"
|
SYSTEM_VERSION = "3.3.0"
|
||||||
DEVELOPMENT_BUILD = false
|
DEVELOPMENT_BUILD = false
|
||||||
|
|
||||||
/* System Constants */
|
/* System Constants */
|
||||||
@@ -119,10 +119,15 @@ var (
|
|||||||
|
|
||||||
/* Global Variables and Handlers */
|
/* Global Variables and Handlers */
|
||||||
var (
|
var (
|
||||||
|
/* System */
|
||||||
nodeUUID = "generic" //System uuid in uuidv4 format, load from database on startup
|
nodeUUID = "generic" //System uuid in uuidv4 format, load from database on startup
|
||||||
bootTime = time.Now().Unix()
|
bootTime = time.Now().Unix()
|
||||||
requireAuth = true //Require authentication for webmin panel, override from flag
|
requireAuth = true //Require authentication for webmin panel, override from flag
|
||||||
|
|
||||||
|
/* mDNS */
|
||||||
|
previousmdnsScanResults = []*mdns.NetworkHost{}
|
||||||
|
mdnsTickerStop chan bool
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Binary Embedding File System
|
Binary Embedding File System
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package redirection
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
@@ -16,10 +17,10 @@ import (
|
|||||||
|
|
||||||
type RuleTable struct {
|
type RuleTable struct {
|
||||||
AllowRegex bool //Allow regular expression to be used in rule matching. Require up to O(n^m) time complexity
|
AllowRegex bool //Allow regular expression to be used in rule matching. Require up to O(n^m) time complexity
|
||||||
Logger *logger.Logger
|
CaseSensitive bool //Force case sensitive URL matching
|
||||||
configPath string //The location where the redirection rules is stored
|
configPath string //The location where the redirection rules is stored
|
||||||
rules sync.Map //Store the redirection rules for this reverse proxy instance
|
rules sync.Map //Store map[string]*RedirectRules for this reverse proxy instance
|
||||||
|
Logger *logger.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
type RedirectRules struct {
|
type RedirectRules struct {
|
||||||
@@ -27,13 +28,15 @@ type RedirectRules struct {
|
|||||||
TargetURL string //The destination redirection url
|
TargetURL string //The destination redirection url
|
||||||
ForwardChildpath bool //Also redirect the pathname
|
ForwardChildpath bool //Also redirect the pathname
|
||||||
StatusCode int //Status Code for redirection
|
StatusCode int //Status Code for redirection
|
||||||
|
RequireExactMatch bool //Require exact URL match instead of prefix matching
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRuleTable(configPath string, allowRegex bool, logger *logger.Logger) (*RuleTable, error) {
|
func NewRuleTable(configPath string, allowRegex bool, caseSensitive bool, logger *logger.Logger) (*RuleTable, error) {
|
||||||
thisRuleTable := RuleTable{
|
thisRuleTable := RuleTable{
|
||||||
rules: sync.Map{},
|
rules: sync.Map{},
|
||||||
configPath: configPath,
|
configPath: configPath,
|
||||||
AllowRegex: allowRegex,
|
AllowRegex: allowRegex,
|
||||||
|
CaseSensitive: caseSensitive,
|
||||||
Logger: logger,
|
Logger: logger,
|
||||||
}
|
}
|
||||||
//Load all the rules from the config path
|
//Load all the rules from the config path
|
||||||
@@ -74,13 +77,14 @@ func NewRuleTable(configPath string, allowRegex bool, logger *logger.Logger) (*R
|
|||||||
return &thisRuleTable, nil
|
return &thisRuleTable, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *RuleTable) AddRedirectRule(redirectURL string, destURL string, forwardPathname bool, statusCode int) error {
|
func (t *RuleTable) AddRedirectRule(redirectURL string, destURL string, forwardPathname bool, statusCode int, requireExactMatch bool) error {
|
||||||
// Create a new RedirectRules object with the given parameters
|
// Create a new RedirectRules object with the given parameters
|
||||||
newRule := &RedirectRules{
|
newRule := &RedirectRules{
|
||||||
RedirectURL: redirectURL,
|
RedirectURL: redirectURL,
|
||||||
TargetURL: destURL,
|
TargetURL: destURL,
|
||||||
ForwardChildpath: forwardPathname,
|
ForwardChildpath: forwardPathname,
|
||||||
StatusCode: statusCode,
|
StatusCode: statusCode,
|
||||||
|
RequireExactMatch: requireExactMatch,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert the redirectURL to a valid filename by replacing "/" with "-" and "." with "_"
|
// Convert the redirectURL to a valid filename by replacing "/" with "-" and "." with "_"
|
||||||
@@ -111,12 +115,13 @@ func (t *RuleTable) AddRedirectRule(redirectURL string, destURL string, forwardP
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Edit an existing redirection rule, the oldRedirectURL is used to find the rule to be edited
|
// Edit an existing redirection rule, the oldRedirectURL is used to find the rule to be edited
|
||||||
func (t *RuleTable) EditRedirectRule(oldRedirectURL string, newRedirectURL string, destURL string, forwardPathname bool, statusCode int) error {
|
func (t *RuleTable) EditRedirectRule(oldRedirectURL string, newRedirectURL string, destURL string, forwardPathname bool, statusCode int, requireExactMatch bool) error {
|
||||||
newRule := &RedirectRules{
|
newRule := &RedirectRules{
|
||||||
RedirectURL: newRedirectURL,
|
RedirectURL: newRedirectURL,
|
||||||
TargetURL: destURL,
|
TargetURL: destURL,
|
||||||
ForwardChildpath: forwardPathname,
|
ForwardChildpath: forwardPathname,
|
||||||
StatusCode: statusCode,
|
StatusCode: statusCode,
|
||||||
|
RequireExactMatch: requireExactMatch,
|
||||||
}
|
}
|
||||||
|
|
||||||
//Remove the old rule
|
//Remove the old rule
|
||||||
@@ -189,29 +194,57 @@ func (t *RuleTable) MatchRedirectRule(requestedURL string) *RedirectRules {
|
|||||||
var targetRedirectionRule *RedirectRules = nil
|
var targetRedirectionRule *RedirectRules = nil
|
||||||
var maxMatch int = 0
|
var maxMatch int = 0
|
||||||
t.rules.Range(func(key interface{}, value interface{}) bool {
|
t.rules.Range(func(key interface{}, value interface{}) bool {
|
||||||
// Check if the requested URL starts with the key as a prefix
|
rule := value.(*RedirectRules)
|
||||||
|
keyStr := key.(string)
|
||||||
|
|
||||||
if t.AllowRegex {
|
if t.AllowRegex {
|
||||||
//Regexp matching rule
|
//Regexp matching rule
|
||||||
matched, err := regexp.MatchString(key.(string), requestedURL)
|
matched, err := regexp.MatchString(keyStr, requestedURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
//Something wrong with the regex?
|
//Something wrong with the regex?
|
||||||
t.log("Unable to match regex", err)
|
t.log("Unable to match regex", err)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if matched {
|
if matched {
|
||||||
maxMatch = len(key.(string))
|
maxMatch = len(keyStr)
|
||||||
targetRedirectionRule = value.(*RedirectRules)
|
targetRedirectionRule = rule
|
||||||
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Check matching based on exact match requirement
|
||||||
|
var matched bool
|
||||||
|
if rule.RequireExactMatch {
|
||||||
|
fmt.Println(requestedURL, keyStr)
|
||||||
|
//Exact match required
|
||||||
|
if t.CaseSensitive {
|
||||||
|
matched = requestedURL == keyStr
|
||||||
|
} else {
|
||||||
|
matched = strings.EqualFold(requestedURL, keyStr)
|
||||||
|
}
|
||||||
|
if !matched {
|
||||||
|
//Also check for trailing slash case
|
||||||
|
if t.CaseSensitive {
|
||||||
|
matched = requestedURL == keyStr+"/"
|
||||||
|
} else {
|
||||||
|
matched = strings.EqualFold(requestedURL, keyStr+"/")
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
//Default: prefix matching redirect
|
//Default: prefix matching redirect
|
||||||
if strings.HasPrefix(requestedURL, key.(string)) {
|
if t.CaseSensitive {
|
||||||
// This request URL matched the domain
|
matched = strings.HasPrefix(requestedURL, keyStr)
|
||||||
if len(key.(string)) > maxMatch {
|
} else {
|
||||||
maxMatch = len(key.(string))
|
matched = strings.HasPrefix(strings.ToLower(requestedURL), strings.ToLower(keyStr))
|
||||||
targetRedirectionRule = value.(*RedirectRules)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if matched {
|
||||||
|
// This request URL matched the rule
|
||||||
|
if len(keyStr) > maxMatch {
|
||||||
|
maxMatch = len(keyStr)
|
||||||
|
targetRedirectionRule = rule
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
|
|||||||
@@ -41,6 +41,12 @@ func handleAddRedirectionRule(w http.ResponseWriter, r *http.Request) {
|
|||||||
forwardChildpath = "true"
|
forwardChildpath = "true"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
requireExactMatch, err := utils.PostPara(r, "requireExactMatch")
|
||||||
|
if err != nil {
|
||||||
|
//Assume false
|
||||||
|
requireExactMatch = "false"
|
||||||
|
}
|
||||||
|
|
||||||
redirectTypeString, err := utils.PostPara(r, "redirectType")
|
redirectTypeString, err := utils.PostPara(r, "redirectType")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
redirectTypeString = "307"
|
redirectTypeString = "307"
|
||||||
@@ -52,7 +58,7 @@ func handleAddRedirectionRule(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = redirectTable.AddRedirectRule(redirectUrl, destUrl, forwardChildpath == "true", redirectionStatusCode)
|
err = redirectTable.AddRedirectRule(redirectUrl, destUrl, forwardChildpath == "true", redirectionStatusCode, requireExactMatch == "true")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.SendErrorResponse(w, err.Error())
|
utils.SendErrorResponse(w, err.Error())
|
||||||
return
|
return
|
||||||
@@ -101,6 +107,12 @@ func handleEditRedirectionRule(w http.ResponseWriter, r *http.Request) {
|
|||||||
forwardChildpath = "true"
|
forwardChildpath = "true"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
requireExactMatch, err := utils.PostPara(r, "requireExactMatch")
|
||||||
|
if err != nil {
|
||||||
|
//Assume false
|
||||||
|
requireExactMatch = "false"
|
||||||
|
}
|
||||||
|
|
||||||
redirectTypeString, err := utils.PostPara(r, "redirectType")
|
redirectTypeString, err := utils.PostPara(r, "redirectType")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
redirectTypeString = "307"
|
redirectTypeString = "307"
|
||||||
@@ -112,7 +124,7 @@ func handleEditRedirectionRule(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = redirectTable.EditRedirectRule(originalRedirectUrl, newRedirectUrl, destUrl, forwardChildpath == "true", redirectionStatusCode)
|
err = redirectTable.EditRedirectRule(originalRedirectUrl, newRedirectUrl, destUrl, forwardChildpath == "true", redirectionStatusCode, requireExactMatch == "true")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.SendErrorResponse(w, err.Error())
|
utils.SendErrorResponse(w, err.Error())
|
||||||
return
|
return
|
||||||
@@ -147,3 +159,30 @@ func handleToggleRedirectRegexpSupport(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
utils.SendOK(w)
|
utils.SendOK(w)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Toggle redirection case sensitivity. Note that this affects all redirection rules
|
||||||
|
func handleToggleRedirectCaseSensitivity(w http.ResponseWriter, r *http.Request) {
|
||||||
|
enabled, err := utils.PostPara(r, "enable")
|
||||||
|
if err != nil {
|
||||||
|
//Return the current state of the case sensitivity
|
||||||
|
js, _ := json.Marshal(redirectTable.CaseSensitive)
|
||||||
|
utils.SendJSONResponse(w, string(js))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//Update the current case sensitivity rule enable state
|
||||||
|
enableCaseSensitivity := strings.EqualFold(strings.TrimSpace(enabled), "true")
|
||||||
|
redirectTable.CaseSensitive = enableCaseSensitivity
|
||||||
|
err = sysdb.Write("redirect", "case_sensitive", enableCaseSensitivity)
|
||||||
|
|
||||||
|
if enableCaseSensitivity {
|
||||||
|
SystemWideLogger.PrintAndLog("redirect", "Case sensitive redirect rule enabled", nil)
|
||||||
|
} else {
|
||||||
|
SystemWideLogger.PrintAndLog("redirect", "Case sensitive redirect rule disabled", nil)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
utils.SendErrorResponse(w, "unable to save settings")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
utils.SendOK(w)
|
||||||
|
}
|
||||||
|
|||||||
12
src/start.go
12
src/start.go
@@ -50,14 +50,6 @@ import (
|
|||||||
Don't touch this function unless you know what you are doing
|
Don't touch this function unless you know what you are doing
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var (
|
|
||||||
/*
|
|
||||||
MDNS related
|
|
||||||
*/
|
|
||||||
previousmdnsScanResults = []*mdns.NetworkHost{}
|
|
||||||
mdnsTickerStop chan bool
|
|
||||||
)
|
|
||||||
|
|
||||||
func startupSequence() {
|
func startupSequence() {
|
||||||
//Start a system wide logger and log viewer
|
//Start a system wide logger and log viewer
|
||||||
l, err := logger.NewLogger(LOG_PREFIX, *path_logFile)
|
l, err := logger.NewLogger(LOG_PREFIX, *path_logFile)
|
||||||
@@ -149,7 +141,9 @@ func startupSequence() {
|
|||||||
db.NewTable("redirect")
|
db.NewTable("redirect")
|
||||||
redirectAllowRegexp := false
|
redirectAllowRegexp := false
|
||||||
db.Read("redirect", "regex", &redirectAllowRegexp)
|
db.Read("redirect", "regex", &redirectAllowRegexp)
|
||||||
redirectTable, err = redirection.NewRuleTable(CONF_REDIRECTION, redirectAllowRegexp, SystemWideLogger)
|
redirectCaseSensitive := false
|
||||||
|
db.Read("redirect", "case_sensitive", &redirectCaseSensitive)
|
||||||
|
redirectTable, err = redirection.NewRuleTable(CONF_REDIRECTION, redirectAllowRegexp, redirectCaseSensitive, SystemWideLogger)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
<th>Redirection URL</th>
|
<th>Redirection URL</th>
|
||||||
<th>Destination URL</th>
|
<th>Destination URL</th>
|
||||||
<th class="no-sort">Copy Pathname</th>
|
<th class="no-sort">Copy Pathname</th>
|
||||||
|
<th class="no-sort">Require Exact Match</th>
|
||||||
<th class="no-sort">Status Code</th>
|
<th class="no-sort">Status Code</th>
|
||||||
<th class="no-sort">Actions</th>
|
<th class="no-sort">Actions</th>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -44,6 +45,12 @@
|
|||||||
<small>Regular expression redirection check will noticeably slow down page load<br>
|
<small>Regular expression redirection check will noticeably slow down page load<br>
|
||||||
Support <a href="https://yourbasic.org/golang/regexp-cheat-sheet/" target="_blank">Go style regex</a>. e.g. <code style="background-color: rgb(44, 44, 44); color: white">.\.redirect\.example\.com</code></small></label>
|
Support <a href="https://yourbasic.org/golang/regexp-cheat-sheet/" target="_blank">Go style regex</a>. e.g. <code style="background-color: rgb(44, 44, 44); color: white">.\.redirect\.example\.com</code></small></label>
|
||||||
</div>
|
</div>
|
||||||
|
<br>
|
||||||
|
<div class="ui toggle checkbox" style="margin-top: 0.4em;">
|
||||||
|
<input id="redirectCaseSensitive" type="checkbox">
|
||||||
|
<label>Force Case Sensitive Check<br>
|
||||||
|
<small>If enabled, URL matching will be case sensitive</small></label>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -56,12 +63,20 @@
|
|||||||
<div class="field">
|
<div class="field">
|
||||||
<label>Redirection URL (From)</label>
|
<label>Redirection URL (From)</label>
|
||||||
<input type="text" id="rurl" name="redirection-url" placeholder="Redirection URL">
|
<input type="text" id="rurl" name="redirection-url" placeholder="Redirection URL">
|
||||||
<small><i class="ui circle info icon"></i> Any matching prefix of the request URL will be redirected to the destination URL, e.g. redirect.example.com</small>
|
<small> Any matching prefix of the request URL will be redirected to the destination URL, e.g. redirect.example.com</small>
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label>Destination URL (To)</label>
|
<label>Destination URL (To)</label>
|
||||||
<input type="text" name="destination-url" placeholder="Destination URL">
|
<input type="text" name="destination-url" placeholder="Destination URL">
|
||||||
<small><i class="ui circle info icon"></i> The target URL request being redirected to, e.g. dest.example.com/mysite/ or dest.example.com/script.php, <b>sometime you might need to add tailing slash (/) to your URL depending on your use cases</b></small>
|
<small>The target URL request being redirected to, e.g. dest.example.com/mysite/ or dest.example.com/script.php, <b>sometime you might need to add tailing slash (/) to your URL depending on your use cases</b></small>
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<div class="ui checkbox">
|
||||||
|
<input type="checkbox" name="require-exact-match" tabindex="0" class="hidden">
|
||||||
|
<label>Require Exact Match</label>
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
<small>If enabled, only exact URL matches will be redirected (no prefix matching)</small>
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<div class="ui checkbox">
|
<div class="ui checkbox">
|
||||||
@@ -108,12 +123,14 @@
|
|||||||
document.getElementById("rurl").value = "";
|
document.getElementById("rurl").value = "";
|
||||||
document.getElementsByName("destination-url")[0].value = "";
|
document.getElementsByName("destination-url")[0].value = "";
|
||||||
document.getElementsByName("forward-childpath")[0].checked = true;
|
document.getElementsByName("forward-childpath")[0].checked = true;
|
||||||
|
document.getElementsByName("require-exact-match")[0].checked = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function addRules(){
|
function addRules(){
|
||||||
let redirectUrl = document.querySelector('input[name="redirection-url"]').value;
|
let redirectUrl = document.querySelector('input[name="redirection-url"]').value;
|
||||||
let destUrl = document.querySelector('input[name="destination-url"]').value;
|
let destUrl = document.querySelector('input[name="destination-url"]').value;
|
||||||
let forwardChildpath = document.querySelector('input[name="forward-childpath"]').checked;
|
let forwardChildpath = document.querySelector('input[name="forward-childpath"]').checked;
|
||||||
|
let requireExactMatch = document.querySelector('input[name="require-exact-match"]').checked;
|
||||||
let redirectType = document.querySelector('input[name="redirect-type"]:checked').value;
|
let redirectType = document.querySelector('input[name="redirect-type"]:checked').value;
|
||||||
|
|
||||||
$.cjax({
|
$.cjax({
|
||||||
@@ -123,6 +140,7 @@
|
|||||||
redirectUrl: redirectUrl,
|
redirectUrl: redirectUrl,
|
||||||
destUrl: destUrl,
|
destUrl: destUrl,
|
||||||
forwardChildpath: forwardChildpath,
|
forwardChildpath: forwardChildpath,
|
||||||
|
requireExactMatch: requireExactMatch,
|
||||||
redirectType: parseInt(redirectType),
|
redirectType: parseInt(redirectType),
|
||||||
},
|
},
|
||||||
success: function(data){
|
success: function(data){
|
||||||
@@ -172,6 +190,7 @@
|
|||||||
<td><a href="${hrefURL}" target="_blank">${entry.RedirectURL}</a></td>
|
<td><a href="${hrefURL}" target="_blank">${entry.RedirectURL}</a></td>
|
||||||
<td>${entry.TargetURL}</td>
|
<td>${entry.TargetURL}</td>
|
||||||
<td>${entry.ForwardChildpath?"<i class='ui green checkmark icon'></i>":"<i class='ui red remove icon'></i>"}</td>
|
<td>${entry.ForwardChildpath?"<i class='ui green checkmark icon'></i>":"<i class='ui red remove icon'></i>"}</td>
|
||||||
|
<td>${entry.RequireExactMatch?"<i class='ui green checkmark icon'></i>":"<i class='ui red remove icon'></i>"}</td>
|
||||||
<td>${entry.StatusCode==307?"Temporary Redirect (307)":"Moved Permanently (301)"}</td>
|
<td>${entry.StatusCode==307?"Temporary Redirect (307)":"Moved Permanently (301)"}</td>
|
||||||
<td>
|
<td>
|
||||||
<button onclick="editRule(this);" payload="${encodedEntry}" title="Edit redirection rule" class="ui mini circular icon basic button redirectEditBtn"><i class="edit icon"></i></button>
|
<button onclick="editRule(this);" payload="${encodedEntry}" title="Edit redirection rule" class="ui mini circular icon basic button redirectEditBtn"><i class="edit icon"></i></button>
|
||||||
@@ -181,7 +200,7 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (data.length == 0){
|
if (data.length == 0){
|
||||||
$("#redirectionRuleList").append(`<tr><td colspan="5"><i class="green check circle icon"></i> No redirection rule</td></tr>`);
|
$("#redirectionRuleList").append(`<tr><td colspan="6"><i class="green check circle icon"></i> No redirection rule</td></tr>`);
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
@@ -195,6 +214,7 @@
|
|||||||
let redirectUrl = payload.RedirectURL;
|
let redirectUrl = payload.RedirectURL;
|
||||||
let destUrl = payload.TargetURL;
|
let destUrl = payload.TargetURL;
|
||||||
let forwardChildpath = payload.ForwardChildpath;
|
let forwardChildpath = payload.ForwardChildpath;
|
||||||
|
let requireExactMatch = payload.RequireExactMatch || false;
|
||||||
let statusCode = payload.StatusCode;
|
let statusCode = payload.StatusCode;
|
||||||
|
|
||||||
row.html(`
|
row.html(`
|
||||||
@@ -209,6 +229,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td><div class="ui toggle checkbox"><input type="checkbox" ${forwardChildpath ? "checked" : ""} id="editForwardChildpath"><label></label></div></td>
|
<td><div class="ui toggle checkbox"><input type="checkbox" ${forwardChildpath ? "checked" : ""} id="editForwardChildpath"><label></label></div></td>
|
||||||
|
<td><div class="ui toggle checkbox"><input type="checkbox" ${requireExactMatch ? "checked" : ""} id="editRequireExactMatch"><label></label></div></td>
|
||||||
<td>
|
<td>
|
||||||
<div class="ui radio checkbox"><input type="radio" name="editStatusCode" value="307" ${statusCode == 307 ? "checked" : ""}><label>Temporary Redirect (307)</label></div><br>
|
<div class="ui radio checkbox"><input type="radio" name="editStatusCode" value="307" ${statusCode == 307 ? "checked" : ""}><label>Temporary Redirect (307)</label></div><br>
|
||||||
<div class="ui radio checkbox"><input type="radio" name="editStatusCode" value="301" ${statusCode == 301 ? "checked" : ""}><label>Moved Permanently (301)</label></div>
|
<div class="ui radio checkbox"><input type="radio" name="editStatusCode" value="301" ${statusCode == 301 ? "checked" : ""}><label>Moved Permanently (301)</label></div>
|
||||||
@@ -227,6 +248,7 @@
|
|||||||
let redirectUrl = $("#editRedirectUrl").val();
|
let redirectUrl = $("#editRedirectUrl").val();
|
||||||
let destUrl = $("#editDestUrl").val();
|
let destUrl = $("#editDestUrl").val();
|
||||||
let forwardChildpath = $("#editForwardChildpath").is(":checked");
|
let forwardChildpath = $("#editForwardChildpath").is(":checked");
|
||||||
|
let requireExactMatch = $("#editRequireExactMatch").is(":checked");
|
||||||
let statusCode = parseInt($("input[name='editStatusCode']:checked").val());
|
let statusCode = parseInt($("input[name='editStatusCode']:checked").val());
|
||||||
|
|
||||||
$.cjax({
|
$.cjax({
|
||||||
@@ -237,6 +259,7 @@
|
|||||||
newRedirectUrl: redirectUrl,
|
newRedirectUrl: redirectUrl,
|
||||||
destUrl: destUrl,
|
destUrl: destUrl,
|
||||||
forwardChildpath: forwardChildpath,
|
forwardChildpath: forwardChildpath,
|
||||||
|
requireExactMatch: requireExactMatch,
|
||||||
redirectType: statusCode,
|
redirectType: statusCode,
|
||||||
},
|
},
|
||||||
success: function(data){
|
success: function(data){
|
||||||
@@ -279,6 +302,35 @@
|
|||||||
|
|
||||||
initRegexpSupportToggle();
|
initRegexpSupportToggle();
|
||||||
|
|
||||||
|
function initCaseSensitivityToggle(){
|
||||||
|
$.get("/api/redirect/case_sensitive", function(data){
|
||||||
|
//Set the checkbox initial state
|
||||||
|
if (data == true){
|
||||||
|
$("#redirectCaseSensitive").parent().checkbox("set checked");
|
||||||
|
}else{
|
||||||
|
$("#redirectCaseSensitive").parent().checkbox("set unchecked");
|
||||||
|
}
|
||||||
|
|
||||||
|
//Bind event to the checkbox
|
||||||
|
$("#redirectCaseSensitive").on("change", function(){
|
||||||
|
$.cjax({
|
||||||
|
url: "/api/redirect/case_sensitive",
|
||||||
|
method: "POST",
|
||||||
|
data: {"enable": $(this)[0].checked},
|
||||||
|
success: function(data){
|
||||||
|
if (data.error != undefined){
|
||||||
|
msgbox(data.error, false);
|
||||||
|
}else{
|
||||||
|
msgbox("Case sensitive redirect setting updated", true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
initCaseSensitivityToggle();
|
||||||
|
|
||||||
$("#rurl").on('change', (event) => {
|
$("#rurl").on('change', (event) => {
|
||||||
const value = event.target.value.trim().replace(/^(https?:\/\/)/, '');
|
const value = event.target.value.trim().replace(/^(https?:\/\/)/, '');
|
||||||
event.target.value = value;
|
event.target.value = value;
|
||||||
|
|||||||
Reference in New Issue
Block a user