first commit

This commit is contained in:
CHIEFSOFT\ameye
2024-03-11 18:35:09 -04:00
commit 481c17499d
1371 changed files with 206438 additions and 0 deletions
+16
View File
@@ -0,0 +1,16 @@
import { Polling as XHR } from "./polling";
import { WebSocket } from "./websocket";
declare const _default: {
polling: typeof polling;
websocket: typeof WebSocket;
};
export default _default;
/**
* Polling polymorphic constructor.
*
* @api private
*/
declare function polling(req: any): XHR;
declare namespace polling {
var upgradesTo: string[];
}
+23
View File
@@ -0,0 +1,23 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const polling_1 = require("./polling");
const polling_jsonp_1 = require("./polling-jsonp");
const websocket_1 = require("./websocket");
exports.default = {
polling: polling,
websocket: websocket_1.WebSocket
};
/**
* Polling polymorphic constructor.
*
* @api private
*/
function polling(req) {
if ("string" === typeof req._query.j) {
return new polling_jsonp_1.JSONP(req);
}
else {
return new polling_1.Polling(req);
}
}
polling.upgradesTo = ["websocket"];
+24
View File
@@ -0,0 +1,24 @@
import { Polling } from "./polling";
export declare class JSONP extends Polling {
private readonly head;
private readonly foot;
/**
* JSON-P polling transport.
*
* @api public
*/
constructor(req: any);
/**
* Handles incoming data.
* Due to a bug in \n handling by browsers, we expect a escaped string.
*
* @api private
*/
onData(data: any): void;
/**
* Performs the write.
*
* @api private
*/
doWrite(data: any, options: any, callback: any): void;
}
+54
View File
@@ -0,0 +1,54 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.JSONP = void 0;
const polling_1 = require("./polling");
const qs = require("querystring");
const rDoubleSlashes = /\\\\n/g;
const rSlashes = /(\\)?\\n/g;
class JSONP extends polling_1.Polling {
/**
* JSON-P polling transport.
*
* @api public
*/
constructor(req) {
super(req);
this.head = "___eio[" + (req._query.j || "").replace(/[^0-9]/g, "") + "](";
this.foot = ");";
}
/**
* Handles incoming data.
* Due to a bug in \n handling by browsers, we expect a escaped string.
*
* @api private
*/
onData(data) {
// we leverage the qs module so that we get built-in DoS protection
// and the fast alternative to decodeURIComponent
data = qs.parse(data).d;
if ("string" === typeof data) {
// client will send already escaped newlines as \\\\n and newlines as \\n
// \\n must be replaced with \n and \\\\n with \\n
data = data.replace(rSlashes, function (match, slashes) {
return slashes ? match : "\n";
});
super.onData(data.replace(rDoubleSlashes, "\\n"));
}
}
/**
* Performs the write.
*
* @api private
*/
doWrite(data, options, callback) {
// we must output valid javascript, not valid json
// see: http://timelessrepo.com/json-isnt-a-javascript-subset
const js = JSON.stringify(data)
.replace(/\u2028/g, "\\u2028")
.replace(/\u2029/g, "\\u2029");
// prepare response
data = this.head + js + this.foot;
super.doWrite(data, options, callback);
}
}
exports.JSONP = JSONP;
+96
View File
@@ -0,0 +1,96 @@
import { Transport } from "../transport";
export declare class Polling extends Transport {
maxHttpBufferSize: number;
httpCompression: any;
private res;
private dataReq;
private dataRes;
private shouldClose;
private readonly closeTimeout;
/**
* HTTP polling constructor.
*
* @api public.
*/
constructor(req: any);
/**
* Transport name
*
* @api public
*/
get name(): string;
get supportsFraming(): boolean;
/**
* Overrides onRequest.
*
* @param {http.IncomingMessage}
* @api private
*/
onRequest(req: any): void;
/**
* The client sends a request awaiting for us to send data.
*
* @api private
*/
onPollRequest(req: any, res: any): void;
/**
* The client sends a request with data.
*
* @api private
*/
onDataRequest(req: any, res: any): void;
/**
* Processes the incoming data payload.
*
* @param {String} encoded payload
* @api private
*/
onData(data: any): void;
/**
* Overrides onClose.
*
* @api private
*/
onClose(): void;
/**
* Writes a packet payload.
*
* @param {Object} packet
* @api private
*/
send(packets: any): void;
/**
* Writes data as response to poll request.
*
* @param {String} data
* @param {Object} options
* @api private
*/
write(data: any, options: any): void;
/**
* Performs the write.
*
* @api private
*/
doWrite(data: any, options: any, callback: any): void;
/**
* Compresses data.
*
* @api private
*/
compress(data: any, encoding: any, callback: any): void;
/**
* Closes the transport.
*
* @api private
*/
doClose(fn: any): void;
/**
* Returns headers for a response.
*
* @param {http.IncomingMessage} request
* @param {Object} extra headers
* @api private
*/
headers(req: any, headers: any): any;
}
+342
View File
@@ -0,0 +1,342 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Polling = void 0;
const transport_1 = require("../transport");
const zlib_1 = require("zlib");
const accepts = require("accepts");
const debug_1 = require("debug");
const debug = (0, debug_1.default)("engine:polling");
const compressionMethods = {
gzip: zlib_1.createGzip,
deflate: zlib_1.createDeflate
};
class Polling extends transport_1.Transport {
/**
* HTTP polling constructor.
*
* @api public.
*/
constructor(req) {
super(req);
this.closeTimeout = 30 * 1000;
}
/**
* Transport name
*
* @api public
*/
get name() {
return "polling";
}
get supportsFraming() {
return false;
}
/**
* Overrides onRequest.
*
* @param {http.IncomingMessage}
* @api private
*/
onRequest(req) {
const res = req.res;
if ("GET" === req.method) {
this.onPollRequest(req, res);
}
else if ("POST" === req.method) {
this.onDataRequest(req, res);
}
else {
res.writeHead(500);
res.end();
}
}
/**
* The client sends a request awaiting for us to send data.
*
* @api private
*/
onPollRequest(req, res) {
if (this.req) {
debug("request overlap");
// assert: this.res, '.req and .res should be (un)set together'
this.onError("overlap from client");
res.writeHead(500);
res.end();
return;
}
debug("setting request");
this.req = req;
this.res = res;
const onClose = () => {
this.onError("poll connection closed prematurely");
};
const cleanup = () => {
req.removeListener("close", onClose);
this.req = this.res = null;
};
req.cleanup = cleanup;
req.on("close", onClose);
this.writable = true;
this.emit("drain");
// if we're still writable but had a pending close, trigger an empty send
if (this.writable && this.shouldClose) {
debug("triggering empty send to append close packet");
this.send([{ type: "noop" }]);
}
}
/**
* The client sends a request with data.
*
* @api private
*/
onDataRequest(req, res) {
if (this.dataReq) {
// assert: this.dataRes, '.dataReq and .dataRes should be (un)set together'
this.onError("data request overlap from client");
res.writeHead(500);
res.end();
return;
}
const isBinary = "application/octet-stream" === req.headers["content-type"];
if (isBinary && this.protocol === 4) {
return this.onError("invalid content");
}
this.dataReq = req;
this.dataRes = res;
let chunks = isBinary ? Buffer.concat([]) : "";
const cleanup = () => {
req.removeListener("data", onData);
req.removeListener("end", onEnd);
req.removeListener("close", onClose);
this.dataReq = this.dataRes = chunks = null;
};
const onClose = () => {
cleanup();
this.onError("data request connection closed prematurely");
};
const onData = data => {
let contentLength;
if (isBinary) {
chunks = Buffer.concat([chunks, data]);
contentLength = chunks.length;
}
else {
chunks += data;
contentLength = Buffer.byteLength(chunks);
}
if (contentLength > this.maxHttpBufferSize) {
chunks = isBinary ? Buffer.concat([]) : "";
req.connection.destroy();
}
};
const onEnd = () => {
this.onData(chunks);
const headers = {
// text/html is required instead of text/plain to avoid an
// unwanted download dialog on certain user-agents (GH-43)
"Content-Type": "text/html",
"Content-Length": 2
};
res.writeHead(200, this.headers(req, headers));
res.end("ok");
cleanup();
};
req.on("close", onClose);
if (!isBinary)
req.setEncoding("utf8");
req.on("data", onData);
req.on("end", onEnd);
}
/**
* Processes the incoming data payload.
*
* @param {String} encoded payload
* @api private
*/
onData(data) {
debug('received "%s"', data);
const callback = packet => {
if ("close" === packet.type) {
debug("got xhr close packet");
this.onClose();
return false;
}
this.onPacket(packet);
};
if (this.protocol === 3) {
this.parser.decodePayload(data, callback);
}
else {
this.parser.decodePayload(data).forEach(callback);
}
}
/**
* Overrides onClose.
*
* @api private
*/
onClose() {
if (this.writable) {
// close pending poll request
this.send([{ type: "noop" }]);
}
super.onClose();
}
/**
* Writes a packet payload.
*
* @param {Object} packet
* @api private
*/
send(packets) {
this.writable = false;
if (this.shouldClose) {
debug("appending close packet to payload");
packets.push({ type: "close" });
this.shouldClose();
this.shouldClose = null;
}
const doWrite = data => {
const compress = packets.some(packet => {
return packet.options && packet.options.compress;
});
this.write(data, { compress });
};
if (this.protocol === 3) {
this.parser.encodePayload(packets, this.supportsBinary, doWrite);
}
else {
this.parser.encodePayload(packets, doWrite);
}
}
/**
* Writes data as response to poll request.
*
* @param {String} data
* @param {Object} options
* @api private
*/
write(data, options) {
debug('writing "%s"', data);
this.doWrite(data, options, () => {
this.req.cleanup();
});
}
/**
* Performs the write.
*
* @api private
*/
doWrite(data, options, callback) {
// explicit UTF-8 is required for pages not served under utf
const isString = typeof data === "string";
const contentType = isString
? "text/plain; charset=UTF-8"
: "application/octet-stream";
const headers = {
"Content-Type": contentType
};
const respond = data => {
headers["Content-Length"] =
"string" === typeof data ? Buffer.byteLength(data) : data.length;
this.res.writeHead(200, this.headers(this.req, headers));
this.res.end(data);
callback();
};
if (!this.httpCompression || !options.compress) {
respond(data);
return;
}
const len = isString ? Buffer.byteLength(data) : data.length;
if (len < this.httpCompression.threshold) {
respond(data);
return;
}
const encoding = accepts(this.req).encodings(["gzip", "deflate"]);
if (!encoding) {
respond(data);
return;
}
this.compress(data, encoding, (err, data) => {
if (err) {
this.res.writeHead(500);
this.res.end();
callback(err);
return;
}
headers["Content-Encoding"] = encoding;
respond(data);
});
}
/**
* Compresses data.
*
* @api private
*/
compress(data, encoding, callback) {
debug("compressing");
const buffers = [];
let nread = 0;
compressionMethods[encoding](this.httpCompression)
.on("error", callback)
.on("data", function (chunk) {
buffers.push(chunk);
nread += chunk.length;
})
.on("end", function () {
callback(null, Buffer.concat(buffers, nread));
})
.end(data);
}
/**
* Closes the transport.
*
* @api private
*/
doClose(fn) {
debug("closing");
let closeTimeoutTimer;
if (this.dataReq) {
debug("aborting ongoing data request");
this.dataReq.destroy();
}
const onClose = () => {
clearTimeout(closeTimeoutTimer);
fn();
this.onClose();
};
if (this.writable) {
debug("transport writable - closing right away");
this.send([{ type: "close" }]);
onClose();
}
else if (this.discarded) {
debug("transport discarded - closing right away");
onClose();
}
else {
debug("transport not writable - buffering orderly close");
this.shouldClose = onClose;
closeTimeoutTimer = setTimeout(onClose, this.closeTimeout);
}
}
/**
* Returns headers for a response.
*
* @param {http.IncomingMessage} request
* @param {Object} extra headers
* @api private
*/
headers(req, headers) {
headers = headers || {};
// prevent XSS warnings on IE
// https://github.com/LearnBoost/socket.io/pull/1333
const ua = req.headers["user-agent"];
if (ua && (~ua.indexOf(";MSIE") || ~ua.indexOf("Trident/"))) {
headers["X-XSS-Protection"] = "0";
}
this.emit("headers", headers, req);
return headers;
}
}
exports.Polling = Polling;
+43
View File
@@ -0,0 +1,43 @@
import { Transport } from "../transport";
export declare class WebSocket extends Transport {
protected perMessageDeflate: any;
private socket;
/**
* WebSocket transport
*
* @param {http.IncomingMessage}
* @api public
*/
constructor(req: any);
/**
* Transport name
*
* @api public
*/
get name(): string;
/**
* Advertise upgrade support.
*
* @api public
*/
get handlesUpgrades(): boolean;
/**
* Advertise framing support.
*
* @api public
*/
get supportsFraming(): boolean;
/**
* Writes a packet payload.
*
* @param {Array} packets
* @api private
*/
send(packets: any): void;
/**
* Closes the transport.
*
* @api private
*/
doClose(fn: any): void;
}
+102
View File
@@ -0,0 +1,102 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.WebSocket = void 0;
const transport_1 = require("../transport");
const debug_1 = require("debug");
const debug = (0, debug_1.default)("engine:ws");
class WebSocket extends transport_1.Transport {
/**
* WebSocket transport
*
* @param {http.IncomingMessage}
* @api public
*/
constructor(req) {
super(req);
this.socket = req.websocket;
this.socket.on("message", (data, isBinary) => {
const message = isBinary ? data : data.toString();
debug('received "%s"', message);
super.onData(message);
});
this.socket.once("close", this.onClose.bind(this));
this.socket.on("error", this.onError.bind(this));
this.writable = true;
this.perMessageDeflate = null;
}
/**
* Transport name
*
* @api public
*/
get name() {
return "websocket";
}
/**
* Advertise upgrade support.
*
* @api public
*/
get handlesUpgrades() {
return true;
}
/**
* Advertise framing support.
*
* @api public
*/
get supportsFraming() {
return true;
}
/**
* Writes a packet payload.
*
* @param {Array} packets
* @api private
*/
send(packets) {
const packet = packets.shift();
if (typeof packet === "undefined") {
this.writable = true;
this.emit("drain");
return;
}
// always creates a new object since ws modifies it
const opts = {};
if (packet.options) {
opts.compress = packet.options.compress;
}
const send = data => {
if (this.perMessageDeflate) {
const len = "string" === typeof data ? Buffer.byteLength(data) : data.length;
if (len < this.perMessageDeflate.threshold) {
opts.compress = false;
}
}
debug('writing "%s"', data);
this.writable = false;
this.socket.send(data, opts, err => {
if (err)
return this.onError("write error", err.stack);
this.send(packets);
});
};
if (packet.options && typeof packet.options.wsPreEncoded === "string") {
send(packet.options.wsPreEncoded);
}
else {
this.parser.encodePacket(packet, this.supportsBinary, send);
}
}
/**
* Closes the transport.
*
* @api private
*/
doClose(fn) {
debug("closing");
this.socket.close();
fn && fn();
}
}
exports.WebSocket = WebSocket;