Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

wisp-server-node

Package Overview
Dependencies
Maintainers
0
Versions
13
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

wisp-server-node - npm Package Compare versions

Comparing version 1.1.4 to 1.1.5

dist/utils/Error.d.ts

4

dist/ConnectionHandler.d.ts

@@ -1,5 +0,5 @@

import { WispOptions } from "./Types";
import { IncomingMessage } from "node:http";
import WebSocket from "ws";
import { Socket } from "node:net";
import { IncomingMessage } from "node:http";
import { WispOptions } from "./Types.ts";
export declare function routeRequest(wsOrIncomingMessage: WebSocket | IncomingMessage, socket?: Socket, head?: Buffer, options?: WispOptions): Promise<void>;

@@ -6,0 +6,0 @@ declare const _default: {

@@ -1,51 +0,18 @@

"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.routeRequest = routeRequest;
const Types_1 = require("./Types");
const Logger_1 = require("./Logger");
const ws_1 = __importDefault(require("ws"));
const node_net_1 = __importDefault(require("node:net"));
const node_dgram_1 = __importDefault(require("node:dgram"));
const Packets_1 = __importStar(require("./Packets"));
const wsproxy_1 = require("./wsproxy");
const promises_1 = __importDefault(require("node:dns/promises"));
const Utils_1 = require("./Utils");
const wss = new ws_1.default.Server({ noServer: true });
const defaultOptions = { logLevel: Types_1.LOG_LEVEL.INFO };
// Accepts either routeRequest(ws) or routeRequest(request, socket, head) like bare
async function routeRequest(wsOrIncomingMessage, socket, head, options = defaultOptions) {
import WebSocket from "ws";
import net from "node:net";
import dns from "node:dns/promises";
import dgram from "node:dgram";
import FrameParsers from "./Packets.ts";
import { STREAM_TYPE, PACKET_TYPE, LOG_LEVEL } from "./Types.ts";
import { Logger } from "./utils/Logger.ts";
import { handleWsProxy } from "./wsproxy.ts";
import { checkErrorCode } from "./utils/Error.ts";
const wss = new WebSocket.Server({ noServer: true });
const defaultOptions = { logLevel: LOG_LEVEL.INFO };
export async function routeRequest(wsOrIncomingMessage, socket, head, options = defaultOptions) {
options = Object.assign({}, defaultOptions, options);
if (!(wsOrIncomingMessage instanceof ws_1.default) && socket && head) {
// Wsproxy is handled here because if we're just passed the websocket then we don't even know it's URL
// Compatibility with bare like "handle upgrade" syntax
if (!(wsOrIncomingMessage instanceof WebSocket) && socket && head) {
wss.handleUpgrade(wsOrIncomingMessage, socket, head, (ws) => {
if (!wsOrIncomingMessage.url?.endsWith("/")) {
// if a URL ends with / then its not a wsproxy connection, its wisp
(0, wsproxy_1.handleWsProxy)(ws, wsOrIncomingMessage.url);
handleWsProxy(ws, wsOrIncomingMessage.url);
return;

@@ -57,10 +24,9 @@ }

}
if (!(wsOrIncomingMessage instanceof ws_1.default))
return; // something went wrong, abort
const ws = wsOrIncomingMessage; // now that we are SURE we have a Websocket object, continue...
if (!(wsOrIncomingMessage instanceof WebSocket))
return;
const ws = wsOrIncomingMessage;
const connections = new Map();
const logger = new Logger_1.Logger(options.logLevel);
const logger = new Logger(options.logLevel);
ws.on("message", async (data, isBinary) => {
try {
// Ensure that the incoming data is a valid WebSocket message
if (!Buffer.isBuffer(data) && !(data instanceof ArrayBuffer)) {

@@ -70,10 +36,7 @@ logger.error("Invalid WebSocket message data");

}
const wispFrame = Packets_1.default.wispFrameParser(Buffer.from(data));
// Routing
if (wispFrame.type === Types_1.CONNECT_TYPE.CONNECT) {
// CONNECT frame data
const connectFrame = Packets_1.default.connectPacketParser(wispFrame.payload);
if (connectFrame.streamType === Types_1.STREAM_TYPE.TCP) {
// Initialize and register Socket that will handle this stream
const client = new node_net_1.default.Socket();
const wispFrame = FrameParsers.wispFrameParser(Buffer.from(data));
if (wispFrame.type === PACKET_TYPE.CONNECT) {
const connectFrame = FrameParsers.connectPacketParser(wispFrame.payload);
if (connectFrame.streamType === STREAM_TYPE.TCP) {
const client = new net.Socket();
client.connect(connectFrame.port, connectFrame.hostname);

@@ -84,25 +47,24 @@ connections.set(wispFrame.streamID, {

});
// Send Socket's data back to client
client.on("data", function (data) {
ws.send(Packets_1.default.dataPacketMaker(wispFrame, data));
ws.send(FrameParsers.dataPacketMaker(wispFrame, data));
});
// Close stream if there is some network error
client.on("error", function (err) {
logger.error(`An error occured in the connection to ${connectFrame.hostname} (${wispFrame.streamID}) with the message ${err.message}`);
ws.send(Packets_1.default.closePacketMaker(wispFrame, (0, Utils_1.checkErrorCode)(err)));
ws.send(FrameParsers.closePacketMaker(wispFrame, checkErrorCode(err)));
connections.delete(wispFrame.streamID);
});
client.on("close", function () {
ws.send(Packets_1.default.closePacketMaker(wispFrame, 0x02));
connections.delete(wispFrame.streamID);
if (connections.get(wispFrame.streamID)) {
ws.send(FrameParsers.closePacketMaker(wispFrame, 0x02));
connections.delete(wispFrame.streamID);
}
});
}
else if (connectFrame.streamType === Types_1.STREAM_TYPE.UDP) {
let iplevel = node_net_1.default.isIP(connectFrame.hostname); // Can be 0: DNS NAME, 4: IPv4, 6: IPv6
else if (connectFrame.streamType === STREAM_TYPE.UDP) {
let iplevel = net.isIP(connectFrame.hostname);
let host = connectFrame.hostname;
if (iplevel === 0) {
// is DNS
try {
host = (await promises_1.default.resolve(connectFrame.hostname))[0];
iplevel = node_net_1.default.isIP(host); // can't be 0 now
host = (await dns.resolve(connectFrame.hostname))[0];
iplevel = net.isIP(host);
}

@@ -114,27 +76,21 @@ catch (e) {

e);
ws.send(Packets_1.default.closePacketMaker(wispFrame, 0x42));
return; // we're done here, ignore doing anything to this message now.
ws.send(FrameParsers.closePacketMaker(wispFrame, 0x42));
return;
}
}
// iplevel is now guaranteed to be 6 or 4, fingers crossed, so we can define the UDP type now
if (iplevel != 4 && iplevel != 6) {
return; // something went wrong.. neither ipv4 nor ipv6
if (iplevel !== 4 && iplevel !== 6) {
return;
}
// Create a new UDP socket
const client = node_dgram_1.default.createSocket(iplevel === 6 ? "udp6" : "udp4");
const client = dgram.createSocket(iplevel === 6 ? "udp6" : "udp4");
client.connect(connectFrame.port, host);
//@ts-expect-error stupid workaround
client.connected = false;
client.on("connect", () => {
//@ts-expect-error really dumb workaround
client.connected = true;
});
// Handle incoming UDP data
client.on("message", (data, rinfo) => {
ws.send(Packets_1.default.dataPacketMaker(wispFrame, data));
ws.send(FrameParsers.dataPacketMaker(wispFrame, data));
});
// Handle errors
client.on("error", (err) => {
logger.error(`An error occured in the connection to ${connectFrame.hostname} (${wispFrame.streamID}) with the message ${err.message}`);
ws.send(Packets_1.default.closePacketMaker(wispFrame, (0, Utils_1.checkErrorCode)(err)));
ws.send(FrameParsers.closePacketMaker(wispFrame, checkErrorCode(err)));
connections.delete(wispFrame.streamID);

@@ -144,6 +100,7 @@ client.close();

client.on("close", function () {
ws.send(Packets_1.default.closePacketMaker(wispFrame, 0x02));
connections.delete(wispFrame.streamID);
if (connections.get(wispFrame.streamID)) {
ws.send(FrameParsers.closePacketMaker(wispFrame, 0x02));
connections.delete(wispFrame.streamID);
}
});
// Store the UDP socket and connectFrame in the connections map
connections.set(wispFrame.streamID, {

@@ -154,5 +111,5 @@ client,

}
if (wispFrame.type === Types_1.CONNECT_TYPE.DATA) {
if (wispFrame.type === PACKET_TYPE.DATA) {
const stream = connections.get(wispFrame.streamID);
if (stream && stream.client instanceof node_net_1.default.Socket) {
if (stream && stream.client instanceof net.Socket) {
stream.client.write(wispFrame.payload);

@@ -162,9 +119,9 @@ stream.buffer--;

stream.buffer = 127;
ws.send((0, Packets_1.continuePacketMaker)(wispFrame, stream.buffer));
ws.send(FrameParsers.continuePacketMaker(wispFrame, stream.buffer));
}
}
else if (stream && stream.client instanceof node_dgram_1.default.Socket) {
else if (stream && stream.client instanceof dgram.Socket) {
stream.client.send(wispFrame.payload, undefined, undefined, (err) => {
if (err) {
ws.send(Packets_1.default.closePacketMaker(wispFrame, 0x03));
ws.send(FrameParsers.closePacketMaker(wispFrame, checkErrorCode(err)));
if (stream.client.connected) {

@@ -178,10 +135,9 @@ stream.client.close();

}
if (wispFrame.type === Types_1.CONNECT_TYPE.CLOSE) {
// its joever
if (wispFrame.type === PACKET_TYPE.CLOSE) {
logger.log("Client decided to terminate with reason " + new DataView(wispFrame.payload.buffer).getUint8(0));
const stream = connections.get(wispFrame.streamID);
if (stream && stream.client instanceof node_net_1.default.Socket) {
if (stream && stream.client instanceof net.Socket) {
stream.client.destroy();
}
else if (stream && stream.client instanceof node_dgram_1.default.Socket) {
else if (stream && stream.client instanceof dgram.Socket) {
stream.client.close();

@@ -193,10 +149,9 @@ }

catch (e) {
ws.close(); // something went SUPER wrong, like its probably not even a wisp connection
ws.close();
logger.error(`WISP incoming message handler error: `, e);
// cleanup
for (const { client } of connections.values()) {
if (client instanceof node_net_1.default.Socket) {
if (client instanceof net.Socket) {
client.destroy();
}
else if (client instanceof node_dgram_1.default.Socket) {
else if (client instanceof dgram.Socket) {
client.close();

@@ -208,10 +163,9 @@ }

});
// Close all open sockets when the WebSocket connection is closed
ws.on("close", (code, reason) => {
logger.debug(`WebSocket connection closed with code ${code} and reason: ${reason}`);
for (const { client } of connections.values()) {
if (client instanceof node_net_1.default.Socket) {
if (client instanceof net.Socket) {
client.destroy();
}
else if (client instanceof node_dgram_1.default.Socket) {
else if (client instanceof dgram.Socket) {
client.close();

@@ -222,8 +176,7 @@ }

});
// SEND the initial continue packet with streamID 0 and 127 queue limit
ws.send(Packets_1.default.continuePacketMaker({ streamID: 0 }, 127));
ws.send(FrameParsers.continuePacketMaker({ streamID: 0 }, 127));
}
exports.default = {
export default {
routeRequest,
};
//# sourceMappingURL=ConnectionHandler.js.map

@@ -1,15 +0,10 @@

"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const ConnectionHandler_1 = __importDefault(require("./ConnectionHandler"));
const node_http_1 = __importDefault(require("node:http"));
const Types_1 = require("./Types");
const httpServer = node_http_1.default.createServer().listen(process.env.PORT || 3000);
import wisp from "./ConnectionHandler.ts";
import http from "node:http";
import { LOG_LEVEL } from "./Types.ts";
const httpServer = http.createServer().listen(process.env.PORT || 3000);
httpServer.on("upgrade", (req, socket, head) => {
ConnectionHandler_1.default.routeRequest(req, socket, head, {
logLevel: Types_1.LOG_LEVEL.DEBUG
wisp.routeRequest(req, socket, head, {
logLevel: LOG_LEVEL.DEBUG
});
});
//# sourceMappingURL=createServer.js.map

@@ -1,2 +0,2 @@

import { LOG_LEVEL } from "./Types";
import { LOG_LEVEL } from "./Types.ts";
export declare class Logger {

@@ -3,0 +3,0 @@ logLevel: number;

@@ -1,6 +0,3 @@

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Logger = void 0;
const Types_1 = require("./Types");
class Logger {
import { LOG_LEVEL } from "./Types";
export class Logger {
logLevel;

@@ -17,3 +14,3 @@ constructor(logLevel) {

debug(...messages) {
if (this.logLevel > Types_1.LOG_LEVEL.DEBUG)
if (this.logLevel > LOG_LEVEL.DEBUG)
return;

@@ -23,3 +20,3 @@ console.debug(this.getTimestamp() + " debug:", ...messages);

info(...messages) {
if (this.logLevel > Types_1.LOG_LEVEL.INFO)
if (this.logLevel > LOG_LEVEL.INFO)
return;

@@ -29,3 +26,3 @@ console.info(this.getTimestamp() + " info:", ...messages);

log(...messages) {
if (this.logLevel > Types_1.LOG_LEVEL.INFO)
if (this.logLevel > LOG_LEVEL.INFO)
return;

@@ -35,3 +32,3 @@ console.log(this.getTimestamp() + " log:", ...messages);

warn(...messages) {
if (this.logLevel > Types_1.LOG_LEVEL.WARN)
if (this.logLevel > LOG_LEVEL.WARN)
return;

@@ -41,3 +38,3 @@ console.warn(this.getTimestamp() + " warn:", ...messages);

error(...messages) {
if (this.logLevel > Types_1.LOG_LEVEL.ERROR)
if (this.logLevel > LOG_LEVEL.ERROR)
return;

@@ -47,3 +44,2 @@ console.error(this.getTimestamp() + " error:", ...messages);

}
exports.Logger = Logger;
//# sourceMappingURL=Logger.js.map

@@ -1,2 +0,2 @@

import { WispFrame } from "./Types";
import { WispFrame } from "./Types.ts";
export declare function wispFrameParser(data: Buffer): WispFrame;

@@ -11,3 +11,3 @@ export declare function connectPacketParser(payload: Uint8Array): {

export declare function closePacketMaker(wispFrame: WispFrame, reason: number): ArrayBuffer;
export declare function dataPacketMaker(wispFrame: WispFrame, data: Buffer): Buffer;
export declare function dataPacketMaker(wispFrame: WispFrame, data: any): Buffer;
declare const _default: {

@@ -14,0 +14,0 @@ wispFrameParser: typeof wispFrameParser;

@@ -1,10 +0,3 @@

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.wispFrameParser = wispFrameParser;
exports.connectPacketParser = connectPacketParser;
exports.continuePacketMaker = continuePacketMaker;
exports.closePacketMaker = closePacketMaker;
exports.dataPacketMaker = dataPacketMaker;
const Types_1 = require("./Types");
function wispFrameParser(data) {
import { PACKET_TYPE } from "./Types.ts";
export function wispFrameParser(data) {
const uint8arrayView = new Uint8Array(data);

@@ -21,5 +14,5 @@ const dataView = new DataView(uint8arrayView.buffer);

}
function connectPacketParser(payload) {
export function connectPacketParser(payload) {
const dataview = new DataView(payload.buffer);
const streamType = dataview.getUint8(0); // for future use, makes it easier to retrofit UDP support
const streamType = dataview.getUint8(0);
const port = dataview.getUint16(1, true);

@@ -34,5 +27,5 @@ const hostname = new TextDecoder("utf8").decode(dataview.buffer.slice(3, dataview.buffer.byteLength));

}
function continuePacketMaker(wispFrame, queue) {
export function continuePacketMaker(wispFrame, queue) {
const initialPacket = new DataView(new Uint8Array(9).buffer);
initialPacket.setUint8(0, Types_1.CONNECT_TYPE.CONTINUE);
initialPacket.setUint8(0, PACKET_TYPE.CONTINUE);
initialPacket.setUint32(1, wispFrame.streamID, true);

@@ -42,5 +35,5 @@ initialPacket.setUint32(5, queue, true);

}
function closePacketMaker(wispFrame, reason) {
export function closePacketMaker(wispFrame, reason) {
const closePacket = new DataView(new Uint8Array(9).buffer);
closePacket.setUint8(0, Types_1.CONNECT_TYPE.CLOSE);
closePacket.setUint8(0, PACKET_TYPE.CLOSE);
closePacket.setUint32(1, wispFrame.streamID, true);

@@ -50,12 +43,9 @@ closePacket.setUint8(5, reason);

}
function dataPacketMaker(wispFrame, data) {
// Only function here that returns a node buffer instead ArrayBufferLike
// Packet header creation
export function dataPacketMaker(wispFrame, data) {
const dataPacketHeader = new DataView(new Uint8Array(5).buffer);
dataPacketHeader.setUint8(0, Types_1.CONNECT_TYPE.DATA);
dataPacketHeader.setUint32(1, wispFrame.streamID, true); // Technically should be uint32 little endian, but libcurl bug
// Combine the data and the packet header and send to client
dataPacketHeader.setUint8(0, PACKET_TYPE.DATA);
dataPacketHeader.setUint32(1, wispFrame.streamID, true);
return Buffer.concat([Buffer.from(dataPacketHeader.buffer), data]);
}
exports.default = {
export default {
wispFrameParser,

@@ -62,0 +52,0 @@ connectPacketParser,

export type WispFrame = {
type: CONNECT_TYPE;
type: PACKET_TYPE;
streamID: number;
payload: Uint8Array;
};
export declare enum CONNECT_TYPE {
export declare enum PACKET_TYPE {
CONNECT = 1,

@@ -25,2 +25,3 @@ DATA = 2,

logLevel: LOG_LEVEL;
pingInterval: number;
};

@@ -1,17 +0,14 @@

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.LOG_LEVEL = exports.STREAM_TYPE = exports.CONNECT_TYPE = void 0;
var CONNECT_TYPE;
(function (CONNECT_TYPE) {
CONNECT_TYPE[CONNECT_TYPE["CONNECT"] = 1] = "CONNECT";
CONNECT_TYPE[CONNECT_TYPE["DATA"] = 2] = "DATA";
CONNECT_TYPE[CONNECT_TYPE["CONTINUE"] = 3] = "CONTINUE";
CONNECT_TYPE[CONNECT_TYPE["CLOSE"] = 4] = "CLOSE";
})(CONNECT_TYPE || (exports.CONNECT_TYPE = CONNECT_TYPE = {}));
var STREAM_TYPE;
export var PACKET_TYPE;
(function (PACKET_TYPE) {
PACKET_TYPE[PACKET_TYPE["CONNECT"] = 1] = "CONNECT";
PACKET_TYPE[PACKET_TYPE["DATA"] = 2] = "DATA";
PACKET_TYPE[PACKET_TYPE["CONTINUE"] = 3] = "CONTINUE";
PACKET_TYPE[PACKET_TYPE["CLOSE"] = 4] = "CLOSE";
})(PACKET_TYPE || (PACKET_TYPE = {}));
export var STREAM_TYPE;
(function (STREAM_TYPE) {
STREAM_TYPE[STREAM_TYPE["TCP"] = 1] = "TCP";
STREAM_TYPE[STREAM_TYPE["UDP"] = 2] = "UDP";
})(STREAM_TYPE || (exports.STREAM_TYPE = STREAM_TYPE = {}));
var LOG_LEVEL;
})(STREAM_TYPE || (STREAM_TYPE = {}));
export var LOG_LEVEL;
(function (LOG_LEVEL) {

@@ -23,3 +20,3 @@ LOG_LEVEL[LOG_LEVEL["DEBUG"] = 0] = "DEBUG";

LOG_LEVEL[LOG_LEVEL["NONE"] = 4] = "NONE";
})(LOG_LEVEL || (exports.LOG_LEVEL = LOG_LEVEL = {}));
})(LOG_LEVEL || (LOG_LEVEL = {}));
//# sourceMappingURL=Types.js.map

@@ -1,5 +0,2 @@

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.checkErrorCode = checkErrorCode;
function checkErrorCode(err) {
export function checkErrorCode(err) {
//@ts-expect-error https://nodejs.org/api/errors.html#errorcode

@@ -6,0 +3,0 @@ switch (err.code) {

@@ -1,7 +0,4 @@

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.handleWsProxy = handleWsProxy;
const node_net_1 = require("node:net");
async function handleWsProxy(ws, url) {
const client = new node_net_1.Socket();
import { Socket } from "node:net";
export async function handleWsProxy(ws, url) {
const client = new Socket();
try {

@@ -8,0 +5,0 @@ const destination = url.split("/").pop().split(":");

{
"name": "wisp-server-node",
"version": "1.1.4",
"type": "commonjs",
"version": "1.1.5",
"type": "module",
"description": "",

@@ -21,4 +21,4 @@ "main": "dist/ConnectionHandler.js",

"devDependencies": {
"@types/ws": "^8.5.11",
"typescript": "^5.3.3"
"@types/ws": "^8.5.12",
"typescript": "^5.6.2"
},

@@ -25,0 +25,0 @@ "dependencies": {

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc