mirror of
https://github.com/tobychui/zoraxy.git
synced 2025-08-06 21:28:30 +02:00
Added load balancer (wip)
+ Added support for multiple upstreams + Added load balancer + Added upstream abstraction in endpoint + Added load balancer structure + Added breaking change auto-updater + Added uptime monitor proxy type definitions + Added upstream editor UI + Fixed charset bug in many snippets HTML files
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
<html>
|
||||
<head>
|
||||
<!-- Notes: This should be open in its original path-->
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" href="../script/semantic/semantic.min.css">
|
||||
<script src="../script/jquery-3.6.0.min.js"></script>
|
||||
<script src="../script/semantic/semantic.min.js"></script>
|
||||
|
@@ -2,6 +2,7 @@
|
||||
<html>
|
||||
<head>
|
||||
<!-- Notes: This should be open in its original path-->
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" href="../script/semantic/semantic.min.css">
|
||||
<script src="../script/jquery-3.6.0.min.js"></script>
|
||||
<script src="../script/semantic/semantic.min.js"></script>
|
||||
@@ -133,11 +134,17 @@
|
||||
</div>
|
||||
<div class="field dnsChallengeOnly" style="display:none;">
|
||||
<div class="ui divider"></div>
|
||||
<p>DNS Credentials (Leave all fields empty to use previous settings)<br>
|
||||
<small><i class="yellow exclamation triangle icon"></i> Note that domain DNS credentials are stored separately. For each new subdomain, you will need to enter a new DNS credentials.</small></p>
|
||||
<p>DNS Credentials</p>
|
||||
<div id="dnsProviderAPIFields">
|
||||
|
||||
<p><i class="ui loading circle notch icon"></i> Generating WebForm</p>
|
||||
</div>
|
||||
<h4><i class="yellow exclamation triangle icon"></i> Notes & FAQ</h4>
|
||||
<div class="ui bulleted list">
|
||||
<div class="item">Domain DNS credentials are stored separately. For each new subdomain, you will need to enter a new DNS credentials.</div>
|
||||
<div class="item">For some DNS providers like CloudFlare, you do not need to fill in all fields.</div>
|
||||
<div class="item">If you are not sure what to fill in, check out the documentation from <a href="https://go-acme.github.io/lego/dns/" target="_blank">lego (DNS challenge library)</a></div>
|
||||
</div>
|
||||
|
||||
<!--
|
||||
<label>Credentials File Content</label>
|
||||
<textarea id="dnsCredentials" placeholder=""></textarea>
|
||||
@@ -740,6 +747,9 @@
|
||||
function toggleDnsChallenge(){
|
||||
if ( $("#useDnsChallenge")[0].checked){
|
||||
$(".dnsChallengeOnly").show();
|
||||
setTimeout(function(){
|
||||
$("#dnsProvider").dropdown("set text", "Cloudflare");
|
||||
}, 500);
|
||||
}else{
|
||||
$(".dnsChallengeOnly").hide();
|
||||
}
|
||||
|
@@ -2,6 +2,7 @@
|
||||
<html>
|
||||
<head>
|
||||
<!-- Notes: This should be open in its original path-->
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" href="../script/semantic/semantic.min.css">
|
||||
<script src="../script/jquery-3.6.0.min.js"></script>
|
||||
<script src="../script/semantic/semantic.min.js"></script>
|
||||
|
@@ -2,6 +2,7 @@
|
||||
<html>
|
||||
<head>
|
||||
<!-- Notes: This should be open in its original path-->
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" href="../script/semantic/semantic.min.css">
|
||||
<script src="../script/jquery-3.6.0.min.js"></script>
|
||||
<script src="../script/semantic/semantic.min.js"></script>
|
||||
|
@@ -2,6 +2,7 @@
|
||||
<html>
|
||||
<head>
|
||||
<!-- Notes: This should be open in its original path-->
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" href="../script/semantic/semantic.min.css">
|
||||
<script src="../script/jquery-3.6.0.min.js"></script>
|
||||
<script src="../script/semantic/semantic.min.js"></script>
|
||||
|
@@ -2,6 +2,7 @@
|
||||
<html>
|
||||
<head>
|
||||
<!-- Notes: This should be open in its original path-->
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" href="../script/semantic/semantic.min.css">
|
||||
<script src="../script/jquery-3.6.0.min.js"></script>
|
||||
<script src="../script/semantic/semantic.min.js"></script>
|
||||
|
@@ -2,6 +2,7 @@
|
||||
<html>
|
||||
<head>
|
||||
<!-- Notes: This should be open in its original path-->
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" href="../script/semantic/semantic.min.css">
|
||||
<script src="../script/jquery-3.6.0.min.js"></script>
|
||||
<script src="../script/semantic/semantic.min.js"></script>
|
||||
|
@@ -2,6 +2,7 @@
|
||||
<html>
|
||||
<head>
|
||||
<!-- Notes: This should be open in its original path-->
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" href="../script/semantic/semantic.min.css" />
|
||||
<script src="../script/jquery-3.6.0.min.js"></script>
|
||||
<script src="../script/semantic/semantic.min.js"></script>
|
||||
|
@@ -2,6 +2,7 @@
|
||||
<html>
|
||||
<head>
|
||||
<!-- Notes: This should be open in its original path-->
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" href="../script/semantic/semantic.min.css">
|
||||
<script src="../script/jquery-3.6.0.min.js"></script>
|
||||
<script src="../script/semantic/semantic.min.js"></script>
|
||||
|
@@ -2,6 +2,7 @@
|
||||
<html>
|
||||
<head>
|
||||
<!-- Notes: This should be open in its original path-->
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" href="../script/semantic/semantic.min.css">
|
||||
<script src="../script/jquery-3.6.0.min.js"></script>
|
||||
<script src="../script/semantic/semantic.min.js"></script>
|
||||
|
@@ -1,49 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<!-- Notes: This should be open in its original path-->
|
||||
<link rel="stylesheet" href="../script/semantic/semantic.min.css">
|
||||
<script src="../script/jquery-3.6.0.min.js"></script>
|
||||
<script src="../script/semantic/semantic.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<br>
|
||||
<div class="ui container">
|
||||
<div class="ui header">
|
||||
<div class="content">
|
||||
Load Balance
|
||||
<div class="sub header epname"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui divider"></div>
|
||||
|
||||
<div class="ui divider"></div>
|
||||
<div class="field" >
|
||||
<button class="ui basic button" style="float: right;" onclick="closeThisWrapper();">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br><br><br><br>
|
||||
|
||||
</div>
|
||||
<script>
|
||||
let aliasList = [];
|
||||
let editingEndpoint = {};
|
||||
|
||||
if (window.location.hash.length > 1){
|
||||
let payloadHash = window.location.hash.substr(1);
|
||||
try{
|
||||
payloadHash = JSON.parse(decodeURIComponent(payloadHash));
|
||||
$(".epname").text(payloadHash.ep);
|
||||
editingEndpoint = payloadHash;
|
||||
}catch(ex){
|
||||
console.log("Unable to load endpoint data from hash")
|
||||
}
|
||||
}
|
||||
|
||||
function closeThisWrapper(){
|
||||
parent.hideSideWrapper(true);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@@ -1,6 +1,7 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" href="../script/semantic/semantic.min.css">
|
||||
<script src="../script/jquery-3.6.0.min.js"></script>
|
||||
<script src="../script/semantic/semantic.min.js"></script>
|
||||
|
528
src/web/snippet/upstreams.html
Normal file
528
src/web/snippet/upstreams.html
Normal file
@@ -0,0 +1,528 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<!-- Notes: This should be open in its original path-->
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" href="../script/semantic/semantic.min.css">
|
||||
<script src="../script/jquery-3.6.0.min.js"></script>
|
||||
<script src="../script/semantic/semantic.min.js"></script>
|
||||
<style>
|
||||
.upstreamActions{
|
||||
position: absolute;
|
||||
top: 0.6em;
|
||||
right: 0.6em;
|
||||
}
|
||||
|
||||
.upstreamLink{
|
||||
max-width: 220px;
|
||||
display: inline-block;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.upstreamEntry .ui.toggle.checkbox input:checked ~ label::before{
|
||||
background-color: #00ca52 !important;
|
||||
}
|
||||
|
||||
#activateNewUpstream.ui.toggle.checkbox input:checked ~ label::before{
|
||||
background-color: #00ca52 !important;
|
||||
}
|
||||
|
||||
#upstreamTable{
|
||||
max-height: 480px;
|
||||
border-radius: 0.3em;
|
||||
padding: 0.3em;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.upstreamEntry.inactive{
|
||||
background-color: #f3f3f3 !important;
|
||||
}
|
||||
|
||||
.upstreamEntry{
|
||||
border-radius: 0.4em !important;
|
||||
border: 1px solid rgb(233, 233, 233) !important;
|
||||
}
|
||||
|
||||
@media (max-width: 499px) {
|
||||
.upstreamActions{
|
||||
position: relative;
|
||||
margin-top: 1em;
|
||||
margin-left: 0.4em;
|
||||
margin-bottom: 0.4em;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<br>
|
||||
<div class="ui container">
|
||||
<div class="ui header">
|
||||
<div class="content">
|
||||
Upstreams / Load Balance
|
||||
<div class="sub header epname"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui divider"></div>
|
||||
<div class="ui small pointing secondary menu">
|
||||
<a class="item active narrowpadding" data-tab="upstreamlist">Upstreams</a>
|
||||
<a class="item narrowpadding" data-tab="newupstream">Add Upstream</a>
|
||||
</div>
|
||||
<div class="ui tab basic segment active" data-tab="upstreamlist">
|
||||
<!-- A list of current existing upstream on this reverse proxy-->
|
||||
<div id="upstreamTable">
|
||||
<div class="ui segment">
|
||||
<a><i class="ui loading spinner icon"></i> Loading</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui message">
|
||||
<i class="ui blue info circle icon"></i> Round-robin load balancing algorithm will be used for upstreams with same weight. Set weight to 0 for fallback only.
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui tab basic segment" data-tab="newupstream">
|
||||
<!-- Web Form to create a new upstream -->
|
||||
<h4 class="ui header">
|
||||
<i class="green add icon"></i>
|
||||
<div class="content">
|
||||
Add Upstream Server
|
||||
<div class="sub header">Create new load balance or fallback upstream origin</div>
|
||||
</div>
|
||||
</h4>
|
||||
<p style="margin-bottom: 0.4em;">Target IP address with port</p>
|
||||
<div class="ui fluid small input">
|
||||
<input type="text" id="originURL" onchange="cleanProxyTargetValue(this);"><br>
|
||||
</div>
|
||||
<small>E.g. 192.168.0.101:8000 or example.com</small>
|
||||
<br><br>
|
||||
<div id="activateNewUpstream" class="ui toggle checkbox" style="display:inline-block;">
|
||||
<input type="checkbox" id="activateNewUpstreamCheckbox" style="margin-top: 0.4em;" checked>
|
||||
<label>Activate<br>
|
||||
<small>Enable this upstream for load balancing</small></label>
|
||||
</div><br>
|
||||
<div class="ui checkbox" style="margin-top: 1.2em;">
|
||||
<input type="checkbox" id="requireTLS">
|
||||
<label>Require TLS<br>
|
||||
<small>Proxy target require HTTPS connection</small></label>
|
||||
</div><br>
|
||||
<div class="ui checkbox" style="margin-top: 0.6em;">
|
||||
<input type="checkbox" id="skipTlsVerification">
|
||||
<label>Skip Verification<br>
|
||||
<small>Check this if proxy target is using self signed certificates</small></label>
|
||||
</div><br>
|
||||
<div class="ui checkbox" style="margin-top: 0.4em;">
|
||||
<input type="checkbox" id="SkipWebSocketOriginCheck" checked>
|
||||
<label>Skip WebSocket Origin Check<br>
|
||||
<small>Check this to allow cross-origin websocket requests</small></label>
|
||||
</div>
|
||||
<br><br>
|
||||
<button class="ui basic button" onclick="addNewUpstream();"><i class="ui green circle add icon"></i> Create</button>
|
||||
</div>
|
||||
<div class="ui divider"></div>
|
||||
<div class="field" >
|
||||
<button class="ui basic button" style="float: right;" onclick="closeThisWrapper();">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
<br><br><br><br>
|
||||
|
||||
</div>
|
||||
<script>
|
||||
let origins = [];
|
||||
let editingEndpoint = {};
|
||||
$('.menu .item').tab();
|
||||
|
||||
|
||||
function initOriginList(){
|
||||
$.ajax({
|
||||
url: "/api/proxy/upstream/list",
|
||||
method: "POST",
|
||||
data: {
|
||||
"type":"host",
|
||||
"ep": editingEndpoint.ep
|
||||
},
|
||||
success: function(data){
|
||||
if (data.error != undefined){
|
||||
//This endpoint not exists?
|
||||
alert(data.error);
|
||||
return;
|
||||
}else{
|
||||
$("#upstreamTable").html("");
|
||||
|
||||
if (data.ActiveOrigins.length == 0){
|
||||
//There is no upstream for this proxy rule
|
||||
$("#upstreamTable").append(`<tr>
|
||||
<td colspan="2"><b><i class="ui yellow exclamation triangle icon"></i> No Active Upstream Origin</b><br>
|
||||
This HTTP proxy rule will always return Error 521 when requested. To fix this, add or enable a upstream origin to this proxy endpoint.
|
||||
<div class="ui divider"></div>
|
||||
</td>
|
||||
</tr>`);
|
||||
}
|
||||
|
||||
data.ActiveOrigins.forEach(upstream => {
|
||||
renderUpstreamEntryToTable(upstream, true);
|
||||
});
|
||||
|
||||
data.InactiveOrigins.forEach(upstream => {
|
||||
renderUpstreamEntryToTable(upstream, false);
|
||||
});
|
||||
|
||||
let totalUpstreams = data.ActiveOrigins.length + data.InactiveOrigins.length;
|
||||
if (totalUpstreams == 1){
|
||||
$(".lowPriorityButton").addClass('disabled');
|
||||
}
|
||||
|
||||
if (parent && parent.document.getElementById("httpProxyList") != null){
|
||||
//Also update the parent display
|
||||
let element = $(parent.document.getElementById("httpProxyList")).find(".upstreamList.editing");
|
||||
let upstreams = "";
|
||||
data.ActiveOrigins.forEach(upstream => {
|
||||
//Check if the upstreams require TLS connections
|
||||
let tlsIcon = "";
|
||||
if (upstream.RequireTLS){
|
||||
tlsIcon = `<i class="green lock icon" title="TLS Mode"></i>`;
|
||||
if (upstream.SkipCertValidations){
|
||||
tlsIcon = `<i class="yellow lock icon" title="TLS/SSL mode without verification"></i>`
|
||||
}
|
||||
}
|
||||
|
||||
let upstreamLink = `${upstream.RequireTLS?"https://":"http://"}${upstream.OriginIpOrDomain}`;
|
||||
|
||||
upstreams += `<a href="${upstreamLink}" target="_blank">${upstream.OriginIpOrDomain} ${tlsIcon}</a><br>`;
|
||||
});
|
||||
|
||||
if (data.ActiveOrigins.length == 0){
|
||||
upstreams = `<i class="ui yellow exclamation triangle icon"></i> No Active Upstream Origin<br>`
|
||||
}
|
||||
$(element).html(upstreams);
|
||||
}
|
||||
|
||||
$(".ui.checkbox").checkbox();
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function renderUpstreamEntryToTable(upstream, isActive){
|
||||
function newUID(){return"00000000-0000-4000-8000-000000000000".replace(/0/g,function(){return(0|Math.random()*16).toString(16)})};
|
||||
let tlsIcon = "";
|
||||
if (upstream.RequireTLS){
|
||||
tlsIcon = `<i class="green lock icon" title="TLS Mode"></i>`;
|
||||
if (upstream.SkipCertValidations){
|
||||
tlsIcon = `<i class="yellow lock icon" title="TLS/SSL mode without verification"></i>`
|
||||
}
|
||||
}
|
||||
|
||||
//Priority Arrows
|
||||
let downArrowClass = "";
|
||||
if (upstream.Weight == 0 ){
|
||||
//Cannot go any lower
|
||||
downArrowClass = "disabled";
|
||||
}
|
||||
let url = `${upstream.RequireTLS?"https://":"http://"}${upstream.OriginIpOrDomain}`
|
||||
let payload = encodeURIComponent(JSON.stringify(upstream));
|
||||
let domUID = newUID();
|
||||
$("#upstreamTable").append(`<div class="ui upstreamEntry ${isActive?"":"inactive"} basic segment" data-domid="${domUID}" data-payload="${payload}" data-priority="${upstream.Priority}">
|
||||
<h4 class="ui header">
|
||||
<div class="ui toggle checkbox" style="display:inline-block;">
|
||||
<input type="checkbox" class="enableState" name="enabled" style="margin-top: 0.4em;" onchange="saveUpstreamUpdate('${domUID}');" ${isActive?"checked":""}>
|
||||
<label></label>
|
||||
</div>
|
||||
<div class="content">
|
||||
<a href="${url}" target="_blank" class="upstreamLink">${upstream.OriginIpOrDomain} ${tlsIcon}</a>
|
||||
<div class="sub header">${isActive?(upstream.Weight==0?"Fallback Only":"Active"):"Inactive"} | Weight: ${upstream.Weight}x </div>
|
||||
</div>
|
||||
</h4>
|
||||
<div class="advanceOptions" style="display:none;">
|
||||
<div class="upstreamOriginField">
|
||||
<p>New upstream origin IP address or domain</p>
|
||||
<div class="ui small fluid input" style="margin-top: -0.6em;">
|
||||
<input type="text" class="newOrigin" value="${upstream.OriginIpOrDomain}" onchange="handleAutoOriginClean('${domUID}');">
|
||||
</div>
|
||||
<small>e.g. 192.168.0.101:8000 or example.com</small>
|
||||
</div>
|
||||
<div class="ui divider"></div>
|
||||
<div class="ui checkbox">
|
||||
<input type="checkbox" class="reqTLSCheckbox" ${upstream.RequireTLS?"checked":""}>
|
||||
<label>Require TLS<br>
|
||||
<small>Proxy target require HTTPS connection</small></label>
|
||||
</div><br>
|
||||
<div class="ui checkbox" style="margin-top: 0.6em;">
|
||||
<input type="checkbox" class="skipVerificationCheckbox" ${upstream.SkipCertValidations?"checked":""}>
|
||||
<label>Skip Verification<br>
|
||||
<small>Check this if proxy target is using self signed certificates</small></label>
|
||||
</div><br>
|
||||
<div class="ui checkbox" style="margin-top: 0.4em;">
|
||||
<input type="checkbox" class="SkipWebSocketOriginCheck" ${upstream.SkipWebSocketOriginCheck?"checked":""}>
|
||||
<label>Skip WebSocket Origin Check<br>
|
||||
<small>Check this to allow cross-origin websocket requests</small></label>
|
||||
</div><br>
|
||||
</div>
|
||||
<div class="upstreamActions">
|
||||
<!-- Change Priority -->
|
||||
<button class="ui basic circular icon button highPriorityButton" title="Increase Weight" onclick="increaseUpstreamWeight('${domUID}');"><i class="ui arrow up icon"></i></button>
|
||||
<button class="ui basic circular icon button lowPriorityButton ${downArrowClass}" title="Reduce Weight" onclick="decreaseUpstreamWeight('${domUID}');"><i class="ui arrow down icon"></i></button>
|
||||
<button class="ui basic circular icon editbtn button" onclick="handleUpstreamOriginEdit('${domUID}');" title="Edit Upstream Destination"><i class="ui grey edit icon"></i></button>
|
||||
<button style="display:none;" class="ui basic circular icon trashbtn button" onclick="removeUpstream('${domUID}');" title="Remove Upstream"><i class="ui red trash icon"></i></button>
|
||||
<button style="display:none;" class="ui basic circular icon savebtn button" onclick="saveUpstreamUpdate('${domUID}');" title="Save Changes"><i class="ui green save icon"></i></button>
|
||||
<button style="display:none;" class="ui basic circular icon cancelbtn button" onclick="initOriginList();" title="Cancel"><i class="ui grey times icon"></i></button>
|
||||
</div>
|
||||
</div>`);
|
||||
}
|
||||
|
||||
/* New Upstream Origin Functions */
|
||||
|
||||
//Clearn the proxy target value, make sure user do not enter http:// or https://
|
||||
//and auto select TLS checkbox if https:// exists
|
||||
function cleanProxyTargetValue(input){
|
||||
let targetDomain = $(input).val().trim();
|
||||
if (targetDomain.startsWith("http://")){
|
||||
targetDomain = targetDomain.substr(7);
|
||||
$(input).val(targetDomain);
|
||||
$("#requireTLS").parent().checkbox("set unchecked");
|
||||
}else if (targetDomain.startsWith("https://")){
|
||||
targetDomain = targetDomain.substr(8);
|
||||
$(input).val(targetDomain);
|
||||
$("#requireTLS").parent().checkbox("set checked");
|
||||
}else{
|
||||
//URL does not contains https or http protocol tag
|
||||
//sniff header
|
||||
$.ajax({
|
||||
url: "/api/proxy/tlscheck",
|
||||
data: {url: targetDomain},
|
||||
success: function(data){
|
||||
if (data.error != undefined){
|
||||
|
||||
}else if (data == "https"){
|
||||
$("#requireTLS").parent().checkbox("set checked");
|
||||
}else if (data == "http"){
|
||||
$("#requireTLS").parent().checkbox("set unchecked");
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
//Add a new upstream to this http proxy rule
|
||||
function addNewUpstream(){
|
||||
let origin = $("#originURL").val().trim();
|
||||
let requireTLS = $("#requireTLS")[0].checked;
|
||||
let skipVerification = $("#skipTlsVerification")[0].checked;
|
||||
let skipWebSocketOriginCheck = $("#SkipWebSocketOriginCheck")[0].checked;
|
||||
let activateLoadbalancer = $("#activateNewUpstreamCheckbox")[0].checked;
|
||||
|
||||
if (origin == ""){
|
||||
parent.msgbox("Upstream origin cannot be empty", false);
|
||||
return;
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
url: "/api/proxy/upstream/add",
|
||||
method: "POST",
|
||||
data:{
|
||||
"ep": editingEndpoint.ep,
|
||||
"origin": origin,
|
||||
"tls": requireTLS,
|
||||
"tlsval": skipVerification,
|
||||
"bpwsorg":skipWebSocketOriginCheck,
|
||||
"active": activateLoadbalancer,
|
||||
},
|
||||
success: function(data){
|
||||
if (data.error != undefined){
|
||||
parent.msgbox(data.error, false);
|
||||
}else{
|
||||
parent.msgbox("New upstream origin added");
|
||||
initOriginList();
|
||||
$("#originURL").val("");
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
//Get a upstream setting data from DOM element
|
||||
function getUpstreamSettingFromDOM(upstream){
|
||||
//Get the original setting from DOM payload
|
||||
let originalSettings = $(upstream).attr("data-payload");
|
||||
originalSettings = JSON.parse(decodeURIComponent(originalSettings));
|
||||
|
||||
//Get the updated settings if any
|
||||
let requireTLS = $(upstream).find(".reqTLSCheckbox")[0].checked;
|
||||
let skipTLSVerification = $(upstream).find(".skipVerificationCheckbox")[0].checked;
|
||||
let skipWebSocketOriginCheck = $(upstream).find(".SkipWebSocketOriginCheck")[0].checked;
|
||||
|
||||
//Update the original setting with new one just applied
|
||||
originalSettings.OriginIpOrDomain = $(upstream).find(".newOrigin").val();
|
||||
originalSettings.RequireTLS = requireTLS;
|
||||
originalSettings.SkipCertValidations = skipTLSVerification;
|
||||
originalSettings.SkipWebSocketOriginCheck = skipWebSocketOriginCheck;
|
||||
|
||||
//console.log(originalSettings);
|
||||
return originalSettings;
|
||||
}
|
||||
|
||||
//Handle setting change on upstream config
|
||||
function saveUpstreamUpdate(upstreamDomID){
|
||||
let targetDOM = $(`.upstreamEntry[data-domid=${upstreamDomID}]`);
|
||||
let originalSettings = $(targetDOM).attr("data-payload");
|
||||
originalSettings = JSON.parse(decodeURIComponent(originalSettings));
|
||||
let newConfig = getUpstreamSettingFromDOM(targetDOM);
|
||||
let isActive = $(targetDOM).find(".enableState")[0].checked;
|
||||
console.log(newConfig);
|
||||
$.ajax({
|
||||
url: "/api/proxy/upstream/update",
|
||||
method: "POST",
|
||||
data: {
|
||||
ep: editingEndpoint.ep,
|
||||
origin: originalSettings.OriginIpOrDomain, //Original ip or domain as key
|
||||
payload: JSON.stringify(newConfig),
|
||||
active: isActive,
|
||||
},
|
||||
success: function(data){
|
||||
if (data.error != undefined){
|
||||
parent.msgbox(data.error, false);
|
||||
|
||||
}else{
|
||||
parent.msgbox("Upstream setting updated");
|
||||
initOriginList();
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
//Edit the upstream origin of this upstream entry
|
||||
function handleUpstreamOriginEdit(upstreamDomID){
|
||||
let targetDOM = $(`.upstreamEntry[data-domid=${upstreamDomID}]`);
|
||||
let originalSettings = getUpstreamSettingsFromDomID(upstreamDomID);
|
||||
let originIP = originalSettings.OriginIpOrDomain;
|
||||
|
||||
//Change the UI to edit mode
|
||||
$(".editbtn").hide();
|
||||
$(".lowPriorityButton").hide();
|
||||
$(".highPriorityButton").hide();
|
||||
$(targetDOM).find(".trashbtn").show();
|
||||
$(targetDOM).find(".savebtn").show();
|
||||
$(targetDOM).find(".cancelbtn").show();
|
||||
$(targetDOM).find(".advanceOptions").show();
|
||||
}
|
||||
|
||||
//Check if the entered URL contains http or https
|
||||
function handleAutoOriginClean(domid){
|
||||
let targetDOM = $(`.upstreamEntry[data-domid=${domid}]`);
|
||||
let targetTLSCheckbox = $(targetDOM).find(".reqTLSCheckbox");
|
||||
let targetDomain = $(targetDOM).find(".newOrigin").val().trim();
|
||||
if (targetDomain.startsWith("http://")){
|
||||
targetDomain = targetDomain.substr(7);
|
||||
$(input).val(targetDomain);
|
||||
$(targetTLSCheckbox).parent().checkbox("set unchecked");
|
||||
}else if (targetDomain.startsWith("https://")){
|
||||
targetDomain = targetDomain.substr(8);
|
||||
$(input).val(targetDomain);
|
||||
$(targetTLSCheckbox).parent().checkbox("set checked");
|
||||
}else{
|
||||
//URL does not contains https or http protocol tag
|
||||
//sniff header
|
||||
$.ajax({
|
||||
url: "/api/proxy/tlscheck",
|
||||
data: {url: targetDomain},
|
||||
success: function(data){
|
||||
if (data.error != undefined){
|
||||
|
||||
}else if (data == "https"){
|
||||
$(targetTLSCheckbox).parent().checkbox("set checked");
|
||||
}else if (data == "http"){
|
||||
$(targetTLSCheckbox).parent().checkbox("set unchecked");
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function getUpstreamSettingsFromDomID(domid){
|
||||
let targetDOM = $(`.upstreamEntry[data-domid=${domid}]`);
|
||||
if (targetDOM.length == 0){
|
||||
return undefined;
|
||||
}
|
||||
let upstreamSettings = $(targetDOM).attr("data-payload");
|
||||
upstreamSettings = JSON.parse(decodeURIComponent(upstreamSettings));
|
||||
return upstreamSettings;
|
||||
}
|
||||
|
||||
function increaseUpstreamWeight(domid){
|
||||
let upstreamSetting = getUpstreamSettingsFromDomID(domid);
|
||||
let originIP = upstreamSetting.OriginIpOrDomain;
|
||||
let currentWeight = upstreamSetting.Weight;
|
||||
setUpstreamWeight(originIP, currentWeight+1);
|
||||
}
|
||||
|
||||
function decreaseUpstreamWeight(domid){
|
||||
let upstreamSetting = getUpstreamSettingsFromDomID(domid);
|
||||
let originIP = upstreamSetting.OriginIpOrDomain;
|
||||
let currentWeight = upstreamSetting.Weight;
|
||||
setUpstreamWeight(originIP, currentWeight-1);
|
||||
}
|
||||
|
||||
//Set a weight of a upstream
|
||||
function setUpstreamWeight(originIP, newWeight){
|
||||
$.ajax({
|
||||
url: "/api/proxy/upstream/setPriority",
|
||||
method: "POST",
|
||||
data: {
|
||||
ep: editingEndpoint.ep,
|
||||
origin: originIP,
|
||||
weight: newWeight,
|
||||
},
|
||||
success: function(data){
|
||||
if (data.error != undefined){
|
||||
parent.msgbox(data.error, false);
|
||||
}else{
|
||||
parent.msgbox("Upstream Weight Updated");
|
||||
initOriginList();
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
//Handle removal of an upstream
|
||||
function removeUpstream(domid){
|
||||
let targetDOM = $(`.upstreamEntry[data-domid=${domid}]`);
|
||||
let originalSettings = $(targetDOM).attr("data-payload");
|
||||
originalSettings = JSON.parse(decodeURIComponent(originalSettings));
|
||||
let UpstreamKey = originalSettings.OriginIpOrDomain;
|
||||
if (!confirm("Confirm removing " + UpstreamKey + " from upstream?")){
|
||||
return;
|
||||
}
|
||||
//Remove the upstream
|
||||
$.ajax({
|
||||
url: "/api/proxy/upstream/remove",
|
||||
method: "POST",
|
||||
data: {
|
||||
ep: editingEndpoint.ep,
|
||||
origin: originalSettings.OriginIpOrDomain, //Original ip or domain as key
|
||||
},
|
||||
success: function(data){
|
||||
if (data.error != undefined){
|
||||
parent.msgbox(data.error, false);
|
||||
|
||||
}else{
|
||||
parent.msgbox("Upstream deleted");
|
||||
initOriginList();
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if (window.location.hash.length > 1){
|
||||
let payloadHash = window.location.hash.substr(1);
|
||||
try{
|
||||
payloadHash = JSON.parse(decodeURIComponent(payloadHash));
|
||||
$(".epname").text(payloadHash.ep);
|
||||
editingEndpoint = payloadHash;
|
||||
initOriginList();
|
||||
}catch(ex){
|
||||
console.log("Unable to load endpoint data from hash")
|
||||
}
|
||||
}
|
||||
|
||||
function closeThisWrapper(){
|
||||
parent.hideSideWrapper(true);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Reference in New Issue
Block a user