trying to fix turn server for firefox

This commit is contained in:
Klemek
2025-03-18 18:00:22 +01:00
parent fa4e6391e3
commit 7de550b63b
+86 -47
View File
@@ -12,15 +12,24 @@ const utils = {
}, },
userAgent(raw) { userAgent(raw) {
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Browser_detection_using_the_user_agent#which_part_of_the_user_agent_contains_the_information_you_are_looking_for // https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Browser_detection_using_the_user_agent#which_part_of_the_user_agent_contains_the_information_you_are_looking_for
const userAgents = ['Seamonkey','Firefox','Chromium','Edg.*', 'Chrome', 'Safari', 'OPR', 'Opera']; const userAgents = [
for (let index = 0; index < userAgents.length; index+=1) { "Seamonkey",
"Firefox",
"Chromium",
"Edg.*",
"Chrome",
"Safari",
"OPR",
"Opera",
];
for (let index = 0; index < userAgents.length; index += 1) {
const userAgent = userAgents[index]; const userAgent = userAgents[index];
const result = new RegExp(`(${userAgent}\\/\\d+\\.\\d+)`, 'iu').exec(raw); const result = new RegExp(`(${userAgent}\\/\\d+\\.\\d+)`, "iu").exec(raw);
if (result) { if (result) {
return result[0]; return result[0];
} }
} }
return 'Unknown' return "Unknown";
}, },
prettyBytes(byteCount) { prettyBytes(byteCount) {
let size = byteCount / 1000; let size = byteCount / 1000;
@@ -41,14 +50,21 @@ const utils = {
return `<1s`; return `<1s`;
} }
if (time < 60) { if (time < 60) {
return `${Math.floor(time).toFixed(0).padStart(2, '0')}s`; return `${Math.floor(time).toFixed(0).padStart(2, "0")}s`;
} }
time /= 60; time /= 60;
if (time < 60) { if (time < 60) {
return `${Math.floor(time).toFixed(0).padStart(2, '0')}m${((time * 60) % 60).toFixed(0).padStart(2, '0')}s`; return `${Math.floor(time).toFixed(0).padStart(2, "0")}m${(
(time * 60) %
60
)
.toFixed(0)
.padStart(2, "0")}s`;
} }
time /= 60; time /= 60;
return `${Math.floor(time).toFixed(0).padStart(2, '0')}h${((time * 60) % 60).toFixed(0).padStart(2, '0')}m`; return `${Math.floor(time).toFixed(0).padStart(2, "0")}h${((time * 60) % 60)
.toFixed(0)
.padStart(2, "0")}m`;
}, },
}; };
@@ -123,44 +139,46 @@ const app = createApp({
return this.error; return this.error;
} }
if (!this.canConnect) { if (!this.canConnect) {
return 'Acquiring ID...'; return "Acquiring ID...";
} }
if (this.isServer) { if (this.isServer) {
if (! this.server.data) { if (!this.server.data) {
return 'Waiting for file upload'; return "Waiting for file upload";
} }
return 'Ready to send file'; return "Ready to send file";
} }
if (! this.client.connected) { if (!this.client.connected) {
return 'Connecting to peer...'; return "Connecting to peer...";
} }
if (this.readyToDownload) { if (this.readyToDownload) {
return 'Ready to download'; return "Ready to download";
} }
if (! this.downloading) { if (!this.downloading) {
return 'Waiting for file info...'; return "Waiting for file info...";
} }
if (this.client.downloadEnd) { if (this.client.downloadEnd) {
return 'File downloaded'; return "File downloaded";
} }
return 'Downloading...'; return "Downloading...";
}, },
prettyFileSize() { prettyFileSize() {
return utils.prettyBytes(this.fileSize); return utils.prettyBytes(this.fileSize);
}, },
prettyDownloadSpeed() { prettyDownloadSpeed() {
if (! this.client.downloadStart) { if (!this.client.downloadStart) {
return ''; return "";
} }
const time = (this.client.downloadEnd ?? (new Date())) - this.client.downloadStart; const time =
const speed = 1000 * this.downloadProgress / time; (this.client.downloadEnd ?? new Date()) - this.client.downloadStart;
const speed = (1000 * this.downloadProgress) / time;
return `${utils.prettyBytes(speed)}/s`; return `${utils.prettyBytes(speed)}/s`;
}, },
prettyRemainingTime() { prettyRemainingTime() {
if (! this.client.downloadStart || this.client.downloadEnd) { if (!this.client.downloadStart || this.client.downloadEnd) {
return ''; return "";
} }
const time = (this.client.downloadEnd ?? (new Date())) - this.client.downloadStart; const time =
(this.client.downloadEnd ?? new Date()) - this.client.downloadStart;
const speed = this.downloadProgress / time; const speed = this.downloadProgress / time;
const remainingBytes = this.downloadTotal - this.downloadProgress; const remainingBytes = this.downloadTotal - this.downloadProgress;
const remainingTime = remainingBytes / speed; const remainingTime = remainingBytes / speed;
@@ -188,8 +206,9 @@ const app = createApp({
}, },
initClient() { initClient() {
const url = new URL(window.location); const url = new URL(window.location);
const remoteId = url.searchParams.get("s") ?? ''; const remoteId = url.searchParams.get("s") ?? "";
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$/iu; const uuidRegex =
/^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$/iu;
if (uuidRegex.test(remoteId)) { if (uuidRegex.test(remoteId)) {
this.isServer = false; this.isServer = false;
this.client.remoteId = remoteId; this.client.remoteId = remoteId;
@@ -203,11 +222,18 @@ const app = createApp({
secure: true, secure: true,
config: { config: {
iceServers: [ iceServers: [
{ url: 'stun:stun.l.google.com:19302' },
{ {
urls: [`turn:klemek.fr:3478`, `turns:klemek.fr:5349`], urls: ["stun:klemek.fr:3478"],
username: "username", },
credential: "credential", {
urls: ["turns:klemek.fr:5349"],
username: "anonymous",
credential: "anonymous",
},
{
urls: ["turn:klemek.fr:3478"],
username: "anonymous",
credential: "anonymous",
}, },
], ],
}, },
@@ -219,16 +245,24 @@ const app = createApp({
this.peer.on("error", this.onPeerError); this.peer.on("error", this.onPeerError);
}, },
initServerConnection(conn) { initServerConnection(conn) {
const index = this.server.clients.length; let index = this.server.clients.findIndex(
this.server.clients.push({ (client) => client.id === conn.peer
);
const clientData = {
connection: conn, connection: conn,
id: conn.peer, id: conn.peer,
done: false, done: false,
sent: 0, sent: 0,
connected: false, connected: false,
status: 'Connecting...', status: "Connecting...",
userAgent: null, userAgent: null,
}); };
if (index === -1) {
index = this.server.clients.length;
this.server.clients.push(clientData);
} else {
this.server.clients[index] = clientData;
}
conn.on("open", () => this.onServerConnectionOpen(index)); conn.on("open", () => this.onServerConnectionOpen(index));
conn.on("close", () => this.onServerConnectionClose(index)); conn.on("close", () => this.onServerConnectionClose(index));
conn.on("data", (data) => this.onServerConnectionData(index, data)); conn.on("data", (data) => this.onServerConnectionData(index, data));
@@ -259,7 +293,7 @@ const app = createApp({
}, },
clientOpenConnection() { clientOpenConnection() {
this.initClientConnection( this.initClientConnection(
this.peer.connect(this.client.remoteId, { reliable: false }), this.peer.connect(this.client.remoteId, { reliable: false })
); );
}, },
// PEER EVENTS // PEER EVENTS
@@ -297,7 +331,7 @@ const app = createApp({
onServerConnectionOpen(index) { onServerConnectionOpen(index) {
console.log("onServerConnectionOpen", index); console.log("onServerConnectionOpen", index);
this.server.clients[index].connected = true; this.server.clients[index].connected = true;
this.server.clients[index].status = 'Connected'; this.server.clients[index].status = "Connected";
this.sendServerInfo(index); this.sendServerInfo(index);
}, },
onServerConnectionData(index, data) { onServerConnectionData(index, data) {
@@ -319,11 +353,11 @@ const app = createApp({
}, },
onServerConnectionClose(index) { onServerConnectionClose(index) {
console.log("onServerConnectionClose", index); console.log("onServerConnectionClose", index);
this.server.clients[index].status = 'Disconnected'; this.server.clients[index].status = "Disconnected";
}, },
onServerConnectionError(index, err) { onServerConnectionError(index, err) {
console.log("onServerConnectionError", index, err); console.log("onServerConnectionError", index, err);
this.server.clients[index].status = 'Error'; this.server.clients[index].status = "Error";
}, },
// CLIENT CONNECTION EVENTS // CLIENT CONNECTION EVENTS
onClientConnectionOpen() { onClientConnectionOpen() {
@@ -354,7 +388,7 @@ const app = createApp({
}, },
onClientConnectionError(err) { onClientConnectionError(err) {
console.log("onClientConnectionError", err); console.log("onClientConnectionError", err);
this.error = `Connection failed: ${err.type}. Reconnecting...` this.error = `Connection failed: ${err.type}. Reconnecting...`;
setTimeout(this.clientOpenConnection, 1000); setTimeout(this.clientOpenConnection, 1000);
}, },
// EXCHANGES // EXCHANGES
@@ -381,7 +415,7 @@ const app = createApp({
handleServerChunk(data) { handleServerChunk(data) {
new Uint8Array(this.client.buffer).set( new Uint8Array(this.client.buffer).set(
new Uint8Array(data.bytes), new Uint8Array(data.bytes),
data.index, data.index
); );
this.client.received.push(data.index); this.client.received.push(data.index);
}, },
@@ -389,7 +423,6 @@ const app = createApp({
this.server.clients[index].connection.send({ this.server.clients[index].connection.send({
type: MESSAGE_TYPE.ServerDone, type: MESSAGE_TYPE.ServerDone,
}); });
}, },
handleServerDone() { handleServerDone() {
const indexes = []; const indexes = [];
@@ -427,7 +460,11 @@ const app = createApp({
setTimeout(() => this.sendServerChunk(index, chunkIndex)); setTimeout(() => this.sendServerChunk(index, chunkIndex));
}); });
} else { } else {
for (let chunkIndex = 0; chunkIndex < this.fileSize; chunkIndex += MAX_CHUNK_SIZE) { for (
let chunkIndex = 0;
chunkIndex < this.fileSize;
chunkIndex += MAX_CHUNK_SIZE
) {
setTimeout(() => this.sendServerChunk(index, chunkIndex)); setTimeout(() => this.sendServerChunk(index, chunkIndex));
} }
} }
@@ -441,7 +478,7 @@ const app = createApp({
handleClientDone(index) { handleClientDone(index) {
this.server.clients[index].connection.close(); this.server.clients[index].connection.close();
this.server.clients[index].done = true; this.server.clients[index].done = true;
this.server.clients[index].status = 'Done'; this.server.clients[index].status = "Done";
}, },
// UI EVENTS // UI EVENTS
onFileChange(event) { onFileChange(event) {
@@ -470,13 +507,15 @@ const app = createApp({
navigator.share({ navigator.share({
url: this.server.url, url: this.server.url,
title: window.title, title: window.title,
}) });
} else { } else {
navigator.clipboard.writeText(this.server.url); navigator.clipboard.writeText(this.server.url);
this.server.copied = true; this.server.copied = true;
setTimeout(() => {this.server.copied = false;}, 5000); setTimeout(() => {
this.server.copied = false;
}, 5000);
} }
} },
}, },
}); });