Send OPTIONS request to the WebSockets interface once per Timeout interval. This allows some deployment environment to correctly detect the status of the application
This commit is contained in:
@@ -156,3 +156,8 @@ func (s socketVerification) Get(
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s socketVerification) Options(
|
||||
w http.ResponseWriter, r *http.Request, l log.Logger) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
16
ui/app.js
16
ui/app.js
@@ -200,25 +200,29 @@ function startApp(rootEl) {
|
||||
await cipher.hmac512(enc.encode(finalKey), enc.encode(rTime))
|
||||
).slice(0, 32);
|
||||
},
|
||||
buildBackendSocketURL() {
|
||||
let r = "";
|
||||
buildBackendSocketURLs() {
|
||||
let r = {
|
||||
webSocket: "",
|
||||
keepAlive: "",
|
||||
};
|
||||
|
||||
switch (location.protocol) {
|
||||
case "https:":
|
||||
r = "wss://";
|
||||
r.webSocket = "wss://";
|
||||
break;
|
||||
|
||||
default:
|
||||
r = "ws://";
|
||||
r.webSocket = "ws://";
|
||||
}
|
||||
|
||||
r += location.host + socksInterface;
|
||||
r.webSocket += location.host + socksInterface;
|
||||
r.keepAlive = location.protocol + "//" + location.host + socksInterface;
|
||||
|
||||
return r;
|
||||
},
|
||||
buildSocket(key, dialTimeout, heartbeatInterval) {
|
||||
return new Socket(
|
||||
this.buildBackendSocketURL(),
|
||||
this.buildBackendSocketURLs(),
|
||||
key,
|
||||
dialTimeout * 1000,
|
||||
heartbeatInterval * 1000
|
||||
|
||||
20
ui/socket.js
20
ui/socket.js
@@ -19,6 +19,7 @@ import * as crypt from "./crypto.js";
|
||||
import * as reader from "./stream/reader.js";
|
||||
import * as sender from "./stream/sender.js";
|
||||
import * as streams from "./stream/streams.js";
|
||||
import * as xhr from "./xhr.js";
|
||||
|
||||
export const ECHO_FAILED = streams.ECHO_FAILED;
|
||||
|
||||
@@ -39,19 +40,22 @@ class Dial {
|
||||
this.address = address;
|
||||
this.timeout = timeout;
|
||||
this.privateKey = privateKey;
|
||||
this.keepAliveTicker = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to the remote server
|
||||
*
|
||||
* @param {string} address Target URL address
|
||||
* @param {number} timeout Connect timeout
|
||||
*
|
||||
* @returns {Promise<WebSocket>} When connection is established
|
||||
*
|
||||
*/
|
||||
connect(timeout) {
|
||||
connect(address, timeout) {
|
||||
const self = this;
|
||||
return new Promise((resolve, reject) => {
|
||||
let ws = new WebSocket(this.address),
|
||||
let ws = new WebSocket(address.webSocket),
|
||||
promised = false,
|
||||
timeoutTimer = setTimeout(() => {
|
||||
ws.close();
|
||||
@@ -77,6 +81,12 @@ class Dial {
|
||||
return reject(e);
|
||||
};
|
||||
|
||||
if (!self.keepAliveTicker) {
|
||||
self.keepAliveTicker = setInterval(() => {
|
||||
xhr.options(address.keepAlive, {});
|
||||
}, self.timeout);
|
||||
}
|
||||
|
||||
ws.addEventListener("open", (_event) => {
|
||||
myRes(ws);
|
||||
});
|
||||
@@ -87,10 +97,14 @@ class Dial {
|
||||
};
|
||||
|
||||
myRej(event);
|
||||
clearInterval(self.keepAliveTicker);
|
||||
self.keepAliveTicker = null;
|
||||
});
|
||||
|
||||
ws.addEventListener("error", (_event) => {
|
||||
ws.close();
|
||||
clearInterval(self.keepAliveTicker);
|
||||
self.keepAliveTicker = null;
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -123,7 +137,7 @@ class Dial {
|
||||
*
|
||||
*/
|
||||
async dial(callbacks) {
|
||||
let ws = await this.connect(this.timeout);
|
||||
let ws = await this.connect(this.address, this.timeout);
|
||||
|
||||
try {
|
||||
let rd = new reader.Reader(new reader.Multiple(() => {}), (data) => {
|
||||
|
||||
12
ui/xhr.js
12
ui/xhr.js
@@ -15,7 +15,7 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
export function get(url, headers) {
|
||||
function send(method, url, headers) {
|
||||
return new Promise((res, rej) => {
|
||||
let authReq = new XMLHttpRequest();
|
||||
|
||||
@@ -35,7 +35,7 @@ export function get(url, headers) {
|
||||
rej(e);
|
||||
});
|
||||
|
||||
authReq.open("GET", url, true);
|
||||
authReq.open(method, url, true);
|
||||
|
||||
for (let h in headers) {
|
||||
authReq.setRequestHeader(h, headers[h]);
|
||||
@@ -44,3 +44,11 @@ export function get(url, headers) {
|
||||
authReq.send();
|
||||
});
|
||||
}
|
||||
|
||||
export function get(url, headers) {
|
||||
return send("GET", url, headers);
|
||||
}
|
||||
|
||||
export function options(url, headers) {
|
||||
return send("OPTIONS", url, headers);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user