WS pings to maintain connection, fixed server crash when sending malformed data

This commit is contained in:
ari melody 2023-10-01 19:31:32 +01:00
parent 42ba0e3275
commit cd3912293f
Signed by: ari
GPG key ID: CF99829C92678188
4 changed files with 76 additions and 21 deletions

View file

@ -31,6 +31,9 @@
<footer> <footer>
<ul> <ul>
<li><a href="https://arimelody.me" target="_blank">made with &lt;3 by ari melody</a></li> <li><a href="https://arimelody.me" target="_blank">made with &lt;3 by ari melody</a></li>
</ul>
<ul>
<li><a href="https://github.com/mellodoot/openterminal/issues" target="_blank">issues</a></li>
<li><a href="https://github.com/mellodoot/openterminal" target="_blank">source</a></li> <li><a href="https://github.com/mellodoot/openterminal" target="_blank">source</a></li>
</ul> </ul>
</footer> </footer>

View file

@ -11,12 +11,13 @@ var pre_buffer_chars = 0;
var server_url = ""; var server_url = "";
const DATA_TYPES = { const DATA_TYPES = {
text: 0, ping: 0,
colour: 1, text: 1,
buffer: 2, colour: 2,
backspace: 3, buffer: 3,
backword: 4, backspace: 4,
arrow: 5, backword: 5,
arrow: 6,
}; };
function start() { function start() {
@ -108,6 +109,9 @@ function handle_message(data) {
const is_at_bottom = content.scrollHeight - content.offsetHeight - content.scrollTop < 10; const is_at_bottom = content.scrollHeight - content.offsetHeight - content.scrollTop < 10;
switch (data.type) { switch (data.type) {
case DATA_TYPES.ping:
client.send(JSON.stringify({type: DATA_TYPES.ping}));
break;
case DATA_TYPES.colour: case DATA_TYPES.colour:
my_colour = data.colour; my_colour = data.colour;
console.log(`%cColour has been changed to ${my_colour}`, `color: ${my_colour}`); console.log(`%cColour has been changed to ${my_colour}`, `color: ${my_colour}`);
@ -253,7 +257,7 @@ function handle_paste(event) {
type: DATA_TYPES.text, type: DATA_TYPES.text,
text: paste, text: paste,
}); });
content.scrollTop = content.scrollHeight - content.offsetHeight - 28; content.scrollTop = content.scrollHeight - content.offsetHeight;
} }
const PALETTE = { const PALETTE = {

View file

@ -52,14 +52,14 @@ footer {
display: flex; display: flex;
gap: 1em; gap: 1em;
align-items: center; align-items: center;
justify-content: space-between;
} }
footer ul { footer ul {
width: 100%;
margin: 0; margin: 0;
padding: 0; padding: 0;
display: flex; display: flex;
justify-content: space-between; gap: 1em;
} }
footer li { footer li {

View file

@ -21,12 +21,13 @@ const MIME_TYPES = {
}; };
const DATA_TYPES = { const DATA_TYPES = {
text: 0, ping: 0,
colour: 1, text: 1,
buffer: 2, colour: 2,
backspace: 3, buffer: 3,
backword: 4, backspace: 4,
arrow: 5, backword: 5,
arrow: 6,
}; };
const MOTDS = [ const MOTDS = [
@ -46,16 +47,27 @@ const MOTDS = [
const STATIC_PATH = path.join(process.cwd(), "public"); const STATIC_PATH = path.join(process.cwd(), "public");
const banner = const BANNER =
`Welcome to OpenTerminal! `Welcome to OpenTerminal!
`; `;
const FAKE_CRASH =
`
=========================================
This copy of OpenTerminal is not genuine.
Please acquire a genuine copy.
This connection will now terminate.
=========================================
`;
const PORT = process.env.PORT || 8080; const PORT = process.env.PORT || 8080;
const PING_INTERVAL = 10000;
let sockets = []; let sockets = [];
let buffer = ""; let buffer = "";
const MAX_BUFFER_SIZE = 10240; const MAX_BUFFER_SIZE = 1024 * 1000;
const MAX_MESSAGE_LENGTH = 1024; const MAX_MESSAGE_LENGTH = 1024;
/** /**
@ -103,7 +115,7 @@ wss.on('connection', socket => {
*/ */
socket.send(JSON.stringify({ socket.send(JSON.stringify({
type: DATA_TYPES.text, type: DATA_TYPES.text,
text: `${banner}/* ${MOTDS[Math.floor(Math.random() * MOTDS.length)]} */\n\n`, text: `${BANNER}/* ${MOTDS[Math.floor(Math.random() * MOTDS.length)]} */\n\n`,
colour: false, colour: false,
sticky: true, sticky: true,
})); }));
@ -114,18 +126,40 @@ wss.on('connection', socket => {
})); }));
} }
const ping_interval = setInterval(
function() {
socket.send(JSON.stringify({
type: DATA_TYPES.ping,
}))
}, PING_INTERVAL);
socket.ping_interval = ping_interval;
sockets.push(socket); sockets.push(socket);
// console.log(`new connection.\n\tcurrent connections: ${sockets.length}`); // console.log(`new connection.\n\tcurrent connections: ${sockets.length}`);
socket.on('message', event => { handle_message(JSON.parse(event), socket) }); socket.on('message', event => {
try {
handle_message(JSON.parse(event), socket)
} catch (error) {
socket.send(JSON.stringify({
type: DATA_TYPES.text,
text: FAKE_CRASH,
}));
console.error(error);
}
});
socket.on('close', () => { socket.on('close', () => {
clearInterval(socket.ping_interval);
sockets = sockets.filter(s => s !== socket); sockets = sockets.filter(s => s !== socket);
// console.log(`connection closed.\n\tcurrent connections: ${sockets.length}`); // console.log(`connection closed.\n\tcurrent connections: ${sockets.length}`);
}); });
}); });
/**
* handles parsed JSON data sent by the client.
*/
function handle_message(data, user) { function handle_message(data, user) {
switch (data.type) { switch (data.type) {
case DATA_TYPES.backword: case DATA_TYPES.backword:
@ -149,6 +183,11 @@ function handle_message(data, user) {
return; return;
} }
if (data.text.length > MAX_MESSAGE_LENGTH) { if (data.text.length > MAX_MESSAGE_LENGTH) {
user.send(JSON.stringify({
type: DATA_TYPES.text,
text: "bleeeehhhh :P\n(message too long!)\n",
}))
user.close();
return; return;
} }
block = { block = {
@ -161,12 +200,15 @@ function handle_message(data, user) {
} }
if (buffer.length > MAX_BUFFER_SIZE) { if (buffer.length > MAX_BUFFER_SIZE) {
send_as_server(`\n\nSERVER: This channel's maximum buffer length has been hit (${MAX_BUFFER_SIZE}).\n` + broadcast_as_server(`\n\nSERVER: This channel's maximum buffer length has been hit (${MAX_BUFFER_SIZE}).\n` +
`You will need to make more room, or the server will have to be restarted.\n` + `You will need to make more room, or the server will have to be restarted.\n` +
`Apologies for the inconvenience!`) `Apologies for the inconvenience!`)
} }
} }
/**
* generates a random hexadecimal colour value (ex. #ff00ff)
*/
function generate_colour() { function generate_colour() {
let result = '#'; let result = '#';
let hexref = '0123456789abcdef'; let hexref = '0123456789abcdef';
@ -180,7 +222,10 @@ server.listen(PORT, () => {
console.log(`OpenTerminal is now LIVE on https://127.0.0.1:${PORT}!`); console.log(`OpenTerminal is now LIVE on https://127.0.0.1:${PORT}!`);
}); });
function send_as_server(message) { /**
* sends a server-wide message to all connected clients.
*/
function broadcast_as_server(message) {
broadcast(JSON.stringify({ broadcast(JSON.stringify({
type: DATA_TYPES.text, type: DATA_TYPES.text,
text: message, text: message,
@ -188,6 +233,9 @@ function send_as_server(message) {
})); }));
} }
/**
* sends raw data to all connected clients.
*/
function broadcast(data) { function broadcast(data) {
sockets.forEach(s => s.send(data)); sockets.forEach(s => s.send(data));
} }