Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

faye-websocket.js 100KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494
  1. /*!
  2. * faye-websocket@0.11.1 - Standards-compliant WebSocket server and client
  3. * Copyright (c) 2019, James Coglan (MIT)
  4. * https://github.com/faye/faye-websocket-node
  5. *
  6. * License for websocket-driver@0.7.0:
  7. *
  8. * # The MIT License
  9. *
  10. * Copyright (c) 2010-2017 James Coglan
  11. *
  12. * Permission is hereby granted, free of charge, to any person obtaining a copy
  13. * of this software and associated documentation files (the 'Software'), to deal
  14. * in the Software without restriction, including without limitation the rights
  15. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  16. * copies of the Software, and to permit persons to whom the Software is
  17. * furnished to do so, subject to the following conditions:
  18. *
  19. * The above copyright notice and this permission notice shall be included in
  20. * all copies or substantial portions of the Software.
  21. *
  22. * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  23. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  24. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  25. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  26. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  27. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  28. * SOFTWARE.
  29. *
  30. * License for http-parser-js@0.5.0:
  31. *
  32. * Copyright (c) 2015 Tim Caswell (https://github.com/creationix) and other
  33. * contributors. All rights reserved.
  34. *
  35. * Permission is hereby granted, free of charge, to any person obtaining a copy
  36. * of this software and associated documentation files (the "Software"), to deal
  37. * in the Software without restriction, including without limitation the rights
  38. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  39. * copies of the Software, and to permit persons to whom the Software is
  40. * furnished to do so, subject to the following conditions:
  41. *
  42. * The above copyright notice and this permission notice shall be included in
  43. * all copies or substantial portions of the Software.
  44. *
  45. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  46. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  47. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  48. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  49. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  50. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  51. * SOFTWARE.
  52. *
  53. * Some files from the tests folder are from joyent/node and mscedex/io.js, a
  54. * fork of nodejs/io.js:
  55. *
  56. * - tests/iojs/test-http-parser-durability.js
  57. *
  58. * This file is from
  59. * https://github.com/mscdex/io.js/blob/js-http-parser/test/pummel/test-http-parser-durability.js
  60. * with modifications by Jan Schär (jscissr).
  61. *
  62. * """ Copyright io.js contributors. All rights reserved.
  63. *
  64. * Permission is hereby granted, free of charge, to any person obtaining a copy
  65. * of this software and associated documentation files (the "Software"), to deal
  66. * in the Software without restriction, including without limitation the rights
  67. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  68. * copies of the Software, and to permit persons to whom the Software is
  69. * furnished to do so, subject to the following conditions:
  70. *
  71. * The above copyright notice and this permission notice shall be included in
  72. * all copies or substantial portions of the Software.
  73. *
  74. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  75. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  76. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  77. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  78. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  79. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  80. * SOFTWARE. """
  81. *
  82. * - tests/fixtures/* tests/parallel/* tests/testpy/* tests/common.js
  83. * tests/test.py tests/utils.py
  84. *
  85. * These files are from https://github.com/nodejs/node with changes by Jan Schär
  86. * (jscissr).
  87. *
  88. * Node.js is licensed for use as follows:
  89. *
  90. * """ Copyright Node.js contributors. All rights reserved.
  91. *
  92. * Permission is hereby granted, free of charge, to any person obtaining a copy
  93. * of this software and associated documentation files (the "Software"), to deal
  94. * in the Software without restriction, including without limitation the rights
  95. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  96. * copies of the Software, and to permit persons to whom the Software is
  97. * furnished to do so, subject to the following conditions:
  98. *
  99. * The above copyright notice and this permission notice shall be included in
  100. * all copies or substantial portions of the Software.
  101. *
  102. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  103. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  104. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  105. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  106. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  107. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  108. * SOFTWARE. """
  109. *
  110. * This license applies to parts of Node.js originating from the
  111. * https://github.com/joyent/node repository:
  112. *
  113. * """ Copyright Joyent, Inc. and other Node contributors. All rights reserved.
  114. * Permission is hereby granted, free of charge, to any person obtaining a copy
  115. * of this software and associated documentation files (the "Software"), to deal
  116. * in the Software without restriction, including without limitation the rights
  117. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  118. * copies of the Software, and to permit persons to whom the Software is
  119. * furnished to do so, subject to the following conditions:
  120. *
  121. * The above copyright notice and this permission notice shall be included in
  122. * all copies or substantial portions of the Software.
  123. *
  124. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  125. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  126. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  127. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  128. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  129. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  130. * SOFTWARE. """
  131. *
  132. * License for websocket-extensions@0.1.3:
  133. *
  134. * # The MIT License
  135. *
  136. * Copyright (c) 2014-2017 James Coglan
  137. *
  138. * Permission is hereby granted, free of charge, to any person obtaining a copy
  139. * of this software and associated documentation files (the 'Software'), to deal
  140. * in the Software without restriction, including without limitation the rights
  141. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  142. * copies of the Software, and to permit persons to whom the Software is
  143. * furnished to do so, subject to the following conditions:
  144. *
  145. * The above copyright notice and this permission notice shall be included in
  146. * all copies or substantial portions of the Software.
  147. *
  148. * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  149. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  150. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  151. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  152. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  153. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  154. * SOFTWARE.
  155. */
  156. var __node_modules__ = [
  157. [/* 0 */ 'faye-websocket', '/lib/faye/websocket.js', function(exports, module, __filename, __dirname, __meta) {
  158. // API references:
  159. //
  160. // * https://html.spec.whatwg.org/multipage/comms.html#network
  161. // * https://dom.spec.whatwg.org/#interface-eventtarget
  162. // * https://dom.spec.whatwg.org/#interface-event
  163. var util = require('util'),
  164. driver = __node_require__(1 /* 'websocket-driver' */),
  165. API = __node_require__(23 /* './websocket/api' */);
  166. var WebSocket = function(request, socket, body, protocols, options) {
  167. options = options || {};
  168. this._stream = socket;
  169. this._driver = driver.http(request, {maxLength: options.maxLength, protocols: protocols});
  170. var self = this;
  171. if (!this._stream || !this._stream.writable) return;
  172. if (!this._stream.readable) return this._stream.end();
  173. var catchup = function() { self._stream.removeListener('data', catchup) };
  174. this._stream.on('data', catchup);
  175. API.call(this, options);
  176. process.nextTick(function() {
  177. self._driver.start();
  178. self._driver.io.write(body);
  179. });
  180. };
  181. util.inherits(WebSocket, API);
  182. WebSocket.isWebSocket = function(request) {
  183. return driver.isWebSocket(request);
  184. };
  185. WebSocket.validateOptions = function(options, validKeys) {
  186. driver.validateOptions(options, validKeys);
  187. };
  188. WebSocket.WebSocket = WebSocket;
  189. WebSocket.Client = __node_require__(26 /* './websocket/client' */);
  190. WebSocket.EventSource = __node_require__(27 /* './eventsource' */);
  191. module.exports = WebSocket;
  192. }],
  193. [/* 1 */ 'websocket-driver', '/lib/websocket/driver.js', function(exports, module, __filename, __dirname, __meta) {
  194. 'use strict';
  195. // Protocol references:
  196. //
  197. // * http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-75
  198. // * http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-76
  199. // * http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-17
  200. var Base = __node_require__(2 /* './driver/base' */),
  201. Client = __node_require__(6 /* './driver/client' */),
  202. Server = __node_require__(20 /* './driver/server' */);
  203. var Driver = {
  204. client: function(url, options) {
  205. options = options || {};
  206. if (options.masking === undefined) options.masking = true;
  207. return new Client(url, options);
  208. },
  209. server: function(options) {
  210. options = options || {};
  211. if (options.requireMasking === undefined) options.requireMasking = true;
  212. return new Server(options);
  213. },
  214. http: function() {
  215. return Server.http.apply(Server, arguments);
  216. },
  217. isSecureRequest: function(request) {
  218. return Server.isSecureRequest(request);
  219. },
  220. isWebSocket: function(request) {
  221. if (request.method !== 'GET') return false;
  222. var connection = request.headers.connection || '',
  223. upgrade = request.headers.upgrade || '';
  224. return request.method === 'GET' &&
  225. connection.toLowerCase().split(/ *, */).indexOf('upgrade') >= 0 &&
  226. upgrade.toLowerCase() === 'websocket';
  227. },
  228. validateOptions: function(options, validKeys) {
  229. Base.validateOptions(options, validKeys);
  230. }
  231. };
  232. module.exports = Driver;
  233. }],
  234. [/* 2 */ 'websocket-driver', '/lib/websocket/driver/base.js', function(exports, module, __filename, __dirname, __meta) {
  235. 'use strict';
  236. var Emitter = require('events').EventEmitter,
  237. util = require('util'),
  238. streams = __node_require__(3 /* '../streams' */),
  239. Headers = __node_require__(4 /* './headers' */),
  240. Reader = __node_require__(5 /* './stream_reader' */);
  241. var Base = function(request, url, options) {
  242. Emitter.call(this);
  243. Base.validateOptions(options || {}, ['maxLength', 'masking', 'requireMasking', 'protocols']);
  244. this._request = request;
  245. this._reader = new Reader();
  246. this._options = options || {};
  247. this._maxLength = this._options.maxLength || this.MAX_LENGTH;
  248. this._headers = new Headers();
  249. this.__queue = [];
  250. this.readyState = 0;
  251. this.url = url;
  252. this.io = new streams.IO(this);
  253. this.messages = new streams.Messages(this);
  254. this._bindEventListeners();
  255. };
  256. util.inherits(Base, Emitter);
  257. Base.validateOptions = function(options, validKeys) {
  258. for (var key in options) {
  259. if (validKeys.indexOf(key) < 0)
  260. throw new Error('Unrecognized option: ' + key);
  261. }
  262. };
  263. var instance = {
  264. // This is 64MB, small enough for an average VPS to handle without
  265. // crashing from process out of memory
  266. MAX_LENGTH: 0x3ffffff,
  267. STATES: ['connecting', 'open', 'closing', 'closed'],
  268. _bindEventListeners: function() {
  269. var self = this;
  270. // Protocol errors are informational and do not have to be handled
  271. this.messages.on('error', function() {});
  272. this.on('message', function(event) {
  273. var messages = self.messages;
  274. if (messages.readable) messages.emit('data', event.data);
  275. });
  276. this.on('error', function(error) {
  277. var messages = self.messages;
  278. if (messages.readable) messages.emit('error', error);
  279. });
  280. this.on('close', function() {
  281. var messages = self.messages;
  282. if (!messages.readable) return;
  283. messages.readable = messages.writable = false;
  284. messages.emit('end');
  285. });
  286. },
  287. getState: function() {
  288. return this.STATES[this.readyState] || null;
  289. },
  290. addExtension: function(extension) {
  291. return false;
  292. },
  293. setHeader: function(name, value) {
  294. if (this.readyState > 0) return false;
  295. this._headers.set(name, value);
  296. return true;
  297. },
  298. start: function() {
  299. if (this.readyState !== 0) return false;
  300. var response = this._handshakeResponse();
  301. if (!response) return false;
  302. this._write(response);
  303. if (this._stage !== -1) this._open();
  304. return true;
  305. },
  306. text: function(message) {
  307. return this.frame(message);
  308. },
  309. binary: function(message) {
  310. return false;
  311. },
  312. ping: function() {
  313. return false;
  314. },
  315. pong: function() {
  316. return false;
  317. },
  318. close: function(reason, code) {
  319. if (this.readyState !== 1) return false;
  320. this.readyState = 3;
  321. this.emit('close', new Base.CloseEvent(null, null));
  322. return true;
  323. },
  324. _open: function() {
  325. this.readyState = 1;
  326. this.__queue.forEach(function(args) { this.frame.apply(this, args) }, this);
  327. this.__queue = [];
  328. this.emit('open', new Base.OpenEvent());
  329. },
  330. _queue: function(message) {
  331. this.__queue.push(message);
  332. return true;
  333. },
  334. _write: function(chunk) {
  335. var io = this.io;
  336. if (io.readable) io.emit('data', chunk);
  337. }
  338. };
  339. for (var key in instance)
  340. Base.prototype[key] = instance[key];
  341. Base.ConnectEvent = function() {};
  342. Base.OpenEvent = function() {};
  343. Base.CloseEvent = function(code, reason) {
  344. this.code = code;
  345. this.reason = reason;
  346. };
  347. Base.MessageEvent = function(data) {
  348. this.data = data;
  349. };
  350. Base.PingEvent = function(data) {
  351. this.data = data;
  352. };
  353. Base.PongEvent = function(data) {
  354. this.data = data;
  355. };
  356. module.exports = Base;
  357. }],
  358. [/* 3 */ 'websocket-driver', '/lib/websocket/streams.js', function(exports, module, __filename, __dirname, __meta) {
  359. 'use strict';
  360. /**
  361. Streams in a WebSocket connection
  362. ---------------------------------
  363. We model a WebSocket as two duplex streams: one stream is for the wire protocol
  364. over an I/O socket, and the other is for incoming/outgoing messages.
  365. +----------+ +---------+ +----------+
  366. [1] write(chunk) -->| ~~~~~~~~ +----->| parse() +----->| ~~~~~~~~ +--> emit('data') [2]
  367. | | +----+----+ | |
  368. | | | | |
  369. | IO | | [5] | Messages |
  370. | | V | |
  371. | | +---------+ | |
  372. [4] emit('data') <--+ ~~~~~~~~ |<-----+ frame() |<-----+ ~~~~~~~~ |<-- write(chunk) [3]
  373. +----------+ +---------+ +----------+
  374. Message transfer in each direction is simple: IO receives a byte stream [1] and
  375. sends this stream for parsing. The parser will periodically emit a complete
  376. message text on the Messages stream [2]. Similarly, when messages are written
  377. to the Messages stream [3], they are framed using the WebSocket wire format and
  378. emitted via IO [4].
  379. There is a feedback loop via [5] since some input from [1] will be things like
  380. ping, pong and close frames. In these cases the protocol responds by emitting
  381. responses directly back to [4] rather than emitting messages via [2].
  382. For the purposes of flow control, we consider the sources of each Readable
  383. stream to be as follows:
  384. * [2] receives input from [1]
  385. * [4] receives input from [1] and [3]
  386. The classes below express the relationships described above without prescribing
  387. anything about how parse() and frame() work, other than assuming they emit
  388. 'data' events to the IO and Messages streams. They will work with any protocol
  389. driver having these two methods.
  390. **/
  391. var Stream = require('stream').Stream,
  392. util = require('util');
  393. var IO = function(driver) {
  394. this.readable = this.writable = true;
  395. this._paused = false;
  396. this._driver = driver;
  397. };
  398. util.inherits(IO, Stream);
  399. // The IO pause() and resume() methods will be called when the socket we are
  400. // piping to gets backed up and drains. Since IO output [4] comes from IO input
  401. // [1] and Messages input [3], we need to tell both of those to return false
  402. // from write() when this stream is paused.
  403. IO.prototype.pause = function() {
  404. this._paused = true;
  405. this._driver.messages._paused = true;
  406. };
  407. IO.prototype.resume = function() {
  408. this._paused = false;
  409. this.emit('drain');
  410. var messages = this._driver.messages;
  411. messages._paused = false;
  412. messages.emit('drain');
  413. };
  414. // When we receive input from a socket, send it to the parser and tell the
  415. // source whether to back off.
  416. IO.prototype.write = function(chunk) {
  417. if (!this.writable) return false;
  418. this._driver.parse(chunk);
  419. return !this._paused;
  420. };
  421. // The IO end() method will be called when the socket piping into it emits
  422. // 'close' or 'end', i.e. the socket is closed. In this situation the Messages
  423. // stream will not emit any more data so we emit 'end'.
  424. IO.prototype.end = function(chunk) {
  425. if (!this.writable) return;
  426. if (chunk !== undefined) this.write(chunk);
  427. this.writable = false;
  428. var messages = this._driver.messages;
  429. if (messages.readable) {
  430. messages.readable = messages.writable = false;
  431. messages.emit('end');
  432. }
  433. };
  434. IO.prototype.destroy = function() {
  435. this.end();
  436. };
  437. var Messages = function(driver) {
  438. this.readable = this.writable = true;
  439. this._paused = false;
  440. this._driver = driver;
  441. };
  442. util.inherits(Messages, Stream);
  443. // The Messages pause() and resume() methods will be called when the app that's
  444. // processing the messages gets backed up and drains. If we're emitting
  445. // messages too fast we should tell the source to slow down. Message output [2]
  446. // comes from IO input [1].
  447. Messages.prototype.pause = function() {
  448. this._driver.io._paused = true;
  449. };
  450. Messages.prototype.resume = function() {
  451. this._driver.io._paused = false;
  452. this._driver.io.emit('drain');
  453. };
  454. // When we receive messages from the user, send them to the formatter and tell
  455. // the source whether to back off.
  456. Messages.prototype.write = function(message) {
  457. if (!this.writable) return false;
  458. if (typeof message === 'string') this._driver.text(message);
  459. else this._driver.binary(message);
  460. return !this._paused;
  461. };
  462. // The Messages end() method will be called when a stream piping into it emits
  463. // 'end'. Many streams may be piped into the WebSocket and one of them ending
  464. // does not mean the whole socket is done, so just process the input and move
  465. // on leaving the socket open.
  466. Messages.prototype.end = function(message) {
  467. if (message !== undefined) this.write(message);
  468. };
  469. Messages.prototype.destroy = function() {};
  470. exports.IO = IO;
  471. exports.Messages = Messages;
  472. }],
  473. [/* 4 */ 'websocket-driver', '/lib/websocket/driver/headers.js', function(exports, module, __filename, __dirname, __meta) {
  474. 'use strict';
  475. var Headers = function() {
  476. this.clear();
  477. };
  478. Headers.prototype.ALLOWED_DUPLICATES = ['set-cookie', 'set-cookie2', 'warning', 'www-authenticate'];
  479. Headers.prototype.clear = function() {
  480. this._sent = {};
  481. this._lines = [];
  482. };
  483. Headers.prototype.set = function(name, value) {
  484. if (value === undefined) return;
  485. name = this._strip(name);
  486. value = this._strip(value);
  487. var key = name.toLowerCase();
  488. if (!this._sent.hasOwnProperty(key) || this.ALLOWED_DUPLICATES.indexOf(key) >= 0) {
  489. this._sent[key] = true;
  490. this._lines.push(name + ': ' + value + '\r\n');
  491. }
  492. };
  493. Headers.prototype.toString = function() {
  494. return this._lines.join('');
  495. };
  496. Headers.prototype._strip = function(string) {
  497. return string.toString().replace(/^ */, '').replace(/ *$/, '');
  498. };
  499. module.exports = Headers;
  500. }],
  501. [/* 5 */ 'websocket-driver', '/lib/websocket/driver/stream_reader.js', function(exports, module, __filename, __dirname, __meta) {
  502. 'use strict';
  503. var StreamReader = function() {
  504. this._queue = [];
  505. this._queueSize = 0;
  506. this._offset = 0;
  507. };
  508. StreamReader.prototype.put = function(buffer) {
  509. if (!buffer || buffer.length === 0) return;
  510. if (!buffer.copy) buffer = new Buffer(buffer);
  511. this._queue.push(buffer);
  512. this._queueSize += buffer.length;
  513. };
  514. StreamReader.prototype.read = function(length) {
  515. if (length > this._queueSize) return null;
  516. if (length === 0) return new Buffer(0);
  517. this._queueSize -= length;
  518. var queue = this._queue,
  519. remain = length,
  520. first = queue[0],
  521. buffers, buffer;
  522. if (first.length >= length) {
  523. if (first.length === length) {
  524. return queue.shift();
  525. } else {
  526. buffer = first.slice(0, length);
  527. queue[0] = first.slice(length);
  528. return buffer;
  529. }
  530. }
  531. for (var i = 0, n = queue.length; i < n; i++) {
  532. if (remain < queue[i].length) break;
  533. remain -= queue[i].length;
  534. }
  535. buffers = queue.splice(0, i);
  536. if (remain > 0 && queue.length > 0) {
  537. buffers.push(queue[0].slice(0, remain));
  538. queue[0] = queue[0].slice(remain);
  539. }
  540. return this._concat(buffers, length);
  541. };
  542. StreamReader.prototype.eachByte = function(callback, context) {
  543. var buffer, n, index;
  544. while (this._queue.length > 0) {
  545. buffer = this._queue[0];
  546. n = buffer.length;
  547. while (this._offset < n) {
  548. index = this._offset;
  549. this._offset += 1;
  550. callback.call(context, buffer[index]);
  551. }
  552. this._offset = 0;
  553. this._queue.shift();
  554. }
  555. };
  556. StreamReader.prototype._concat = function(buffers, length) {
  557. if (Buffer.concat) return Buffer.concat(buffers, length);
  558. var buffer = new Buffer(length),
  559. offset = 0;
  560. for (var i = 0, n = buffers.length; i < n; i++) {
  561. buffers[i].copy(buffer, offset);
  562. offset += buffers[i].length;
  563. }
  564. return buffer;
  565. };
  566. module.exports = StreamReader;
  567. }],
  568. [/* 6 */ 'websocket-driver', '/lib/websocket/driver/client.js', function(exports, module, __filename, __dirname, __meta) {
  569. 'use strict';
  570. var crypto = require('crypto'),
  571. url = require('url'),
  572. util = require('util'),
  573. HttpParser = __node_require__(7 /* '../http_parser' */),
  574. Base = __node_require__(2 /* './base' */),
  575. Hybi = __node_require__(9 /* './hybi' */),
  576. Proxy = __node_require__(19 /* './proxy' */);
  577. var Client = function(_url, options) {
  578. this.version = 'hybi-13';
  579. Hybi.call(this, null, _url, options);
  580. this.readyState = -1;
  581. this._key = Client.generateKey();
  582. this._accept = Hybi.generateAccept(this._key);
  583. this._http = new HttpParser('response');
  584. var uri = url.parse(this.url),
  585. auth = uri.auth && new Buffer(uri.auth, 'utf8').toString('base64');
  586. if (this.VALID_PROTOCOLS.indexOf(uri.protocol) < 0)
  587. throw new Error(this.url + ' is not a valid WebSocket URL');
  588. this._pathname = (uri.pathname || '/') + (uri.search || '');
  589. this._headers.set('Host', uri.host);
  590. this._headers.set('Upgrade', 'websocket');
  591. this._headers.set('Connection', 'Upgrade');
  592. this._headers.set('Sec-WebSocket-Key', this._key);
  593. this._headers.set('Sec-WebSocket-Version', '13');
  594. if (this._protocols.length > 0)
  595. this._headers.set('Sec-WebSocket-Protocol', this._protocols.join(', '));
  596. if (auth)
  597. this._headers.set('Authorization', 'Basic ' + auth);
  598. };
  599. util.inherits(Client, Hybi);
  600. Client.generateKey = function() {
  601. return crypto.randomBytes(16).toString('base64');
  602. };
  603. var instance = {
  604. VALID_PROTOCOLS: ['ws:', 'wss:'],
  605. proxy: function(origin, options) {
  606. return new Proxy(this, origin, options);
  607. },
  608. start: function() {
  609. if (this.readyState !== -1) return false;
  610. this._write(this._handshakeRequest());
  611. this.readyState = 0;
  612. return true;
  613. },
  614. parse: function(chunk) {
  615. if (this.readyState === 3) return;
  616. if (this.readyState > 0) return Hybi.prototype.parse.call(this, chunk);
  617. this._http.parse(chunk);
  618. if (!this._http.isComplete()) return;
  619. this._validateHandshake();
  620. if (this.readyState === 3) return;
  621. this._open();
  622. this.parse(this._http.body);
  623. },
  624. _handshakeRequest: function() {
  625. var extensions = this._extensions.generateOffer();
  626. if (extensions)
  627. this._headers.set('Sec-WebSocket-Extensions', extensions);
  628. var start = 'GET ' + this._pathname + ' HTTP/1.1',
  629. headers = [start, this._headers.toString(), ''];
  630. return new Buffer(headers.join('\r\n'), 'utf8');
  631. },
  632. _failHandshake: function(message) {
  633. message = 'Error during WebSocket handshake: ' + message;
  634. this.readyState = 3;
  635. this.emit('error', new Error(message));
  636. this.emit('close', new Base.CloseEvent(this.ERRORS.protocol_error, message));
  637. },
  638. _validateHandshake: function() {
  639. this.statusCode = this._http.statusCode;
  640. this.headers = this._http.headers;
  641. if (this._http.error)
  642. return this._failHandshake(this._http.error.message);
  643. if (this._http.statusCode !== 101)
  644. return this._failHandshake('Unexpected response code: ' + this._http.statusCode);
  645. var headers = this._http.headers,
  646. upgrade = headers['upgrade'] || '',
  647. connection = headers['connection'] || '',
  648. accept = headers['sec-websocket-accept'] || '',
  649. protocol = headers['sec-websocket-protocol'] || '';
  650. if (upgrade === '')
  651. return this._failHandshake("'Upgrade' header is missing");
  652. if (upgrade.toLowerCase() !== 'websocket')
  653. return this._failHandshake("'Upgrade' header value is not 'WebSocket'");
  654. if (connection === '')
  655. return this._failHandshake("'Connection' header is missing");
  656. if (connection.toLowerCase() !== 'upgrade')
  657. return this._failHandshake("'Connection' header value is not 'Upgrade'");
  658. if (accept !== this._accept)
  659. return this._failHandshake('Sec-WebSocket-Accept mismatch');
  660. this.protocol = null;
  661. if (protocol !== '') {
  662. if (this._protocols.indexOf(protocol) < 0)
  663. return this._failHandshake('Sec-WebSocket-Protocol mismatch');
  664. else
  665. this.protocol = protocol;
  666. }
  667. try {
  668. this._extensions.activate(this.headers['sec-websocket-extensions']);
  669. } catch (e) {
  670. return this._failHandshake(e.message);
  671. }
  672. }
  673. };
  674. for (var key in instance)
  675. Client.prototype[key] = instance[key];
  676. module.exports = Client;
  677. }],
  678. [/* 7 */ 'websocket-driver', '/lib/websocket/http_parser.js', function(exports, module, __filename, __dirname, __meta) {
  679. 'use strict';
  680. var NodeHTTPParser = __node_require__(8 /* 'http-parser-js' */).HTTPParser;
  681. var VERSION = process.version.match(/[0-9]+/g).map(function(n) { return parseInt(n, 10) });
  682. var TYPES = {
  683. request: NodeHTTPParser.REQUEST || 'request',
  684. response: NodeHTTPParser.RESPONSE || 'response'
  685. };
  686. var HttpParser = function(type) {
  687. this._type = type;
  688. this._parser = new NodeHTTPParser(TYPES[type]);
  689. this._complete = false;
  690. this.headers = {};
  691. var current = null,
  692. self = this;
  693. this._parser.onHeaderField = function(b, start, length) {
  694. current = b.toString('utf8', start, start + length).toLowerCase();
  695. };
  696. this._parser.onHeaderValue = function(b, start, length) {
  697. var value = b.toString('utf8', start, start + length);
  698. if (self.headers.hasOwnProperty(current))
  699. self.headers[current] += ', ' + value;
  700. else
  701. self.headers[current] = value;
  702. };
  703. this._parser.onHeadersComplete = this._parser[NodeHTTPParser.kOnHeadersComplete] =
  704. function(majorVersion, minorVersion, headers, method, pathname, statusCode) {
  705. var info = arguments[0];
  706. if (typeof info === 'object') {
  707. method = info.method;
  708. pathname = info.url;
  709. statusCode = info.statusCode;
  710. headers = info.headers;
  711. }
  712. self.method = (typeof method === 'number') ? HttpParser.METHODS[method] : method;
  713. self.statusCode = statusCode;
  714. self.url = pathname;
  715. if (!headers) return;
  716. for (var i = 0, n = headers.length, key, value; i < n; i += 2) {
  717. key = headers[i].toLowerCase();
  718. value = headers[i+1];
  719. if (self.headers.hasOwnProperty(key))
  720. self.headers[key] += ', ' + value;
  721. else
  722. self.headers[key] = value;
  723. }
  724. self._complete = true;
  725. };
  726. };
  727. HttpParser.METHODS = {
  728. 0: 'DELETE',
  729. 1: 'GET',
  730. 2: 'HEAD',
  731. 3: 'POST',
  732. 4: 'PUT',
  733. 5: 'CONNECT',
  734. 6: 'OPTIONS',
  735. 7: 'TRACE',
  736. 8: 'COPY',
  737. 9: 'LOCK',
  738. 10: 'MKCOL',
  739. 11: 'MOVE',
  740. 12: 'PROPFIND',
  741. 13: 'PROPPATCH',
  742. 14: 'SEARCH',
  743. 15: 'UNLOCK',
  744. 16: 'BIND',
  745. 17: 'REBIND',
  746. 18: 'UNBIND',
  747. 19: 'ACL',
  748. 20: 'REPORT',
  749. 21: 'MKACTIVITY',
  750. 22: 'CHECKOUT',
  751. 23: 'MERGE',
  752. 24: 'M-SEARCH',
  753. 25: 'NOTIFY',
  754. 26: 'SUBSCRIBE',
  755. 27: 'UNSUBSCRIBE',
  756. 28: 'PATCH',
  757. 29: 'PURGE',
  758. 30: 'MKCALENDAR',
  759. 31: 'LINK',
  760. 32: 'UNLINK'
  761. };
  762. if (VERSION[0] === 0 && VERSION[1] === 12) {
  763. HttpParser.METHODS[16] = 'REPORT';
  764. HttpParser.METHODS[17] = 'MKACTIVITY';
  765. HttpParser.METHODS[18] = 'CHECKOUT';
  766. HttpParser.METHODS[19] = 'MERGE';
  767. HttpParser.METHODS[20] = 'M-SEARCH';
  768. HttpParser.METHODS[21] = 'NOTIFY';
  769. HttpParser.METHODS[22] = 'SUBSCRIBE';
  770. HttpParser.METHODS[23] = 'UNSUBSCRIBE';
  771. HttpParser.METHODS[24] = 'PATCH';
  772. HttpParser.METHODS[25] = 'PURGE';
  773. }
  774. HttpParser.prototype.isComplete = function() {
  775. return this._complete;
  776. };
  777. HttpParser.prototype.parse = function(chunk) {
  778. var consumed = this._parser.execute(chunk, 0, chunk.length);
  779. if (typeof consumed !== 'number') {
  780. this.error = consumed;
  781. this._complete = true;
  782. return;
  783. }
  784. if (VERSION[0] === 0 && VERSION[1] < 6) consumed += 1;
  785. if (this._complete)
  786. this.body = (consumed < chunk.length)
  787. ? chunk.slice(consumed)
  788. : new Buffer(0);
  789. };
  790. module.exports = HttpParser;
  791. }],
  792. [/* 8 */ 'http-parser-js', '/http-parser.js', function(exports, module, __filename, __dirname, __meta) {
  793. /*jshint node:true */
  794. var assert = require('assert');
  795. exports.HTTPParser = HTTPParser;
  796. function HTTPParser(type) {
  797. assert.ok(type === HTTPParser.REQUEST || type === HTTPParser.RESPONSE);
  798. this.type = type;
  799. this.state = type + '_LINE';
  800. this.info = {
  801. headers: [],
  802. upgrade: false
  803. };
  804. this.trailers = [];
  805. this.line = '';
  806. this.isChunked = false;
  807. this.connection = '';
  808. this.headerSize = 0; // for preventing too big headers
  809. this.body_bytes = null;
  810. this.isUserCall = false;
  811. this.hadError = false;
  812. }
  813. HTTPParser.encoding = 'ascii';
  814. HTTPParser.maxHeaderSize = 80 * 1024; // maxHeaderSize (in bytes) is configurable, but 80kb by default;
  815. HTTPParser.REQUEST = 'REQUEST';
  816. HTTPParser.RESPONSE = 'RESPONSE';
  817. var kOnHeaders = HTTPParser.kOnHeaders = 0;
  818. var kOnHeadersComplete = HTTPParser.kOnHeadersComplete = 1;
  819. var kOnBody = HTTPParser.kOnBody = 2;
  820. var kOnMessageComplete = HTTPParser.kOnMessageComplete = 3;
  821. // Some handler stubs, needed for compatibility
  822. HTTPParser.prototype[kOnHeaders] =
  823. HTTPParser.prototype[kOnHeadersComplete] =
  824. HTTPParser.prototype[kOnBody] =
  825. HTTPParser.prototype[kOnMessageComplete] = function () {};
  826. var compatMode0_12 = true;
  827. Object.defineProperty(HTTPParser, 'kOnExecute', {
  828. get: function () {
  829. // hack for backward compatibility
  830. compatMode0_12 = false;
  831. return 4;
  832. }
  833. });
  834. var methods = exports.methods = HTTPParser.methods = [
  835. 'DELETE',
  836. 'GET',
  837. 'HEAD',
  838. 'POST',
  839. 'PUT',
  840. 'CONNECT',
  841. 'OPTIONS',
  842. 'TRACE',
  843. 'COPY',
  844. 'LOCK',
  845. 'MKCOL',
  846. 'MOVE',
  847. 'PROPFIND',
  848. 'PROPPATCH',
  849. 'SEARCH',
  850. 'UNLOCK',
  851. 'BIND',
  852. 'REBIND',
  853. 'UNBIND',
  854. 'ACL',
  855. 'REPORT',
  856. 'MKACTIVITY',
  857. 'CHECKOUT',
  858. 'MERGE',
  859. 'M-SEARCH',
  860. 'NOTIFY',
  861. 'SUBSCRIBE',
  862. 'UNSUBSCRIBE',
  863. 'PATCH',
  864. 'PURGE',
  865. 'MKCALENDAR',
  866. 'LINK',
  867. 'UNLINK'
  868. ];
  869. var method_connect = methods.indexOf('CONNECT');
  870. HTTPParser.prototype.reinitialize = HTTPParser;
  871. HTTPParser.prototype.close =
  872. HTTPParser.prototype.pause =
  873. HTTPParser.prototype.resume =
  874. HTTPParser.prototype.free = function () {};
  875. HTTPParser.prototype._compatMode0_11 = false;
  876. HTTPParser.prototype.getAsyncId = function() { return 0; };
  877. var headerState = {
  878. REQUEST_LINE: true,
  879. RESPONSE_LINE: true,
  880. HEADER: true
  881. };
  882. HTTPParser.prototype.execute = function (chunk, start, length) {
  883. if (!(this instanceof HTTPParser)) {
  884. throw new TypeError('not a HTTPParser');
  885. }
  886. // backward compat to node < 0.11.4
  887. // Note: the start and length params were removed in newer version
  888. start = start || 0;
  889. length = typeof length === 'number' ? length : chunk.length;
  890. this.chunk = chunk;
  891. this.offset = start;
  892. var end = this.end = start + length;
  893. try {
  894. while (this.offset < end) {
  895. if (this[this.state]()) {
  896. break;
  897. }
  898. }
  899. } catch (err) {
  900. if (this.isUserCall) {
  901. throw err;
  902. }
  903. this.hadError = true;
  904. return err;
  905. }
  906. this.chunk = null;
  907. length = this.offset - start;
  908. if (headerState[this.state]) {
  909. this.headerSize += length;
  910. if (this.headerSize > HTTPParser.maxHeaderSize) {
  911. return new Error('max header size exceeded');
  912. }
  913. }
  914. return length;
  915. };
  916. var stateFinishAllowed = {
  917. REQUEST_LINE: true,
  918. RESPONSE_LINE: true,
  919. BODY_RAW: true
  920. };
  921. HTTPParser.prototype.finish = function () {
  922. if (this.hadError) {
  923. return;
  924. }
  925. if (!stateFinishAllowed[this.state]) {
  926. return new Error('invalid state for EOF');
  927. }
  928. if (this.state === 'BODY_RAW') {
  929. this.userCall()(this[kOnMessageComplete]());
  930. }
  931. };
  932. // These three methods are used for an internal speed optimization, and it also
  933. // works if theses are noops. Basically consume() asks us to read the bytes
  934. // ourselves, but if we don't do it we get them through execute().
  935. HTTPParser.prototype.consume =
  936. HTTPParser.prototype.unconsume =
  937. HTTPParser.prototype.getCurrentBuffer = function () {};
  938. //For correct error handling - see HTTPParser#execute
  939. //Usage: this.userCall()(userFunction('arg'));
  940. HTTPParser.prototype.userCall = function () {
  941. this.isUserCall = true;
  942. var self = this;
  943. return function (ret) {
  944. self.isUserCall = false;
  945. return ret;
  946. };
  947. };
  948. HTTPParser.prototype.nextRequest = function () {
  949. this.userCall()(this[kOnMessageComplete]());
  950. this.reinitialize(this.type);
  951. };
  952. HTTPParser.prototype.consumeLine = function () {
  953. var end = this.end,
  954. chunk = this.chunk;
  955. for (var i = this.offset; i < end; i++) {
  956. if (chunk[i] === 0x0a) { // \n
  957. var line = this.line + chunk.toString(HTTPParser.encoding, this.offset, i);
  958. if (line.charAt(line.length - 1) === '\r') {
  959. line = line.substr(0, line.length - 1);
  960. }
  961. this.line = '';
  962. this.offset = i + 1;
  963. return line;
  964. }
  965. }
  966. //line split over multiple chunks
  967. this.line += chunk.toString(HTTPParser.encoding, this.offset, this.end);
  968. this.offset = this.end;
  969. };
  970. var headerExp = /^([^: \t]+):[ \t]*((?:.*[^ \t])|)/;
  971. var headerContinueExp = /^[ \t]+(.*[^ \t])/;
  972. HTTPParser.prototype.parseHeader = function (line, headers) {
  973. if (line.indexOf('\r') !== -1) {
  974. throw parseErrorCode('HPE_LF_EXPECTED');
  975. }
  976. var match = headerExp.exec(line);
  977. var k = match && match[1];
  978. if (k) { // skip empty string (malformed header)
  979. headers.push(k);
  980. headers.push(match[2]);
  981. } else {
  982. var matchContinue = headerContinueExp.exec(line);
  983. if (matchContinue && headers.length) {
  984. if (headers[headers.length - 1]) {
  985. headers[headers.length - 1] += ' ';
  986. }
  987. headers[headers.length - 1] += matchContinue[1];
  988. }
  989. }
  990. };
  991. var requestExp = /^([A-Z-]+) ([^ ]+) HTTP\/(\d)\.(\d)$/;
  992. HTTPParser.prototype.REQUEST_LINE = function () {
  993. var line = this.consumeLine();
  994. if (!line) {
  995. return;
  996. }
  997. var match = requestExp.exec(line);
  998. if (match === null) {
  999. throw parseErrorCode('HPE_INVALID_CONSTANT');
  1000. }
  1001. this.info.method = this._compatMode0_11 ? match[1] : methods.indexOf(match[1]);
  1002. if (this.info.method === -1) {
  1003. throw new Error('invalid request method');
  1004. }
  1005. this.info.url = match[2];
  1006. this.info.versionMajor = +match[3];
  1007. this.info.versionMinor = +match[4];
  1008. this.body_bytes = 0;
  1009. this.state = 'HEADER';
  1010. };
  1011. var responseExp = /^HTTP\/(\d)\.(\d) (\d{3}) ?(.*)$/;
  1012. HTTPParser.prototype.RESPONSE_LINE = function () {
  1013. var line = this.consumeLine();
  1014. if (!line) {
  1015. return;
  1016. }
  1017. var match = responseExp.exec(line);
  1018. if (match === null) {
  1019. throw parseErrorCode('HPE_INVALID_CONSTANT');
  1020. }
  1021. this.info.versionMajor = +match[1];
  1022. this.info.versionMinor = +match[2];
  1023. var statusCode = this.info.statusCode = +match[3];
  1024. this.info.statusMessage = match[4];
  1025. // Implied zero length.
  1026. if ((statusCode / 100 | 0) === 1 || statusCode === 204 || statusCode === 304) {
  1027. this.body_bytes = 0;
  1028. }
  1029. this.state = 'HEADER';
  1030. };
  1031. HTTPParser.prototype.shouldKeepAlive = function () {
  1032. if (this.info.versionMajor > 0 && this.info.versionMinor > 0) {
  1033. if (this.connection.indexOf('close') !== -1) {
  1034. return false;
  1035. }
  1036. } else if (this.connection.indexOf('keep-alive') === -1) {
  1037. return false;
  1038. }
  1039. if (this.body_bytes !== null || this.isChunked) { // || skipBody
  1040. return true;
  1041. }
  1042. return false;
  1043. };
  1044. HTTPParser.prototype.HEADER = function () {
  1045. var line = this.consumeLine();
  1046. if (line === undefined) {
  1047. return;
  1048. }
  1049. var info = this.info;
  1050. if (line) {
  1051. this.parseHeader(line, info.headers);
  1052. } else {
  1053. var headers = info.headers;
  1054. var hasContentLength = false;
  1055. var currentContentLengthValue;
  1056. var hasUpgradeHeader = false;
  1057. for (var i = 0; i < headers.length; i += 2) {
  1058. switch (headers[i].toLowerCase()) {
  1059. case 'transfer-encoding':
  1060. this.isChunked = headers[i + 1].toLowerCase() === 'chunked';
  1061. break;
  1062. case 'content-length':
  1063. currentContentLengthValue = +headers[i + 1];
  1064. if (hasContentLength) {
  1065. // Fix duplicate Content-Length header with same values.
  1066. // Throw error only if values are different.
  1067. // Known issues:
  1068. // https://github.com/request/request/issues/2091#issuecomment-328715113
  1069. // https://github.com/nodejs/node/issues/6517#issuecomment-216263771
  1070. if (currentContentLengthValue !== this.body_bytes) {
  1071. throw parseErrorCode('HPE_UNEXPECTED_CONTENT_LENGTH');
  1072. }
  1073. } else {
  1074. hasContentLength = true;
  1075. this.body_bytes = currentContentLengthValue;
  1076. }
  1077. break;
  1078. case 'connection':
  1079. this.connection += headers[i + 1].toLowerCase();
  1080. break;
  1081. case 'upgrade':
  1082. hasUpgradeHeader = true;
  1083. break;
  1084. }
  1085. }
  1086. // if both isChunked and hasContentLength, isChunked wins
  1087. // This is required so the body is parsed using the chunked method, and matches
  1088. // Chrome's behavior. We could, maybe, ignore them both (would get chunked
  1089. // encoding into the body), and/or disable shouldKeepAlive to be more
  1090. // resilient.
  1091. if (this.isChunked && hasContentLength) {
  1092. hasContentLength = false;
  1093. this.body_bytes = null;
  1094. }
  1095. // Logic from https://github.com/nodejs/http-parser/blob/921d5585515a153fa00e411cf144280c59b41f90/http_parser.c#L1727-L1737
  1096. // "For responses, "Upgrade: foo" and "Connection: upgrade" are
  1097. // mandatory only when it is a 101 Switching Protocols response,
  1098. // otherwise it is purely informational, to announce support.
  1099. if (hasUpgradeHeader && this.connection.indexOf('upgrade') != -1) {
  1100. info.upgrade = this.type === HTTPParser.REQUEST || info.statusCode === 101;
  1101. } else {
  1102. info.upgrade = info.method === method_connect;
  1103. }
  1104. info.shouldKeepAlive = this.shouldKeepAlive();
  1105. //problem which also exists in original node: we should know skipBody before calling onHeadersComplete
  1106. var skipBody;
  1107. if (compatMode0_12) {
  1108. skipBody = this.userCall()(this[kOnHeadersComplete](info));
  1109. } else {
  1110. skipBody = this.userCall()(this[kOnHeadersComplete](info.versionMajor,
  1111. info.versionMinor, info.headers, info.method, info.url, info.statusCode,
  1112. info.statusMessage, info.upgrade, info.shouldKeepAlive));
  1113. }
  1114. if (skipBody === 2) {
  1115. this.nextRequest();
  1116. return true;
  1117. } else if (this.isChunked && !skipBody) {
  1118. this.state = 'BODY_CHUNKHEAD';
  1119. } else if (skipBody || this.body_bytes === 0) {
  1120. this.nextRequest();
  1121. // For older versions of node (v6.x and older?), that return skipBody=1 or skipBody=true,
  1122. // need this "return true;" if it's an upgrade request.
  1123. return info.upgrade;
  1124. } else if (this.body_bytes === null) {
  1125. this.state = 'BODY_RAW';
  1126. } else {
  1127. this.state = 'BODY_SIZED';
  1128. }
  1129. }
  1130. };
  1131. HTTPParser.prototype.BODY_CHUNKHEAD = function () {
  1132. var line = this.consumeLine();
  1133. if (line === undefined) {
  1134. return;
  1135. }
  1136. this.body_bytes = parseInt(line, 16);
  1137. if (!this.body_bytes) {
  1138. this.state = 'BODY_CHUNKTRAILERS';
  1139. } else {
  1140. this.state = 'BODY_CHUNK';
  1141. }
  1142. };
  1143. HTTPParser.prototype.BODY_CHUNK = function () {
  1144. var length = Math.min(this.end - this.offset, this.body_bytes);
  1145. this.userCall()(this[kOnBody](this.chunk, this.offset, length));
  1146. this.offset += length;
  1147. this.body_bytes -= length;
  1148. if (!this.body_bytes) {
  1149. this.state = 'BODY_CHUNKEMPTYLINE';
  1150. }
  1151. };
  1152. HTTPParser.prototype.BODY_CHUNKEMPTYLINE = function () {
  1153. var line = this.consumeLine();
  1154. if (line === undefined) {
  1155. return;
  1156. }
  1157. assert.equal(line, '');
  1158. this.state = 'BODY_CHUNKHEAD';
  1159. };
  1160. HTTPParser.prototype.BODY_CHUNKTRAILERS = function () {
  1161. var line = this.consumeLine();
  1162. if (line === undefined) {
  1163. return;
  1164. }
  1165. if (line) {
  1166. this.parseHeader(line, this.trailers);
  1167. } else {
  1168. if (this.trailers.length) {
  1169. this.userCall()(this[kOnHeaders](this.trailers, ''));
  1170. }
  1171. this.nextRequest();
  1172. }
  1173. };
  1174. HTTPParser.prototype.BODY_RAW = function () {
  1175. var length = this.end - this.offset;
  1176. this.userCall()(this[kOnBody](this.chunk, this.offset, length));
  1177. this.offset = this.end;
  1178. };
  1179. HTTPParser.prototype.BODY_SIZED = function () {
  1180. var length = Math.min(this.end - this.offset, this.body_bytes);
  1181. this.userCall()(this[kOnBody](this.chunk, this.offset, length));
  1182. this.offset += length;
  1183. this.body_bytes -= length;
  1184. if (!this.body_bytes) {
  1185. this.nextRequest();
  1186. }
  1187. };
  1188. // backward compat to node < 0.11.6
  1189. ['Headers', 'HeadersComplete', 'Body', 'MessageComplete'].forEach(function (name) {
  1190. var k = HTTPParser['kOn' + name];
  1191. Object.defineProperty(HTTPParser.prototype, 'on' + name, {
  1192. get: function () {
  1193. return this[k];
  1194. },
  1195. set: function (to) {
  1196. // hack for backward compatibility
  1197. this._compatMode0_11 = true;
  1198. method_connect = 'CONNECT';
  1199. return (this[k] = to);
  1200. }
  1201. });
  1202. });
  1203. function parseErrorCode(code) {
  1204. var err = new Error('Parse Error');
  1205. err.code = code;
  1206. return err;
  1207. }
  1208. }],
  1209. [/* 9 */ 'websocket-driver', '/lib/websocket/driver/hybi.js', function(exports, module, __filename, __dirname, __meta) {
  1210. 'use strict';
  1211. var crypto = require('crypto'),
  1212. util = require('util'),
  1213. Extensions = __node_require__(10 /* 'websocket-extensions' */),
  1214. Base = __node_require__(2 /* './base' */),
  1215. Frame = __node_require__(17 /* './hybi/frame' */),
  1216. Message = __node_require__(18 /* './hybi/message' */);
  1217. var Hybi = function(request, url, options) {
  1218. Base.apply(this, arguments);
  1219. this._extensions = new Extensions();
  1220. this._stage = 0;
  1221. this._masking = this._options.masking;
  1222. this._protocols = this._options.protocols || [];
  1223. this._requireMasking = this._options.requireMasking;
  1224. this._pingCallbacks = {};
  1225. if (typeof this._protocols === 'string')
  1226. this._protocols = this._protocols.split(/ *, */);
  1227. if (!this._request) return;
  1228. var secKey = this._request.headers['sec-websocket-key'],
  1229. protos = this._request.headers['sec-websocket-protocol'],
  1230. version = this._request.headers['sec-websocket-version'],
  1231. supported = this._protocols;
  1232. this._headers.set('Upgrade', 'websocket');
  1233. this._headers.set('Connection', 'Upgrade');
  1234. this._headers.set('Sec-WebSocket-Accept', Hybi.generateAccept(secKey));
  1235. if (protos !== undefined) {
  1236. if (typeof protos === 'string') protos = protos.split(/ *, */);
  1237. this.protocol = protos.filter(function(p) { return supported.indexOf(p) >= 0 })[0];
  1238. if (this.protocol) this._headers.set('Sec-WebSocket-Protocol', this.protocol);
  1239. }
  1240. this.version = 'hybi-' + version;
  1241. };
  1242. util.inherits(Hybi, Base);
  1243. Hybi.mask = function(payload, mask, offset) {
  1244. if (!mask || mask.length === 0) return payload;
  1245. offset = offset || 0;
  1246. for (var i = 0, n = payload.length - offset; i < n; i++) {
  1247. payload[offset + i] = payload[offset + i] ^ mask[i % 4];
  1248. }
  1249. return payload;
  1250. };
  1251. Hybi.generateAccept = function(key) {
  1252. var sha1 = crypto.createHash('sha1');
  1253. sha1.update(key + Hybi.GUID);
  1254. return sha1.digest('base64');
  1255. };
  1256. Hybi.GUID = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11';
  1257. var instance = {
  1258. FIN: 0x80,
  1259. MASK: 0x80,
  1260. RSV1: 0x40,
  1261. RSV2: 0x20,
  1262. RSV3: 0x10,
  1263. OPCODE: 0x0F,
  1264. LENGTH: 0x7F,
  1265. OPCODES: {
  1266. continuation: 0,
  1267. text: 1,
  1268. binary: 2,
  1269. close: 8,
  1270. ping: 9,
  1271. pong: 10
  1272. },
  1273. OPCODE_CODES: [0, 1, 2, 8, 9, 10],
  1274. MESSAGE_OPCODES: [0, 1, 2],
  1275. OPENING_OPCODES: [1, 2],
  1276. ERRORS: {
  1277. normal_closure: 1000,
  1278. going_away: 1001,
  1279. protocol_error: 1002,
  1280. unacceptable: 1003,
  1281. encoding_error: 1007,
  1282. policy_violation: 1008,
  1283. too_large: 1009,
  1284. extension_error: 1010,
  1285. unexpected_condition: 1011
  1286. },
  1287. ERROR_CODES: [1000, 1001, 1002, 1003, 1007, 1008, 1009, 1010, 1011],
  1288. DEFAULT_ERROR_CODE: 1000,
  1289. MIN_RESERVED_ERROR: 3000,
  1290. MAX_RESERVED_ERROR: 4999,
  1291. // http://www.w3.org/International/questions/qa-forms-utf-8.en.php
  1292. UTF8_MATCH: /^([\x00-\x7F]|[\xC2-\xDF][\x80-\xBF]|\xE0[\xA0-\xBF][\x80-\xBF]|[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}|\xED[\x80-\x9F][\x80-\xBF]|\xF0[\x90-\xBF][\x80-\xBF]{2}|[\xF1-\xF3][\x80-\xBF]{3}|\xF4[\x80-\x8F][\x80-\xBF]{2})*$/,
  1293. addExtension: function(extension) {
  1294. this._extensions.add(extension);
  1295. return true;
  1296. },
  1297. parse: function(chunk) {
  1298. this._reader.put(chunk);
  1299. var buffer = true;
  1300. while (buffer) {
  1301. switch (this._stage) {
  1302. case 0:
  1303. buffer = this._reader.read(1);
  1304. if (buffer) this._parseOpcode(buffer[0]);
  1305. break;
  1306. case 1:
  1307. buffer = this._reader.read(1);
  1308. if (buffer) this._parseLength(buffer[0]);
  1309. break;
  1310. case 2:
  1311. buffer = this._reader.read(this._frame.lengthBytes);
  1312. if (buffer) this._parseExtendedLength(buffer);
  1313. break;
  1314. case 3:
  1315. buffer = this._reader.read(4);
  1316. if (buffer) {
  1317. this._stage = 4;
  1318. this._frame.maskingKey = buffer;
  1319. }
  1320. break;
  1321. case 4:
  1322. buffer = this._reader.read(this._frame.length);
  1323. if (buffer) {
  1324. this._stage = 0;
  1325. this._emitFrame(buffer);
  1326. }
  1327. break;
  1328. default:
  1329. buffer = null;
  1330. }
  1331. }
  1332. },
  1333. text: function(message) {
  1334. if (this.readyState > 1) return false;
  1335. return this.frame(message, 'text');
  1336. },
  1337. binary: function(message) {
  1338. if (this.readyState > 1) return false;
  1339. return this.frame(message, 'binary');
  1340. },
  1341. ping: function(message, callback) {
  1342. if (this.readyState > 1) return false;
  1343. message = message || '';
  1344. if (callback) this._pingCallbacks[message] = callback;
  1345. return this.frame(message, 'ping');
  1346. },
  1347. pong: function(message) {
  1348. if (this.readyState > 1) return false;
  1349. message = message ||'';
  1350. return this.frame(message, 'pong');
  1351. },
  1352. close: function(reason, code) {
  1353. reason = reason || '';
  1354. code = code || this.ERRORS.normal_closure;
  1355. if (this.readyState <= 0) {
  1356. this.readyState = 3;
  1357. this.emit('close', new Base.CloseEvent(code, reason));
  1358. return true;
  1359. } else if (this.readyState === 1) {
  1360. this.readyState = 2;
  1361. this._extensions.close(function() { this.frame(reason, 'close', code) }, this);
  1362. return true;
  1363. } else {
  1364. return false;
  1365. }
  1366. },
  1367. frame: function(buffer, type, code) {
  1368. if (this.readyState <= 0) return this._queue([buffer, type, code]);
  1369. if (this.readyState > 2) return false;
  1370. if (buffer instanceof Array) buffer = new Buffer(buffer);
  1371. if (typeof buffer === 'number') buffer = buffer.toString();
  1372. var message = new Message(),
  1373. isText = (typeof buffer === 'string'),
  1374. payload, copy;
  1375. message.rsv1 = message.rsv2 = message.rsv3 = false;
  1376. message.opcode = this.OPCODES[type || (isText ? 'text' : 'binary')];
  1377. payload = isText ? new Buffer(buffer, 'utf8') : buffer;
  1378. if (code) {
  1379. copy = payload;
  1380. payload = new Buffer(2 + copy.length);
  1381. payload.writeUInt16BE(code, 0);
  1382. copy.copy(payload, 2);
  1383. }
  1384. message.data = payload;
  1385. var onMessageReady = function(message) {
  1386. var frame = new Frame();
  1387. frame.final = true;
  1388. frame.rsv1 = message.rsv1;
  1389. frame.rsv2 = message.rsv2;
  1390. frame.rsv3 = message.rsv3;
  1391. frame.opcode = message.opcode;
  1392. frame.masked = !!this._masking;
  1393. frame.length = message.data.length;
  1394. frame.payload = message.data;
  1395. if (frame.masked) frame.maskingKey = crypto.randomBytes(4);
  1396. this._sendFrame(frame);
  1397. };
  1398. if (this.MESSAGE_OPCODES.indexOf(message.opcode) >= 0)
  1399. this._extensions.processOutgoingMessage(message, function(error, message) {
  1400. if (error) return this._fail('extension_error', error.message);
  1401. onMessageReady.call(this, message);
  1402. }, this);
  1403. else
  1404. onMessageReady.call(this, message);
  1405. return true;
  1406. },
  1407. _sendFrame: function(frame) {
  1408. var length = frame.length,
  1409. header = (length <= 125) ? 2 : (length <= 65535 ? 4 : 10),
  1410. offset = header + (frame.masked ? 4 : 0),
  1411. buffer = new Buffer(offset + length),
  1412. masked = frame.masked ? this.MASK : 0;
  1413. buffer[0] = (frame.final ? this.FIN : 0) |
  1414. (frame.rsv1 ? this.RSV1 : 0) |
  1415. (frame.rsv2 ? this.RSV2 : 0) |
  1416. (frame.rsv3 ? this.RSV3 : 0) |
  1417. frame.opcode;
  1418. if (length <= 125) {
  1419. buffer[1] = masked | length;
  1420. } else if (length <= 65535) {
  1421. buffer[1] = masked | 126;
  1422. buffer.writeUInt16BE(length, 2);
  1423. } else {
  1424. buffer[1] = masked | 127;
  1425. buffer.writeUInt32BE(Math.floor(length / 0x100000000), 2);
  1426. buffer.writeUInt32BE(length % 0x100000000, 6);
  1427. }
  1428. frame.payload.copy(buffer, offset);
  1429. if (frame.masked) {
  1430. frame.maskingKey.copy(buffer, header);
  1431. Hybi.mask(buffer, frame.maskingKey, offset);
  1432. }
  1433. this._write(buffer);
  1434. },
  1435. _handshakeResponse: function() {
  1436. try {
  1437. var extensions = this._extensions.generateResponse(this._request.headers['sec-websocket-extensions']);
  1438. } catch (e) {
  1439. return this._fail('protocol_error', e.message);
  1440. }
  1441. if (extensions) this._headers.set('Sec-WebSocket-Extensions', extensions);
  1442. var start = 'HTTP/1.1 101 Switching Protocols',
  1443. headers = [start, this._headers.toString(), ''];
  1444. return new Buffer(headers.join('\r\n'), 'utf8');
  1445. },
  1446. _shutdown: function(code, reason, error) {
  1447. delete this._frame;
  1448. delete this._message;
  1449. this._stage = 5;
  1450. var sendCloseFrame = (this.readyState === 1);
  1451. this.readyState = 2;
  1452. this._extensions.close(function() {
  1453. if (sendCloseFrame) this.frame(reason, 'close', code);
  1454. this.readyState = 3;
  1455. if (error) this.emit('error', new Error(reason));
  1456. this.emit('close', new Base.CloseEvent(code, reason));
  1457. }, this);
  1458. },
  1459. _fail: function(type, message) {
  1460. if (this.readyState > 1) return;
  1461. this._shutdown(this.ERRORS[type], message, true);
  1462. },
  1463. _parseOpcode: function(octet) {
  1464. var rsvs = [this.RSV1, this.RSV2, this.RSV3].map(function(rsv) {
  1465. return (octet & rsv) === rsv;
  1466. });
  1467. var frame = this._frame = new Frame();
  1468. frame.final = (octet & this.FIN) === this.FIN;
  1469. frame.rsv1 = rsvs[0];
  1470. frame.rsv2 = rsvs[1];
  1471. frame.rsv3 = rsvs[2];
  1472. frame.opcode = (octet & this.OPCODE);
  1473. this._stage = 1;
  1474. if (!this._extensions.validFrameRsv(frame))
  1475. return this._fail('protocol_error',
  1476. 'One or more reserved bits are on: reserved1 = ' + (frame.rsv1 ? 1 : 0) +
  1477. ', reserved2 = ' + (frame.rsv2 ? 1 : 0) +
  1478. ', reserved3 = ' + (frame.rsv3 ? 1 : 0));
  1479. if (this.OPCODE_CODES.indexOf(frame.opcode) < 0)
  1480. return this._fail('protocol_error', 'Unrecognized frame opcode: ' + frame.opcode);
  1481. if (this.MESSAGE_OPCODES.indexOf(frame.opcode) < 0 && !frame.final)
  1482. return this._fail('protocol_error', 'Received fragmented control frame: opcode = ' + frame.opcode);
  1483. if (this._message && this.OPENING_OPCODES.indexOf(frame.opcode) >= 0)
  1484. return this._fail('protocol_error', 'Received new data frame but previous continuous frame is unfinished');
  1485. },
  1486. _parseLength: function(octet) {
  1487. var frame = this._frame;
  1488. frame.masked = (octet & this.MASK) === this.MASK;
  1489. frame.length = (octet & this.LENGTH);
  1490. if (frame.length >= 0 && frame.length <= 125) {
  1491. this._stage = frame.masked ? 3 : 4;
  1492. if (!this._checkFrameLength()) return;
  1493. } else {
  1494. this._stage = 2;
  1495. frame.lengthBytes = (frame.length === 126 ? 2 : 8);
  1496. }
  1497. if (this._requireMasking && !frame.masked)
  1498. return this._fail('unacceptable', 'Received unmasked frame but masking is required');
  1499. },
  1500. _parseExtendedLength: function(buffer) {
  1501. var frame = this._frame;
  1502. frame.length = this._readUInt(buffer);
  1503. this._stage = frame.masked ? 3 : 4;
  1504. if (this.MESSAGE_OPCODES.indexOf(frame.opcode) < 0 && frame.length > 125)
  1505. return this._fail('protocol_error', 'Received control frame having too long payload: ' + frame.length);
  1506. if (!this._checkFrameLength()) return;
  1507. },
  1508. _checkFrameLength: function() {
  1509. var length = this._message ? this._message.length : 0;
  1510. if (length + this._frame.length > this._maxLength) {
  1511. this._fail('too_large', 'WebSocket frame length too large');
  1512. return false;
  1513. } else {
  1514. return true;
  1515. }
  1516. },
  1517. _emitFrame: function(buffer) {
  1518. var frame = this._frame,
  1519. payload = frame.payload = Hybi.mask(buffer, frame.maskingKey),
  1520. opcode = frame.opcode,
  1521. message,
  1522. code, reason,
  1523. callbacks, callback;
  1524. delete this._frame;
  1525. if (opcode === this.OPCODES.continuation) {
  1526. if (!this._message) return this._fail('protocol_error', 'Received unexpected continuation frame');
  1527. this._message.pushFrame(frame);
  1528. }
  1529. if (opcode === this.OPCODES.text || opcode === this.OPCODES.binary) {
  1530. this._message = new Message();
  1531. this._message.pushFrame(frame);
  1532. }
  1533. if (frame.final && this.MESSAGE_OPCODES.indexOf(opcode) >= 0)
  1534. return this._emitMessage(this._message);
  1535. if (opcode === this.OPCODES.close) {
  1536. code = (payload.length >= 2) ? payload.readUInt16BE(0) : null;
  1537. reason = (payload.length > 2) ? this._encode(payload.slice(2)) : null;
  1538. if (!(payload.length === 0) &&
  1539. !(code !== null && code >= this.MIN_RESERVED_ERROR && code <= this.MAX_RESERVED_ERROR) &&
  1540. this.ERROR_CODES.indexOf(code) < 0)
  1541. code = this.ERRORS.protocol_error;
  1542. if (payload.length > 125 || (payload.length > 2 && !reason))
  1543. code = this.ERRORS.protocol_error;
  1544. this._shutdown(code || this.DEFAULT_ERROR_CODE, reason || '');
  1545. }
  1546. if (opcode === this.OPCODES.ping) {
  1547. this.frame(payload, 'pong');
  1548. this.emit('ping', new Base.PingEvent(payload.toString()))
  1549. }
  1550. if (opcode === this.OPCODES.pong) {
  1551. callbacks = this._pingCallbacks;
  1552. message = this._encode(payload);
  1553. callback = callbacks[message];
  1554. delete callbacks[message];
  1555. if (callback) callback()
  1556. this.emit('pong', new Base.PongEvent(payload.toString()))
  1557. }
  1558. },
  1559. _emitMessage: function(message) {
  1560. var message = this._message;
  1561. message.read();
  1562. delete this._message;
  1563. this._extensions.processIncomingMessage(message, function(error, message) {
  1564. if (error) return this._fail('extension_error', error.message);
  1565. var payload = message.data;
  1566. if (message.opcode === this.OPCODES.text) payload = this._encode(payload);
  1567. if (payload === null)
  1568. return this._fail('encoding_error', 'Could not decode a text frame as UTF-8');
  1569. else
  1570. this.emit('message', new Base.MessageEvent(payload));
  1571. }, this);
  1572. },
  1573. _encode: function(buffer) {
  1574. try {
  1575. var string = buffer.toString('binary', 0, buffer.length);
  1576. if (!this.UTF8_MATCH.test(string)) return null;
  1577. } catch (e) {}
  1578. return buffer.toString('utf8', 0, buffer.length);
  1579. },
  1580. _readUInt: function(buffer) {
  1581. if (buffer.length === 2) return buffer.readUInt16BE(0);
  1582. return buffer.readUInt32BE(0) * 0x100000000 +
  1583. buffer.readUInt32BE(4);
  1584. }
  1585. };
  1586. for (var key in instance)
  1587. Hybi.prototype[key] = instance[key];
  1588. module.exports = Hybi;
  1589. }],
  1590. [/* 10 */ 'websocket-extensions', '/lib/websocket_extensions.js', function(exports, module, __filename, __dirname, __meta) {
  1591. 'use strict';
  1592. var Parser = __node_require__(11 /* './parser' */),
  1593. Pipeline = __node_require__(12 /* './pipeline' */);
  1594. var Extensions = function() {
  1595. this._rsv1 = this._rsv2 = this._rsv3 = null;
  1596. this._byName = {};
  1597. this._inOrder = [];
  1598. this._sessions = [];
  1599. this._index = {};
  1600. };
  1601. Extensions.MESSAGE_OPCODES = [1, 2];
  1602. var instance = {
  1603. add: function(ext) {
  1604. if (typeof ext.name !== 'string') throw new TypeError('extension.name must be a string');
  1605. if (ext.type !== 'permessage') throw new TypeError('extension.type must be "permessage"');
  1606. if (typeof ext.rsv1 !== 'boolean') throw new TypeError('extension.rsv1 must be true or false');
  1607. if (typeof ext.rsv2 !== 'boolean') throw new TypeError('extension.rsv2 must be true or false');
  1608. if (typeof ext.rsv3 !== 'boolean') throw new TypeError('extension.rsv3 must be true or false');
  1609. if (this._byName.hasOwnProperty(ext.name))
  1610. throw new TypeError('An extension with name "' + ext.name + '" is already registered');
  1611. this._byName[ext.name] = ext;
  1612. this._inOrder.push(ext);
  1613. },
  1614. generateOffer: function() {
  1615. var sessions = [],
  1616. offer = [],
  1617. index = {};
  1618. this._inOrder.forEach(function(ext) {
  1619. var session = ext.createClientSession();
  1620. if (!session) return;
  1621. var record = [ext, session];
  1622. sessions.push(record);
  1623. index[ext.name] = record;
  1624. var offers = session.generateOffer();
  1625. offers = offers ? [].concat(offers) : [];
  1626. offers.forEach(function(off) {
  1627. offer.push(Parser.serializeParams(ext.name, off));
  1628. }, this);
  1629. }, this);
  1630. this._sessions = sessions;
  1631. this._index = index;
  1632. return offer.length > 0 ? offer.join(', ') : null;
  1633. },
  1634. activate: function(header) {
  1635. var responses = Parser.parseHeader(header),
  1636. sessions = [];
  1637. responses.eachOffer(function(name, params) {
  1638. var record = this._index[name];
  1639. if (!record)
  1640. throw new Error('Server sent an extension response for unknown extension "' + name + '"');
  1641. var ext = record[0],
  1642. session = record[1],
  1643. reserved = this._reserved(ext);
  1644. if (reserved)
  1645. throw new Error('Server sent two extension responses that use the RSV' +
  1646. reserved[0] + ' bit: "' +
  1647. reserved[1] + '" and "' + ext.name + '"');
  1648. if (session.activate(params) !== true)
  1649. throw new Error('Server sent unacceptable extension parameters: ' +
  1650. Parser.serializeParams(name, params));
  1651. this._reserve(ext);
  1652. sessions.push(record);
  1653. }, this);
  1654. this._sessions = sessions;
  1655. this._pipeline = new Pipeline(sessions);
  1656. },
  1657. generateResponse: function(header) {
  1658. var sessions = [],
  1659. response = [],
  1660. offers = Parser.parseHeader(header);
  1661. this._inOrder.forEach(function(ext) {
  1662. var offer = offers.byName(ext.name);
  1663. if (offer.length === 0 || this._reserved(ext)) return;
  1664. var session = ext.createServerSession(offer);
  1665. if (!session) return;
  1666. this._reserve(ext);
  1667. sessions.push([ext, session]);
  1668. response.push(Parser.serializeParams(ext.name, session.generateResponse()));
  1669. }, this);
  1670. this._sessions = sessions;
  1671. this._pipeline = new Pipeline(sessions);
  1672. return response.length > 0 ? response.join(', ') : null;
  1673. },
  1674. validFrameRsv: function(frame) {
  1675. var allowed = {rsv1: false, rsv2: false, rsv3: false},
  1676. ext;
  1677. if (Extensions.MESSAGE_OPCODES.indexOf(frame.opcode) >= 0) {
  1678. for (var i = 0, n = this._sessions.length; i < n; i++) {
  1679. ext = this._sessions[i][0];
  1680. allowed.rsv1 = allowed.rsv1 || ext.rsv1;
  1681. allowed.rsv2 = allowed.rsv2 || ext.rsv2;
  1682. allowed.rsv3 = allowed.rsv3 || ext.rsv3;
  1683. }
  1684. }
  1685. return (allowed.rsv1 || !frame.rsv1) &&
  1686. (allowed.rsv2 || !frame.rsv2) &&
  1687. (allowed.rsv3 || !frame.rsv3);
  1688. },
  1689. processIncomingMessage: function(message, callback, context) {
  1690. this._pipeline.processIncomingMessage(message, callback, context);
  1691. },
  1692. processOutgoingMessage: function(message, callback, context) {
  1693. this._pipeline.processOutgoingMessage(message, callback, context);
  1694. },
  1695. close: function(callback, context) {
  1696. if (!this._pipeline) return callback.call(context);
  1697. this._pipeline.close(callback, context);
  1698. },
  1699. _reserve: function(ext) {
  1700. this._rsv1 = this._rsv1 || (ext.rsv1 && ext.name);
  1701. this._rsv2 = this._rsv2 || (ext.rsv2 && ext.name);
  1702. this._rsv3 = this._rsv3 || (ext.rsv3 && ext.name);
  1703. },
  1704. _reserved: function(ext) {
  1705. if (this._rsv1 && ext.rsv1) return [1, this._rsv1];
  1706. if (this._rsv2 && ext.rsv2) return [2, this._rsv2];
  1707. if (this._rsv3 && ext.rsv3) return [3, this._rsv3];
  1708. return false;
  1709. }
  1710. };
  1711. for (var key in instance)
  1712. Extensions.prototype[key] = instance[key];
  1713. module.exports = Extensions;
  1714. }],
  1715. [/* 11 */ 'websocket-extensions', '/lib/parser.js', function(exports, module, __filename, __dirname, __meta) {
  1716. 'use strict';
  1717. var TOKEN = /([!#\$%&'\*\+\-\.\^_`\|~0-9A-Za-z]+)/,
  1718. NOTOKEN = /([^!#\$%&'\*\+\-\.\^_`\|~0-9A-Za-z])/g,
  1719. QUOTED = /"((?:\\[\x00-\x7f]|[^\x00-\x08\x0a-\x1f\x7f"])*)"/,
  1720. PARAM = new RegExp(TOKEN.source + '(?:=(?:' + TOKEN.source + '|' + QUOTED.source + '))?'),
  1721. EXT = new RegExp(TOKEN.source + '(?: *; *' + PARAM.source + ')*', 'g'),
  1722. EXT_LIST = new RegExp('^' + EXT.source + '(?: *, *' + EXT.source + ')*$'),
  1723. NUMBER = /^-?(0|[1-9][0-9]*)(\.[0-9]+)?$/;
  1724. var hasOwnProperty = Object.prototype.hasOwnProperty;
  1725. var Parser = {
  1726. parseHeader: function(header) {
  1727. var offers = new Offers();
  1728. if (header === '' || header === undefined) return offers;
  1729. if (!EXT_LIST.test(header))
  1730. throw new SyntaxError('Invalid Sec-WebSocket-Extensions header: ' + header);
  1731. var values = header.match(EXT);
  1732. values.forEach(function(value) {
  1733. var params = value.match(new RegExp(PARAM.source, 'g')),
  1734. name = params.shift(),
  1735. offer = {};
  1736. params.forEach(function(param) {
  1737. var args = param.match(PARAM), key = args[1], data;
  1738. if (args[2] !== undefined) {
  1739. data = args[2];
  1740. } else if (args[3] !== undefined) {
  1741. data = args[3].replace(/\\/g, '');
  1742. } else {
  1743. data = true;
  1744. }
  1745. if (NUMBER.test(data)) data = parseFloat(data);
  1746. if (hasOwnProperty.call(offer, key)) {
  1747. offer[key] = [].concat(offer[key]);
  1748. offer[key].push(data);
  1749. } else {
  1750. offer[key] = data;
  1751. }
  1752. }, this);
  1753. offers.push(name, offer);
  1754. }, this);
  1755. return offers;
  1756. },
  1757. serializeParams: function(name, params) {
  1758. var values = [];
  1759. var print = function(key, value) {
  1760. if (value instanceof Array) {
  1761. value.forEach(function(v) { print(key, v) });
  1762. } else if (value === true) {
  1763. values.push(key);
  1764. } else if (typeof value === 'number') {
  1765. values.push(key + '=' + value);
  1766. } else if (NOTOKEN.test(value)) {
  1767. values.push(key + '="' + value.replace(/"/g, '\\"') + '"');
  1768. } else {
  1769. values.push(key + '=' + value);
  1770. }
  1771. };
  1772. for (var key in params) print(key, params[key]);
  1773. return [name].concat(values).join('; ');
  1774. }
  1775. };
  1776. var Offers = function() {
  1777. this._byName = {};
  1778. this._inOrder = [];
  1779. };
  1780. Offers.prototype.push = function(name, params) {
  1781. if (!hasOwnProperty.call(this._byName, name))
  1782. this._byName[name] = [];
  1783. this._byName[name].push(params);
  1784. this._inOrder.push({name: name, params: params});
  1785. };
  1786. Offers.prototype.eachOffer = function(callback, context) {
  1787. var list = this._inOrder;
  1788. for (var i = 0, n = list.length; i < n; i++)
  1789. callback.call(context, list[i].name, list[i].params);
  1790. };
  1791. Offers.prototype.byName = function(name) {
  1792. return this._byName[name] || [];
  1793. };
  1794. Offers.prototype.toArray = function() {
  1795. return this._inOrder.slice();
  1796. };
  1797. module.exports = Parser;
  1798. }],
  1799. [/* 12 */ 'websocket-extensions', '/lib/pipeline/index.js', function(exports, module, __filename, __dirname, __meta) {
  1800. 'use strict';
  1801. var Cell = __node_require__(13 /* './cell' */),
  1802. Pledge = __node_require__(16 /* './pledge' */);
  1803. var Pipeline = function(sessions) {
  1804. this._cells = sessions.map(function(session) { return new Cell(session) });
  1805. this._stopped = {incoming: false, outgoing: false};
  1806. };
  1807. Pipeline.prototype.processIncomingMessage = function(message, callback, context) {
  1808. if (this._stopped.incoming) return;
  1809. this._loop('incoming', this._cells.length - 1, -1, -1, message, callback, context);
  1810. };
  1811. Pipeline.prototype.processOutgoingMessage = function(message, callback, context) {
  1812. if (this._stopped.outgoing) return;
  1813. this._loop('outgoing', 0, this._cells.length, 1, message, callback, context);
  1814. };
  1815. Pipeline.prototype.close = function(callback, context) {
  1816. this._stopped = {incoming: true, outgoing: true};
  1817. var closed = this._cells.map(function(a) { return a.close() });
  1818. if (callback)
  1819. Pledge.all(closed).then(function() { callback.call(context) });
  1820. };
  1821. Pipeline.prototype._loop = function(direction, start, end, step, message, callback, context) {
  1822. var cells = this._cells,
  1823. n = cells.length,
  1824. self = this;
  1825. while (n--) cells[n].pending(direction);
  1826. var pipe = function(index, error, msg) {
  1827. if (index === end) return callback.call(context, error, msg);
  1828. cells[index][direction](error, msg, function(err, m) {
  1829. if (err) self._stopped[direction] = true;
  1830. pipe(index + step, err, m);
  1831. });
  1832. };
  1833. pipe(start, null, message);
  1834. };
  1835. module.exports = Pipeline;
  1836. }],
  1837. [/* 13 */ 'websocket-extensions', '/lib/pipeline/cell.js', function(exports, module, __filename, __dirname, __meta) {
  1838. 'use strict';
  1839. var Functor = __node_require__(14 /* './functor' */),
  1840. Pledge = __node_require__(16 /* './pledge' */);
  1841. var Cell = function(tuple) {
  1842. this._ext = tuple[0];
  1843. this._session = tuple[1];
  1844. this._functors = {
  1845. incoming: new Functor(this._session, 'processIncomingMessage'),
  1846. outgoing: new Functor(this._session, 'processOutgoingMessage')
  1847. };
  1848. };
  1849. Cell.prototype.pending = function(direction) {
  1850. var functor = this._functors[direction];
  1851. if (!functor._stopped) functor.pending += 1;
  1852. };
  1853. Cell.prototype.incoming = function(error, message, callback, context) {
  1854. this._exec('incoming', error, message, callback, context);
  1855. };
  1856. Cell.prototype.outgoing = function(error, message, callback, context) {
  1857. this._exec('outgoing', error, message, callback, context);
  1858. };
  1859. Cell.prototype.close = function() {
  1860. this._closed = this._closed || new Pledge();
  1861. this._doClose();
  1862. return this._closed;
  1863. };
  1864. Cell.prototype._exec = function(direction, error, message, callback, context) {
  1865. this._functors[direction].call(error, message, function(err, msg) {
  1866. if (err) err.message = this._ext.name + ': ' + err.message;
  1867. callback.call(context, err, msg);
  1868. this._doClose();
  1869. }, this);
  1870. };
  1871. Cell.prototype._doClose = function() {
  1872. var fin = this._functors.incoming,
  1873. fout = this._functors.outgoing;
  1874. if (!this._closed || fin.pending + fout.pending !== 0) return;
  1875. if (this._session) this._session.close();
  1876. this._session = null;
  1877. this._closed.done();
  1878. };
  1879. module.exports = Cell;
  1880. }],
  1881. [/* 14 */ 'websocket-extensions', '/lib/pipeline/functor.js', function(exports, module, __filename, __dirname, __meta) {
  1882. 'use strict';
  1883. var RingBuffer = __node_require__(15 /* './ring_buffer' */);
  1884. var Functor = function(session, method) {
  1885. this._session = session;
  1886. this._method = method;
  1887. this._queue = new RingBuffer(Functor.QUEUE_SIZE);
  1888. this._stopped = false;
  1889. this.pending = 0;
  1890. };
  1891. Functor.QUEUE_SIZE = 8;
  1892. Functor.prototype.call = function(error, message, callback, context) {
  1893. if (this._stopped) return;
  1894. var record = {error: error, message: message, callback: callback, context: context, done: false},
  1895. called = false,
  1896. self = this;
  1897. this._queue.push(record);
  1898. if (record.error) {
  1899. record.done = true;
  1900. this._stop();
  1901. return this._flushQueue();
  1902. }
  1903. var handler = function(err, msg) {
  1904. if (!(called ^ (called = true))) return;
  1905. if (err) {
  1906. self._stop();
  1907. record.error = err;
  1908. record.message = null;
  1909. } else {
  1910. record.message = msg;
  1911. }
  1912. record.done = true;
  1913. self._flushQueue();
  1914. };
  1915. try {
  1916. this._session[this._method](message, handler);
  1917. } catch (err) {
  1918. handler(err);
  1919. }
  1920. };
  1921. Functor.prototype._stop = function() {
  1922. this.pending = this._queue.length;
  1923. this._stopped = true;
  1924. };
  1925. Functor.prototype._flushQueue = function() {
  1926. var queue = this._queue, record;
  1927. while (queue.length > 0 && queue.peek().done) {
  1928. record = queue.shift();
  1929. if (record.error) {
  1930. this.pending = 0;
  1931. queue.clear();
  1932. } else {
  1933. this.pending -= 1;
  1934. }
  1935. record.callback.call(record.context, record.error, record.message);
  1936. }
  1937. };
  1938. module.exports = Functor;
  1939. }],
  1940. [/* 15 */ 'websocket-extensions', '/lib/pipeline/ring_buffer.js', function(exports, module, __filename, __dirname, __meta) {
  1941. 'use strict';
  1942. var RingBuffer = function(bufferSize) {
  1943. this._bufferSize = bufferSize;
  1944. this.clear();
  1945. };
  1946. RingBuffer.prototype.clear = function() {
  1947. this._buffer = new Array(this._bufferSize);
  1948. this._ringOffset = 0;
  1949. this._ringSize = this._bufferSize;
  1950. this._head = 0;
  1951. this._tail = 0;
  1952. this.length = 0;
  1953. };
  1954. RingBuffer.prototype.push = function(value) {
  1955. var expandBuffer = false,
  1956. expandRing = false;
  1957. if (this._ringSize < this._bufferSize) {
  1958. expandBuffer = (this._tail === 0);
  1959. } else if (this._ringOffset === this._ringSize) {
  1960. expandBuffer = true;
  1961. expandRing = (this._tail === 0);
  1962. }
  1963. if (expandBuffer) {
  1964. this._tail = this._bufferSize;
  1965. this._buffer = this._buffer.concat(new Array(this._bufferSize));
  1966. this._bufferSize = this._buffer.length;
  1967. if (expandRing)
  1968. this._ringSize = this._bufferSize;
  1969. }
  1970. this._buffer[this._tail] = value;
  1971. this.length += 1;
  1972. if (this._tail < this._ringSize) this._ringOffset += 1;
  1973. this._tail = (this._tail + 1) % this._bufferSize;
  1974. };
  1975. RingBuffer.prototype.peek = function() {
  1976. if (this.length === 0) return void 0;
  1977. return this._buffer[this._head];
  1978. };
  1979. RingBuffer.prototype.shift = function() {
  1980. if (this.length === 0) return void 0;
  1981. var value = this._buffer[this._head];
  1982. this._buffer[this._head] = void 0;
  1983. this.length -= 1;
  1984. this._ringOffset -= 1;
  1985. if (this._ringOffset === 0 && this.length > 0) {
  1986. this._head = this._ringSize;
  1987. this._ringOffset = this.length;
  1988. this._ringSize = this._bufferSize;
  1989. } else {
  1990. this._head = (this._head + 1) % this._ringSize;
  1991. }
  1992. return value;
  1993. };
  1994. module.exports = RingBuffer;
  1995. }],
  1996. [/* 16 */ 'websocket-extensions', '/lib/pipeline/pledge.js', function(exports, module, __filename, __dirname, __meta) {
  1997. 'use strict';
  1998. var RingBuffer = __node_require__(15 /* './ring_buffer' */);
  1999. var Pledge = function() {
  2000. this._complete = false;
  2001. this._callbacks = new RingBuffer(Pledge.QUEUE_SIZE);
  2002. };
  2003. Pledge.QUEUE_SIZE = 4;
  2004. Pledge.all = function(list) {
  2005. var pledge = new Pledge(),
  2006. pending = list.length,
  2007. n = pending;
  2008. if (pending === 0) pledge.done();
  2009. while (n--) list[n].then(function() {
  2010. pending -= 1;
  2011. if (pending === 0) pledge.done();
  2012. });
  2013. return pledge;
  2014. };
  2015. Pledge.prototype.then = function(callback) {
  2016. if (this._complete) callback();
  2017. else this._callbacks.push(callback);
  2018. };
  2019. Pledge.prototype.done = function() {
  2020. this._complete = true;
  2021. var callbacks = this._callbacks, callback;
  2022. while (callback = callbacks.shift()) callback();
  2023. };
  2024. module.exports = Pledge;
  2025. }],
  2026. [/* 17 */ 'websocket-driver', '/lib/websocket/driver/hybi/frame.js', function(exports, module, __filename, __dirname, __meta) {
  2027. 'use strict';
  2028. var Frame = function() {};
  2029. var instance = {
  2030. final: false,
  2031. rsv1: false,
  2032. rsv2: false,
  2033. rsv3: false,
  2034. opcode: null,
  2035. masked: false,
  2036. maskingKey: null,
  2037. lengthBytes: 1,
  2038. length: 0,
  2039. payload: null
  2040. };
  2041. for (var key in instance)
  2042. Frame.prototype[key] = instance[key];
  2043. module.exports = Frame;
  2044. }],
  2045. [/* 18 */ 'websocket-driver', '/lib/websocket/driver/hybi/message.js', function(exports, module, __filename, __dirname, __meta) {
  2046. 'use strict';
  2047. var Message = function() {
  2048. this.rsv1 = false;
  2049. this.rsv2 = false;
  2050. this.rsv3 = false;
  2051. this.opcode = null
  2052. this.length = 0;
  2053. this._chunks = [];
  2054. };
  2055. var instance = {
  2056. read: function() {
  2057. if (this.data) return this.data;
  2058. this.data = new Buffer(this.length);
  2059. var offset = 0;
  2060. for (var i = 0, n = this._chunks.length; i < n; i++) {
  2061. this._chunks[i].copy(this.data, offset);
  2062. offset += this._chunks[i].length;
  2063. }
  2064. return this.data;
  2065. },
  2066. pushFrame: function(frame) {
  2067. this.rsv1 = this.rsv1 || frame.rsv1;
  2068. this.rsv2 = this.rsv2 || frame.rsv2;
  2069. this.rsv3 = this.rsv3 || frame.rsv3;
  2070. if (this.opcode === null) this.opcode = frame.opcode;
  2071. this._chunks.push(frame.payload);
  2072. this.length += frame.length;
  2073. }
  2074. };
  2075. for (var key in instance)
  2076. Message.prototype[key] = instance[key];
  2077. module.exports = Message;
  2078. }],
  2079. [/* 19 */ 'websocket-driver', '/lib/websocket/driver/proxy.js', function(exports, module, __filename, __dirname, __meta) {
  2080. 'use strict';
  2081. var Stream = require('stream').Stream,
  2082. url = require('url'),
  2083. util = require('util'),
  2084. Base = __node_require__(2 /* './base' */),
  2085. Headers = __node_require__(4 /* './headers' */),
  2086. HttpParser = __node_require__(7 /* '../http_parser' */);
  2087. var PORTS = {'ws:': 80, 'wss:': 443};
  2088. var Proxy = function(client, origin, options) {
  2089. this._client = client;
  2090. this._http = new HttpParser('response');
  2091. this._origin = (typeof client.url === 'object') ? client.url : url.parse(client.url);
  2092. this._url = (typeof origin === 'object') ? origin : url.parse(origin);
  2093. this._options = options || {};
  2094. this._state = 0;
  2095. this.readable = this.writable = true;
  2096. this._paused = false;
  2097. this._headers = new Headers();
  2098. this._headers.set('Host', this._origin.host);
  2099. this._headers.set('Connection', 'keep-alive');
  2100. this._headers.set('Proxy-Connection', 'keep-alive');
  2101. var auth = this._url.auth && new Buffer(this._url.auth, 'utf8').toString('base64');
  2102. if (auth) this._headers.set('Proxy-Authorization', 'Basic ' + auth);
  2103. };
  2104. util.inherits(Proxy, Stream);
  2105. var instance = {
  2106. setHeader: function(name, value) {
  2107. if (this._state !== 0) return false;
  2108. this._headers.set(name, value);
  2109. return true;
  2110. },
  2111. start: function() {
  2112. if (this._state !== 0) return false;
  2113. this._state = 1;
  2114. var origin = this._origin,
  2115. port = origin.port || PORTS[origin.protocol],
  2116. start = 'CONNECT ' + origin.hostname + ':' + port + ' HTTP/1.1';
  2117. var headers = [start, this._headers.toString(), ''];
  2118. this.emit('data', new Buffer(headers.join('\r\n'), 'utf8'));
  2119. return true;
  2120. },
  2121. pause: function() {
  2122. this._paused = true;
  2123. },
  2124. resume: function() {
  2125. this._paused = false;
  2126. this.emit('drain');
  2127. },
  2128. write: function(chunk) {
  2129. if (!this.writable) return false;
  2130. this._http.parse(chunk);
  2131. if (!this._http.isComplete()) return !this._paused;
  2132. this.statusCode = this._http.statusCode;
  2133. this.headers = this._http.headers;
  2134. if (this.statusCode === 200) {
  2135. this.emit('connect', new Base.ConnectEvent());
  2136. } else {
  2137. var message = "Can't establish a connection to the server at " + this._origin.href;
  2138. this.emit('error', new Error(message));
  2139. }
  2140. this.end();
  2141. return !this._paused;
  2142. },
  2143. end: function(chunk) {
  2144. if (!this.writable) return;
  2145. if (chunk !== undefined) this.write(chunk);
  2146. this.readable = this.writable = false;
  2147. this.emit('close');
  2148. this.emit('end');
  2149. },
  2150. destroy: function() {
  2151. this.end();
  2152. }
  2153. };
  2154. for (var key in instance)
  2155. Proxy.prototype[key] = instance[key];
  2156. module.exports = Proxy;
  2157. }],
  2158. [/* 20 */ 'websocket-driver', '/lib/websocket/driver/server.js', function(exports, module, __filename, __dirname, __meta) {
  2159. 'use strict';
  2160. var util = require('util'),
  2161. HttpParser = __node_require__(7 /* '../http_parser' */),
  2162. Base = __node_require__(2 /* './base' */),
  2163. Draft75 = __node_require__(21 /* './draft75' */),
  2164. Draft76 = __node_require__(22 /* './draft76' */),
  2165. Hybi = __node_require__(9 /* './hybi' */);
  2166. var Server = function(options) {
  2167. Base.call(this, null, null, options);
  2168. this._http = new HttpParser('request');
  2169. };
  2170. util.inherits(Server, Base);
  2171. var instance = {
  2172. EVENTS: ['open', 'message', 'error', 'close'],
  2173. _bindEventListeners: function() {
  2174. this.messages.on('error', function() {});
  2175. this.on('error', function() {});
  2176. },
  2177. parse: function(chunk) {
  2178. if (this._delegate) return this._delegate.parse(chunk);
  2179. this._http.parse(chunk);
  2180. if (!this._http.isComplete()) return;
  2181. this.method = this._http.method;
  2182. this.url = this._http.url;
  2183. this.headers = this._http.headers;
  2184. this.body = this._http.body;
  2185. var self = this;
  2186. this._delegate = Server.http(this, this._options);
  2187. this._delegate.messages = this.messages;
  2188. this._delegate.io = this.io;
  2189. this._open();
  2190. this.EVENTS.forEach(function(event) {
  2191. this._delegate.on(event, function(e) { self.emit(event, e) });
  2192. }, this);
  2193. this.protocol = this._delegate.protocol;
  2194. this.version = this._delegate.version;
  2195. this.parse(this._http.body);
  2196. this.emit('connect', new Base.ConnectEvent());
  2197. },
  2198. _open: function() {
  2199. this.__queue.forEach(function(msg) {
  2200. this._delegate[msg[0]].apply(this._delegate, msg[1]);
  2201. }, this);
  2202. this.__queue = [];
  2203. }
  2204. };
  2205. ['addExtension', 'setHeader', 'start', 'frame', 'text', 'binary', 'ping', 'close'].forEach(function(method) {
  2206. instance[method] = function() {
  2207. if (this._delegate) {
  2208. return this._delegate[method].apply(this._delegate, arguments);
  2209. } else {
  2210. this.__queue.push([method, arguments]);
  2211. return true;
  2212. }
  2213. };
  2214. });
  2215. for (var key in instance)
  2216. Server.prototype[key] = instance[key];
  2217. Server.isSecureRequest = function(request) {
  2218. if (request.connection && request.connection.authorized !== undefined) return true;
  2219. if (request.socket && request.socket.secure) return true;
  2220. var headers = request.headers;
  2221. if (!headers) return false;
  2222. if (headers['https'] === 'on') return true;
  2223. if (headers['x-forwarded-ssl'] === 'on') return true;
  2224. if (headers['x-forwarded-scheme'] === 'https') return true;
  2225. if (headers['x-forwarded-proto'] === 'https') return true;
  2226. return false;
  2227. };
  2228. Server.determineUrl = function(request) {
  2229. var scheme = this.isSecureRequest(request) ? 'wss:' : 'ws:';
  2230. return scheme + '//' + request.headers.host + request.url;
  2231. };
  2232. Server.http = function(request, options) {
  2233. options = options || {};
  2234. if (options.requireMasking === undefined) options.requireMasking = true;
  2235. var headers = request.headers,
  2236. url = this.determineUrl(request);
  2237. if (headers['sec-websocket-version'])
  2238. return new Hybi(request, url, options);
  2239. else if (headers['sec-websocket-key1'])
  2240. return new Draft76(request, url, options);
  2241. else
  2242. return new Draft75(request, url, options);
  2243. };
  2244. module.exports = Server;
  2245. }],
  2246. [/* 21 */ 'websocket-driver', '/lib/websocket/driver/draft75.js', function(exports, module, __filename, __dirname, __meta) {
  2247. 'use strict';
  2248. var Base = __node_require__(2 /* './base' */),
  2249. util = require('util');
  2250. var Draft75 = function(request, url, options) {
  2251. Base.apply(this, arguments);
  2252. this._stage = 0;
  2253. this.version = 'hixie-75';
  2254. this._headers.set('Upgrade', 'WebSocket');
  2255. this._headers.set('Connection', 'Upgrade');
  2256. this._headers.set('WebSocket-Origin', this._request.headers.origin);
  2257. this._headers.set('WebSocket-Location', this.url);
  2258. };
  2259. util.inherits(Draft75, Base);
  2260. var instance = {
  2261. close: function() {
  2262. if (this.readyState === 3) return false;
  2263. this.readyState = 3;
  2264. this.emit('close', new Base.CloseEvent(null, null));
  2265. return true;
  2266. },
  2267. parse: function(chunk) {
  2268. if (this.readyState > 1) return;
  2269. this._reader.put(chunk);
  2270. this._reader.eachByte(function(octet) {
  2271. var message;
  2272. switch (this._stage) {
  2273. case -1:
  2274. this._body.push(octet);
  2275. this._sendHandshakeBody();
  2276. break;
  2277. case 0:
  2278. this._parseLeadingByte(octet);
  2279. break;
  2280. case 1:
  2281. this._length = (octet & 0x7F) + 128 * this._length;
  2282. if (this._closing && this._length === 0) {
  2283. return this.close();
  2284. }
  2285. else if ((octet & 0x80) !== 0x80) {
  2286. if (this._length === 0) {
  2287. this._stage = 0;
  2288. }
  2289. else {
  2290. this._skipped = 0;
  2291. this._stage = 2;
  2292. }
  2293. }
  2294. break;
  2295. case 2:
  2296. if (octet === 0xFF) {
  2297. this._stage = 0;
  2298. message = new Buffer(this._buffer).toString('utf8', 0, this._buffer.length);
  2299. this.emit('message', new Base.MessageEvent(message));
  2300. }
  2301. else {
  2302. if (this._length) {
  2303. this._skipped += 1;
  2304. if (this._skipped === this._length)
  2305. this._stage = 0;
  2306. } else {
  2307. this._buffer.push(octet);
  2308. if (this._buffer.length > this._maxLength) return this.close();
  2309. }
  2310. }
  2311. break;
  2312. }
  2313. }, this);
  2314. },
  2315. frame: function(buffer) {
  2316. if (this.readyState === 0) return this._queue([buffer]);
  2317. if (this.readyState > 1) return false;
  2318. if (typeof buffer !== 'string') buffer = buffer.toString();
  2319. var payload = new Buffer(buffer, 'utf8'),
  2320. frame = new Buffer(payload.length + 2);
  2321. frame[0] = 0x00;
  2322. frame[payload.length + 1] = 0xFF;
  2323. payload.copy(frame, 1);
  2324. this._write(frame);
  2325. return true;
  2326. },
  2327. _handshakeResponse: function() {
  2328. var start = 'HTTP/1.1 101 Web Socket Protocol Handshake',
  2329. headers = [start, this._headers.toString(), ''];
  2330. return new Buffer(headers.join('\r\n'), 'utf8');
  2331. },
  2332. _parseLeadingByte: function(octet) {
  2333. if ((octet & 0x80) === 0x80) {
  2334. this._length = 0;
  2335. this._stage = 1;
  2336. } else {
  2337. delete this._length;
  2338. delete this._skipped;
  2339. this._buffer = [];
  2340. this._stage = 2;
  2341. }
  2342. }
  2343. };
  2344. for (var key in instance)
  2345. Draft75.prototype[key] = instance[key];
  2346. module.exports = Draft75;
  2347. }],
  2348. [/* 22 */ 'websocket-driver', '/lib/websocket/driver/draft76.js', function(exports, module, __filename, __dirname, __meta) {
  2349. 'use strict';
  2350. var Base = __node_require__(2 /* './base' */),
  2351. Draft75 = __node_require__(21 /* './draft75' */),
  2352. crypto = require('crypto'),
  2353. util = require('util');
  2354. var numberFromKey = function(key) {
  2355. return parseInt(key.match(/[0-9]/g).join(''), 10);
  2356. };
  2357. var spacesInKey = function(key) {
  2358. return key.match(/ /g).length;
  2359. };
  2360. var Draft76 = function(request, url, options) {
  2361. Draft75.apply(this, arguments);
  2362. this._stage = -1;
  2363. this._body = [];
  2364. this.version = 'hixie-76';
  2365. this._headers.clear();
  2366. this._headers.set('Upgrade', 'WebSocket');
  2367. this._headers.set('Connection', 'Upgrade');
  2368. this._headers.set('Sec-WebSocket-Origin', this._request.headers.origin);
  2369. this._headers.set('Sec-WebSocket-Location', this.url);
  2370. };
  2371. util.inherits(Draft76, Draft75);
  2372. var instance = {
  2373. BODY_SIZE: 8,
  2374. start: function() {
  2375. if (!Draft75.prototype.start.call(this)) return false;
  2376. this._started = true;
  2377. this._sendHandshakeBody();
  2378. return true;
  2379. },
  2380. close: function() {
  2381. if (this.readyState === 3) return false;
  2382. this._write(new Buffer([0xFF, 0x00]));
  2383. this.readyState = 3;
  2384. this.emit('close', new Base.CloseEvent(null, null));
  2385. return true;
  2386. },
  2387. _handshakeResponse: function() {
  2388. var headers = this._request.headers,
  2389. key1 = headers['sec-websocket-key1'],
  2390. number1 = numberFromKey(key1),
  2391. spaces1 = spacesInKey(key1),
  2392. key2 = headers['sec-websocket-key2'],
  2393. number2 = numberFromKey(key2),
  2394. spaces2 = spacesInKey(key2);
  2395. if (number1 % spaces1 !== 0 || number2 % spaces2 !== 0) {
  2396. this.emit('error', new Error('Client sent invalid Sec-WebSocket-Key headers'));
  2397. this.close();
  2398. return null;
  2399. }
  2400. this._keyValues = [number1 / spaces1, number2 / spaces2];
  2401. var start = 'HTTP/1.1 101 WebSocket Protocol Handshake',
  2402. headers = [start, this._headers.toString(), ''];
  2403. return new Buffer(headers.join('\r\n'), 'binary');
  2404. },
  2405. _handshakeSignature: function() {
  2406. if (this._body.length < this.BODY_SIZE) return null;
  2407. var md5 = crypto.createHash('md5'),
  2408. buffer = new Buffer(8 + this.BODY_SIZE);
  2409. buffer.writeUInt32BE(this._keyValues[0], 0);
  2410. buffer.writeUInt32BE(this._keyValues[1], 4);
  2411. new Buffer(this._body).copy(buffer, 8, 0, this.BODY_SIZE);
  2412. md5.update(buffer);
  2413. return new Buffer(md5.digest('binary'), 'binary');
  2414. },
  2415. _sendHandshakeBody: function() {
  2416. if (!this._started) return;
  2417. var signature = this._handshakeSignature();
  2418. if (!signature) return;
  2419. this._write(signature);
  2420. this._stage = 0;
  2421. this._open();
  2422. if (this._body.length > this.BODY_SIZE)
  2423. this.parse(this._body.slice(this.BODY_SIZE));
  2424. },
  2425. _parseLeadingByte: function(octet) {
  2426. if (octet !== 0xFF)
  2427. return Draft75.prototype._parseLeadingByte.call(this, octet);
  2428. this._closing = true;
  2429. this._length = 0;
  2430. this._stage = 1;
  2431. }
  2432. };
  2433. for (var key in instance)
  2434. Draft76.prototype[key] = instance[key];
  2435. module.exports = Draft76;
  2436. }],
  2437. [/* 23 */ 'faye-websocket', '/lib/faye/websocket/api.js', function(exports, module, __filename, __dirname, __meta) {
  2438. var Stream = require('stream').Stream,
  2439. util = require('util'),
  2440. driver = __node_require__(1 /* 'websocket-driver' */),
  2441. EventTarget = __node_require__(24 /* './api/event_target' */),
  2442. Event = __node_require__(25 /* './api/event' */);
  2443. var API = function(options) {
  2444. options = options || {};
  2445. driver.validateOptions(options, ['headers', 'extensions', 'maxLength', 'ping', 'proxy', 'tls', 'ca']);
  2446. this.readable = this.writable = true;
  2447. var headers = options.headers;
  2448. if (headers) {
  2449. for (var name in headers) this._driver.setHeader(name, headers[name]);
  2450. }
  2451. var extensions = options.extensions;
  2452. if (extensions) {
  2453. [].concat(extensions).forEach(this._driver.addExtension, this._driver);
  2454. }
  2455. this._ping = options.ping;
  2456. this._pingId = 0;
  2457. this.readyState = API.CONNECTING;
  2458. this.bufferedAmount = 0;
  2459. this.protocol = '';
  2460. this.url = this._driver.url;
  2461. this.version = this._driver.version;
  2462. var self = this;
  2463. this._driver.on('open', function(e) { self._open() });
  2464. this._driver.on('message', function(e) { self._receiveMessage(e.data) });
  2465. this._driver.on('close', function(e) { self._beginClose(e.reason, e.code) });
  2466. this._driver.on('error', function(error) {
  2467. self._emitError(error.message);
  2468. });
  2469. this.on('error', function() {});
  2470. this._driver.messages.on('drain', function() {
  2471. self.emit('drain');
  2472. });
  2473. if (this._ping)
  2474. this._pingTimer = setInterval(function() {
  2475. self._pingId += 1;
  2476. self.ping(self._pingId.toString());
  2477. }, this._ping * 1000);
  2478. this._configureStream();
  2479. if (!this._proxy) {
  2480. this._stream.pipe(this._driver.io);
  2481. this._driver.io.pipe(this._stream);
  2482. }
  2483. };
  2484. util.inherits(API, Stream);
  2485. API.CONNECTING = 0;
  2486. API.OPEN = 1;
  2487. API.CLOSING = 2;
  2488. API.CLOSED = 3;
  2489. API.CLOSE_TIMEOUT = 30000;
  2490. var instance = {
  2491. write: function(data) {
  2492. return this.send(data);
  2493. },
  2494. end: function(data) {
  2495. if (data !== undefined) this.send(data);
  2496. this.close();
  2497. },
  2498. pause: function() {
  2499. return this._driver.messages.pause();
  2500. },
  2501. resume: function() {
  2502. return this._driver.messages.resume();
  2503. },
  2504. send: function(data) {
  2505. if (this.readyState > API.OPEN) return false;
  2506. if (!(data instanceof Buffer)) data = String(data);
  2507. return this._driver.messages.write(data);
  2508. },
  2509. ping: function(message, callback) {
  2510. if (this.readyState > API.OPEN) return false;
  2511. return this._driver.ping(message, callback);
  2512. },
  2513. close: function(code, reason) {
  2514. if (code === undefined) code = 1000;
  2515. if (reason === undefined) reason = '';
  2516. if (code !== 1000 && (code < 3000 || code > 4999))
  2517. throw new Error("Failed to execute 'close' on WebSocket: " +
  2518. "The code must be either 1000, or between 3000 and 4999. " +
  2519. code + " is neither.");
  2520. if (this.readyState !== API.CLOSED) this.readyState = API.CLOSING;
  2521. var self = this;
  2522. this._closeTimer = setTimeout(function() {
  2523. self._beginClose('', 1006);
  2524. }, API.CLOSE_TIMEOUT);
  2525. this._driver.close(reason, code);
  2526. },
  2527. _configureStream: function() {
  2528. var self = this;
  2529. this._stream.setTimeout(0);
  2530. this._stream.setNoDelay(true);
  2531. ['close', 'end'].forEach(function(event) {
  2532. this._stream.on(event, function() { self._finalizeClose() });
  2533. }, this);
  2534. this._stream.on('error', function(error) {
  2535. self._emitError('Network error: ' + self.url + ': ' + error.message);
  2536. self._finalizeClose();
  2537. });
  2538. },
  2539. _open: function() {
  2540. if (this.readyState !== API.CONNECTING) return;
  2541. this.readyState = API.OPEN;
  2542. this.protocol = this._driver.protocol || '';
  2543. var event = new Event('open');
  2544. event.initEvent('open', false, false);
  2545. this.dispatchEvent(event);
  2546. },
  2547. _receiveMessage: function(data) {
  2548. if (this.readyState > API.OPEN) return false;
  2549. if (this.readable) this.emit('data', data);
  2550. var event = new Event('message', {data: data});
  2551. event.initEvent('message', false, false);
  2552. this.dispatchEvent(event);
  2553. },
  2554. _emitError: function(message) {
  2555. if (this.readyState >= API.CLOSING) return;
  2556. var event = new Event('error', {message: message});
  2557. event.initEvent('error', false, false);
  2558. this.dispatchEvent(event);
  2559. },
  2560. _beginClose: function(reason, code) {
  2561. if (this.readyState === API.CLOSED) return;
  2562. this.readyState = API.CLOSING;
  2563. this._closeParams = [reason, code];
  2564. if (this._stream) {
  2565. this._stream.destroy();
  2566. if (!this._stream.readable) this._finalizeClose();
  2567. }
  2568. },
  2569. _finalizeClose: function() {
  2570. if (this._closeTimer) clearTimeout(this._closeTimer);
  2571. if (this.readyState === API.CLOSED) return;
  2572. this.readyState = API.CLOSED;
  2573. if (this._pingTimer) clearInterval(this._pingTimer);
  2574. if (this._stream) this._stream.end();
  2575. if (this.readable) this.emit('end');
  2576. this.readable = this.writable = false;
  2577. var reason = this._closeParams ? this._closeParams[0] : '',
  2578. code = this._closeParams ? this._closeParams[1] : 1006;
  2579. var event = new Event('close', {code: code, reason: reason});
  2580. event.initEvent('close', false, false);
  2581. this.dispatchEvent(event);
  2582. }
  2583. };
  2584. for (var method in instance) API.prototype[method] = instance[method];
  2585. for (var key in EventTarget) API.prototype[key] = EventTarget[key];
  2586. module.exports = API;
  2587. }],
  2588. [/* 24 */ 'faye-websocket', '/lib/faye/websocket/api/event_target.js', function(exports, module, __filename, __dirname, __meta) {
  2589. var Event = __node_require__(25 /* './event' */);
  2590. var EventTarget = {
  2591. onopen: null,
  2592. onmessage: null,
  2593. onerror: null,
  2594. onclose: null,
  2595. addEventListener: function(eventType, listener, useCapture) {
  2596. this.on(eventType, listener);
  2597. },
  2598. removeEventListener: function(eventType, listener, useCapture) {
  2599. this.removeListener(eventType, listener);
  2600. },
  2601. dispatchEvent: function(event) {
  2602. event.target = event.currentTarget = this;
  2603. event.eventPhase = Event.AT_TARGET;
  2604. if (this['on' + event.type])
  2605. this['on' + event.type](event);
  2606. this.emit(event.type, event);
  2607. }
  2608. };
  2609. module.exports = EventTarget;
  2610. }],
  2611. [/* 25 */ 'faye-websocket', '/lib/faye/websocket/api/event.js', function(exports, module, __filename, __dirname, __meta) {
  2612. var Event = function(eventType, options) {
  2613. this.type = eventType;
  2614. for (var key in options)
  2615. this[key] = options[key];
  2616. };
  2617. Event.prototype.initEvent = function(eventType, canBubble, cancelable) {
  2618. this.type = eventType;
  2619. this.bubbles = canBubble;
  2620. this.cancelable = cancelable;
  2621. };
  2622. Event.prototype.stopPropagation = function() {};
  2623. Event.prototype.preventDefault = function() {};
  2624. Event.CAPTURING_PHASE = 1;
  2625. Event.AT_TARGET = 2;
  2626. Event.BUBBLING_PHASE = 3;
  2627. module.exports = Event;
  2628. }],
  2629. [/* 26 */ 'faye-websocket', '/lib/faye/websocket/client.js', function(exports, module, __filename, __dirname, __meta) {
  2630. var util = require('util'),
  2631. net = require('net'),
  2632. tls = require('tls'),
  2633. url = require('url'),
  2634. driver = __node_require__(1 /* 'websocket-driver' */),
  2635. API = __node_require__(23 /* './api' */),
  2636. Event = __node_require__(25 /* './api/event' */);
  2637. var DEFAULT_PORTS = {'http:': 80, 'https:': 443, 'ws:':80, 'wss:': 443},
  2638. SECURE_PROTOCOLS = ['https:', 'wss:'];
  2639. var Client = function(_url, protocols, options) {
  2640. options = options || {};
  2641. this.url = _url;
  2642. this._driver = driver.client(this.url, {maxLength: options.maxLength, protocols: protocols});
  2643. ['open', 'error'].forEach(function(event) {
  2644. this._driver.on(event, function() {
  2645. self.headers = self._driver.headers;
  2646. self.statusCode = self._driver.statusCode;
  2647. });
  2648. }, this);
  2649. var proxy = options.proxy || {},
  2650. endpoint = url.parse(proxy.origin || this.url),
  2651. port = endpoint.port || DEFAULT_PORTS[endpoint.protocol],
  2652. secure = SECURE_PROTOCOLS.indexOf(endpoint.protocol) >= 0,
  2653. onConnect = function() { self._onConnect() },
  2654. netOptions = options.net || {},
  2655. originTLS = options.tls || {},
  2656. socketTLS = proxy.origin ? (proxy.tls || {}) : originTLS,
  2657. self = this;
  2658. netOptions.host = socketTLS.host = endpoint.hostname;
  2659. netOptions.port = socketTLS.port = port;
  2660. originTLS.ca = originTLS.ca || options.ca;
  2661. socketTLS.servername = socketTLS.servername || endpoint.hostname;
  2662. this._stream = secure
  2663. ? tls.connect(socketTLS, onConnect)
  2664. : net.connect(netOptions, onConnect);
  2665. if (proxy.origin) this._configureProxy(proxy, originTLS);
  2666. API.call(this, options);
  2667. };
  2668. util.inherits(Client, API);
  2669. Client.prototype._onConnect = function() {
  2670. var worker = this._proxy || this._driver;
  2671. worker.start();
  2672. };
  2673. Client.prototype._configureProxy = function(proxy, originTLS) {
  2674. var uri = url.parse(this.url),
  2675. secure = SECURE_PROTOCOLS.indexOf(uri.protocol) >= 0,
  2676. self = this,
  2677. name;
  2678. this._proxy = this._driver.proxy(proxy.origin);
  2679. if (proxy.headers) {
  2680. for (name in proxy.headers) this._proxy.setHeader(name, proxy.headers[name]);
  2681. }
  2682. this._proxy.pipe(this._stream, {end: false});
  2683. this._stream.pipe(this._proxy);
  2684. this._proxy.on('connect', function() {
  2685. if (secure) {
  2686. var options = {socket: self._stream, servername: uri.hostname};
  2687. for (name in originTLS) options[name] = originTLS[name];
  2688. self._stream = tls.connect(options);
  2689. self._configureStream();
  2690. }
  2691. self._driver.io.pipe(self._stream);
  2692. self._stream.pipe(self._driver.io);
  2693. self._driver.start();
  2694. });
  2695. this._proxy.on('error', function(error) {
  2696. self._driver.emit('error', error);
  2697. });
  2698. };
  2699. module.exports = Client;
  2700. }],
  2701. [/* 27 */ 'faye-websocket', '/lib/faye/eventsource.js', function(exports, module, __filename, __dirname, __meta) {
  2702. var Stream = require('stream').Stream,
  2703. util = require('util'),
  2704. driver = __node_require__(1 /* 'websocket-driver' */),
  2705. Headers = __node_require__(4 /* 'websocket-driver/lib/websocket/driver/headers' */),
  2706. API = __node_require__(23 /* './websocket/api' */),
  2707. EventTarget = __node_require__(24 /* './websocket/api/event_target' */),
  2708. Event = __node_require__(25 /* './websocket/api/event' */);
  2709. var EventSource = function(request, response, options) {
  2710. this.writable = true;
  2711. options = options || {};
  2712. this._stream = response.socket;
  2713. this._ping = options.ping || this.DEFAULT_PING;
  2714. this._retry = options.retry || this.DEFAULT_RETRY;
  2715. var scheme = driver.isSecureRequest(request) ? 'https:' : 'http:';
  2716. this.url = scheme + '//' + request.headers.host + request.url;
  2717. this.lastEventId = request.headers['last-event-id'] || '';
  2718. this.readyState = API.CONNECTING;
  2719. var headers = new Headers(),
  2720. self = this;
  2721. if (options.headers) {
  2722. for (var key in options.headers) headers.set(key, options.headers[key]);
  2723. }
  2724. if (!this._stream || !this._stream.writable) return;
  2725. process.nextTick(function() { self._open() });
  2726. this._stream.setTimeout(0);
  2727. this._stream.setNoDelay(true);
  2728. var handshake = 'HTTP/1.1 200 OK\r\n' +
  2729. 'Content-Type: text/event-stream\r\n' +
  2730. 'Cache-Control: no-cache, no-store\r\n' +
  2731. 'Connection: close\r\n' +
  2732. headers.toString() +
  2733. '\r\n' +
  2734. 'retry: ' + Math.floor(this._retry * 1000) + '\r\n\r\n';
  2735. this._write(handshake);
  2736. this._stream.on('drain', function() { self.emit('drain') });
  2737. if (this._ping)
  2738. this._pingTimer = setInterval(function() { self.ping() }, this._ping * 1000);
  2739. ['error', 'end'].forEach(function(event) {
  2740. self._stream.on(event, function() { self.close() });
  2741. });
  2742. };
  2743. util.inherits(EventSource, Stream);
  2744. EventSource.isEventSource = function(request) {
  2745. if (request.method !== 'GET') return false;
  2746. var accept = (request.headers.accept || '').split(/\s*,\s*/);
  2747. return accept.indexOf('text/event-stream') >= 0;
  2748. };
  2749. var instance = {
  2750. DEFAULT_PING: 10,
  2751. DEFAULT_RETRY: 5,
  2752. _write: function(chunk) {
  2753. if (!this.writable) return false;
  2754. try {
  2755. return this._stream.write(chunk, 'utf8');
  2756. } catch (e) {
  2757. return false;
  2758. }
  2759. },
  2760. _open: function() {
  2761. if (this.readyState !== API.CONNECTING) return;
  2762. this.readyState = API.OPEN;
  2763. var event = new Event('open');
  2764. event.initEvent('open', false, false);
  2765. this.dispatchEvent(event);
  2766. },
  2767. write: function(message) {
  2768. return this.send(message);
  2769. },
  2770. end: function(message) {
  2771. if (message !== undefined) this.write(message);
  2772. this.close();
  2773. },
  2774. send: function(message, options) {
  2775. if (this.readyState > API.OPEN) return false;
  2776. message = String(message).replace(/(\r\n|\r|\n)/g, '$1data: ');
  2777. options = options || {};
  2778. var frame = '';
  2779. if (options.event) frame += 'event: ' + options.event + '\r\n';
  2780. if (options.id) frame += 'id: ' + options.id + '\r\n';
  2781. frame += 'data: ' + message + '\r\n\r\n';
  2782. return this._write(frame);
  2783. },
  2784. ping: function() {
  2785. return this._write(':\r\n\r\n');
  2786. },
  2787. close: function() {
  2788. if (this.readyState > API.OPEN) return false;
  2789. this.readyState = API.CLOSED;
  2790. this.writable = false;
  2791. if (this._pingTimer) clearInterval(this._pingTimer);
  2792. if (this._stream) this._stream.end();
  2793. var event = new Event('close');
  2794. event.initEvent('close', false, false);
  2795. this.dispatchEvent(event);
  2796. return true;
  2797. }
  2798. };
  2799. for (var method in instance) EventSource.prototype[method] = instance[method];
  2800. for (var key in EventTarget) EventSource.prototype[key] = EventTarget[key];
  2801. module.exports = EventSource;
  2802. }]
  2803. ];
  2804. var __node_cache__ = [];
  2805. function __node_error__(location) {
  2806. var err = new Error('Cannot find module \'' + location + '\'');
  2807. err.code = 'MODULE_NOT_FOUND';
  2808. throw err;
  2809. }
  2810. function __node_require__(id) {
  2811. if ((id >>> 0) !== id || id > __node_modules__.length)
  2812. return __node_error__(id);
  2813. while (__node_cache__.length <= id)
  2814. __node_cache__.push(null);
  2815. var cache = __node_cache__[id];
  2816. if (cache)
  2817. return cache.exports;
  2818. var mod = __node_modules__[id];
  2819. var name = mod[0];
  2820. var path = mod[1];
  2821. var func = mod[2];
  2822. var meta;
  2823. var _exports = exports;
  2824. var _module = module;
  2825. if (id !== 0) {
  2826. _exports = {};
  2827. _module = {
  2828. id: '/' + name + path,
  2829. exports: _exports,
  2830. parent: module.parent,
  2831. filename: module.filename,
  2832. loaded: false,
  2833. children: module.children,
  2834. paths: module.paths
  2835. };
  2836. }
  2837. __node_cache__[id] = _module;
  2838. try {
  2839. func.call(_exports, _exports, _module,
  2840. __filename, __dirname, meta);
  2841. } catch (e) {
  2842. __node_cache__[id] = null;
  2843. throw e;
  2844. }
  2845. __node_modules__[id] = null;
  2846. if (id !== 0)
  2847. _module.loaded = true;
  2848. return _module.exports;
  2849. }
  2850. __node_require__(0);