From 09a479fb0f550a35feaeb98dd942a92441213f3d Mon Sep 17 00:00:00 2001 From: Tara Drwenski Date: Thu, 27 Aug 2026 14:32:05 -0700 Subject: [PATCH 01/14] Use wss on https pages; allow proxy path in Host field Hardcoded ws:// was blocked as mixed content on https pages. Derive the scheme from the page, and let Host include a path (e.g. host/glvis-ws) to reach the socket via a reverse proxy. Plain host:port use is unchanged. --- live/index.html | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/live/index.html b/live/index.html index dbf18a9..e7a7d38 100644 --- a/live/index.html +++ b/live/index.html @@ -1112,9 +1112,18 @@ return; } + // Match the page's protocol so an https page uses wss (a ws socket + // would be blocked as mixed content). + const proto = window.location.protocol === "https:" ? "wss" : "ws"; + + // A Host containing "/" is treated as a full "host[:port]/path" + // address (e.g. behind a reverse proxy) and used as-is, ignoring the + // Port field. Otherwise Host and Port are combined as "host:port". const host = this.socketHost; const port = this.socketPort; - const addr = `ws:\/\/${host}:${port}`; + const addr = host.includes("/") + ? `${proto}:\/\/${host}` + : `${proto}:\/\/${host}:${port}`; console.log(`trying to connect websocket to ${addr}`); this.glvSocket = new WebSocket(addr); From dd959799cdbe5d84ac4c91003d823e65a42c44cb Mon Sep 17 00:00:00 2001 From: Tara Drwenski Date: Thu, 3 Sep 2026 11:18:29 -0700 Subject: [PATCH 02/14] Default proxied GLVis pages to the socket route --- live/index.html | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/live/index.html b/live/index.html index e7a7d38..20e1da5 100644 --- a/live/index.html +++ b/live/index.html @@ -852,6 +852,9 @@ if (host === "127.0.0.1" || host === "glvis.org") { host = "localhost"; } + const socketHost = window.location.pathname.startsWith("/glvis/") + ? `${window.location.host}/glvis-ws` + : host; console.log(`host = ${host}`); const touch = matchMedia("(hover: none), (pointer: coarse)").matches; @@ -867,7 +870,7 @@ websocketDialogActive: false, logWindowActive: false, connectWebsocketButtonLabel: "Connect", - socketHost: host, + socketHost: socketHost, socketPort: "8080", controlWindowActive: false, helpWindowActive: false, From 6ac339a6618b60274b100f76a7c135892fd2acad Mon Sep 17 00:00:00 2001 From: Tara Drwenski Date: Thu, 3 Sep 2026 14:57:22 -0700 Subject: [PATCH 03/14] Configure the socket endpoint from the URL --- live/index.html | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/live/index.html b/live/index.html index 20e1da5..7a5bd99 100644 --- a/live/index.html +++ b/live/index.html @@ -852,8 +852,11 @@ if (host === "127.0.0.1" || host === "glvis.org") { host = "localhost"; } - const socketHost = window.location.pathname.startsWith("/glvis/") - ? `${window.location.host}/glvis-ws` + const socket = new URLSearchParams(window.location.search).get("socket"); + const socketHost = socket + ? socket.startsWith("/") + ? `${window.location.host}${socket}` + : socket : host; console.log(`host = ${host}`); @@ -1120,13 +1123,17 @@ const proto = window.location.protocol === "https:" ? "wss" : "ws"; // A Host containing "/" is treated as a full "host[:port]/path" - // address (e.g. behind a reverse proxy) and used as-is, ignoring the - // Port field. Otherwise Host and Port are combined as "host:port". + // address (e.g. behind a reverse proxy). A ws:// or wss:// URL is + // also used as-is, ignoring the Port field. const host = this.socketHost; const port = this.socketPort; - const addr = host.includes("/") - ? `${proto}:\/\/${host}` - : `${proto}:\/\/${host}:${port}`; + const hostUrl = new URL(`${proto}://${host}`); + const addr = + host.startsWith("ws://") || host.startsWith("wss://") + ? host + : host.includes("/") || hostUrl.port + ? `${proto}:\/\/${host}` + : `${proto}:\/\/${host}:${port}`; console.log(`trying to connect websocket to ${addr}`); this.glvSocket = new WebSocket(addr); From 775e077483de1feda8dd4ed8f7bda1f6eee69714 Mon Sep 17 00:00:00 2001 From: Tara Drwenski Date: Fri, 4 Sep 2026 09:57:59 -0700 Subject: [PATCH 04/14] Avoid parsing full WebSocket URLs as hostnames --- live/index.html | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/live/index.html b/live/index.html index 7a5bd99..11b7b8b 100644 --- a/live/index.html +++ b/live/index.html @@ -1127,13 +1127,16 @@ // also used as-is, ignoring the Port field. const host = this.socketHost; const port = this.socketPort; - const hostUrl = new URL(`${proto}://${host}`); - const addr = - host.startsWith("ws://") || host.startsWith("wss://") - ? host - : host.includes("/") || hostUrl.port + let addr; + if (host.startsWith("ws://") || host.startsWith("wss://")) { + addr = host; + } else { + const hostUrl = new URL(`${proto}://${host}`); + addr = + host.includes("/") || hostUrl.port ? `${proto}:\/\/${host}` : `${proto}:\/\/${host}:${port}`; + } console.log(`trying to connect websocket to ${addr}`); this.glvSocket = new WebSocket(addr); From bae3bcea80787756e825e90cf2e58e303d689074 Mon Sep 17 00:00:00 2001 From: Tara Drwenski Date: Fri, 4 Sep 2026 10:01:15 -0700 Subject: [PATCH 05/14] Automatically connect when a socket endpoint is provided --- live/index.html | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/live/index.html b/live/index.html index 11b7b8b..4607771 100644 --- a/live/index.html +++ b/live/index.html @@ -1080,6 +1080,10 @@ await new Promise((r) => setTimeout(r, 50 + this.streamDelay * 10)); }); + if (socket) { + this.connectWebsocket(); + } + this.glvIsLoading = false; }, watch: { From de1187271cf604e2f006ccee179895b0ce5c532d Mon Sep 17 00:00:00 2001 From: Tara Drwenski Date: Wed, 9 Sep 2026 15:20:23 -0700 Subject: [PATCH 06/14] Preserve loopback WebSocket connections --- live/index.html | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/live/index.html b/live/index.html index 4607771..0e222d8 100644 --- a/live/index.html +++ b/live/index.html @@ -1122,10 +1122,6 @@ return; } - // Match the page's protocol so an https page uses wss (a ws socket - // would be blocked as mixed content). - const proto = window.location.protocol === "https:" ? "wss" : "ws"; - // A Host containing "/" is treated as a full "host[:port]/path" // address (e.g. behind a reverse proxy). A ws:// or wss:// URL is // also used as-is, ignoring the Port field. @@ -1135,7 +1131,16 @@ if (host.startsWith("ws://") || host.startsWith("wss://")) { addr = host; } else { - const hostUrl = new URL(`${proto}://${host}`); + const hostUrl = new URL(`http://${host}`); + const isLoopback = ["localhost", "127.0.0.1"].includes( + hostUrl.hostname, + ); + // HTTPS pages need WSS for remote endpoints, but browsers permit + // the established local ws://localhost:8080 workflow. + const proto = + window.location.protocol === "https:" && !isLoopback + ? "wss" + : "ws"; addr = host.includes("/") || hostUrl.port ? `${proto}:\/\/${host}` From 8f54984348a9bcd18850cb725cc15a3c6a12e52b Mon Sep 17 00:00:00 2001 From: Tara Drwenski Date: Wed, 9 Sep 2026 16:41:02 -0700 Subject: [PATCH 07/14] Improve websocket connection interface --- live/index.html | 85 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 56 insertions(+), 29 deletions(-) diff --git a/live/index.html b/live/index.html index 0e222d8..8e847f6 100644 --- a/live/index.html +++ b/live/index.html @@ -214,16 +214,45 @@ + + + + + + +
+ {{ websocketAddress() }} +
{{ connectWebsocketButtonLabel }} @@ -853,11 +882,11 @@ host = "localhost"; } const socket = new URLSearchParams(window.location.search).get("socket"); - const socketHost = socket - ? socket.startsWith("/") + const socketHost = + socket && socket.startsWith("/") ? `${window.location.host}${socket}` - : socket - : host; + : host; + const socketUrl = socket && !socket.startsWith("/") ? socket : ""; console.log(`host = ${host}`); const touch = matchMedia("(hover: none), (pointer: coarse)").matches; @@ -873,8 +902,11 @@ websocketDialogActive: false, logWindowActive: false, connectWebsocketButtonLabel: "Connect", + socketConnectionMode: socketUrl ? "url" : "address", socketHost: socketHost, socketPort: "8080", + socketPath: "/", + socketUrl: socketUrl, controlWindowActive: false, helpWindowActive: false, fullScreenMode: false, @@ -1099,6 +1131,24 @@ }, }, methods: { + websocketAddress: function () { + if (this.socketConnectionMode === "url") { + return this.socketUrl; + } + + const isLoopback = ["localhost", "127.0.0.1"].includes( + this.socketHost, + ); + const proto = + window.location.protocol === "https:" && !isLoopback ? "wss" : "ws"; + const port = this.socketPort ? `:${this.socketPort}` : ""; + const path = this.socketPath + ? this.socketPath.startsWith("/") + ? this.socketPath + : `/${this.socketPath}` + : "/"; + return `${proto}://${this.socketHost}${port}${path}`; + }, updateCanvasSize: function () { [w, h] = windowDim(); this.glv.setSize(w, h); @@ -1122,30 +1172,7 @@ return; } - // A Host containing "/" is treated as a full "host[:port]/path" - // address (e.g. behind a reverse proxy). A ws:// or wss:// URL is - // also used as-is, ignoring the Port field. - const host = this.socketHost; - const port = this.socketPort; - let addr; - if (host.startsWith("ws://") || host.startsWith("wss://")) { - addr = host; - } else { - const hostUrl = new URL(`http://${host}`); - const isLoopback = ["localhost", "127.0.0.1"].includes( - hostUrl.hostname, - ); - // HTTPS pages need WSS for remote endpoints, but browsers permit - // the established local ws://localhost:8080 workflow. - const proto = - window.location.protocol === "https:" && !isLoopback - ? "wss" - : "ws"; - addr = - host.includes("/") || hostUrl.port - ? `${proto}:\/\/${host}` - : `${proto}:\/\/${host}:${port}`; - } + const addr = this.websocketAddress(); console.log(`trying to connect websocket to ${addr}`); this.glvSocket = new WebSocket(addr); From c2b5f20df6ea56abcb920878574a4e9c1cc3486a Mon Sep 17 00:00:00 2001 From: Tara Drwenski Date: Wed, 9 Sep 2026 18:20:55 -0700 Subject: [PATCH 08/14] Fix socket query param --- live/index.html | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/live/index.html b/live/index.html index 8e847f6..f5df7a0 100644 --- a/live/index.html +++ b/live/index.html @@ -882,10 +882,10 @@ host = "localhost"; } const socket = new URLSearchParams(window.location.search).get("socket"); - const socketHost = - socket && socket.startsWith("/") - ? `${window.location.host}${socket}` - : host; + const socketIsPath = socket && socket.startsWith("/"); + const socketHost = socketIsPath ? window.location.host : host; + const socketPort = socketIsPath ? "" : "8080"; + const socketPath = socketIsPath ? socket : "/"; const socketUrl = socket && !socket.startsWith("/") ? socket : ""; console.log(`host = ${host}`); @@ -904,8 +904,8 @@ connectWebsocketButtonLabel: "Connect", socketConnectionMode: socketUrl ? "url" : "address", socketHost: socketHost, - socketPort: "8080", - socketPath: "/", + socketPort: socketPort, + socketPath: socketPath, socketUrl: socketUrl, controlWindowActive: false, helpWindowActive: false, From 4f01d6deb5e932ef8a9c339b685a9e366479771a Mon Sep 17 00:00:00 2001 From: Tara Drwenski Date: Wed, 9 Sep 2026 18:22:42 -0700 Subject: [PATCH 09/14] Style fix --- live/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/live/index.html b/live/index.html index f5df7a0..4f4b077 100644 --- a/live/index.html +++ b/live/index.html @@ -1137,7 +1137,7 @@ } const isLoopback = ["localhost", "127.0.0.1"].includes( - this.socketHost, + this.socketHost ); const proto = window.location.protocol === "https:" && !isLoopback ? "wss" : "ws"; From e14c62aa44b39420add21f81f56e6f115f2bb26c Mon Sep 17 00:00:00 2001 From: Tara Drwenski Date: Mon, 14 Sep 2026 09:23:56 -0700 Subject: [PATCH 10/14] Style improvement in ternary if Co-authored-by: Jan Nikl --- live/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/live/index.html b/live/index.html index 4f4b077..c8c8a4e 100644 --- a/live/index.html +++ b/live/index.html @@ -1140,7 +1140,7 @@ this.socketHost ); const proto = - window.location.protocol === "https:" && !isLoopback ? "wss" : "ws"; + (window.location.protocol === "https:" && !isLoopback) ? "wss" : "ws"; const port = this.socketPort ? `:${this.socketPort}` : ""; const path = this.socketPath ? this.socketPath.startsWith("/") From 44a8c9dbbb5dda31502204baf7a8b5d8617e66fc Mon Sep 17 00:00:00 2001 From: Tara Drwenski Date: Mon, 14 Sep 2026 09:17:12 -0700 Subject: [PATCH 11/14] Log socket connection settings --- live/index.html | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/live/index.html b/live/index.html index c8c8a4e..66b0c0b 100644 --- a/live/index.html +++ b/live/index.html @@ -887,7 +887,15 @@ const socketPort = socketIsPath ? "" : "8080"; const socketPath = socketIsPath ? socket : "/"; const socketUrl = socket && !socket.startsWith("/") ? socket : ""; - console.log(`host = ${host}`); + console.log("socket settings:", { + host, + socket, + socketIsPath, + socketHost, + socketPort, + socketPath, + socketUrl, + }); const touch = matchMedia("(hover: none), (pointer: coarse)").matches; console.log(`touch = ${touch}`); From 6dfc9f8732f3eebfc3794547d7f3803e5cb13bb2 Mon Sep 17 00:00:00 2001 From: Tara Drwenski Date: Mon, 14 Sep 2026 09:33:34 -0700 Subject: [PATCH 12/14] Remove unneeded empty string check --- live/index.html | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/live/index.html b/live/index.html index 66b0c0b..c27f003 100644 --- a/live/index.html +++ b/live/index.html @@ -1150,11 +1150,9 @@ const proto = (window.location.protocol === "https:" && !isLoopback) ? "wss" : "ws"; const port = this.socketPort ? `:${this.socketPort}` : ""; - const path = this.socketPath - ? this.socketPath.startsWith("/") - ? this.socketPath - : `/${this.socketPath}` - : "/"; + const path = this.socketPath.startsWith("/") + ? this.socketPath + : `/${this.socketPath}`; return `${proto}://${this.socketHost}${port}${path}`; }, updateCanvasSize: function () { From 2d1017ee30362216742e582c3112e133c392bcc2 Mon Sep 17 00:00:00 2001 From: Tara Drwenski Date: Mon, 14 Sep 2026 10:11:48 -0700 Subject: [PATCH 13/14] Simplify socket connection options --- live/index.html | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/live/index.html b/live/index.html index c27f003..4dcc72f 100644 --- a/live/index.html +++ b/live/index.html @@ -239,11 +239,6 @@ v-model="socketPort" label="Port (optional)" > - Date: Mon, 14 Sep 2026 10:47:32 -0700 Subject: [PATCH 14/14] Apply make style --- live/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/live/index.html b/live/index.html index 4dcc72f..24cf7fa 100644 --- a/live/index.html +++ b/live/index.html @@ -1144,7 +1144,7 @@ this.socketHost ); const proto = - (window.location.protocol === "https:" && !isLoopback) ? "wss" : "ws"; + window.location.protocol === "https:" && !isLoopback ? "wss" : "ws"; const port = this.socketPort ? `:${this.socketPort}` : ""; return `${proto}://${this.socketHost}${port}`; },