Initial commit: restructure to flat layout with ui/ and web/ at root
This commit is contained in:
66
web/server/lib/terminal/input-ws-protocol.js
Normal file
66
web/server/lib/terminal/input-ws-protocol.js
Normal file
@@ -0,0 +1,66 @@
|
||||
export const TERMINAL_INPUT_WS_PATH = '/api/terminal/input-ws';
|
||||
export const TERMINAL_INPUT_WS_CONTROL_TAG_JSON = 0x01;
|
||||
export const TERMINAL_INPUT_WS_MAX_PAYLOAD_BYTES = 64 * 1024;
|
||||
|
||||
export const parseRequestPathname = (requestUrl) => {
|
||||
if (typeof requestUrl !== 'string' || requestUrl.length === 0) {
|
||||
return '';
|
||||
}
|
||||
|
||||
try {
|
||||
return new URL(requestUrl, 'http://localhost').pathname;
|
||||
} catch {
|
||||
return '';
|
||||
}
|
||||
};
|
||||
|
||||
export const normalizeTerminalInputWsMessageToBuffer = (rawData) => {
|
||||
if (Buffer.isBuffer(rawData)) {
|
||||
return rawData;
|
||||
}
|
||||
|
||||
if (Array.isArray(rawData)) {
|
||||
return Buffer.concat(rawData.map((chunk) => (Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk))));
|
||||
}
|
||||
|
||||
return Buffer.from(rawData);
|
||||
};
|
||||
|
||||
export const normalizeTerminalInputWsMessageToText = (rawData) => {
|
||||
if (typeof rawData === 'string') {
|
||||
return rawData;
|
||||
}
|
||||
|
||||
return normalizeTerminalInputWsMessageToBuffer(rawData).toString('utf8');
|
||||
};
|
||||
|
||||
export const readTerminalInputWsControlFrame = (rawData) => {
|
||||
if (!rawData) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const buffer = normalizeTerminalInputWsMessageToBuffer(rawData);
|
||||
if (buffer.length < 2 || buffer[0] !== TERMINAL_INPUT_WS_CONTROL_TAG_JSON) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
const parsed = JSON.parse(buffer.subarray(1).toString('utf8'));
|
||||
if (!parsed || typeof parsed !== 'object') {
|
||||
return null;
|
||||
}
|
||||
return parsed;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
export const createTerminalInputWsControlFrame = (payload) => {
|
||||
const jsonBytes = Buffer.from(JSON.stringify(payload), 'utf8');
|
||||
return Buffer.concat([Buffer.from([TERMINAL_INPUT_WS_CONTROL_TAG_JSON]), jsonBytes]);
|
||||
};
|
||||
|
||||
export const pruneRebindTimestamps = (timestamps, now, windowMs) =>
|
||||
timestamps.filter((timestamp) => now - timestamp < windowMs);
|
||||
|
||||
export const isRebindRateLimited = (timestamps, maxPerWindow) => timestamps.length >= maxPerWindow;
|
||||
Reference in New Issue
Block a user