313 lines
9.8 KiB
JavaScript
313 lines
9.8 KiB
JavaScript
"use strict";
|
|
|
|
function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
|
|
|
|
function _get(target, property, receiver) { if (typeof Reflect !== "undefined" && Reflect.get) { _get = Reflect.get; } else { _get = function _get(target, property, receiver) { var base = _superPropBase(target, property); if (!base) return; var desc = Object.getOwnPropertyDescriptor(base, property); if (desc.get) { return desc.get.call(receiver); } return desc.value; }; } return _get(target, property, receiver || target); }
|
|
|
|
function _superPropBase(object, property) { while (!Object.prototype.hasOwnProperty.call(object, property)) { object = _getPrototypeOf(object); if (object === null) break; } return object; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
|
|
|
|
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
|
|
|
|
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
|
|
|
|
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
|
|
|
|
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
|
|
|
|
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
|
|
|
|
// Provides native APIs for RPCWebSocket transport.
|
|
//
|
|
// Because we're passing through some native APIs, e.g. net, we recast its API
|
|
// to something more browser-safe, so don't assume the APIs are 1:1 or behave
|
|
// exactly like the native APIs.
|
|
var EventEmitter = require('events');
|
|
|
|
var http = require('http');
|
|
|
|
var ws = require('ws');
|
|
|
|
var origInstanceMap = new WeakMap(); // converts Node.js Buffer to ArrayBuffer
|
|
|
|
function toArrayBuffer(buffer) {
|
|
return buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength);
|
|
}
|
|
|
|
function recastWSSocket(socket, req) {
|
|
var WSSocket =
|
|
/*#__PURE__*/
|
|
function (_EventEmitter) {
|
|
_inherits(WSSocket, _EventEmitter);
|
|
|
|
function WSSocket() {
|
|
var _this;
|
|
|
|
_classCallCheck(this, WSSocket);
|
|
|
|
_this = _possibleConstructorReturn(this, _getPrototypeOf(WSSocket).call(this));
|
|
_this.upgradeReq = {
|
|
url: req.url,
|
|
headers: {
|
|
origin: req.headers.origin
|
|
}
|
|
};
|
|
socket.on('error', function (err) {
|
|
return _this.emit('error', err);
|
|
});
|
|
socket.on('close', function (code, message) {
|
|
return _this.emit('close', code, message);
|
|
});
|
|
socket.on('message', function (data) {
|
|
if (data instanceof Buffer) {
|
|
data = toArrayBuffer(data);
|
|
}
|
|
|
|
_this.emit('message', data);
|
|
});
|
|
return _this;
|
|
}
|
|
|
|
_createClass(WSSocket, [{
|
|
key: "send",
|
|
value: function send(data) {
|
|
var opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
|
|
if (opts.binary) {
|
|
data = Buffer.from(data);
|
|
}
|
|
|
|
try {
|
|
socket.send(data, opts);
|
|
} catch (e) {
|
|
// ws shouldn't be throwing when CLOSED or CLOSING
|
|
// currently being addressed in https://github.com/websockets/ws/pull/1532
|
|
if (!e.message.match(/CLOS(ED|ING)/)) {
|
|
throw e;
|
|
}
|
|
}
|
|
}
|
|
}, {
|
|
key: "close",
|
|
value: function close(code, message) {
|
|
socket.close(code, message);
|
|
}
|
|
}]);
|
|
|
|
return WSSocket;
|
|
}(EventEmitter);
|
|
|
|
return new WSSocket();
|
|
}
|
|
|
|
function getWrappedWSServer() {
|
|
var wss;
|
|
return (
|
|
/*#__PURE__*/
|
|
function (_EventEmitter2) {
|
|
_inherits(ProxiedWSServer, _EventEmitter2);
|
|
|
|
function ProxiedWSServer(opts) {
|
|
var _this2;
|
|
|
|
_classCallCheck(this, ProxiedWSServer);
|
|
|
|
_this2 = _possibleConstructorReturn(this, _getPrototypeOf(ProxiedWSServer).call(this)); // opts.server that comes in is our remapped server, so we
|
|
// get the original
|
|
|
|
if (opts.server) {
|
|
opts.server = origInstanceMap.get(opts.server);
|
|
}
|
|
|
|
wss = new ws.Server(opts);
|
|
wss.on('connection', function (socket, req) {
|
|
return _this2.emit('connection', recastWSSocket(socket, req));
|
|
});
|
|
return _this2;
|
|
}
|
|
|
|
return ProxiedWSServer;
|
|
}(EventEmitter)
|
|
);
|
|
}
|
|
|
|
var proxiedWS = {
|
|
get Server() {
|
|
return getWrappedWSServer();
|
|
}
|
|
|
|
};
|
|
|
|
function recastHTTPReq(req) {
|
|
var ProxiedHTTPRequest =
|
|
/*#__PURE__*/
|
|
function (_EventEmitter3) {
|
|
_inherits(ProxiedHTTPRequest, _EventEmitter3);
|
|
|
|
function ProxiedHTTPRequest() {
|
|
var _getPrototypeOf2;
|
|
|
|
var _this3;
|
|
|
|
_classCallCheck(this, ProxiedHTTPRequest);
|
|
|
|
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
args[_key] = arguments[_key];
|
|
}
|
|
|
|
_this3 = _possibleConstructorReturn(this, (_getPrototypeOf2 = _getPrototypeOf(ProxiedHTTPRequest)).call.apply(_getPrototypeOf2, [this].concat(args)));
|
|
_this3.attached = false;
|
|
return _this3;
|
|
}
|
|
|
|
_createClass(ProxiedHTTPRequest, [{
|
|
key: "on",
|
|
value: function on(evt) {
|
|
var _this4 = this,
|
|
_get2;
|
|
|
|
// We need to attach listeners for data only on data event, which sets the
|
|
// request to flowing mode.
|
|
if (evt === 'data' && !this.attached) {
|
|
req.on('error', function (err) {
|
|
return _this4.emit('error', err);
|
|
});
|
|
req.on('end', function () {
|
|
return _this4.emit('end');
|
|
});
|
|
req.on('data', function (data) {
|
|
// force cast the data to a string
|
|
// this is because we only deal with string data on http requests so far
|
|
_this4.emit('data', '' + data);
|
|
});
|
|
this.attached = true;
|
|
}
|
|
|
|
for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
|
|
args[_key2 - 1] = arguments[_key2];
|
|
}
|
|
|
|
(_get2 = _get(_getPrototypeOf(ProxiedHTTPRequest.prototype), "on", this)).call.apply(_get2, [this, evt].concat(args));
|
|
}
|
|
}, {
|
|
key: "url",
|
|
get: function get() {
|
|
return req.url;
|
|
}
|
|
}, {
|
|
key: "method",
|
|
get: function get() {
|
|
return req.method;
|
|
}
|
|
}, {
|
|
key: "headers",
|
|
get: function get() {
|
|
return req.headers;
|
|
}
|
|
}]);
|
|
|
|
return ProxiedHTTPRequest;
|
|
}(EventEmitter);
|
|
|
|
var recast = new ProxiedHTTPRequest();
|
|
origInstanceMap.set(recast, req);
|
|
return recast;
|
|
}
|
|
|
|
function recastHTTPRes(res) {
|
|
var ProxiedHTTPResponse =
|
|
/*#__PURE__*/
|
|
function () {
|
|
function ProxiedHTTPResponse() {
|
|
_classCallCheck(this, ProxiedHTTPResponse);
|
|
}
|
|
|
|
_createClass(ProxiedHTTPResponse, [{
|
|
key: "setHeader",
|
|
value: function setHeader(header, value) {
|
|
res.setHeader(header, value);
|
|
}
|
|
}, {
|
|
key: "writeHead",
|
|
value: function writeHead(status, headers) {
|
|
res.writeHead(status, headers);
|
|
}
|
|
}, {
|
|
key: "end",
|
|
value: function end(body) {
|
|
res.end(body);
|
|
}
|
|
}]);
|
|
|
|
return ProxiedHTTPResponse;
|
|
}();
|
|
|
|
var recast = new ProxiedHTTPResponse();
|
|
origInstanceMap.set(recast, res);
|
|
return recast;
|
|
}
|
|
|
|
function createWrappedHTTPServer() {
|
|
var server = http.createServer();
|
|
|
|
var ProxiedHTTPServer =
|
|
/*#__PURE__*/
|
|
function (_EventEmitter4) {
|
|
_inherits(ProxiedHTTPServer, _EventEmitter4);
|
|
|
|
function ProxiedHTTPServer() {
|
|
var _this5;
|
|
|
|
_classCallCheck(this, ProxiedHTTPServer);
|
|
|
|
_this5 = _possibleConstructorReturn(this, _getPrototypeOf(ProxiedHTTPServer).call(this));
|
|
server.on('error', function (err) {
|
|
return _this5.emit('error', err);
|
|
});
|
|
server.on('request', function (_req, _res) {
|
|
var req = recastHTTPReq(_req);
|
|
var res = recastHTTPRes(_res);
|
|
|
|
_this5.emit('request', req, res);
|
|
});
|
|
return _this5;
|
|
}
|
|
|
|
_createClass(ProxiedHTTPServer, [{
|
|
key: "address",
|
|
value: function address() {
|
|
return server.address();
|
|
}
|
|
}, {
|
|
key: "listen",
|
|
value: function listen(port, host, callback) {
|
|
server.listen(port, host, callback);
|
|
}
|
|
}, {
|
|
key: "listening",
|
|
get: function get() {
|
|
return server.listening;
|
|
}
|
|
}]);
|
|
|
|
return ProxiedHTTPServer;
|
|
}(EventEmitter);
|
|
|
|
var recast = new ProxiedHTTPServer();
|
|
origInstanceMap.set(recast, server);
|
|
return recast;
|
|
}
|
|
|
|
var proxiedHTTP = {
|
|
createServer: createWrappedHTTPServer
|
|
};
|
|
module.exports = {
|
|
ws: proxiedWS,
|
|
http: proxiedHTTP
|
|
};
|