index.js 107 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120
  1. module.exports = (function() {
  2. var __MODS__ = {};
  3. var __DEFINE__ = function(modId, func, req) { var m = { exports: {}, _tempexports: {} }; __MODS__[modId] = { status: 0, func: func, req: req, m: m }; };
  4. var __REQUIRE__ = function(modId, source) { if(!__MODS__[modId]) return require(source); if(!__MODS__[modId].status) { var m = __MODS__[modId].m; m._exports = m._tempexports; var desp = Object.getOwnPropertyDescriptor(m, "exports"); if (desp && desp.configurable) Object.defineProperty(m, "exports", { set: function (val) { if(typeof val === "object" && val !== m._exports) { m._exports.__proto__ = val.__proto__; Object.keys(val).forEach(function (k) { m._exports[k] = val[k]; }); } m._tempexports = val }, get: function () { return m._tempexports; } }); __MODS__[modId].status = 1; __MODS__[modId].func(__MODS__[modId].req, m, m.exports); } return __MODS__[modId].m.exports; };
  5. var __REQUIRE_WILDCARD__ = function(obj) { if(obj && obj.__esModule) { return obj; } else { var newObj = {}; if(obj != null) { for(var k in obj) { if (Object.prototype.hasOwnProperty.call(obj, k)) newObj[k] = obj[k]; } } newObj.default = obj; return newObj; } };
  6. var __REQUIRE_DEFAULT__ = function(obj) { return obj && obj.__esModule ? obj.default : obj; };
  7. __DEFINE__(1682324647593, function(require, module, exports) {
  8. const WebSocket = require('./lib/websocket');
  9. WebSocket.createWebSocketStream = require('./lib/stream');
  10. WebSocket.Server = require('./lib/websocket-server');
  11. WebSocket.Receiver = require('./lib/receiver');
  12. WebSocket.Sender = require('./lib/sender');
  13. module.exports = WebSocket;
  14. }, function(modId) {var map = {"./lib/websocket":1682324647594,"./lib/stream":1682324647595,"./lib/websocket-server":1682324647605,"./lib/receiver":1682324647600,"./lib/sender":1682324647602}; return __REQUIRE__(map[modId], modId); })
  15. __DEFINE__(1682324647594, function(require, module, exports) {
  16. /* eslint no-unused-vars: ["error", { "varsIgnorePattern": "^Readable$" }] */
  17. const EventEmitter = require('events');
  18. const https = require('https');
  19. const http = require('http');
  20. const net = require('net');
  21. const tls = require('tls');
  22. const { randomBytes, createHash } = require('crypto');
  23. const { Readable } = require('stream');
  24. const { URL } = require('url');
  25. const PerMessageDeflate = require('./permessage-deflate');
  26. const Receiver = require('./receiver');
  27. const Sender = require('./sender');
  28. const {
  29. BINARY_TYPES,
  30. EMPTY_BUFFER,
  31. GUID,
  32. kStatusCode,
  33. kWebSocket,
  34. NOOP
  35. } = require('./constants');
  36. const { addEventListener, removeEventListener } = require('./event-target');
  37. const { format, parse } = require('./extension');
  38. const { toBuffer } = require('./buffer-util');
  39. const readyStates = ['CONNECTING', 'OPEN', 'CLOSING', 'CLOSED'];
  40. const protocolVersions = [8, 13];
  41. const closeTimeout = 30 * 1000;
  42. /**
  43. * Class representing a WebSocket.
  44. *
  45. * @extends EventEmitter
  46. */
  47. class WebSocket extends EventEmitter {
  48. /**
  49. * Create a new `WebSocket`.
  50. *
  51. * @param {(String|URL)} address The URL to which to connect
  52. * @param {(String|String[])} [protocols] The subprotocols
  53. * @param {Object} [options] Connection options
  54. */
  55. constructor(address, protocols, options) {
  56. super();
  57. this._binaryType = BINARY_TYPES[0];
  58. this._closeCode = 1006;
  59. this._closeFrameReceived = false;
  60. this._closeFrameSent = false;
  61. this._closeMessage = '';
  62. this._closeTimer = null;
  63. this._extensions = {};
  64. this._protocol = '';
  65. this._readyState = WebSocket.CONNECTING;
  66. this._receiver = null;
  67. this._sender = null;
  68. this._socket = null;
  69. if (address !== null) {
  70. this._bufferedAmount = 0;
  71. this._isServer = false;
  72. this._redirects = 0;
  73. if (Array.isArray(protocols)) {
  74. protocols = protocols.join(', ');
  75. } else if (typeof protocols === 'object' && protocols !== null) {
  76. options = protocols;
  77. protocols = undefined;
  78. }
  79. initAsClient(this, address, protocols, options);
  80. } else {
  81. this._isServer = true;
  82. }
  83. }
  84. /**
  85. * This deviates from the WHATWG interface since ws doesn't support the
  86. * required default "blob" type (instead we define a custom "nodebuffer"
  87. * type).
  88. *
  89. * @type {String}
  90. */
  91. get binaryType() {
  92. return this._binaryType;
  93. }
  94. set binaryType(type) {
  95. if (!BINARY_TYPES.includes(type)) return;
  96. this._binaryType = type;
  97. //
  98. // Allow to change `binaryType` on the fly.
  99. //
  100. if (this._receiver) this._receiver._binaryType = type;
  101. }
  102. /**
  103. * @type {Number}
  104. */
  105. get bufferedAmount() {
  106. if (!this._socket) return this._bufferedAmount;
  107. return this._socket._writableState.length + this._sender._bufferedBytes;
  108. }
  109. /**
  110. * @type {String}
  111. */
  112. get extensions() {
  113. return Object.keys(this._extensions).join();
  114. }
  115. /**
  116. * @type {Function}
  117. */
  118. /* istanbul ignore next */
  119. get onclose() {
  120. return undefined;
  121. }
  122. /* istanbul ignore next */
  123. set onclose(listener) {}
  124. /**
  125. * @type {Function}
  126. */
  127. /* istanbul ignore next */
  128. get onerror() {
  129. return undefined;
  130. }
  131. /* istanbul ignore next */
  132. set onerror(listener) {}
  133. /**
  134. * @type {Function}
  135. */
  136. /* istanbul ignore next */
  137. get onopen() {
  138. return undefined;
  139. }
  140. /* istanbul ignore next */
  141. set onopen(listener) {}
  142. /**
  143. * @type {Function}
  144. */
  145. /* istanbul ignore next */
  146. get onmessage() {
  147. return undefined;
  148. }
  149. /* istanbul ignore next */
  150. set onmessage(listener) {}
  151. /**
  152. * @type {String}
  153. */
  154. get protocol() {
  155. return this._protocol;
  156. }
  157. /**
  158. * @type {Number}
  159. */
  160. get readyState() {
  161. return this._readyState;
  162. }
  163. /**
  164. * @type {String}
  165. */
  166. get url() {
  167. return this._url;
  168. }
  169. /**
  170. * Set up the socket and the internal resources.
  171. *
  172. * @param {(net.Socket|tls.Socket)} socket The network socket between the
  173. * server and client
  174. * @param {Buffer} head The first packet of the upgraded stream
  175. * @param {Number} [maxPayload=0] The maximum allowed message size
  176. * @private
  177. */
  178. setSocket(socket, head, maxPayload) {
  179. const receiver = new Receiver(
  180. this.binaryType,
  181. this._extensions,
  182. this._isServer,
  183. maxPayload
  184. );
  185. this._sender = new Sender(socket, this._extensions);
  186. this._receiver = receiver;
  187. this._socket = socket;
  188. receiver[kWebSocket] = this;
  189. socket[kWebSocket] = this;
  190. receiver.on('conclude', receiverOnConclude);
  191. receiver.on('drain', receiverOnDrain);
  192. receiver.on('error', receiverOnError);
  193. receiver.on('message', receiverOnMessage);
  194. receiver.on('ping', receiverOnPing);
  195. receiver.on('pong', receiverOnPong);
  196. socket.setTimeout(0);
  197. socket.setNoDelay();
  198. if (head.length > 0) socket.unshift(head);
  199. socket.on('close', socketOnClose);
  200. socket.on('data', socketOnData);
  201. socket.on('end', socketOnEnd);
  202. socket.on('error', socketOnError);
  203. this._readyState = WebSocket.OPEN;
  204. this.emit('open');
  205. }
  206. /**
  207. * Emit the `'close'` event.
  208. *
  209. * @private
  210. */
  211. emitClose() {
  212. if (!this._socket) {
  213. this._readyState = WebSocket.CLOSED;
  214. this.emit('close', this._closeCode, this._closeMessage);
  215. return;
  216. }
  217. if (this._extensions[PerMessageDeflate.extensionName]) {
  218. this._extensions[PerMessageDeflate.extensionName].cleanup();
  219. }
  220. this._receiver.removeAllListeners();
  221. this._readyState = WebSocket.CLOSED;
  222. this.emit('close', this._closeCode, this._closeMessage);
  223. }
  224. /**
  225. * Start a closing handshake.
  226. *
  227. * +----------+ +-----------+ +----------+
  228. * - - -|ws.close()|-->|close frame|-->|ws.close()|- - -
  229. * | +----------+ +-----------+ +----------+ |
  230. * +----------+ +-----------+ |
  231. * CLOSING |ws.close()|<--|close frame|<--+-----+ CLOSING
  232. * +----------+ +-----------+ |
  233. * | | | +---+ |
  234. * +------------------------+-->|fin| - - - -
  235. * | +---+ | +---+
  236. * - - - - -|fin|<---------------------+
  237. * +---+
  238. *
  239. * @param {Number} [code] Status code explaining why the connection is closing
  240. * @param {String} [data] A string explaining why the connection is closing
  241. * @public
  242. */
  243. close(code, data) {
  244. if (this.readyState === WebSocket.CLOSED) return;
  245. if (this.readyState === WebSocket.CONNECTING) {
  246. const msg = 'WebSocket was closed before the connection was established';
  247. return abortHandshake(this, this._req, msg);
  248. }
  249. if (this.readyState === WebSocket.CLOSING) {
  250. if (
  251. this._closeFrameSent &&
  252. (this._closeFrameReceived || this._receiver._writableState.errorEmitted)
  253. ) {
  254. this._socket.end();
  255. }
  256. return;
  257. }
  258. this._readyState = WebSocket.CLOSING;
  259. this._sender.close(code, data, !this._isServer, (err) => {
  260. //
  261. // This error is handled by the `'error'` listener on the socket. We only
  262. // want to know if the close frame has been sent here.
  263. //
  264. if (err) return;
  265. this._closeFrameSent = true;
  266. if (
  267. this._closeFrameReceived ||
  268. this._receiver._writableState.errorEmitted
  269. ) {
  270. this._socket.end();
  271. }
  272. });
  273. //
  274. // Specify a timeout for the closing handshake to complete.
  275. //
  276. this._closeTimer = setTimeout(
  277. this._socket.destroy.bind(this._socket),
  278. closeTimeout
  279. );
  280. }
  281. /**
  282. * Send a ping.
  283. *
  284. * @param {*} [data] The data to send
  285. * @param {Boolean} [mask] Indicates whether or not to mask `data`
  286. * @param {Function} [cb] Callback which is executed when the ping is sent
  287. * @public
  288. */
  289. ping(data, mask, cb) {
  290. if (this.readyState === WebSocket.CONNECTING) {
  291. throw new Error('WebSocket is not open: readyState 0 (CONNECTING)');
  292. }
  293. if (typeof data === 'function') {
  294. cb = data;
  295. data = mask = undefined;
  296. } else if (typeof mask === 'function') {
  297. cb = mask;
  298. mask = undefined;
  299. }
  300. if (typeof data === 'number') data = data.toString();
  301. if (this.readyState !== WebSocket.OPEN) {
  302. sendAfterClose(this, data, cb);
  303. return;
  304. }
  305. if (mask === undefined) mask = !this._isServer;
  306. this._sender.ping(data || EMPTY_BUFFER, mask, cb);
  307. }
  308. /**
  309. * Send a pong.
  310. *
  311. * @param {*} [data] The data to send
  312. * @param {Boolean} [mask] Indicates whether or not to mask `data`
  313. * @param {Function} [cb] Callback which is executed when the pong is sent
  314. * @public
  315. */
  316. pong(data, mask, cb) {
  317. if (this.readyState === WebSocket.CONNECTING) {
  318. throw new Error('WebSocket is not open: readyState 0 (CONNECTING)');
  319. }
  320. if (typeof data === 'function') {
  321. cb = data;
  322. data = mask = undefined;
  323. } else if (typeof mask === 'function') {
  324. cb = mask;
  325. mask = undefined;
  326. }
  327. if (typeof data === 'number') data = data.toString();
  328. if (this.readyState !== WebSocket.OPEN) {
  329. sendAfterClose(this, data, cb);
  330. return;
  331. }
  332. if (mask === undefined) mask = !this._isServer;
  333. this._sender.pong(data || EMPTY_BUFFER, mask, cb);
  334. }
  335. /**
  336. * Send a data message.
  337. *
  338. * @param {*} data The message to send
  339. * @param {Object} [options] Options object
  340. * @param {Boolean} [options.compress] Specifies whether or not to compress
  341. * `data`
  342. * @param {Boolean} [options.binary] Specifies whether `data` is binary or
  343. * text
  344. * @param {Boolean} [options.fin=true] Specifies whether the fragment is the
  345. * last one
  346. * @param {Boolean} [options.mask] Specifies whether or not to mask `data`
  347. * @param {Function} [cb] Callback which is executed when data is written out
  348. * @public
  349. */
  350. send(data, options, cb) {
  351. if (this.readyState === WebSocket.CONNECTING) {
  352. throw new Error('WebSocket is not open: readyState 0 (CONNECTING)');
  353. }
  354. if (typeof options === 'function') {
  355. cb = options;
  356. options = {};
  357. }
  358. if (typeof data === 'number') data = data.toString();
  359. if (this.readyState !== WebSocket.OPEN) {
  360. sendAfterClose(this, data, cb);
  361. return;
  362. }
  363. const opts = {
  364. binary: typeof data !== 'string',
  365. mask: !this._isServer,
  366. compress: true,
  367. fin: true,
  368. ...options
  369. };
  370. if (!this._extensions[PerMessageDeflate.extensionName]) {
  371. opts.compress = false;
  372. }
  373. this._sender.send(data || EMPTY_BUFFER, opts, cb);
  374. }
  375. /**
  376. * Forcibly close the connection.
  377. *
  378. * @public
  379. */
  380. terminate() {
  381. if (this.readyState === WebSocket.CLOSED) return;
  382. if (this.readyState === WebSocket.CONNECTING) {
  383. const msg = 'WebSocket was closed before the connection was established';
  384. return abortHandshake(this, this._req, msg);
  385. }
  386. if (this._socket) {
  387. this._readyState = WebSocket.CLOSING;
  388. this._socket.destroy();
  389. }
  390. }
  391. }
  392. /**
  393. * @constant {Number} CONNECTING
  394. * @memberof WebSocket
  395. */
  396. Object.defineProperty(WebSocket, 'CONNECTING', {
  397. enumerable: true,
  398. value: readyStates.indexOf('CONNECTING')
  399. });
  400. /**
  401. * @constant {Number} CONNECTING
  402. * @memberof WebSocket.prototype
  403. */
  404. Object.defineProperty(WebSocket.prototype, 'CONNECTING', {
  405. enumerable: true,
  406. value: readyStates.indexOf('CONNECTING')
  407. });
  408. /**
  409. * @constant {Number} OPEN
  410. * @memberof WebSocket
  411. */
  412. Object.defineProperty(WebSocket, 'OPEN', {
  413. enumerable: true,
  414. value: readyStates.indexOf('OPEN')
  415. });
  416. /**
  417. * @constant {Number} OPEN
  418. * @memberof WebSocket.prototype
  419. */
  420. Object.defineProperty(WebSocket.prototype, 'OPEN', {
  421. enumerable: true,
  422. value: readyStates.indexOf('OPEN')
  423. });
  424. /**
  425. * @constant {Number} CLOSING
  426. * @memberof WebSocket
  427. */
  428. Object.defineProperty(WebSocket, 'CLOSING', {
  429. enumerable: true,
  430. value: readyStates.indexOf('CLOSING')
  431. });
  432. /**
  433. * @constant {Number} CLOSING
  434. * @memberof WebSocket.prototype
  435. */
  436. Object.defineProperty(WebSocket.prototype, 'CLOSING', {
  437. enumerable: true,
  438. value: readyStates.indexOf('CLOSING')
  439. });
  440. /**
  441. * @constant {Number} CLOSED
  442. * @memberof WebSocket
  443. */
  444. Object.defineProperty(WebSocket, 'CLOSED', {
  445. enumerable: true,
  446. value: readyStates.indexOf('CLOSED')
  447. });
  448. /**
  449. * @constant {Number} CLOSED
  450. * @memberof WebSocket.prototype
  451. */
  452. Object.defineProperty(WebSocket.prototype, 'CLOSED', {
  453. enumerable: true,
  454. value: readyStates.indexOf('CLOSED')
  455. });
  456. [
  457. 'binaryType',
  458. 'bufferedAmount',
  459. 'extensions',
  460. 'protocol',
  461. 'readyState',
  462. 'url'
  463. ].forEach((property) => {
  464. Object.defineProperty(WebSocket.prototype, property, { enumerable: true });
  465. });
  466. //
  467. // Add the `onopen`, `onerror`, `onclose`, and `onmessage` attributes.
  468. // See https://html.spec.whatwg.org/multipage/comms.html#the-websocket-interface
  469. //
  470. ['open', 'error', 'close', 'message'].forEach((method) => {
  471. Object.defineProperty(WebSocket.prototype, `on${method}`, {
  472. enumerable: true,
  473. get() {
  474. const listeners = this.listeners(method);
  475. for (let i = 0; i < listeners.length; i++) {
  476. if (listeners[i]._listener) return listeners[i]._listener;
  477. }
  478. return undefined;
  479. },
  480. set(listener) {
  481. const listeners = this.listeners(method);
  482. for (let i = 0; i < listeners.length; i++) {
  483. //
  484. // Remove only the listeners added via `addEventListener`.
  485. //
  486. if (listeners[i]._listener) this.removeListener(method, listeners[i]);
  487. }
  488. this.addEventListener(method, listener);
  489. }
  490. });
  491. });
  492. WebSocket.prototype.addEventListener = addEventListener;
  493. WebSocket.prototype.removeEventListener = removeEventListener;
  494. module.exports = WebSocket;
  495. /**
  496. * Initialize a WebSocket client.
  497. *
  498. * @param {WebSocket} websocket The client to initialize
  499. * @param {(String|URL)} address The URL to which to connect
  500. * @param {String} [protocols] The subprotocols
  501. * @param {Object} [options] Connection options
  502. * @param {(Boolean|Object)} [options.perMessageDeflate=true] Enable/disable
  503. * permessage-deflate
  504. * @param {Number} [options.handshakeTimeout] Timeout in milliseconds for the
  505. * handshake request
  506. * @param {Number} [options.protocolVersion=13] Value of the
  507. * `Sec-WebSocket-Version` header
  508. * @param {String} [options.origin] Value of the `Origin` or
  509. * `Sec-WebSocket-Origin` header
  510. * @param {Number} [options.maxPayload=104857600] The maximum allowed message
  511. * size
  512. * @param {Boolean} [options.followRedirects=false] Whether or not to follow
  513. * redirects
  514. * @param {Number} [options.maxRedirects=10] The maximum number of redirects
  515. * allowed
  516. * @private
  517. */
  518. function initAsClient(websocket, address, protocols, options) {
  519. const opts = {
  520. protocolVersion: protocolVersions[1],
  521. maxPayload: 100 * 1024 * 1024,
  522. perMessageDeflate: true,
  523. followRedirects: false,
  524. maxRedirects: 10,
  525. ...options,
  526. createConnection: undefined,
  527. socketPath: undefined,
  528. hostname: undefined,
  529. protocol: undefined,
  530. timeout: undefined,
  531. method: undefined,
  532. host: undefined,
  533. path: undefined,
  534. port: undefined
  535. };
  536. if (!protocolVersions.includes(opts.protocolVersion)) {
  537. throw new RangeError(
  538. `Unsupported protocol version: ${opts.protocolVersion} ` +
  539. `(supported versions: ${protocolVersions.join(', ')})`
  540. );
  541. }
  542. let parsedUrl;
  543. if (address instanceof URL) {
  544. parsedUrl = address;
  545. websocket._url = address.href;
  546. } else {
  547. parsedUrl = new URL(address);
  548. websocket._url = address;
  549. }
  550. const isUnixSocket = parsedUrl.protocol === 'ws+unix:';
  551. if (!parsedUrl.host && (!isUnixSocket || !parsedUrl.pathname)) {
  552. const err = new Error(`Invalid URL: ${websocket.url}`);
  553. if (websocket._redirects === 0) {
  554. throw err;
  555. } else {
  556. emitErrorAndClose(websocket, err);
  557. return;
  558. }
  559. }
  560. const isSecure =
  561. parsedUrl.protocol === 'wss:' || parsedUrl.protocol === 'https:';
  562. const defaultPort = isSecure ? 443 : 80;
  563. const key = randomBytes(16).toString('base64');
  564. const get = isSecure ? https.get : http.get;
  565. let perMessageDeflate;
  566. opts.createConnection = isSecure ? tlsConnect : netConnect;
  567. opts.defaultPort = opts.defaultPort || defaultPort;
  568. opts.port = parsedUrl.port || defaultPort;
  569. opts.host = parsedUrl.hostname.startsWith('[')
  570. ? parsedUrl.hostname.slice(1, -1)
  571. : parsedUrl.hostname;
  572. opts.headers = {
  573. 'Sec-WebSocket-Version': opts.protocolVersion,
  574. 'Sec-WebSocket-Key': key,
  575. Connection: 'Upgrade',
  576. Upgrade: 'websocket',
  577. ...opts.headers
  578. };
  579. opts.path = parsedUrl.pathname + parsedUrl.search;
  580. opts.timeout = opts.handshakeTimeout;
  581. if (opts.perMessageDeflate) {
  582. perMessageDeflate = new PerMessageDeflate(
  583. opts.perMessageDeflate !== true ? opts.perMessageDeflate : {},
  584. false,
  585. opts.maxPayload
  586. );
  587. opts.headers['Sec-WebSocket-Extensions'] = format({
  588. [PerMessageDeflate.extensionName]: perMessageDeflate.offer()
  589. });
  590. }
  591. if (protocols) {
  592. opts.headers['Sec-WebSocket-Protocol'] = protocols;
  593. }
  594. if (opts.origin) {
  595. if (opts.protocolVersion < 13) {
  596. opts.headers['Sec-WebSocket-Origin'] = opts.origin;
  597. } else {
  598. opts.headers.Origin = opts.origin;
  599. }
  600. }
  601. if (parsedUrl.username || parsedUrl.password) {
  602. opts.auth = `${parsedUrl.username}:${parsedUrl.password}`;
  603. }
  604. if (isUnixSocket) {
  605. const parts = opts.path.split(':');
  606. opts.socketPath = parts[0];
  607. opts.path = parts[1];
  608. }
  609. if (opts.followRedirects) {
  610. if (websocket._redirects === 0) {
  611. websocket._originalUnixSocket = isUnixSocket;
  612. websocket._originalSecure = isSecure;
  613. websocket._originalHostOrSocketPath = isUnixSocket
  614. ? opts.socketPath
  615. : parsedUrl.host;
  616. const headers = options && options.headers;
  617. //
  618. // Shallow copy the user provided options so that headers can be changed
  619. // without mutating the original object.
  620. //
  621. options = { ...options, headers: {} };
  622. if (headers) {
  623. for (const [key, value] of Object.entries(headers)) {
  624. options.headers[key.toLowerCase()] = value;
  625. }
  626. }
  627. } else {
  628. const isSameHost = isUnixSocket
  629. ? websocket._originalUnixSocket
  630. ? opts.socketPath === websocket._originalHostOrSocketPath
  631. : false
  632. : websocket._originalUnixSocket
  633. ? false
  634. : parsedUrl.host === websocket._originalHostOrSocketPath;
  635. if (!isSameHost || (websocket._originalSecure && !isSecure)) {
  636. //
  637. // Match curl 7.77.0 behavior and drop the following headers. These
  638. // headers are also dropped when following a redirect to a subdomain.
  639. //
  640. delete opts.headers.authorization;
  641. delete opts.headers.cookie;
  642. if (!isSameHost) delete opts.headers.host;
  643. opts.auth = undefined;
  644. }
  645. }
  646. //
  647. // Match curl 7.77.0 behavior and make the first `Authorization` header win.
  648. // If the `Authorization` header is set, then there is nothing to do as it
  649. // will take precedence.
  650. //
  651. if (opts.auth && !options.headers.authorization) {
  652. options.headers.authorization =
  653. 'Basic ' + Buffer.from(opts.auth).toString('base64');
  654. }
  655. }
  656. let req = (websocket._req = get(opts));
  657. if (opts.timeout) {
  658. req.on('timeout', () => {
  659. abortHandshake(websocket, req, 'Opening handshake has timed out');
  660. });
  661. }
  662. req.on('error', (err) => {
  663. if (req === null || req.aborted) return;
  664. req = websocket._req = null;
  665. emitErrorAndClose(websocket, err);
  666. });
  667. req.on('response', (res) => {
  668. const location = res.headers.location;
  669. const statusCode = res.statusCode;
  670. if (
  671. location &&
  672. opts.followRedirects &&
  673. statusCode >= 300 &&
  674. statusCode < 400
  675. ) {
  676. if (++websocket._redirects > opts.maxRedirects) {
  677. abortHandshake(websocket, req, 'Maximum redirects exceeded');
  678. return;
  679. }
  680. req.abort();
  681. let addr;
  682. try {
  683. addr = new URL(location, address);
  684. } catch (err) {
  685. emitErrorAndClose(websocket, err);
  686. return;
  687. }
  688. initAsClient(websocket, addr, protocols, options);
  689. } else if (!websocket.emit('unexpected-response', req, res)) {
  690. abortHandshake(
  691. websocket,
  692. req,
  693. `Unexpected server response: ${res.statusCode}`
  694. );
  695. }
  696. });
  697. req.on('upgrade', (res, socket, head) => {
  698. websocket.emit('upgrade', res);
  699. //
  700. // The user may have closed the connection from a listener of the `upgrade`
  701. // event.
  702. //
  703. if (websocket.readyState !== WebSocket.CONNECTING) return;
  704. req = websocket._req = null;
  705. if (res.headers.upgrade.toLowerCase() !== 'websocket') {
  706. abortHandshake(websocket, socket, 'Invalid Upgrade header');
  707. return;
  708. }
  709. const digest = createHash('sha1')
  710. .update(key + GUID)
  711. .digest('base64');
  712. if (res.headers['sec-websocket-accept'] !== digest) {
  713. abortHandshake(websocket, socket, 'Invalid Sec-WebSocket-Accept header');
  714. return;
  715. }
  716. const serverProt = res.headers['sec-websocket-protocol'];
  717. const protList = (protocols || '').split(/, */);
  718. let protError;
  719. if (!protocols && serverProt) {
  720. protError = 'Server sent a subprotocol but none was requested';
  721. } else if (protocols && !serverProt) {
  722. protError = 'Server sent no subprotocol';
  723. } else if (serverProt && !protList.includes(serverProt)) {
  724. protError = 'Server sent an invalid subprotocol';
  725. }
  726. if (protError) {
  727. abortHandshake(websocket, socket, protError);
  728. return;
  729. }
  730. if (serverProt) websocket._protocol = serverProt;
  731. const secWebSocketExtensions = res.headers['sec-websocket-extensions'];
  732. if (secWebSocketExtensions !== undefined) {
  733. if (!perMessageDeflate) {
  734. const message =
  735. 'Server sent a Sec-WebSocket-Extensions header but no extension ' +
  736. 'was requested';
  737. abortHandshake(websocket, socket, message);
  738. return;
  739. }
  740. let extensions;
  741. try {
  742. extensions = parse(secWebSocketExtensions);
  743. } catch (err) {
  744. const message = 'Invalid Sec-WebSocket-Extensions header';
  745. abortHandshake(websocket, socket, message);
  746. return;
  747. }
  748. const extensionNames = Object.keys(extensions);
  749. if (extensionNames.length) {
  750. if (
  751. extensionNames.length !== 1 ||
  752. extensionNames[0] !== PerMessageDeflate.extensionName
  753. ) {
  754. const message =
  755. 'Server indicated an extension that was not requested';
  756. abortHandshake(websocket, socket, message);
  757. return;
  758. }
  759. try {
  760. perMessageDeflate.accept(extensions[PerMessageDeflate.extensionName]);
  761. } catch (err) {
  762. const message = 'Invalid Sec-WebSocket-Extensions header';
  763. abortHandshake(websocket, socket, message);
  764. return;
  765. }
  766. websocket._extensions[PerMessageDeflate.extensionName] =
  767. perMessageDeflate;
  768. }
  769. }
  770. websocket.setSocket(socket, head, opts.maxPayload);
  771. });
  772. }
  773. /**
  774. * Emit the `'error'` and `'close'` event.
  775. *
  776. * @param {WebSocket} websocket The WebSocket instance
  777. * @param {Error} The error to emit
  778. * @private
  779. */
  780. function emitErrorAndClose(websocket, err) {
  781. websocket._readyState = WebSocket.CLOSING;
  782. websocket.emit('error', err);
  783. websocket.emitClose();
  784. }
  785. /**
  786. * Create a `net.Socket` and initiate a connection.
  787. *
  788. * @param {Object} options Connection options
  789. * @return {net.Socket} The newly created socket used to start the connection
  790. * @private
  791. */
  792. function netConnect(options) {
  793. options.path = options.socketPath;
  794. return net.connect(options);
  795. }
  796. /**
  797. * Create a `tls.TLSSocket` and initiate a connection.
  798. *
  799. * @param {Object} options Connection options
  800. * @return {tls.TLSSocket} The newly created socket used to start the connection
  801. * @private
  802. */
  803. function tlsConnect(options) {
  804. options.path = undefined;
  805. if (!options.servername && options.servername !== '') {
  806. options.servername = net.isIP(options.host) ? '' : options.host;
  807. }
  808. return tls.connect(options);
  809. }
  810. /**
  811. * Abort the handshake and emit an error.
  812. *
  813. * @param {WebSocket} websocket The WebSocket instance
  814. * @param {(http.ClientRequest|net.Socket|tls.Socket)} stream The request to
  815. * abort or the socket to destroy
  816. * @param {String} message The error message
  817. * @private
  818. */
  819. function abortHandshake(websocket, stream, message) {
  820. websocket._readyState = WebSocket.CLOSING;
  821. const err = new Error(message);
  822. Error.captureStackTrace(err, abortHandshake);
  823. if (stream.setHeader) {
  824. stream.abort();
  825. if (stream.socket && !stream.socket.destroyed) {
  826. //
  827. // On Node.js >= 14.3.0 `request.abort()` does not destroy the socket if
  828. // called after the request completed. See
  829. // https://github.com/websockets/ws/issues/1869.
  830. //
  831. stream.socket.destroy();
  832. }
  833. stream.once('abort', websocket.emitClose.bind(websocket));
  834. websocket.emit('error', err);
  835. } else {
  836. stream.destroy(err);
  837. stream.once('error', websocket.emit.bind(websocket, 'error'));
  838. stream.once('close', websocket.emitClose.bind(websocket));
  839. }
  840. }
  841. /**
  842. * Handle cases where the `ping()`, `pong()`, or `send()` methods are called
  843. * when the `readyState` attribute is `CLOSING` or `CLOSED`.
  844. *
  845. * @param {WebSocket} websocket The WebSocket instance
  846. * @param {*} [data] The data to send
  847. * @param {Function} [cb] Callback
  848. * @private
  849. */
  850. function sendAfterClose(websocket, data, cb) {
  851. if (data) {
  852. const length = toBuffer(data).length;
  853. //
  854. // The `_bufferedAmount` property is used only when the peer is a client and
  855. // the opening handshake fails. Under these circumstances, in fact, the
  856. // `setSocket()` method is not called, so the `_socket` and `_sender`
  857. // properties are set to `null`.
  858. //
  859. if (websocket._socket) websocket._sender._bufferedBytes += length;
  860. else websocket._bufferedAmount += length;
  861. }
  862. if (cb) {
  863. const err = new Error(
  864. `WebSocket is not open: readyState ${websocket.readyState} ` +
  865. `(${readyStates[websocket.readyState]})`
  866. );
  867. cb(err);
  868. }
  869. }
  870. /**
  871. * The listener of the `Receiver` `'conclude'` event.
  872. *
  873. * @param {Number} code The status code
  874. * @param {String} reason The reason for closing
  875. * @private
  876. */
  877. function receiverOnConclude(code, reason) {
  878. const websocket = this[kWebSocket];
  879. websocket._closeFrameReceived = true;
  880. websocket._closeMessage = reason;
  881. websocket._closeCode = code;
  882. if (websocket._socket[kWebSocket] === undefined) return;
  883. websocket._socket.removeListener('data', socketOnData);
  884. process.nextTick(resume, websocket._socket);
  885. if (code === 1005) websocket.close();
  886. else websocket.close(code, reason);
  887. }
  888. /**
  889. * The listener of the `Receiver` `'drain'` event.
  890. *
  891. * @private
  892. */
  893. function receiverOnDrain() {
  894. this[kWebSocket]._socket.resume();
  895. }
  896. /**
  897. * The listener of the `Receiver` `'error'` event.
  898. *
  899. * @param {(RangeError|Error)} err The emitted error
  900. * @private
  901. */
  902. function receiverOnError(err) {
  903. const websocket = this[kWebSocket];
  904. if (websocket._socket[kWebSocket] !== undefined) {
  905. websocket._socket.removeListener('data', socketOnData);
  906. //
  907. // On Node.js < 14.0.0 the `'error'` event is emitted synchronously. See
  908. // https://github.com/websockets/ws/issues/1940.
  909. //
  910. process.nextTick(resume, websocket._socket);
  911. websocket.close(err[kStatusCode]);
  912. }
  913. websocket.emit('error', err);
  914. }
  915. /**
  916. * The listener of the `Receiver` `'finish'` event.
  917. *
  918. * @private
  919. */
  920. function receiverOnFinish() {
  921. this[kWebSocket].emitClose();
  922. }
  923. /**
  924. * The listener of the `Receiver` `'message'` event.
  925. *
  926. * @param {(String|Buffer|ArrayBuffer|Buffer[])} data The message
  927. * @private
  928. */
  929. function receiverOnMessage(data) {
  930. this[kWebSocket].emit('message', data);
  931. }
  932. /**
  933. * The listener of the `Receiver` `'ping'` event.
  934. *
  935. * @param {Buffer} data The data included in the ping frame
  936. * @private
  937. */
  938. function receiverOnPing(data) {
  939. const websocket = this[kWebSocket];
  940. websocket.pong(data, !websocket._isServer, NOOP);
  941. websocket.emit('ping', data);
  942. }
  943. /**
  944. * The listener of the `Receiver` `'pong'` event.
  945. *
  946. * @param {Buffer} data The data included in the pong frame
  947. * @private
  948. */
  949. function receiverOnPong(data) {
  950. this[kWebSocket].emit('pong', data);
  951. }
  952. /**
  953. * Resume a readable stream
  954. *
  955. * @param {Readable} stream The readable stream
  956. * @private
  957. */
  958. function resume(stream) {
  959. stream.resume();
  960. }
  961. /**
  962. * The listener of the `net.Socket` `'close'` event.
  963. *
  964. * @private
  965. */
  966. function socketOnClose() {
  967. const websocket = this[kWebSocket];
  968. this.removeListener('close', socketOnClose);
  969. this.removeListener('data', socketOnData);
  970. this.removeListener('end', socketOnEnd);
  971. websocket._readyState = WebSocket.CLOSING;
  972. let chunk;
  973. //
  974. // The close frame might not have been received or the `'end'` event emitted,
  975. // for example, if the socket was destroyed due to an error. Ensure that the
  976. // `receiver` stream is closed after writing any remaining buffered data to
  977. // it. If the readable side of the socket is in flowing mode then there is no
  978. // buffered data as everything has been already written and `readable.read()`
  979. // will return `null`. If instead, the socket is paused, any possible buffered
  980. // data will be read as a single chunk.
  981. //
  982. if (
  983. !this._readableState.endEmitted &&
  984. !websocket._closeFrameReceived &&
  985. !websocket._receiver._writableState.errorEmitted &&
  986. (chunk = websocket._socket.read()) !== null
  987. ) {
  988. websocket._receiver.write(chunk);
  989. }
  990. websocket._receiver.end();
  991. this[kWebSocket] = undefined;
  992. clearTimeout(websocket._closeTimer);
  993. if (
  994. websocket._receiver._writableState.finished ||
  995. websocket._receiver._writableState.errorEmitted
  996. ) {
  997. websocket.emitClose();
  998. } else {
  999. websocket._receiver.on('error', receiverOnFinish);
  1000. websocket._receiver.on('finish', receiverOnFinish);
  1001. }
  1002. }
  1003. /**
  1004. * The listener of the `net.Socket` `'data'` event.
  1005. *
  1006. * @param {Buffer} chunk A chunk of data
  1007. * @private
  1008. */
  1009. function socketOnData(chunk) {
  1010. if (!this[kWebSocket]._receiver.write(chunk)) {
  1011. this.pause();
  1012. }
  1013. }
  1014. /**
  1015. * The listener of the `net.Socket` `'end'` event.
  1016. *
  1017. * @private
  1018. */
  1019. function socketOnEnd() {
  1020. const websocket = this[kWebSocket];
  1021. websocket._readyState = WebSocket.CLOSING;
  1022. websocket._receiver.end();
  1023. this.end();
  1024. }
  1025. /**
  1026. * The listener of the `net.Socket` `'error'` event.
  1027. *
  1028. * @private
  1029. */
  1030. function socketOnError() {
  1031. const websocket = this[kWebSocket];
  1032. this.removeListener('error', socketOnError);
  1033. this.on('error', NOOP);
  1034. if (websocket) {
  1035. websocket._readyState = WebSocket.CLOSING;
  1036. this.destroy();
  1037. }
  1038. }
  1039. }, function(modId) { var map = {"stream":1682324647595,"./permessage-deflate":1682324647596,"./receiver":1682324647600,"./sender":1682324647602,"./constants":1682324647598,"./event-target":1682324647603,"./extension":1682324647604,"./buffer-util":1682324647597}; return __REQUIRE__(map[modId], modId); })
  1040. __DEFINE__(1682324647595, function(require, module, exports) {
  1041. const { Duplex } = require('stream');
  1042. /**
  1043. * Emits the `'close'` event on a stream.
  1044. *
  1045. * @param {Duplex} stream The stream.
  1046. * @private
  1047. */
  1048. function emitClose(stream) {
  1049. stream.emit('close');
  1050. }
  1051. /**
  1052. * The listener of the `'end'` event.
  1053. *
  1054. * @private
  1055. */
  1056. function duplexOnEnd() {
  1057. if (!this.destroyed && this._writableState.finished) {
  1058. this.destroy();
  1059. }
  1060. }
  1061. /**
  1062. * The listener of the `'error'` event.
  1063. *
  1064. * @param {Error} err The error
  1065. * @private
  1066. */
  1067. function duplexOnError(err) {
  1068. this.removeListener('error', duplexOnError);
  1069. this.destroy();
  1070. if (this.listenerCount('error') === 0) {
  1071. // Do not suppress the throwing behavior.
  1072. this.emit('error', err);
  1073. }
  1074. }
  1075. /**
  1076. * Wraps a `WebSocket` in a duplex stream.
  1077. *
  1078. * @param {WebSocket} ws The `WebSocket` to wrap
  1079. * @param {Object} [options] The options for the `Duplex` constructor
  1080. * @return {Duplex} The duplex stream
  1081. * @public
  1082. */
  1083. function createWebSocketStream(ws, options) {
  1084. let resumeOnReceiverDrain = true;
  1085. let terminateOnDestroy = true;
  1086. function receiverOnDrain() {
  1087. if (resumeOnReceiverDrain) ws._socket.resume();
  1088. }
  1089. if (ws.readyState === ws.CONNECTING) {
  1090. ws.once('open', function open() {
  1091. ws._receiver.removeAllListeners('drain');
  1092. ws._receiver.on('drain', receiverOnDrain);
  1093. });
  1094. } else {
  1095. ws._receiver.removeAllListeners('drain');
  1096. ws._receiver.on('drain', receiverOnDrain);
  1097. }
  1098. const duplex = new Duplex({
  1099. ...options,
  1100. autoDestroy: false,
  1101. emitClose: false,
  1102. objectMode: false,
  1103. writableObjectMode: false
  1104. });
  1105. ws.on('message', function message(msg) {
  1106. if (!duplex.push(msg)) {
  1107. resumeOnReceiverDrain = false;
  1108. ws._socket.pause();
  1109. }
  1110. });
  1111. ws.once('error', function error(err) {
  1112. if (duplex.destroyed) return;
  1113. // Prevent `ws.terminate()` from being called by `duplex._destroy()`.
  1114. //
  1115. // - If the `'error'` event is emitted before the `'open'` event, then
  1116. // `ws.terminate()` is a noop as no socket is assigned.
  1117. // - Otherwise, the error is re-emitted by the listener of the `'error'`
  1118. // event of the `Receiver` object. The listener already closes the
  1119. // connection by calling `ws.close()`. This allows a close frame to be
  1120. // sent to the other peer. If `ws.terminate()` is called right after this,
  1121. // then the close frame might not be sent.
  1122. terminateOnDestroy = false;
  1123. duplex.destroy(err);
  1124. });
  1125. ws.once('close', function close() {
  1126. if (duplex.destroyed) return;
  1127. duplex.push(null);
  1128. });
  1129. duplex._destroy = function (err, callback) {
  1130. if (ws.readyState === ws.CLOSED) {
  1131. callback(err);
  1132. process.nextTick(emitClose, duplex);
  1133. return;
  1134. }
  1135. let called = false;
  1136. ws.once('error', function error(err) {
  1137. called = true;
  1138. callback(err);
  1139. });
  1140. ws.once('close', function close() {
  1141. if (!called) callback(err);
  1142. process.nextTick(emitClose, duplex);
  1143. });
  1144. if (terminateOnDestroy) ws.terminate();
  1145. };
  1146. duplex._final = function (callback) {
  1147. if (ws.readyState === ws.CONNECTING) {
  1148. ws.once('open', function open() {
  1149. duplex._final(callback);
  1150. });
  1151. return;
  1152. }
  1153. // If the value of the `_socket` property is `null` it means that `ws` is a
  1154. // client websocket and the handshake failed. In fact, when this happens, a
  1155. // socket is never assigned to the websocket. Wait for the `'error'` event
  1156. // that will be emitted by the websocket.
  1157. if (ws._socket === null) return;
  1158. if (ws._socket._writableState.finished) {
  1159. callback();
  1160. if (duplex._readableState.endEmitted) duplex.destroy();
  1161. } else {
  1162. ws._socket.once('finish', function finish() {
  1163. // `duplex` is not destroyed here because the `'end'` event will be
  1164. // emitted on `duplex` after this `'finish'` event. The EOF signaling
  1165. // `null` chunk is, in fact, pushed when the websocket emits `'close'`.
  1166. callback();
  1167. });
  1168. ws.close();
  1169. }
  1170. };
  1171. duplex._read = function () {
  1172. if (
  1173. (ws.readyState === ws.OPEN || ws.readyState === ws.CLOSING) &&
  1174. !resumeOnReceiverDrain
  1175. ) {
  1176. resumeOnReceiverDrain = true;
  1177. if (!ws._receiver._writableState.needDrain) ws._socket.resume();
  1178. }
  1179. };
  1180. duplex._write = function (chunk, encoding, callback) {
  1181. if (ws.readyState === ws.CONNECTING) {
  1182. ws.once('open', function open() {
  1183. duplex._write(chunk, encoding, callback);
  1184. });
  1185. return;
  1186. }
  1187. ws.send(chunk, callback);
  1188. };
  1189. duplex.on('end', duplexOnEnd);
  1190. duplex.on('error', duplexOnError);
  1191. return duplex;
  1192. }
  1193. module.exports = createWebSocketStream;
  1194. }, function(modId) { var map = {"stream":1682324647595}; return __REQUIRE__(map[modId], modId); })
  1195. __DEFINE__(1682324647596, function(require, module, exports) {
  1196. const zlib = require('zlib');
  1197. const bufferUtil = require('./buffer-util');
  1198. const Limiter = require('./limiter');
  1199. const { kStatusCode, NOOP } = require('./constants');
  1200. const TRAILER = Buffer.from([0x00, 0x00, 0xff, 0xff]);
  1201. const kPerMessageDeflate = Symbol('permessage-deflate');
  1202. const kTotalLength = Symbol('total-length');
  1203. const kCallback = Symbol('callback');
  1204. const kBuffers = Symbol('buffers');
  1205. const kError = Symbol('error');
  1206. //
  1207. // We limit zlib concurrency, which prevents severe memory fragmentation
  1208. // as documented in https://github.com/nodejs/node/issues/8871#issuecomment-250915913
  1209. // and https://github.com/websockets/ws/issues/1202
  1210. //
  1211. // Intentionally global; it's the global thread pool that's an issue.
  1212. //
  1213. let zlibLimiter;
  1214. /**
  1215. * permessage-deflate implementation.
  1216. */
  1217. class PerMessageDeflate {
  1218. /**
  1219. * Creates a PerMessageDeflate instance.
  1220. *
  1221. * @param {Object} [options] Configuration options
  1222. * @param {Boolean} [options.serverNoContextTakeover=false] Request/accept
  1223. * disabling of server context takeover
  1224. * @param {Boolean} [options.clientNoContextTakeover=false] Advertise/
  1225. * acknowledge disabling of client context takeover
  1226. * @param {(Boolean|Number)} [options.serverMaxWindowBits] Request/confirm the
  1227. * use of a custom server window size
  1228. * @param {(Boolean|Number)} [options.clientMaxWindowBits] Advertise support
  1229. * for, or request, a custom client window size
  1230. * @param {Object} [options.zlibDeflateOptions] Options to pass to zlib on
  1231. * deflate
  1232. * @param {Object} [options.zlibInflateOptions] Options to pass to zlib on
  1233. * inflate
  1234. * @param {Number} [options.threshold=1024] Size (in bytes) below which
  1235. * messages should not be compressed
  1236. * @param {Number} [options.concurrencyLimit=10] The number of concurrent
  1237. * calls to zlib
  1238. * @param {Boolean} [isServer=false] Create the instance in either server or
  1239. * client mode
  1240. * @param {Number} [maxPayload=0] The maximum allowed message length
  1241. */
  1242. constructor(options, isServer, maxPayload) {
  1243. this._maxPayload = maxPayload | 0;
  1244. this._options = options || {};
  1245. this._threshold =
  1246. this._options.threshold !== undefined ? this._options.threshold : 1024;
  1247. this._isServer = !!isServer;
  1248. this._deflate = null;
  1249. this._inflate = null;
  1250. this.params = null;
  1251. if (!zlibLimiter) {
  1252. const concurrency =
  1253. this._options.concurrencyLimit !== undefined
  1254. ? this._options.concurrencyLimit
  1255. : 10;
  1256. zlibLimiter = new Limiter(concurrency);
  1257. }
  1258. }
  1259. /**
  1260. * @type {String}
  1261. */
  1262. static get extensionName() {
  1263. return 'permessage-deflate';
  1264. }
  1265. /**
  1266. * Create an extension negotiation offer.
  1267. *
  1268. * @return {Object} Extension parameters
  1269. * @public
  1270. */
  1271. offer() {
  1272. const params = {};
  1273. if (this._options.serverNoContextTakeover) {
  1274. params.server_no_context_takeover = true;
  1275. }
  1276. if (this._options.clientNoContextTakeover) {
  1277. params.client_no_context_takeover = true;
  1278. }
  1279. if (this._options.serverMaxWindowBits) {
  1280. params.server_max_window_bits = this._options.serverMaxWindowBits;
  1281. }
  1282. if (this._options.clientMaxWindowBits) {
  1283. params.client_max_window_bits = this._options.clientMaxWindowBits;
  1284. } else if (this._options.clientMaxWindowBits == null) {
  1285. params.client_max_window_bits = true;
  1286. }
  1287. return params;
  1288. }
  1289. /**
  1290. * Accept an extension negotiation offer/response.
  1291. *
  1292. * @param {Array} configurations The extension negotiation offers/reponse
  1293. * @return {Object} Accepted configuration
  1294. * @public
  1295. */
  1296. accept(configurations) {
  1297. configurations = this.normalizeParams(configurations);
  1298. this.params = this._isServer
  1299. ? this.acceptAsServer(configurations)
  1300. : this.acceptAsClient(configurations);
  1301. return this.params;
  1302. }
  1303. /**
  1304. * Releases all resources used by the extension.
  1305. *
  1306. * @public
  1307. */
  1308. cleanup() {
  1309. if (this._inflate) {
  1310. this._inflate.close();
  1311. this._inflate = null;
  1312. }
  1313. if (this._deflate) {
  1314. const callback = this._deflate[kCallback];
  1315. this._deflate.close();
  1316. this._deflate = null;
  1317. if (callback) {
  1318. callback(
  1319. new Error(
  1320. 'The deflate stream was closed while data was being processed'
  1321. )
  1322. );
  1323. }
  1324. }
  1325. }
  1326. /**
  1327. * Accept an extension negotiation offer.
  1328. *
  1329. * @param {Array} offers The extension negotiation offers
  1330. * @return {Object} Accepted configuration
  1331. * @private
  1332. */
  1333. acceptAsServer(offers) {
  1334. const opts = this._options;
  1335. const accepted = offers.find((params) => {
  1336. if (
  1337. (opts.serverNoContextTakeover === false &&
  1338. params.server_no_context_takeover) ||
  1339. (params.server_max_window_bits &&
  1340. (opts.serverMaxWindowBits === false ||
  1341. (typeof opts.serverMaxWindowBits === 'number' &&
  1342. opts.serverMaxWindowBits > params.server_max_window_bits))) ||
  1343. (typeof opts.clientMaxWindowBits === 'number' &&
  1344. !params.client_max_window_bits)
  1345. ) {
  1346. return false;
  1347. }
  1348. return true;
  1349. });
  1350. if (!accepted) {
  1351. throw new Error('None of the extension offers can be accepted');
  1352. }
  1353. if (opts.serverNoContextTakeover) {
  1354. accepted.server_no_context_takeover = true;
  1355. }
  1356. if (opts.clientNoContextTakeover) {
  1357. accepted.client_no_context_takeover = true;
  1358. }
  1359. if (typeof opts.serverMaxWindowBits === 'number') {
  1360. accepted.server_max_window_bits = opts.serverMaxWindowBits;
  1361. }
  1362. if (typeof opts.clientMaxWindowBits === 'number') {
  1363. accepted.client_max_window_bits = opts.clientMaxWindowBits;
  1364. } else if (
  1365. accepted.client_max_window_bits === true ||
  1366. opts.clientMaxWindowBits === false
  1367. ) {
  1368. delete accepted.client_max_window_bits;
  1369. }
  1370. return accepted;
  1371. }
  1372. /**
  1373. * Accept the extension negotiation response.
  1374. *
  1375. * @param {Array} response The extension negotiation response
  1376. * @return {Object} Accepted configuration
  1377. * @private
  1378. */
  1379. acceptAsClient(response) {
  1380. const params = response[0];
  1381. if (
  1382. this._options.clientNoContextTakeover === false &&
  1383. params.client_no_context_takeover
  1384. ) {
  1385. throw new Error('Unexpected parameter "client_no_context_takeover"');
  1386. }
  1387. if (!params.client_max_window_bits) {
  1388. if (typeof this._options.clientMaxWindowBits === 'number') {
  1389. params.client_max_window_bits = this._options.clientMaxWindowBits;
  1390. }
  1391. } else if (
  1392. this._options.clientMaxWindowBits === false ||
  1393. (typeof this._options.clientMaxWindowBits === 'number' &&
  1394. params.client_max_window_bits > this._options.clientMaxWindowBits)
  1395. ) {
  1396. throw new Error(
  1397. 'Unexpected or invalid parameter "client_max_window_bits"'
  1398. );
  1399. }
  1400. return params;
  1401. }
  1402. /**
  1403. * Normalize parameters.
  1404. *
  1405. * @param {Array} configurations The extension negotiation offers/reponse
  1406. * @return {Array} The offers/response with normalized parameters
  1407. * @private
  1408. */
  1409. normalizeParams(configurations) {
  1410. configurations.forEach((params) => {
  1411. Object.keys(params).forEach((key) => {
  1412. let value = params[key];
  1413. if (value.length > 1) {
  1414. throw new Error(`Parameter "${key}" must have only a single value`);
  1415. }
  1416. value = value[0];
  1417. if (key === 'client_max_window_bits') {
  1418. if (value !== true) {
  1419. const num = +value;
  1420. if (!Number.isInteger(num) || num < 8 || num > 15) {
  1421. throw new TypeError(
  1422. `Invalid value for parameter "${key}": ${value}`
  1423. );
  1424. }
  1425. value = num;
  1426. } else if (!this._isServer) {
  1427. throw new TypeError(
  1428. `Invalid value for parameter "${key}": ${value}`
  1429. );
  1430. }
  1431. } else if (key === 'server_max_window_bits') {
  1432. const num = +value;
  1433. if (!Number.isInteger(num) || num < 8 || num > 15) {
  1434. throw new TypeError(
  1435. `Invalid value for parameter "${key}": ${value}`
  1436. );
  1437. }
  1438. value = num;
  1439. } else if (
  1440. key === 'client_no_context_takeover' ||
  1441. key === 'server_no_context_takeover'
  1442. ) {
  1443. if (value !== true) {
  1444. throw new TypeError(
  1445. `Invalid value for parameter "${key}": ${value}`
  1446. );
  1447. }
  1448. } else {
  1449. throw new Error(`Unknown parameter "${key}"`);
  1450. }
  1451. params[key] = value;
  1452. });
  1453. });
  1454. return configurations;
  1455. }
  1456. /**
  1457. * Decompress data. Concurrency limited.
  1458. *
  1459. * @param {Buffer} data Compressed data
  1460. * @param {Boolean} fin Specifies whether or not this is the last fragment
  1461. * @param {Function} callback Callback
  1462. * @public
  1463. */
  1464. decompress(data, fin, callback) {
  1465. zlibLimiter.add((done) => {
  1466. this._decompress(data, fin, (err, result) => {
  1467. done();
  1468. callback(err, result);
  1469. });
  1470. });
  1471. }
  1472. /**
  1473. * Compress data. Concurrency limited.
  1474. *
  1475. * @param {Buffer} data Data to compress
  1476. * @param {Boolean} fin Specifies whether or not this is the last fragment
  1477. * @param {Function} callback Callback
  1478. * @public
  1479. */
  1480. compress(data, fin, callback) {
  1481. zlibLimiter.add((done) => {
  1482. this._compress(data, fin, (err, result) => {
  1483. done();
  1484. callback(err, result);
  1485. });
  1486. });
  1487. }
  1488. /**
  1489. * Decompress data.
  1490. *
  1491. * @param {Buffer} data Compressed data
  1492. * @param {Boolean} fin Specifies whether or not this is the last fragment
  1493. * @param {Function} callback Callback
  1494. * @private
  1495. */
  1496. _decompress(data, fin, callback) {
  1497. const endpoint = this._isServer ? 'client' : 'server';
  1498. if (!this._inflate) {
  1499. const key = `${endpoint}_max_window_bits`;
  1500. const windowBits =
  1501. typeof this.params[key] !== 'number'
  1502. ? zlib.Z_DEFAULT_WINDOWBITS
  1503. : this.params[key];
  1504. this._inflate = zlib.createInflateRaw({
  1505. ...this._options.zlibInflateOptions,
  1506. windowBits
  1507. });
  1508. this._inflate[kPerMessageDeflate] = this;
  1509. this._inflate[kTotalLength] = 0;
  1510. this._inflate[kBuffers] = [];
  1511. this._inflate.on('error', inflateOnError);
  1512. this._inflate.on('data', inflateOnData);
  1513. }
  1514. this._inflate[kCallback] = callback;
  1515. this._inflate.write(data);
  1516. if (fin) this._inflate.write(TRAILER);
  1517. this._inflate.flush(() => {
  1518. const err = this._inflate[kError];
  1519. if (err) {
  1520. this._inflate.close();
  1521. this._inflate = null;
  1522. callback(err);
  1523. return;
  1524. }
  1525. const data = bufferUtil.concat(
  1526. this._inflate[kBuffers],
  1527. this._inflate[kTotalLength]
  1528. );
  1529. if (this._inflate._readableState.endEmitted) {
  1530. this._inflate.close();
  1531. this._inflate = null;
  1532. } else {
  1533. this._inflate[kTotalLength] = 0;
  1534. this._inflate[kBuffers] = [];
  1535. if (fin && this.params[`${endpoint}_no_context_takeover`]) {
  1536. this._inflate.reset();
  1537. }
  1538. }
  1539. callback(null, data);
  1540. });
  1541. }
  1542. /**
  1543. * Compress data.
  1544. *
  1545. * @param {Buffer} data Data to compress
  1546. * @param {Boolean} fin Specifies whether or not this is the last fragment
  1547. * @param {Function} callback Callback
  1548. * @private
  1549. */
  1550. _compress(data, fin, callback) {
  1551. const endpoint = this._isServer ? 'server' : 'client';
  1552. if (!this._deflate) {
  1553. const key = `${endpoint}_max_window_bits`;
  1554. const windowBits =
  1555. typeof this.params[key] !== 'number'
  1556. ? zlib.Z_DEFAULT_WINDOWBITS
  1557. : this.params[key];
  1558. this._deflate = zlib.createDeflateRaw({
  1559. ...this._options.zlibDeflateOptions,
  1560. windowBits
  1561. });
  1562. this._deflate[kTotalLength] = 0;
  1563. this._deflate[kBuffers] = [];
  1564. //
  1565. // An `'error'` event is emitted, only on Node.js < 10.0.0, if the
  1566. // `zlib.DeflateRaw` instance is closed while data is being processed.
  1567. // This can happen if `PerMessageDeflate#cleanup()` is called at the wrong
  1568. // time due to an abnormal WebSocket closure.
  1569. //
  1570. this._deflate.on('error', NOOP);
  1571. this._deflate.on('data', deflateOnData);
  1572. }
  1573. this._deflate[kCallback] = callback;
  1574. this._deflate.write(data);
  1575. this._deflate.flush(zlib.Z_SYNC_FLUSH, () => {
  1576. if (!this._deflate) {
  1577. //
  1578. // The deflate stream was closed while data was being processed.
  1579. //
  1580. return;
  1581. }
  1582. let data = bufferUtil.concat(
  1583. this._deflate[kBuffers],
  1584. this._deflate[kTotalLength]
  1585. );
  1586. if (fin) data = data.slice(0, data.length - 4);
  1587. //
  1588. // Ensure that the callback will not be called again in
  1589. // `PerMessageDeflate#cleanup()`.
  1590. //
  1591. this._deflate[kCallback] = null;
  1592. this._deflate[kTotalLength] = 0;
  1593. this._deflate[kBuffers] = [];
  1594. if (fin && this.params[`${endpoint}_no_context_takeover`]) {
  1595. this._deflate.reset();
  1596. }
  1597. callback(null, data);
  1598. });
  1599. }
  1600. }
  1601. module.exports = PerMessageDeflate;
  1602. /**
  1603. * The listener of the `zlib.DeflateRaw` stream `'data'` event.
  1604. *
  1605. * @param {Buffer} chunk A chunk of data
  1606. * @private
  1607. */
  1608. function deflateOnData(chunk) {
  1609. this[kBuffers].push(chunk);
  1610. this[kTotalLength] += chunk.length;
  1611. }
  1612. /**
  1613. * The listener of the `zlib.InflateRaw` stream `'data'` event.
  1614. *
  1615. * @param {Buffer} chunk A chunk of data
  1616. * @private
  1617. */
  1618. function inflateOnData(chunk) {
  1619. this[kTotalLength] += chunk.length;
  1620. if (
  1621. this[kPerMessageDeflate]._maxPayload < 1 ||
  1622. this[kTotalLength] <= this[kPerMessageDeflate]._maxPayload
  1623. ) {
  1624. this[kBuffers].push(chunk);
  1625. return;
  1626. }
  1627. this[kError] = new RangeError('Max payload size exceeded');
  1628. this[kError].code = 'WS_ERR_UNSUPPORTED_MESSAGE_LENGTH';
  1629. this[kError][kStatusCode] = 1009;
  1630. this.removeListener('data', inflateOnData);
  1631. this.reset();
  1632. }
  1633. /**
  1634. * The listener of the `zlib.InflateRaw` stream `'error'` event.
  1635. *
  1636. * @param {Error} err The emitted error
  1637. * @private
  1638. */
  1639. function inflateOnError(err) {
  1640. //
  1641. // There is no need to call `Zlib#close()` as the handle is automatically
  1642. // closed when an error is emitted.
  1643. //
  1644. this[kPerMessageDeflate]._inflate = null;
  1645. err[kStatusCode] = 1007;
  1646. this[kCallback](err);
  1647. }
  1648. }, function(modId) { var map = {"./buffer-util":1682324647597,"./limiter":1682324647599,"./constants":1682324647598}; return __REQUIRE__(map[modId], modId); })
  1649. __DEFINE__(1682324647597, function(require, module, exports) {
  1650. const { EMPTY_BUFFER } = require('./constants');
  1651. /**
  1652. * Merges an array of buffers into a new buffer.
  1653. *
  1654. * @param {Buffer[]} list The array of buffers to concat
  1655. * @param {Number} totalLength The total length of buffers in the list
  1656. * @return {Buffer} The resulting buffer
  1657. * @public
  1658. */
  1659. function concat(list, totalLength) {
  1660. if (list.length === 0) return EMPTY_BUFFER;
  1661. if (list.length === 1) return list[0];
  1662. const target = Buffer.allocUnsafe(totalLength);
  1663. let offset = 0;
  1664. for (let i = 0; i < list.length; i++) {
  1665. const buf = list[i];
  1666. target.set(buf, offset);
  1667. offset += buf.length;
  1668. }
  1669. if (offset < totalLength) return target.slice(0, offset);
  1670. return target;
  1671. }
  1672. /**
  1673. * Masks a buffer using the given mask.
  1674. *
  1675. * @param {Buffer} source The buffer to mask
  1676. * @param {Buffer} mask The mask to use
  1677. * @param {Buffer} output The buffer where to store the result
  1678. * @param {Number} offset The offset at which to start writing
  1679. * @param {Number} length The number of bytes to mask.
  1680. * @public
  1681. */
  1682. function _mask(source, mask, output, offset, length) {
  1683. for (let i = 0; i < length; i++) {
  1684. output[offset + i] = source[i] ^ mask[i & 3];
  1685. }
  1686. }
  1687. /**
  1688. * Unmasks a buffer using the given mask.
  1689. *
  1690. * @param {Buffer} buffer The buffer to unmask
  1691. * @param {Buffer} mask The mask to use
  1692. * @public
  1693. */
  1694. function _unmask(buffer, mask) {
  1695. // Required until https://github.com/nodejs/node/issues/9006 is resolved.
  1696. const length = buffer.length;
  1697. for (let i = 0; i < length; i++) {
  1698. buffer[i] ^= mask[i & 3];
  1699. }
  1700. }
  1701. /**
  1702. * Converts a buffer to an `ArrayBuffer`.
  1703. *
  1704. * @param {Buffer} buf The buffer to convert
  1705. * @return {ArrayBuffer} Converted buffer
  1706. * @public
  1707. */
  1708. function toArrayBuffer(buf) {
  1709. if (buf.byteLength === buf.buffer.byteLength) {
  1710. return buf.buffer;
  1711. }
  1712. return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
  1713. }
  1714. /**
  1715. * Converts `data` to a `Buffer`.
  1716. *
  1717. * @param {*} data The data to convert
  1718. * @return {Buffer} The buffer
  1719. * @throws {TypeError}
  1720. * @public
  1721. */
  1722. function toBuffer(data) {
  1723. toBuffer.readOnly = true;
  1724. if (Buffer.isBuffer(data)) return data;
  1725. let buf;
  1726. if (data instanceof ArrayBuffer) {
  1727. buf = Buffer.from(data);
  1728. } else if (ArrayBuffer.isView(data)) {
  1729. buf = Buffer.from(data.buffer, data.byteOffset, data.byteLength);
  1730. } else {
  1731. buf = Buffer.from(data);
  1732. toBuffer.readOnly = false;
  1733. }
  1734. return buf;
  1735. }
  1736. try {
  1737. const bufferUtil = require('bufferutil');
  1738. const bu = bufferUtil.BufferUtil || bufferUtil;
  1739. module.exports = {
  1740. concat,
  1741. mask(source, mask, output, offset, length) {
  1742. if (length < 48) _mask(source, mask, output, offset, length);
  1743. else bu.mask(source, mask, output, offset, length);
  1744. },
  1745. toArrayBuffer,
  1746. toBuffer,
  1747. unmask(buffer, mask) {
  1748. if (buffer.length < 32) _unmask(buffer, mask);
  1749. else bu.unmask(buffer, mask);
  1750. }
  1751. };
  1752. } catch (e) /* istanbul ignore next */ {
  1753. module.exports = {
  1754. concat,
  1755. mask: _mask,
  1756. toArrayBuffer,
  1757. toBuffer,
  1758. unmask: _unmask
  1759. };
  1760. }
  1761. }, function(modId) { var map = {"./constants":1682324647598}; return __REQUIRE__(map[modId], modId); })
  1762. __DEFINE__(1682324647598, function(require, module, exports) {
  1763. module.exports = {
  1764. BINARY_TYPES: ['nodebuffer', 'arraybuffer', 'fragments'],
  1765. GUID: '258EAFA5-E914-47DA-95CA-C5AB0DC85B11',
  1766. kStatusCode: Symbol('status-code'),
  1767. kWebSocket: Symbol('websocket'),
  1768. EMPTY_BUFFER: Buffer.alloc(0),
  1769. NOOP: () => {}
  1770. };
  1771. }, function(modId) { var map = {}; return __REQUIRE__(map[modId], modId); })
  1772. __DEFINE__(1682324647599, function(require, module, exports) {
  1773. const kDone = Symbol('kDone');
  1774. const kRun = Symbol('kRun');
  1775. /**
  1776. * A very simple job queue with adjustable concurrency. Adapted from
  1777. * https://github.com/STRML/async-limiter
  1778. */
  1779. class Limiter {
  1780. /**
  1781. * Creates a new `Limiter`.
  1782. *
  1783. * @param {Number} [concurrency=Infinity] The maximum number of jobs allowed
  1784. * to run concurrently
  1785. */
  1786. constructor(concurrency) {
  1787. this[kDone] = () => {
  1788. this.pending--;
  1789. this[kRun]();
  1790. };
  1791. this.concurrency = concurrency || Infinity;
  1792. this.jobs = [];
  1793. this.pending = 0;
  1794. }
  1795. /**
  1796. * Adds a job to the queue.
  1797. *
  1798. * @param {Function} job The job to run
  1799. * @public
  1800. */
  1801. add(job) {
  1802. this.jobs.push(job);
  1803. this[kRun]();
  1804. }
  1805. /**
  1806. * Removes a job from the queue and runs it if possible.
  1807. *
  1808. * @private
  1809. */
  1810. [kRun]() {
  1811. if (this.pending === this.concurrency) return;
  1812. if (this.jobs.length) {
  1813. const job = this.jobs.shift();
  1814. this.pending++;
  1815. job(this[kDone]);
  1816. }
  1817. }
  1818. }
  1819. module.exports = Limiter;
  1820. }, function(modId) { var map = {}; return __REQUIRE__(map[modId], modId); })
  1821. __DEFINE__(1682324647600, function(require, module, exports) {
  1822. const { Writable } = require('stream');
  1823. const PerMessageDeflate = require('./permessage-deflate');
  1824. const {
  1825. BINARY_TYPES,
  1826. EMPTY_BUFFER,
  1827. kStatusCode,
  1828. kWebSocket
  1829. } = require('./constants');
  1830. const { concat, toArrayBuffer, unmask } = require('./buffer-util');
  1831. const { isValidStatusCode, isValidUTF8 } = require('./validation');
  1832. const GET_INFO = 0;
  1833. const GET_PAYLOAD_LENGTH_16 = 1;
  1834. const GET_PAYLOAD_LENGTH_64 = 2;
  1835. const GET_MASK = 3;
  1836. const GET_DATA = 4;
  1837. const INFLATING = 5;
  1838. /**
  1839. * HyBi Receiver implementation.
  1840. *
  1841. * @extends Writable
  1842. */
  1843. class Receiver extends Writable {
  1844. /**
  1845. * Creates a Receiver instance.
  1846. *
  1847. * @param {String} [binaryType=nodebuffer] The type for binary data
  1848. * @param {Object} [extensions] An object containing the negotiated extensions
  1849. * @param {Boolean} [isServer=false] Specifies whether to operate in client or
  1850. * server mode
  1851. * @param {Number} [maxPayload=0] The maximum allowed message length
  1852. */
  1853. constructor(binaryType, extensions, isServer, maxPayload) {
  1854. super();
  1855. this._binaryType = binaryType || BINARY_TYPES[0];
  1856. this[kWebSocket] = undefined;
  1857. this._extensions = extensions || {};
  1858. this._isServer = !!isServer;
  1859. this._maxPayload = maxPayload | 0;
  1860. this._bufferedBytes = 0;
  1861. this._buffers = [];
  1862. this._compressed = false;
  1863. this._payloadLength = 0;
  1864. this._mask = undefined;
  1865. this._fragmented = 0;
  1866. this._masked = false;
  1867. this._fin = false;
  1868. this._opcode = 0;
  1869. this._totalPayloadLength = 0;
  1870. this._messageLength = 0;
  1871. this._fragments = [];
  1872. this._state = GET_INFO;
  1873. this._loop = false;
  1874. }
  1875. /**
  1876. * Implements `Writable.prototype._write()`.
  1877. *
  1878. * @param {Buffer} chunk The chunk of data to write
  1879. * @param {String} encoding The character encoding of `chunk`
  1880. * @param {Function} cb Callback
  1881. * @private
  1882. */
  1883. _write(chunk, encoding, cb) {
  1884. if (this._opcode === 0x08 && this._state == GET_INFO) return cb();
  1885. this._bufferedBytes += chunk.length;
  1886. this._buffers.push(chunk);
  1887. this.startLoop(cb);
  1888. }
  1889. /**
  1890. * Consumes `n` bytes from the buffered data.
  1891. *
  1892. * @param {Number} n The number of bytes to consume
  1893. * @return {Buffer} The consumed bytes
  1894. * @private
  1895. */
  1896. consume(n) {
  1897. this._bufferedBytes -= n;
  1898. if (n === this._buffers[0].length) return this._buffers.shift();
  1899. if (n < this._buffers[0].length) {
  1900. const buf = this._buffers[0];
  1901. this._buffers[0] = buf.slice(n);
  1902. return buf.slice(0, n);
  1903. }
  1904. const dst = Buffer.allocUnsafe(n);
  1905. do {
  1906. const buf = this._buffers[0];
  1907. const offset = dst.length - n;
  1908. if (n >= buf.length) {
  1909. dst.set(this._buffers.shift(), offset);
  1910. } else {
  1911. dst.set(new Uint8Array(buf.buffer, buf.byteOffset, n), offset);
  1912. this._buffers[0] = buf.slice(n);
  1913. }
  1914. n -= buf.length;
  1915. } while (n > 0);
  1916. return dst;
  1917. }
  1918. /**
  1919. * Starts the parsing loop.
  1920. *
  1921. * @param {Function} cb Callback
  1922. * @private
  1923. */
  1924. startLoop(cb) {
  1925. let err;
  1926. this._loop = true;
  1927. do {
  1928. switch (this._state) {
  1929. case GET_INFO:
  1930. err = this.getInfo();
  1931. break;
  1932. case GET_PAYLOAD_LENGTH_16:
  1933. err = this.getPayloadLength16();
  1934. break;
  1935. case GET_PAYLOAD_LENGTH_64:
  1936. err = this.getPayloadLength64();
  1937. break;
  1938. case GET_MASK:
  1939. this.getMask();
  1940. break;
  1941. case GET_DATA:
  1942. err = this.getData(cb);
  1943. break;
  1944. default:
  1945. // `INFLATING`
  1946. this._loop = false;
  1947. return;
  1948. }
  1949. } while (this._loop);
  1950. cb(err);
  1951. }
  1952. /**
  1953. * Reads the first two bytes of a frame.
  1954. *
  1955. * @return {(RangeError|undefined)} A possible error
  1956. * @private
  1957. */
  1958. getInfo() {
  1959. if (this._bufferedBytes < 2) {
  1960. this._loop = false;
  1961. return;
  1962. }
  1963. const buf = this.consume(2);
  1964. if ((buf[0] & 0x30) !== 0x00) {
  1965. this._loop = false;
  1966. return error(
  1967. RangeError,
  1968. 'RSV2 and RSV3 must be clear',
  1969. true,
  1970. 1002,
  1971. 'WS_ERR_UNEXPECTED_RSV_2_3'
  1972. );
  1973. }
  1974. const compressed = (buf[0] & 0x40) === 0x40;
  1975. if (compressed && !this._extensions[PerMessageDeflate.extensionName]) {
  1976. this._loop = false;
  1977. return error(
  1978. RangeError,
  1979. 'RSV1 must be clear',
  1980. true,
  1981. 1002,
  1982. 'WS_ERR_UNEXPECTED_RSV_1'
  1983. );
  1984. }
  1985. this._fin = (buf[0] & 0x80) === 0x80;
  1986. this._opcode = buf[0] & 0x0f;
  1987. this._payloadLength = buf[1] & 0x7f;
  1988. if (this._opcode === 0x00) {
  1989. if (compressed) {
  1990. this._loop = false;
  1991. return error(
  1992. RangeError,
  1993. 'RSV1 must be clear',
  1994. true,
  1995. 1002,
  1996. 'WS_ERR_UNEXPECTED_RSV_1'
  1997. );
  1998. }
  1999. if (!this._fragmented) {
  2000. this._loop = false;
  2001. return error(
  2002. RangeError,
  2003. 'invalid opcode 0',
  2004. true,
  2005. 1002,
  2006. 'WS_ERR_INVALID_OPCODE'
  2007. );
  2008. }
  2009. this._opcode = this._fragmented;
  2010. } else if (this._opcode === 0x01 || this._opcode === 0x02) {
  2011. if (this._fragmented) {
  2012. this._loop = false;
  2013. return error(
  2014. RangeError,
  2015. `invalid opcode ${this._opcode}`,
  2016. true,
  2017. 1002,
  2018. 'WS_ERR_INVALID_OPCODE'
  2019. );
  2020. }
  2021. this._compressed = compressed;
  2022. } else if (this._opcode > 0x07 && this._opcode < 0x0b) {
  2023. if (!this._fin) {
  2024. this._loop = false;
  2025. return error(
  2026. RangeError,
  2027. 'FIN must be set',
  2028. true,
  2029. 1002,
  2030. 'WS_ERR_EXPECTED_FIN'
  2031. );
  2032. }
  2033. if (compressed) {
  2034. this._loop = false;
  2035. return error(
  2036. RangeError,
  2037. 'RSV1 must be clear',
  2038. true,
  2039. 1002,
  2040. 'WS_ERR_UNEXPECTED_RSV_1'
  2041. );
  2042. }
  2043. if (this._payloadLength > 0x7d) {
  2044. this._loop = false;
  2045. return error(
  2046. RangeError,
  2047. `invalid payload length ${this._payloadLength}`,
  2048. true,
  2049. 1002,
  2050. 'WS_ERR_INVALID_CONTROL_PAYLOAD_LENGTH'
  2051. );
  2052. }
  2053. } else {
  2054. this._loop = false;
  2055. return error(
  2056. RangeError,
  2057. `invalid opcode ${this._opcode}`,
  2058. true,
  2059. 1002,
  2060. 'WS_ERR_INVALID_OPCODE'
  2061. );
  2062. }
  2063. if (!this._fin && !this._fragmented) this._fragmented = this._opcode;
  2064. this._masked = (buf[1] & 0x80) === 0x80;
  2065. if (this._isServer) {
  2066. if (!this._masked) {
  2067. this._loop = false;
  2068. return error(
  2069. RangeError,
  2070. 'MASK must be set',
  2071. true,
  2072. 1002,
  2073. 'WS_ERR_EXPECTED_MASK'
  2074. );
  2075. }
  2076. } else if (this._masked) {
  2077. this._loop = false;
  2078. return error(
  2079. RangeError,
  2080. 'MASK must be clear',
  2081. true,
  2082. 1002,
  2083. 'WS_ERR_UNEXPECTED_MASK'
  2084. );
  2085. }
  2086. if (this._payloadLength === 126) this._state = GET_PAYLOAD_LENGTH_16;
  2087. else if (this._payloadLength === 127) this._state = GET_PAYLOAD_LENGTH_64;
  2088. else return this.haveLength();
  2089. }
  2090. /**
  2091. * Gets extended payload length (7+16).
  2092. *
  2093. * @return {(RangeError|undefined)} A possible error
  2094. * @private
  2095. */
  2096. getPayloadLength16() {
  2097. if (this._bufferedBytes < 2) {
  2098. this._loop = false;
  2099. return;
  2100. }
  2101. this._payloadLength = this.consume(2).readUInt16BE(0);
  2102. return this.haveLength();
  2103. }
  2104. /**
  2105. * Gets extended payload length (7+64).
  2106. *
  2107. * @return {(RangeError|undefined)} A possible error
  2108. * @private
  2109. */
  2110. getPayloadLength64() {
  2111. if (this._bufferedBytes < 8) {
  2112. this._loop = false;
  2113. return;
  2114. }
  2115. const buf = this.consume(8);
  2116. const num = buf.readUInt32BE(0);
  2117. //
  2118. // The maximum safe integer in JavaScript is 2^53 - 1. An error is returned
  2119. // if payload length is greater than this number.
  2120. //
  2121. if (num > Math.pow(2, 53 - 32) - 1) {
  2122. this._loop = false;
  2123. return error(
  2124. RangeError,
  2125. 'Unsupported WebSocket frame: payload length > 2^53 - 1',
  2126. false,
  2127. 1009,
  2128. 'WS_ERR_UNSUPPORTED_DATA_PAYLOAD_LENGTH'
  2129. );
  2130. }
  2131. this._payloadLength = num * Math.pow(2, 32) + buf.readUInt32BE(4);
  2132. return this.haveLength();
  2133. }
  2134. /**
  2135. * Payload length has been read.
  2136. *
  2137. * @return {(RangeError|undefined)} A possible error
  2138. * @private
  2139. */
  2140. haveLength() {
  2141. if (this._payloadLength && this._opcode < 0x08) {
  2142. this._totalPayloadLength += this._payloadLength;
  2143. if (this._totalPayloadLength > this._maxPayload && this._maxPayload > 0) {
  2144. this._loop = false;
  2145. return error(
  2146. RangeError,
  2147. 'Max payload size exceeded',
  2148. false,
  2149. 1009,
  2150. 'WS_ERR_UNSUPPORTED_MESSAGE_LENGTH'
  2151. );
  2152. }
  2153. }
  2154. if (this._masked) this._state = GET_MASK;
  2155. else this._state = GET_DATA;
  2156. }
  2157. /**
  2158. * Reads mask bytes.
  2159. *
  2160. * @private
  2161. */
  2162. getMask() {
  2163. if (this._bufferedBytes < 4) {
  2164. this._loop = false;
  2165. return;
  2166. }
  2167. this._mask = this.consume(4);
  2168. this._state = GET_DATA;
  2169. }
  2170. /**
  2171. * Reads data bytes.
  2172. *
  2173. * @param {Function} cb Callback
  2174. * @return {(Error|RangeError|undefined)} A possible error
  2175. * @private
  2176. */
  2177. getData(cb) {
  2178. let data = EMPTY_BUFFER;
  2179. if (this._payloadLength) {
  2180. if (this._bufferedBytes < this._payloadLength) {
  2181. this._loop = false;
  2182. return;
  2183. }
  2184. data = this.consume(this._payloadLength);
  2185. if (this._masked) unmask(data, this._mask);
  2186. }
  2187. if (this._opcode > 0x07) return this.controlMessage(data);
  2188. if (this._compressed) {
  2189. this._state = INFLATING;
  2190. this.decompress(data, cb);
  2191. return;
  2192. }
  2193. if (data.length) {
  2194. //
  2195. // This message is not compressed so its lenght is the sum of the payload
  2196. // length of all fragments.
  2197. //
  2198. this._messageLength = this._totalPayloadLength;
  2199. this._fragments.push(data);
  2200. }
  2201. return this.dataMessage();
  2202. }
  2203. /**
  2204. * Decompresses data.
  2205. *
  2206. * @param {Buffer} data Compressed data
  2207. * @param {Function} cb Callback
  2208. * @private
  2209. */
  2210. decompress(data, cb) {
  2211. const perMessageDeflate = this._extensions[PerMessageDeflate.extensionName];
  2212. perMessageDeflate.decompress(data, this._fin, (err, buf) => {
  2213. if (err) return cb(err);
  2214. if (buf.length) {
  2215. this._messageLength += buf.length;
  2216. if (this._messageLength > this._maxPayload && this._maxPayload > 0) {
  2217. return cb(
  2218. error(
  2219. RangeError,
  2220. 'Max payload size exceeded',
  2221. false,
  2222. 1009,
  2223. 'WS_ERR_UNSUPPORTED_MESSAGE_LENGTH'
  2224. )
  2225. );
  2226. }
  2227. this._fragments.push(buf);
  2228. }
  2229. const er = this.dataMessage();
  2230. if (er) return cb(er);
  2231. this.startLoop(cb);
  2232. });
  2233. }
  2234. /**
  2235. * Handles a data message.
  2236. *
  2237. * @return {(Error|undefined)} A possible error
  2238. * @private
  2239. */
  2240. dataMessage() {
  2241. if (this._fin) {
  2242. const messageLength = this._messageLength;
  2243. const fragments = this._fragments;
  2244. this._totalPayloadLength = 0;
  2245. this._messageLength = 0;
  2246. this._fragmented = 0;
  2247. this._fragments = [];
  2248. if (this._opcode === 2) {
  2249. let data;
  2250. if (this._binaryType === 'nodebuffer') {
  2251. data = concat(fragments, messageLength);
  2252. } else if (this._binaryType === 'arraybuffer') {
  2253. data = toArrayBuffer(concat(fragments, messageLength));
  2254. } else {
  2255. data = fragments;
  2256. }
  2257. this.emit('message', data);
  2258. } else {
  2259. const buf = concat(fragments, messageLength);
  2260. if (!isValidUTF8(buf)) {
  2261. this._loop = false;
  2262. return error(
  2263. Error,
  2264. 'invalid UTF-8 sequence',
  2265. true,
  2266. 1007,
  2267. 'WS_ERR_INVALID_UTF8'
  2268. );
  2269. }
  2270. this.emit('message', buf.toString());
  2271. }
  2272. }
  2273. this._state = GET_INFO;
  2274. }
  2275. /**
  2276. * Handles a control message.
  2277. *
  2278. * @param {Buffer} data Data to handle
  2279. * @return {(Error|RangeError|undefined)} A possible error
  2280. * @private
  2281. */
  2282. controlMessage(data) {
  2283. if (this._opcode === 0x08) {
  2284. this._loop = false;
  2285. if (data.length === 0) {
  2286. this.emit('conclude', 1005, '');
  2287. this.end();
  2288. } else if (data.length === 1) {
  2289. return error(
  2290. RangeError,
  2291. 'invalid payload length 1',
  2292. true,
  2293. 1002,
  2294. 'WS_ERR_INVALID_CONTROL_PAYLOAD_LENGTH'
  2295. );
  2296. } else {
  2297. const code = data.readUInt16BE(0);
  2298. if (!isValidStatusCode(code)) {
  2299. return error(
  2300. RangeError,
  2301. `invalid status code ${code}`,
  2302. true,
  2303. 1002,
  2304. 'WS_ERR_INVALID_CLOSE_CODE'
  2305. );
  2306. }
  2307. const buf = data.slice(2);
  2308. if (!isValidUTF8(buf)) {
  2309. return error(
  2310. Error,
  2311. 'invalid UTF-8 sequence',
  2312. true,
  2313. 1007,
  2314. 'WS_ERR_INVALID_UTF8'
  2315. );
  2316. }
  2317. this.emit('conclude', code, buf.toString());
  2318. this.end();
  2319. }
  2320. } else if (this._opcode === 0x09) {
  2321. this.emit('ping', data);
  2322. } else {
  2323. this.emit('pong', data);
  2324. }
  2325. this._state = GET_INFO;
  2326. }
  2327. }
  2328. module.exports = Receiver;
  2329. /**
  2330. * Builds an error object.
  2331. *
  2332. * @param {function(new:Error|RangeError)} ErrorCtor The error constructor
  2333. * @param {String} message The error message
  2334. * @param {Boolean} prefix Specifies whether or not to add a default prefix to
  2335. * `message`
  2336. * @param {Number} statusCode The status code
  2337. * @param {String} errorCode The exposed error code
  2338. * @return {(Error|RangeError)} The error
  2339. * @private
  2340. */
  2341. function error(ErrorCtor, message, prefix, statusCode, errorCode) {
  2342. const err = new ErrorCtor(
  2343. prefix ? `Invalid WebSocket frame: ${message}` : message
  2344. );
  2345. Error.captureStackTrace(err, error);
  2346. err.code = errorCode;
  2347. err[kStatusCode] = statusCode;
  2348. return err;
  2349. }
  2350. }, function(modId) { var map = {"stream":1682324647595,"./permessage-deflate":1682324647596,"./constants":1682324647598,"./buffer-util":1682324647597,"./validation":1682324647601}; return __REQUIRE__(map[modId], modId); })
  2351. __DEFINE__(1682324647601, function(require, module, exports) {
  2352. /**
  2353. * Checks if a status code is allowed in a close frame.
  2354. *
  2355. * @param {Number} code The status code
  2356. * @return {Boolean} `true` if the status code is valid, else `false`
  2357. * @public
  2358. */
  2359. function isValidStatusCode(code) {
  2360. return (
  2361. (code >= 1000 &&
  2362. code <= 1014 &&
  2363. code !== 1004 &&
  2364. code !== 1005 &&
  2365. code !== 1006) ||
  2366. (code >= 3000 && code <= 4999)
  2367. );
  2368. }
  2369. /**
  2370. * Checks if a given buffer contains only correct UTF-8.
  2371. * Ported from https://www.cl.cam.ac.uk/%7Emgk25/ucs/utf8_check.c by
  2372. * Markus Kuhn.
  2373. *
  2374. * @param {Buffer} buf The buffer to check
  2375. * @return {Boolean} `true` if `buf` contains only correct UTF-8, else `false`
  2376. * @public
  2377. */
  2378. function _isValidUTF8(buf) {
  2379. const len = buf.length;
  2380. let i = 0;
  2381. while (i < len) {
  2382. if ((buf[i] & 0x80) === 0) {
  2383. // 0xxxxxxx
  2384. i++;
  2385. } else if ((buf[i] & 0xe0) === 0xc0) {
  2386. // 110xxxxx 10xxxxxx
  2387. if (
  2388. i + 1 === len ||
  2389. (buf[i + 1] & 0xc0) !== 0x80 ||
  2390. (buf[i] & 0xfe) === 0xc0 // Overlong
  2391. ) {
  2392. return false;
  2393. }
  2394. i += 2;
  2395. } else if ((buf[i] & 0xf0) === 0xe0) {
  2396. // 1110xxxx 10xxxxxx 10xxxxxx
  2397. if (
  2398. i + 2 >= len ||
  2399. (buf[i + 1] & 0xc0) !== 0x80 ||
  2400. (buf[i + 2] & 0xc0) !== 0x80 ||
  2401. (buf[i] === 0xe0 && (buf[i + 1] & 0xe0) === 0x80) || // Overlong
  2402. (buf[i] === 0xed && (buf[i + 1] & 0xe0) === 0xa0) // Surrogate (U+D800 - U+DFFF)
  2403. ) {
  2404. return false;
  2405. }
  2406. i += 3;
  2407. } else if ((buf[i] & 0xf8) === 0xf0) {
  2408. // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
  2409. if (
  2410. i + 3 >= len ||
  2411. (buf[i + 1] & 0xc0) !== 0x80 ||
  2412. (buf[i + 2] & 0xc0) !== 0x80 ||
  2413. (buf[i + 3] & 0xc0) !== 0x80 ||
  2414. (buf[i] === 0xf0 && (buf[i + 1] & 0xf0) === 0x80) || // Overlong
  2415. (buf[i] === 0xf4 && buf[i + 1] > 0x8f) ||
  2416. buf[i] > 0xf4 // > U+10FFFF
  2417. ) {
  2418. return false;
  2419. }
  2420. i += 4;
  2421. } else {
  2422. return false;
  2423. }
  2424. }
  2425. return true;
  2426. }
  2427. try {
  2428. let isValidUTF8 = require('utf-8-validate');
  2429. /* istanbul ignore if */
  2430. if (typeof isValidUTF8 === 'object') {
  2431. isValidUTF8 = isValidUTF8.Validation.isValidUTF8; // utf-8-validate@<3.0.0
  2432. }
  2433. module.exports = {
  2434. isValidStatusCode,
  2435. isValidUTF8(buf) {
  2436. return buf.length < 150 ? _isValidUTF8(buf) : isValidUTF8(buf);
  2437. }
  2438. };
  2439. } catch (e) /* istanbul ignore next */ {
  2440. module.exports = {
  2441. isValidStatusCode,
  2442. isValidUTF8: _isValidUTF8
  2443. };
  2444. }
  2445. }, function(modId) { var map = {}; return __REQUIRE__(map[modId], modId); })
  2446. __DEFINE__(1682324647602, function(require, module, exports) {
  2447. /* eslint no-unused-vars: ["error", { "varsIgnorePattern": "^net|tls$" }] */
  2448. const net = require('net');
  2449. const tls = require('tls');
  2450. const { randomFillSync } = require('crypto');
  2451. const PerMessageDeflate = require('./permessage-deflate');
  2452. const { EMPTY_BUFFER } = require('./constants');
  2453. const { isValidStatusCode } = require('./validation');
  2454. const { mask: applyMask, toBuffer } = require('./buffer-util');
  2455. const mask = Buffer.alloc(4);
  2456. /**
  2457. * HyBi Sender implementation.
  2458. */
  2459. class Sender {
  2460. /**
  2461. * Creates a Sender instance.
  2462. *
  2463. * @param {(net.Socket|tls.Socket)} socket The connection socket
  2464. * @param {Object} [extensions] An object containing the negotiated extensions
  2465. */
  2466. constructor(socket, extensions) {
  2467. this._extensions = extensions || {};
  2468. this._socket = socket;
  2469. this._firstFragment = true;
  2470. this._compress = false;
  2471. this._bufferedBytes = 0;
  2472. this._deflating = false;
  2473. this._queue = [];
  2474. }
  2475. /**
  2476. * Frames a piece of data according to the HyBi WebSocket protocol.
  2477. *
  2478. * @param {Buffer} data The data to frame
  2479. * @param {Object} options Options object
  2480. * @param {Number} options.opcode The opcode
  2481. * @param {Boolean} [options.readOnly=false] Specifies whether `data` can be
  2482. * modified
  2483. * @param {Boolean} [options.fin=false] Specifies whether or not to set the
  2484. * FIN bit
  2485. * @param {Boolean} [options.mask=false] Specifies whether or not to mask
  2486. * `data`
  2487. * @param {Boolean} [options.rsv1=false] Specifies whether or not to set the
  2488. * RSV1 bit
  2489. * @return {Buffer[]} The framed data as a list of `Buffer` instances
  2490. * @public
  2491. */
  2492. static frame(data, options) {
  2493. const merge = options.mask && options.readOnly;
  2494. let offset = options.mask ? 6 : 2;
  2495. let payloadLength = data.length;
  2496. if (data.length >= 65536) {
  2497. offset += 8;
  2498. payloadLength = 127;
  2499. } else if (data.length > 125) {
  2500. offset += 2;
  2501. payloadLength = 126;
  2502. }
  2503. const target = Buffer.allocUnsafe(merge ? data.length + offset : offset);
  2504. target[0] = options.fin ? options.opcode | 0x80 : options.opcode;
  2505. if (options.rsv1) target[0] |= 0x40;
  2506. target[1] = payloadLength;
  2507. if (payloadLength === 126) {
  2508. target.writeUInt16BE(data.length, 2);
  2509. } else if (payloadLength === 127) {
  2510. target.writeUInt32BE(0, 2);
  2511. target.writeUInt32BE(data.length, 6);
  2512. }
  2513. if (!options.mask) return [target, data];
  2514. randomFillSync(mask, 0, 4);
  2515. target[1] |= 0x80;
  2516. target[offset - 4] = mask[0];
  2517. target[offset - 3] = mask[1];
  2518. target[offset - 2] = mask[2];
  2519. target[offset - 1] = mask[3];
  2520. if (merge) {
  2521. applyMask(data, mask, target, offset, data.length);
  2522. return [target];
  2523. }
  2524. applyMask(data, mask, data, 0, data.length);
  2525. return [target, data];
  2526. }
  2527. /**
  2528. * Sends a close message to the other peer.
  2529. *
  2530. * @param {Number} [code] The status code component of the body
  2531. * @param {String} [data] The message component of the body
  2532. * @param {Boolean} [mask=false] Specifies whether or not to mask the message
  2533. * @param {Function} [cb] Callback
  2534. * @public
  2535. */
  2536. close(code, data, mask, cb) {
  2537. let buf;
  2538. if (code === undefined) {
  2539. buf = EMPTY_BUFFER;
  2540. } else if (typeof code !== 'number' || !isValidStatusCode(code)) {
  2541. throw new TypeError('First argument must be a valid error code number');
  2542. } else if (data === undefined || data === '') {
  2543. buf = Buffer.allocUnsafe(2);
  2544. buf.writeUInt16BE(code, 0);
  2545. } else {
  2546. const length = Buffer.byteLength(data);
  2547. if (length > 123) {
  2548. throw new RangeError('The message must not be greater than 123 bytes');
  2549. }
  2550. buf = Buffer.allocUnsafe(2 + length);
  2551. buf.writeUInt16BE(code, 0);
  2552. buf.write(data, 2);
  2553. }
  2554. if (this._deflating) {
  2555. this.enqueue([this.doClose, buf, mask, cb]);
  2556. } else {
  2557. this.doClose(buf, mask, cb);
  2558. }
  2559. }
  2560. /**
  2561. * Frames and sends a close message.
  2562. *
  2563. * @param {Buffer} data The message to send
  2564. * @param {Boolean} [mask=false] Specifies whether or not to mask `data`
  2565. * @param {Function} [cb] Callback
  2566. * @private
  2567. */
  2568. doClose(data, mask, cb) {
  2569. this.sendFrame(
  2570. Sender.frame(data, {
  2571. fin: true,
  2572. rsv1: false,
  2573. opcode: 0x08,
  2574. mask,
  2575. readOnly: false
  2576. }),
  2577. cb
  2578. );
  2579. }
  2580. /**
  2581. * Sends a ping message to the other peer.
  2582. *
  2583. * @param {*} data The message to send
  2584. * @param {Boolean} [mask=false] Specifies whether or not to mask `data`
  2585. * @param {Function} [cb] Callback
  2586. * @public
  2587. */
  2588. ping(data, mask, cb) {
  2589. const buf = toBuffer(data);
  2590. if (buf.length > 125) {
  2591. throw new RangeError('The data size must not be greater than 125 bytes');
  2592. }
  2593. if (this._deflating) {
  2594. this.enqueue([this.doPing, buf, mask, toBuffer.readOnly, cb]);
  2595. } else {
  2596. this.doPing(buf, mask, toBuffer.readOnly, cb);
  2597. }
  2598. }
  2599. /**
  2600. * Frames and sends a ping message.
  2601. *
  2602. * @param {Buffer} data The message to send
  2603. * @param {Boolean} [mask=false] Specifies whether or not to mask `data`
  2604. * @param {Boolean} [readOnly=false] Specifies whether `data` can be modified
  2605. * @param {Function} [cb] Callback
  2606. * @private
  2607. */
  2608. doPing(data, mask, readOnly, cb) {
  2609. this.sendFrame(
  2610. Sender.frame(data, {
  2611. fin: true,
  2612. rsv1: false,
  2613. opcode: 0x09,
  2614. mask,
  2615. readOnly
  2616. }),
  2617. cb
  2618. );
  2619. }
  2620. /**
  2621. * Sends a pong message to the other peer.
  2622. *
  2623. * @param {*} data The message to send
  2624. * @param {Boolean} [mask=false] Specifies whether or not to mask `data`
  2625. * @param {Function} [cb] Callback
  2626. * @public
  2627. */
  2628. pong(data, mask, cb) {
  2629. const buf = toBuffer(data);
  2630. if (buf.length > 125) {
  2631. throw new RangeError('The data size must not be greater than 125 bytes');
  2632. }
  2633. if (this._deflating) {
  2634. this.enqueue([this.doPong, buf, mask, toBuffer.readOnly, cb]);
  2635. } else {
  2636. this.doPong(buf, mask, toBuffer.readOnly, cb);
  2637. }
  2638. }
  2639. /**
  2640. * Frames and sends a pong message.
  2641. *
  2642. * @param {Buffer} data The message to send
  2643. * @param {Boolean} [mask=false] Specifies whether or not to mask `data`
  2644. * @param {Boolean} [readOnly=false] Specifies whether `data` can be modified
  2645. * @param {Function} [cb] Callback
  2646. * @private
  2647. */
  2648. doPong(data, mask, readOnly, cb) {
  2649. this.sendFrame(
  2650. Sender.frame(data, {
  2651. fin: true,
  2652. rsv1: false,
  2653. opcode: 0x0a,
  2654. mask,
  2655. readOnly
  2656. }),
  2657. cb
  2658. );
  2659. }
  2660. /**
  2661. * Sends a data message to the other peer.
  2662. *
  2663. * @param {*} data The message to send
  2664. * @param {Object} options Options object
  2665. * @param {Boolean} [options.compress=false] Specifies whether or not to
  2666. * compress `data`
  2667. * @param {Boolean} [options.binary=false] Specifies whether `data` is binary
  2668. * or text
  2669. * @param {Boolean} [options.fin=false] Specifies whether the fragment is the
  2670. * last one
  2671. * @param {Boolean} [options.mask=false] Specifies whether or not to mask
  2672. * `data`
  2673. * @param {Function} [cb] Callback
  2674. * @public
  2675. */
  2676. send(data, options, cb) {
  2677. const buf = toBuffer(data);
  2678. const perMessageDeflate = this._extensions[PerMessageDeflate.extensionName];
  2679. let opcode = options.binary ? 2 : 1;
  2680. let rsv1 = options.compress;
  2681. if (this._firstFragment) {
  2682. this._firstFragment = false;
  2683. if (rsv1 && perMessageDeflate) {
  2684. rsv1 = buf.length >= perMessageDeflate._threshold;
  2685. }
  2686. this._compress = rsv1;
  2687. } else {
  2688. rsv1 = false;
  2689. opcode = 0;
  2690. }
  2691. if (options.fin) this._firstFragment = true;
  2692. if (perMessageDeflate) {
  2693. const opts = {
  2694. fin: options.fin,
  2695. rsv1,
  2696. opcode,
  2697. mask: options.mask,
  2698. readOnly: toBuffer.readOnly
  2699. };
  2700. if (this._deflating) {
  2701. this.enqueue([this.dispatch, buf, this._compress, opts, cb]);
  2702. } else {
  2703. this.dispatch(buf, this._compress, opts, cb);
  2704. }
  2705. } else {
  2706. this.sendFrame(
  2707. Sender.frame(buf, {
  2708. fin: options.fin,
  2709. rsv1: false,
  2710. opcode,
  2711. mask: options.mask,
  2712. readOnly: toBuffer.readOnly
  2713. }),
  2714. cb
  2715. );
  2716. }
  2717. }
  2718. /**
  2719. * Dispatches a data message.
  2720. *
  2721. * @param {Buffer} data The message to send
  2722. * @param {Boolean} [compress=false] Specifies whether or not to compress
  2723. * `data`
  2724. * @param {Object} options Options object
  2725. * @param {Number} options.opcode The opcode
  2726. * @param {Boolean} [options.readOnly=false] Specifies whether `data` can be
  2727. * modified
  2728. * @param {Boolean} [options.fin=false] Specifies whether or not to set the
  2729. * FIN bit
  2730. * @param {Boolean} [options.mask=false] Specifies whether or not to mask
  2731. * `data`
  2732. * @param {Boolean} [options.rsv1=false] Specifies whether or not to set the
  2733. * RSV1 bit
  2734. * @param {Function} [cb] Callback
  2735. * @private
  2736. */
  2737. dispatch(data, compress, options, cb) {
  2738. if (!compress) {
  2739. this.sendFrame(Sender.frame(data, options), cb);
  2740. return;
  2741. }
  2742. const perMessageDeflate = this._extensions[PerMessageDeflate.extensionName];
  2743. this._bufferedBytes += data.length;
  2744. this._deflating = true;
  2745. perMessageDeflate.compress(data, options.fin, (_, buf) => {
  2746. if (this._socket.destroyed) {
  2747. const err = new Error(
  2748. 'The socket was closed while data was being compressed'
  2749. );
  2750. if (typeof cb === 'function') cb(err);
  2751. for (let i = 0; i < this._queue.length; i++) {
  2752. const callback = this._queue[i][4];
  2753. if (typeof callback === 'function') callback(err);
  2754. }
  2755. return;
  2756. }
  2757. this._bufferedBytes -= data.length;
  2758. this._deflating = false;
  2759. options.readOnly = false;
  2760. this.sendFrame(Sender.frame(buf, options), cb);
  2761. this.dequeue();
  2762. });
  2763. }
  2764. /**
  2765. * Executes queued send operations.
  2766. *
  2767. * @private
  2768. */
  2769. dequeue() {
  2770. while (!this._deflating && this._queue.length) {
  2771. const params = this._queue.shift();
  2772. this._bufferedBytes -= params[1].length;
  2773. Reflect.apply(params[0], this, params.slice(1));
  2774. }
  2775. }
  2776. /**
  2777. * Enqueues a send operation.
  2778. *
  2779. * @param {Array} params Send operation parameters.
  2780. * @private
  2781. */
  2782. enqueue(params) {
  2783. this._bufferedBytes += params[1].length;
  2784. this._queue.push(params);
  2785. }
  2786. /**
  2787. * Sends a frame.
  2788. *
  2789. * @param {Buffer[]} list The frame to send
  2790. * @param {Function} [cb] Callback
  2791. * @private
  2792. */
  2793. sendFrame(list, cb) {
  2794. if (list.length === 2) {
  2795. this._socket.cork();
  2796. this._socket.write(list[0]);
  2797. this._socket.write(list[1], cb);
  2798. this._socket.uncork();
  2799. } else {
  2800. this._socket.write(list[0], cb);
  2801. }
  2802. }
  2803. }
  2804. module.exports = Sender;
  2805. }, function(modId) { var map = {"./permessage-deflate":1682324647596,"./constants":1682324647598,"./validation":1682324647601,"./buffer-util":1682324647597}; return __REQUIRE__(map[modId], modId); })
  2806. __DEFINE__(1682324647603, function(require, module, exports) {
  2807. /**
  2808. * Class representing an event.
  2809. *
  2810. * @private
  2811. */
  2812. class Event {
  2813. /**
  2814. * Create a new `Event`.
  2815. *
  2816. * @param {String} type The name of the event
  2817. * @param {Object} target A reference to the target to which the event was
  2818. * dispatched
  2819. */
  2820. constructor(type, target) {
  2821. this.target = target;
  2822. this.type = type;
  2823. }
  2824. }
  2825. /**
  2826. * Class representing a message event.
  2827. *
  2828. * @extends Event
  2829. * @private
  2830. */
  2831. class MessageEvent extends Event {
  2832. /**
  2833. * Create a new `MessageEvent`.
  2834. *
  2835. * @param {(String|Buffer|ArrayBuffer|Buffer[])} data The received data
  2836. * @param {WebSocket} target A reference to the target to which the event was
  2837. * dispatched
  2838. */
  2839. constructor(data, target) {
  2840. super('message', target);
  2841. this.data = data;
  2842. }
  2843. }
  2844. /**
  2845. * Class representing a close event.
  2846. *
  2847. * @extends Event
  2848. * @private
  2849. */
  2850. class CloseEvent extends Event {
  2851. /**
  2852. * Create a new `CloseEvent`.
  2853. *
  2854. * @param {Number} code The status code explaining why the connection is being
  2855. * closed
  2856. * @param {String} reason A human-readable string explaining why the
  2857. * connection is closing
  2858. * @param {WebSocket} target A reference to the target to which the event was
  2859. * dispatched
  2860. */
  2861. constructor(code, reason, target) {
  2862. super('close', target);
  2863. this.wasClean = target._closeFrameReceived && target._closeFrameSent;
  2864. this.reason = reason;
  2865. this.code = code;
  2866. }
  2867. }
  2868. /**
  2869. * Class representing an open event.
  2870. *
  2871. * @extends Event
  2872. * @private
  2873. */
  2874. class OpenEvent extends Event {
  2875. /**
  2876. * Create a new `OpenEvent`.
  2877. *
  2878. * @param {WebSocket} target A reference to the target to which the event was
  2879. * dispatched
  2880. */
  2881. constructor(target) {
  2882. super('open', target);
  2883. }
  2884. }
  2885. /**
  2886. * Class representing an error event.
  2887. *
  2888. * @extends Event
  2889. * @private
  2890. */
  2891. class ErrorEvent extends Event {
  2892. /**
  2893. * Create a new `ErrorEvent`.
  2894. *
  2895. * @param {Object} error The error that generated this event
  2896. * @param {WebSocket} target A reference to the target to which the event was
  2897. * dispatched
  2898. */
  2899. constructor(error, target) {
  2900. super('error', target);
  2901. this.message = error.message;
  2902. this.error = error;
  2903. }
  2904. }
  2905. /**
  2906. * This provides methods for emulating the `EventTarget` interface. It's not
  2907. * meant to be used directly.
  2908. *
  2909. * @mixin
  2910. */
  2911. const EventTarget = {
  2912. /**
  2913. * Register an event listener.
  2914. *
  2915. * @param {String} type A string representing the event type to listen for
  2916. * @param {Function} listener The listener to add
  2917. * @param {Object} [options] An options object specifies characteristics about
  2918. * the event listener
  2919. * @param {Boolean} [options.once=false] A `Boolean`` indicating that the
  2920. * listener should be invoked at most once after being added. If `true`,
  2921. * the listener would be automatically removed when invoked.
  2922. * @public
  2923. */
  2924. addEventListener(type, listener, options) {
  2925. if (typeof listener !== 'function') return;
  2926. function onMessage(data) {
  2927. listener.call(this, new MessageEvent(data, this));
  2928. }
  2929. function onClose(code, message) {
  2930. listener.call(this, new CloseEvent(code, message, this));
  2931. }
  2932. function onError(error) {
  2933. listener.call(this, new ErrorEvent(error, this));
  2934. }
  2935. function onOpen() {
  2936. listener.call(this, new OpenEvent(this));
  2937. }
  2938. const method = options && options.once ? 'once' : 'on';
  2939. if (type === 'message') {
  2940. onMessage._listener = listener;
  2941. this[method](type, onMessage);
  2942. } else if (type === 'close') {
  2943. onClose._listener = listener;
  2944. this[method](type, onClose);
  2945. } else if (type === 'error') {
  2946. onError._listener = listener;
  2947. this[method](type, onError);
  2948. } else if (type === 'open') {
  2949. onOpen._listener = listener;
  2950. this[method](type, onOpen);
  2951. } else {
  2952. this[method](type, listener);
  2953. }
  2954. },
  2955. /**
  2956. * Remove an event listener.
  2957. *
  2958. * @param {String} type A string representing the event type to remove
  2959. * @param {Function} listener The listener to remove
  2960. * @public
  2961. */
  2962. removeEventListener(type, listener) {
  2963. const listeners = this.listeners(type);
  2964. for (let i = 0; i < listeners.length; i++) {
  2965. if (listeners[i] === listener || listeners[i]._listener === listener) {
  2966. this.removeListener(type, listeners[i]);
  2967. }
  2968. }
  2969. }
  2970. };
  2971. module.exports = EventTarget;
  2972. }, function(modId) { var map = {}; return __REQUIRE__(map[modId], modId); })
  2973. __DEFINE__(1682324647604, function(require, module, exports) {
  2974. //
  2975. // Allowed token characters:
  2976. //
  2977. // '!', '#', '$', '%', '&', ''', '*', '+', '-',
  2978. // '.', 0-9, A-Z, '^', '_', '`', a-z, '|', '~'
  2979. //
  2980. // tokenChars[32] === 0 // ' '
  2981. // tokenChars[33] === 1 // '!'
  2982. // tokenChars[34] === 0 // '"'
  2983. // ...
  2984. //
  2985. // prettier-ignore
  2986. const tokenChars = [
  2987. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0 - 15
  2988. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16 - 31
  2989. 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, // 32 - 47
  2990. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, // 48 - 63
  2991. 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 64 - 79
  2992. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, // 80 - 95
  2993. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 96 - 111
  2994. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0 // 112 - 127
  2995. ];
  2996. /**
  2997. * Adds an offer to the map of extension offers or a parameter to the map of
  2998. * parameters.
  2999. *
  3000. * @param {Object} dest The map of extension offers or parameters
  3001. * @param {String} name The extension or parameter name
  3002. * @param {(Object|Boolean|String)} elem The extension parameters or the
  3003. * parameter value
  3004. * @private
  3005. */
  3006. function push(dest, name, elem) {
  3007. if (dest[name] === undefined) dest[name] = [elem];
  3008. else dest[name].push(elem);
  3009. }
  3010. /**
  3011. * Parses the `Sec-WebSocket-Extensions` header into an object.
  3012. *
  3013. * @param {String} header The field value of the header
  3014. * @return {Object} The parsed object
  3015. * @public
  3016. */
  3017. function parse(header) {
  3018. const offers = Object.create(null);
  3019. if (header === undefined || header === '') return offers;
  3020. let params = Object.create(null);
  3021. let mustUnescape = false;
  3022. let isEscaping = false;
  3023. let inQuotes = false;
  3024. let extensionName;
  3025. let paramName;
  3026. let start = -1;
  3027. let end = -1;
  3028. let i = 0;
  3029. for (; i < header.length; i++) {
  3030. const code = header.charCodeAt(i);
  3031. if (extensionName === undefined) {
  3032. if (end === -1 && tokenChars[code] === 1) {
  3033. if (start === -1) start = i;
  3034. } else if (code === 0x20 /* ' ' */ || code === 0x09 /* '\t' */) {
  3035. if (end === -1 && start !== -1) end = i;
  3036. } else if (code === 0x3b /* ';' */ || code === 0x2c /* ',' */) {
  3037. if (start === -1) {
  3038. throw new SyntaxError(`Unexpected character at index ${i}`);
  3039. }
  3040. if (end === -1) end = i;
  3041. const name = header.slice(start, end);
  3042. if (code === 0x2c) {
  3043. push(offers, name, params);
  3044. params = Object.create(null);
  3045. } else {
  3046. extensionName = name;
  3047. }
  3048. start = end = -1;
  3049. } else {
  3050. throw new SyntaxError(`Unexpected character at index ${i}`);
  3051. }
  3052. } else if (paramName === undefined) {
  3053. if (end === -1 && tokenChars[code] === 1) {
  3054. if (start === -1) start = i;
  3055. } else if (code === 0x20 || code === 0x09) {
  3056. if (end === -1 && start !== -1) end = i;
  3057. } else if (code === 0x3b || code === 0x2c) {
  3058. if (start === -1) {
  3059. throw new SyntaxError(`Unexpected character at index ${i}`);
  3060. }
  3061. if (end === -1) end = i;
  3062. push(params, header.slice(start, end), true);
  3063. if (code === 0x2c) {
  3064. push(offers, extensionName, params);
  3065. params = Object.create(null);
  3066. extensionName = undefined;
  3067. }
  3068. start = end = -1;
  3069. } else if (code === 0x3d /* '=' */ && start !== -1 && end === -1) {
  3070. paramName = header.slice(start, i);
  3071. start = end = -1;
  3072. } else {
  3073. throw new SyntaxError(`Unexpected character at index ${i}`);
  3074. }
  3075. } else {
  3076. //
  3077. // The value of a quoted-string after unescaping must conform to the
  3078. // token ABNF, so only token characters are valid.
  3079. // Ref: https://tools.ietf.org/html/rfc6455#section-9.1
  3080. //
  3081. if (isEscaping) {
  3082. if (tokenChars[code] !== 1) {
  3083. throw new SyntaxError(`Unexpected character at index ${i}`);
  3084. }
  3085. if (start === -1) start = i;
  3086. else if (!mustUnescape) mustUnescape = true;
  3087. isEscaping = false;
  3088. } else if (inQuotes) {
  3089. if (tokenChars[code] === 1) {
  3090. if (start === -1) start = i;
  3091. } else if (code === 0x22 /* '"' */ && start !== -1) {
  3092. inQuotes = false;
  3093. end = i;
  3094. } else if (code === 0x5c /* '\' */) {
  3095. isEscaping = true;
  3096. } else {
  3097. throw new SyntaxError(`Unexpected character at index ${i}`);
  3098. }
  3099. } else if (code === 0x22 && header.charCodeAt(i - 1) === 0x3d) {
  3100. inQuotes = true;
  3101. } else if (end === -1 && tokenChars[code] === 1) {
  3102. if (start === -1) start = i;
  3103. } else if (start !== -1 && (code === 0x20 || code === 0x09)) {
  3104. if (end === -1) end = i;
  3105. } else if (code === 0x3b || code === 0x2c) {
  3106. if (start === -1) {
  3107. throw new SyntaxError(`Unexpected character at index ${i}`);
  3108. }
  3109. if (end === -1) end = i;
  3110. let value = header.slice(start, end);
  3111. if (mustUnescape) {
  3112. value = value.replace(/\\/g, '');
  3113. mustUnescape = false;
  3114. }
  3115. push(params, paramName, value);
  3116. if (code === 0x2c) {
  3117. push(offers, extensionName, params);
  3118. params = Object.create(null);
  3119. extensionName = undefined;
  3120. }
  3121. paramName = undefined;
  3122. start = end = -1;
  3123. } else {
  3124. throw new SyntaxError(`Unexpected character at index ${i}`);
  3125. }
  3126. }
  3127. }
  3128. if (start === -1 || inQuotes) {
  3129. throw new SyntaxError('Unexpected end of input');
  3130. }
  3131. if (end === -1) end = i;
  3132. const token = header.slice(start, end);
  3133. if (extensionName === undefined) {
  3134. push(offers, token, params);
  3135. } else {
  3136. if (paramName === undefined) {
  3137. push(params, token, true);
  3138. } else if (mustUnescape) {
  3139. push(params, paramName, token.replace(/\\/g, ''));
  3140. } else {
  3141. push(params, paramName, token);
  3142. }
  3143. push(offers, extensionName, params);
  3144. }
  3145. return offers;
  3146. }
  3147. /**
  3148. * Builds the `Sec-WebSocket-Extensions` header field value.
  3149. *
  3150. * @param {Object} extensions The map of extensions and parameters to format
  3151. * @return {String} A string representing the given object
  3152. * @public
  3153. */
  3154. function format(extensions) {
  3155. return Object.keys(extensions)
  3156. .map((extension) => {
  3157. let configurations = extensions[extension];
  3158. if (!Array.isArray(configurations)) configurations = [configurations];
  3159. return configurations
  3160. .map((params) => {
  3161. return [extension]
  3162. .concat(
  3163. Object.keys(params).map((k) => {
  3164. let values = params[k];
  3165. if (!Array.isArray(values)) values = [values];
  3166. return values
  3167. .map((v) => (v === true ? k : `${k}=${v}`))
  3168. .join('; ');
  3169. })
  3170. )
  3171. .join('; ');
  3172. })
  3173. .join(', ');
  3174. })
  3175. .join(', ');
  3176. }
  3177. module.exports = { format, parse };
  3178. }, function(modId) { var map = {}; return __REQUIRE__(map[modId], modId); })
  3179. __DEFINE__(1682324647605, function(require, module, exports) {
  3180. /* eslint no-unused-vars: ["error", { "varsIgnorePattern": "^net|tls|https$" }] */
  3181. const EventEmitter = require('events');
  3182. const http = require('http');
  3183. const https = require('https');
  3184. const net = require('net');
  3185. const tls = require('tls');
  3186. const { createHash } = require('crypto');
  3187. const PerMessageDeflate = require('./permessage-deflate');
  3188. const WebSocket = require('./websocket');
  3189. const { format, parse } = require('./extension');
  3190. const { GUID, kWebSocket } = require('./constants');
  3191. const keyRegex = /^[+/0-9A-Za-z]{22}==$/;
  3192. const RUNNING = 0;
  3193. const CLOSING = 1;
  3194. const CLOSED = 2;
  3195. /**
  3196. * Class representing a WebSocket server.
  3197. *
  3198. * @extends EventEmitter
  3199. */
  3200. class WebSocketServer extends EventEmitter {
  3201. /**
  3202. * Create a `WebSocketServer` instance.
  3203. *
  3204. * @param {Object} options Configuration options
  3205. * @param {Number} [options.backlog=511] The maximum length of the queue of
  3206. * pending connections
  3207. * @param {Boolean} [options.clientTracking=true] Specifies whether or not to
  3208. * track clients
  3209. * @param {Function} [options.handleProtocols] A hook to handle protocols
  3210. * @param {String} [options.host] The hostname where to bind the server
  3211. * @param {Number} [options.maxPayload=104857600] The maximum allowed message
  3212. * size
  3213. * @param {Boolean} [options.noServer=false] Enable no server mode
  3214. * @param {String} [options.path] Accept only connections matching this path
  3215. * @param {(Boolean|Object)} [options.perMessageDeflate=false] Enable/disable
  3216. * permessage-deflate
  3217. * @param {Number} [options.port] The port where to bind the server
  3218. * @param {(http.Server|https.Server)} [options.server] A pre-created HTTP/S
  3219. * server to use
  3220. * @param {Function} [options.verifyClient] A hook to reject connections
  3221. * @param {Function} [callback] A listener for the `listening` event
  3222. */
  3223. constructor(options, callback) {
  3224. super();
  3225. options = {
  3226. maxPayload: 100 * 1024 * 1024,
  3227. perMessageDeflate: false,
  3228. handleProtocols: null,
  3229. clientTracking: true,
  3230. verifyClient: null,
  3231. noServer: false,
  3232. backlog: null, // use default (511 as implemented in net.js)
  3233. server: null,
  3234. host: null,
  3235. path: null,
  3236. port: null,
  3237. ...options
  3238. };
  3239. if (
  3240. (options.port == null && !options.server && !options.noServer) ||
  3241. (options.port != null && (options.server || options.noServer)) ||
  3242. (options.server && options.noServer)
  3243. ) {
  3244. throw new TypeError(
  3245. 'One and only one of the "port", "server", or "noServer" options ' +
  3246. 'must be specified'
  3247. );
  3248. }
  3249. if (options.port != null) {
  3250. this._server = http.createServer((req, res) => {
  3251. const body = http.STATUS_CODES[426];
  3252. res.writeHead(426, {
  3253. 'Content-Length': body.length,
  3254. 'Content-Type': 'text/plain'
  3255. });
  3256. res.end(body);
  3257. });
  3258. this._server.listen(
  3259. options.port,
  3260. options.host,
  3261. options.backlog,
  3262. callback
  3263. );
  3264. } else if (options.server) {
  3265. this._server = options.server;
  3266. }
  3267. if (this._server) {
  3268. const emitConnection = this.emit.bind(this, 'connection');
  3269. this._removeListeners = addListeners(this._server, {
  3270. listening: this.emit.bind(this, 'listening'),
  3271. error: this.emit.bind(this, 'error'),
  3272. upgrade: (req, socket, head) => {
  3273. this.handleUpgrade(req, socket, head, emitConnection);
  3274. }
  3275. });
  3276. }
  3277. if (options.perMessageDeflate === true) options.perMessageDeflate = {};
  3278. if (options.clientTracking) this.clients = new Set();
  3279. this.options = options;
  3280. this._state = RUNNING;
  3281. }
  3282. /**
  3283. * Returns the bound address, the address family name, and port of the server
  3284. * as reported by the operating system if listening on an IP socket.
  3285. * If the server is listening on a pipe or UNIX domain socket, the name is
  3286. * returned as a string.
  3287. *
  3288. * @return {(Object|String|null)} The address of the server
  3289. * @public
  3290. */
  3291. address() {
  3292. if (this.options.noServer) {
  3293. throw new Error('The server is operating in "noServer" mode');
  3294. }
  3295. if (!this._server) return null;
  3296. return this._server.address();
  3297. }
  3298. /**
  3299. * Close the server.
  3300. *
  3301. * @param {Function} [cb] Callback
  3302. * @public
  3303. */
  3304. close(cb) {
  3305. if (cb) this.once('close', cb);
  3306. if (this._state === CLOSED) {
  3307. process.nextTick(emitClose, this);
  3308. return;
  3309. }
  3310. if (this._state === CLOSING) return;
  3311. this._state = CLOSING;
  3312. //
  3313. // Terminate all associated clients.
  3314. //
  3315. if (this.clients) {
  3316. for (const client of this.clients) client.terminate();
  3317. }
  3318. const server = this._server;
  3319. if (server) {
  3320. this._removeListeners();
  3321. this._removeListeners = this._server = null;
  3322. //
  3323. // Close the http server if it was internally created.
  3324. //
  3325. if (this.options.port != null) {
  3326. server.close(emitClose.bind(undefined, this));
  3327. return;
  3328. }
  3329. }
  3330. process.nextTick(emitClose, this);
  3331. }
  3332. /**
  3333. * See if a given request should be handled by this server instance.
  3334. *
  3335. * @param {http.IncomingMessage} req Request object to inspect
  3336. * @return {Boolean} `true` if the request is valid, else `false`
  3337. * @public
  3338. */
  3339. shouldHandle(req) {
  3340. if (this.options.path) {
  3341. const index = req.url.indexOf('?');
  3342. const pathname = index !== -1 ? req.url.slice(0, index) : req.url;
  3343. if (pathname !== this.options.path) return false;
  3344. }
  3345. return true;
  3346. }
  3347. /**
  3348. * Handle a HTTP Upgrade request.
  3349. *
  3350. * @param {http.IncomingMessage} req The request object
  3351. * @param {(net.Socket|tls.Socket)} socket The network socket between the
  3352. * server and client
  3353. * @param {Buffer} head The first packet of the upgraded stream
  3354. * @param {Function} cb Callback
  3355. * @public
  3356. */
  3357. handleUpgrade(req, socket, head, cb) {
  3358. socket.on('error', socketOnError);
  3359. const key =
  3360. req.headers['sec-websocket-key'] !== undefined
  3361. ? req.headers['sec-websocket-key'].trim()
  3362. : false;
  3363. const version = +req.headers['sec-websocket-version'];
  3364. const extensions = {};
  3365. if (
  3366. req.method !== 'GET' ||
  3367. req.headers.upgrade.toLowerCase() !== 'websocket' ||
  3368. !key ||
  3369. !keyRegex.test(key) ||
  3370. (version !== 8 && version !== 13) ||
  3371. !this.shouldHandle(req)
  3372. ) {
  3373. return abortHandshake(socket, 400);
  3374. }
  3375. if (this.options.perMessageDeflate) {
  3376. const perMessageDeflate = new PerMessageDeflate(
  3377. this.options.perMessageDeflate,
  3378. true,
  3379. this.options.maxPayload
  3380. );
  3381. try {
  3382. const offers = parse(req.headers['sec-websocket-extensions']);
  3383. if (offers[PerMessageDeflate.extensionName]) {
  3384. perMessageDeflate.accept(offers[PerMessageDeflate.extensionName]);
  3385. extensions[PerMessageDeflate.extensionName] = perMessageDeflate;
  3386. }
  3387. } catch (err) {
  3388. return abortHandshake(socket, 400);
  3389. }
  3390. }
  3391. //
  3392. // Optionally call external client verification handler.
  3393. //
  3394. if (this.options.verifyClient) {
  3395. const info = {
  3396. origin:
  3397. req.headers[`${version === 8 ? 'sec-websocket-origin' : 'origin'}`],
  3398. secure: !!(req.socket.authorized || req.socket.encrypted),
  3399. req
  3400. };
  3401. if (this.options.verifyClient.length === 2) {
  3402. this.options.verifyClient(info, (verified, code, message, headers) => {
  3403. if (!verified) {
  3404. return abortHandshake(socket, code || 401, message, headers);
  3405. }
  3406. this.completeUpgrade(key, extensions, req, socket, head, cb);
  3407. });
  3408. return;
  3409. }
  3410. if (!this.options.verifyClient(info)) return abortHandshake(socket, 401);
  3411. }
  3412. this.completeUpgrade(key, extensions, req, socket, head, cb);
  3413. }
  3414. /**
  3415. * Upgrade the connection to WebSocket.
  3416. *
  3417. * @param {String} key The value of the `Sec-WebSocket-Key` header
  3418. * @param {Object} extensions The accepted extensions
  3419. * @param {http.IncomingMessage} req The request object
  3420. * @param {(net.Socket|tls.Socket)} socket The network socket between the
  3421. * server and client
  3422. * @param {Buffer} head The first packet of the upgraded stream
  3423. * @param {Function} cb Callback
  3424. * @throws {Error} If called more than once with the same socket
  3425. * @private
  3426. */
  3427. completeUpgrade(key, extensions, req, socket, head, cb) {
  3428. //
  3429. // Destroy the socket if the client has already sent a FIN packet.
  3430. //
  3431. if (!socket.readable || !socket.writable) return socket.destroy();
  3432. if (socket[kWebSocket]) {
  3433. throw new Error(
  3434. 'server.handleUpgrade() was called more than once with the same ' +
  3435. 'socket, possibly due to a misconfiguration'
  3436. );
  3437. }
  3438. if (this._state > RUNNING) return abortHandshake(socket, 503);
  3439. const digest = createHash('sha1')
  3440. .update(key + GUID)
  3441. .digest('base64');
  3442. const headers = [
  3443. 'HTTP/1.1 101 Switching Protocols',
  3444. 'Upgrade: websocket',
  3445. 'Connection: Upgrade',
  3446. `Sec-WebSocket-Accept: ${digest}`
  3447. ];
  3448. const ws = new WebSocket(null);
  3449. let protocol = req.headers['sec-websocket-protocol'];
  3450. if (protocol) {
  3451. protocol = protocol.split(',').map(trim);
  3452. //
  3453. // Optionally call external protocol selection handler.
  3454. //
  3455. if (this.options.handleProtocols) {
  3456. protocol = this.options.handleProtocols(protocol, req);
  3457. } else {
  3458. protocol = protocol[0];
  3459. }
  3460. if (protocol) {
  3461. headers.push(`Sec-WebSocket-Protocol: ${protocol}`);
  3462. ws._protocol = protocol;
  3463. }
  3464. }
  3465. if (extensions[PerMessageDeflate.extensionName]) {
  3466. const params = extensions[PerMessageDeflate.extensionName].params;
  3467. const value = format({
  3468. [PerMessageDeflate.extensionName]: [params]
  3469. });
  3470. headers.push(`Sec-WebSocket-Extensions: ${value}`);
  3471. ws._extensions = extensions;
  3472. }
  3473. //
  3474. // Allow external modification/inspection of handshake headers.
  3475. //
  3476. this.emit('headers', headers, req);
  3477. socket.write(headers.concat('\r\n').join('\r\n'));
  3478. socket.removeListener('error', socketOnError);
  3479. ws.setSocket(socket, head, this.options.maxPayload);
  3480. if (this.clients) {
  3481. this.clients.add(ws);
  3482. ws.on('close', () => this.clients.delete(ws));
  3483. }
  3484. cb(ws, req);
  3485. }
  3486. }
  3487. module.exports = WebSocketServer;
  3488. /**
  3489. * Add event listeners on an `EventEmitter` using a map of <event, listener>
  3490. * pairs.
  3491. *
  3492. * @param {EventEmitter} server The event emitter
  3493. * @param {Object.<String, Function>} map The listeners to add
  3494. * @return {Function} A function that will remove the added listeners when
  3495. * called
  3496. * @private
  3497. */
  3498. function addListeners(server, map) {
  3499. for (const event of Object.keys(map)) server.on(event, map[event]);
  3500. return function removeListeners() {
  3501. for (const event of Object.keys(map)) {
  3502. server.removeListener(event, map[event]);
  3503. }
  3504. };
  3505. }
  3506. /**
  3507. * Emit a `'close'` event on an `EventEmitter`.
  3508. *
  3509. * @param {EventEmitter} server The event emitter
  3510. * @private
  3511. */
  3512. function emitClose(server) {
  3513. server._state = CLOSED;
  3514. server.emit('close');
  3515. }
  3516. /**
  3517. * Handle premature socket errors.
  3518. *
  3519. * @private
  3520. */
  3521. function socketOnError() {
  3522. this.destroy();
  3523. }
  3524. /**
  3525. * Close the connection when preconditions are not fulfilled.
  3526. *
  3527. * @param {(net.Socket|tls.Socket)} socket The socket of the upgrade request
  3528. * @param {Number} code The HTTP response status code
  3529. * @param {String} [message] The HTTP response body
  3530. * @param {Object} [headers] Additional HTTP response headers
  3531. * @private
  3532. */
  3533. function abortHandshake(socket, code, message, headers) {
  3534. if (socket.writable) {
  3535. message = message || http.STATUS_CODES[code];
  3536. headers = {
  3537. Connection: 'close',
  3538. 'Content-Type': 'text/html',
  3539. 'Content-Length': Buffer.byteLength(message),
  3540. ...headers
  3541. };
  3542. socket.write(
  3543. `HTTP/1.1 ${code} ${http.STATUS_CODES[code]}\r\n` +
  3544. Object.keys(headers)
  3545. .map((h) => `${h}: ${headers[h]}`)
  3546. .join('\r\n') +
  3547. '\r\n\r\n' +
  3548. message
  3549. );
  3550. }
  3551. socket.removeListener('error', socketOnError);
  3552. socket.destroy();
  3553. }
  3554. /**
  3555. * Remove whitespace characters from both ends of a string.
  3556. *
  3557. * @param {String} str The string
  3558. * @return {String} A new string representing `str` stripped of whitespace
  3559. * characters from both its beginning and end
  3560. * @private
  3561. */
  3562. function trim(str) {
  3563. return str.trim();
  3564. }
  3565. }, function(modId) { var map = {"./permessage-deflate":1682324647596,"./websocket":1682324647594,"./extension":1682324647604,"./constants":1682324647598}; return __REQUIRE__(map[modId], modId); })
  3566. return __REQUIRE__(1682324647593);
  3567. })()
  3568. //miniprogram-npm-outsideDeps=["events","https","http","net","tls","crypto","url","zlib","bufferutil","utf-8-validate"]
  3569. //# sourceMappingURL=index.js.map