Guest User

Untitled

a guest
Jun 20th, 2018
67
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.25 KB | None | 0 0
  1. var net = require('net'),
  2. sys = require('sys');
  3.  
  4. function WSServer(port, ip) {
  5. if(!port) throw('You should assign a port to listen.');
  6. this.port = port;
  7. this.ip = ip||'127.0.0.1';
  8. this.server = null;
  9. var clients = {};
  10. var state = {
  11. handshaked: false
  12. },
  13. requestHeaders = [
  14. /^GET (.*) HTTP\/1\.1$/,
  15. /^Upgrade: WebSocket$/,
  16. /^Connection: Upgrade$/,
  17. /^Host: (.*)$/,
  18. /^Origin: (.*)$/,
  19. /^Sec-WebSocket-Protocol: (.*)$/,
  20. /^Sec-WebSocket-Key1: (.*)$/,
  21. /^Sec-WebSocket-Key2: (.*)$/
  22. ],
  23. responseHeaders = [
  24. 'HTTP/1.1 101 WebSocket Protocol Handshake',
  25. 'Upgrade: WebSocket',
  26. 'Connection: Upgrade',
  27. 'Sec-WebSocket-Origin: {ORIGIN}',
  28. 'Sec-WebSocket-Location: {LOCATION}',
  29. 'Sec-WebSocket-Protocol: {PROTOCOL}'
  30. ];
  31.  
  32. function _abort(stream){
  33. stream.end();
  34. }
  35.  
  36. function pack(num) {
  37. return new Buffer([
  38. num >> 24 & 0xFF,
  39. num >> 16 & 0xFF,
  40. num >> 8 & 0xFF,
  41. num & 0xFF
  42. ]);
  43. };
  44.  
  45. function _getParams(_data, _requestHeaders){
  46. var _responseParam = {
  47. resource:null,
  48. upgrade:null,
  49. connection:null,
  50. host:null,
  51. port:null,
  52. origin:null,
  53. protocol:null,
  54. chalenge:null,
  55. key1:null,
  56. key2:null,
  57. key3:null,
  58. location:null,
  59. k1s:null,
  60. k2s:null
  61. };
  62.  
  63. var data1 = _data.toString('utf8',0,_data.length);
  64. var fields = data1.split('\r\n');
  65. fields.map(function(item){
  66. _requestHeaders.map(function(rule,j){
  67. var matches = [],t;
  68. matches = item.match(rule);
  69. if(matches && matches.length > 0){
  70. switch(j) {
  71. case 0:
  72. if(matches.length==2)
  73. _responseParam.resource = matches[1];
  74. break;
  75. case 1:
  76. if(matches.length==1)
  77. _responseParam.upgrade = matches[0];
  78. break;
  79. case 2:
  80. if(matches.length==1)
  81. _responseParam.connection = matches[0];
  82. break;
  83. case 3:
  84. if(matches.length==2)
  85. t = matches[1];
  86. if(t.indexOf(':') > -1) {
  87. t = t.split(':');
  88. _responseParam.host = t[0];
  89. _responseParam.port = t[1];
  90. } else {
  91. _responseParam.host = t;
  92. }
  93. break;
  94. case 4:
  95. if(matches.length==2)
  96. _responseParam.origin = matches[1];
  97. break;
  98. case 5:
  99. if(matches.length==2)
  100. _responseParam.protocol = matches[1];
  101. break;
  102. case 6:
  103. if(matches.length==2)
  104. t = parseInt(matches[1].replace(/[^\d]/g,''),10);
  105. _responseParam.k1s = matches[1].replace(/[^ ]/g,'').length;
  106. if(0 === (t%_responseParam.k1s) && _responseParam.k1s !== 0 && t < 4294967295) {
  107. _responseParam.key1 = t/_responseParam.k1s;
  108. }
  109. break;
  110. case 7:
  111. if(matches.length==2)
  112. t = parseInt(matches[1].replace(/[^\d]/g,''));
  113. _responseParam.k2s = matches[1].replace(/[^ ]/g,'').length;
  114. if(0 === (t%_responseParam.k2s) && _responseParam.k2s !== 0 && t < 4294967295) {
  115. _responseParam.key2 = t/_responseParam.k2s;
  116. }
  117. break;
  118. }
  119. }
  120. });
  121. });
  122. for(var m=0;m<_data.length;m++) {
  123. if(_data[m]==0x0D && _data[m+1]==0x0A && _data[m+2]==0x0D && _data[m+3]==0x0A) {
  124. _responseParam.key3 = _data.slice(m+4, m+12);
  125. break;
  126. }
  127. }
  128. return _responseParam;
  129. }
  130.  
  131. function _checkRequestValid(_responseParam) {
  132. var required = [
  133. 'resource',
  134. 'upgrade',
  135. 'connection',
  136. 'host',
  137. 'origin',
  138. 'key1',
  139. 'key2',
  140. 'key3'
  141. ];
  142. var flag = true;
  143. required.map(function(item){
  144. if(!_responseParam[item]) {
  145. sys.log('client handshake invalid: ' + item);
  146. flag = false;
  147. }
  148. });
  149. return flag;
  150. }
  151.  
  152. function _handshake(data, requestHeaders, stream){
  153. responseParam = _getParams(data, requestHeaders);
  154. if(!_checkRequestValid(responseParam)) {
  155. _abort(stream);
  156. }
  157. sys.log('client handshake is valid.');
  158. responseParam.location = 'ws://' + responseParam.host + (responseParam.port? ':'+responseParam.port:'') + responseParam.resource;
  159. var responseHeader = responseHeaders.concat('','').join('\r\n');
  160. var md5 = require('crypto').createHash('md5');
  161. md5.update(pack(parseInt(responseParam.key1)).toString('binary'));
  162. md5.update(pack(parseInt(responseParam.key2)).toString('binary'));
  163. md5.update(responseParam.key3.toString('binary',0,responseParam.key3.length));
  164. responseHeader = responseHeader.replace(/\{ORIGIN\}/,responseParam.origin)
  165. .replace(/\{LOCATION\}/,responseParam.location)
  166. .replace(/\{PROTOCOL\}/,responseParam.protocol);
  167. stream.write(responseHeader+md5.digest('binary'),'binary');
  168. sys.log('server handshake sent ok.');
  169. state.handshaked = true;
  170. return;
  171. }
  172.  
  173. function _receiveData(data, stream) {
  174. if(data.length==2) {
  175. if(data[0] == 0xFF && data[1] == 0x00) {
  176. _abort(stream);
  177. return;
  178. }
  179. }
  180. if(data[0] != 0x00) {
  181. return;
  182. }
  183. function writePacket(s) {
  184. stream.write(new Buffer([0]));
  185. stream.write(s,'utf8');
  186. stream.write(new Buffer([255]));
  187. }
  188. var content = data.toString('utf8', 1, data.length-1);
  189. sys.log('frame data: ' + content);
  190. writePacket(content);
  191. }
  192.  
  193. this.start = function() {
  194. this.server = net.createServer(function(stream){
  195.  
  196. stream.on('connect', function(){
  197. this.sid = this.remoteAddress + ((new Date().getTime()) + Math.random()*100);
  198. clients[this.sid] = this;
  199. sys.log('client connected. sid: ['+this.sid+']');
  200. });
  201.  
  202. stream.on('data',function(data){
  203. if(!state.handshaked) {
  204. _handshake(data, requestHeaders, stream);
  205. } else {
  206. _receiveData(data, stream);
  207. }
  208. });
  209. stream.on('end',function(){
  210. stream.end();
  211. sys.log('client end');
  212. });
  213. stream.on('close',function(){
  214. stream.destroy();
  215. delete clients[this.sid];
  216. sys.log('client: ['+this.sid+'] closed');
  217. });
  218. });
  219. this.server.on('close',function(){
  220. sys.log('server closed');
  221. });
  222.  
  223.  
  224. this.server.listen(this.port, this.ip);
  225. };
  226. this.close = function() {
  227. for (i in clients) {
  228. clients[i].end();
  229. clients[i].destroy();
  230. delete clients[i];
  231. }
  232. this.server.close();
  233. };
  234. }
  235.  
  236. var Server = new WSServer(8080, '0.0.0.0');
  237.  
  238. var Admin = net.createServer(function(stream){
  239. var cmd = '';
  240. stream.setEncoding('ascii');
  241. stream.on('data', function(data){
  242. cmd += data;
  243. if(cmd.indexOf('quit')>-1) {
  244. sys.log('server stopping');
  245. stream.end();
  246. stream.destroy();
  247. Server.close();
  248. Admin.close();
  249. }
  250. });
  251. });
  252.  
  253. Server.start();
  254. Admin.listen(8081, '127.0.0.1');
Add Comment
Please, Sign In to add comment