PageRenderTime 39ms CodeModel.GetById 18ms app.highlight 15ms RepoModel.GetById 2ms app.codeStats 0ms

/node_modules/telehash/node_modules/telehash-cs2a/node_modules/node-forge/js/socket.js

https://github.com/ImyarekRu/Paradox
JavaScript | 344 lines | 185 code | 23 blank | 136 comment | 30 complexity | 381a101407fa37b5c4d639de5a0f49fa MD5 | raw file
  1/**
  2 * Socket implementation that uses flash SocketPool class as a backend.
  3 *
  4 * @author Dave Longley
  5 *
  6 * Copyright (c) 2010-2013 Digital Bazaar, Inc.
  7 */
  8(function() {
  9/* ########## Begin module implementation ########## */
 10function initModule(forge) {
 11
 12// define net namespace
 13var net = forge.net = forge.net || {};
 14
 15// map of flash ID to socket pool
 16net.socketPools = {};
 17
 18/**
 19 * Creates a flash socket pool.
 20 *
 21 * @param options:
 22 *          flashId: the dom ID for the flash object element.
 23 *          policyPort: the default policy port for sockets, 0 to use the
 24 *            flash default.
 25 *          policyUrl: the default policy file URL for sockets (if provided
 26 *            used instead of a policy port).
 27 *          msie: true if the browser is msie, false if not.
 28 *
 29 * @return the created socket pool.
 30 */
 31net.createSocketPool = function(options) {
 32  // set default
 33  options.msie = options.msie || false;
 34
 35  // initialize the flash interface
 36  var spId = options.flashId;
 37  var api = document.getElementById(spId);
 38  api.init({marshallExceptions: !options.msie});
 39
 40  // create socket pool entry
 41  var sp = {
 42    // ID of the socket pool
 43    id: spId,
 44    // flash interface
 45    flashApi: api,
 46    // map of socket ID to sockets
 47    sockets: {},
 48    // default policy port
 49    policyPort: options.policyPort || 0,
 50    // default policy URL
 51    policyUrl: options.policyUrl || null
 52  };
 53  net.socketPools[spId] = sp;
 54
 55  // create event handler, subscribe to flash events
 56  if(options.msie === true) {
 57    sp.handler = function(e) {
 58      if(e.id in sp.sockets) {
 59        // get handler function
 60        var f;
 61        switch(e.type) {
 62        case 'connect':
 63          f = 'connected';
 64          break;
 65        case 'close':
 66          f = 'closed';
 67          break;
 68        case 'socketData':
 69          f = 'data';
 70          break;
 71        default:
 72          f = 'error';
 73          break;
 74        }
 75        /* IE calls javascript on the thread of the external object
 76          that triggered the event (in this case flash) ... which will
 77          either run concurrently with other javascript or pre-empt any
 78          running javascript in the middle of its execution (BAD!) ...
 79          calling setTimeout() will schedule the javascript to run on
 80          the javascript thread and solve this EVIL problem. */
 81        setTimeout(function(){sp.sockets[e.id][f](e);}, 0);
 82      }
 83    };
 84  }
 85  else {
 86    sp.handler = function(e) {
 87      if(e.id in sp.sockets) {
 88        // get handler function
 89        var f;
 90        switch(e.type) {
 91        case 'connect':
 92          f = 'connected';
 93          break;
 94        case 'close':
 95          f = 'closed';
 96          break;
 97        case 'socketData':
 98          f = 'data';
 99          break;
100        default:
101          f = 'error';
102          break;
103        }
104        sp.sockets[e.id][f](e);
105      }
106    };
107  }
108  var handler = 'forge.net.socketPools[\'' + spId + '\'].handler';
109  api.subscribe('connect', handler);
110  api.subscribe('close', handler);
111  api.subscribe('socketData', handler);
112  api.subscribe('ioError', handler);
113  api.subscribe('securityError', handler);
114
115  /**
116   * Destroys a socket pool. The socket pool still needs to be cleaned
117   * up via net.cleanup().
118   */
119  sp.destroy = function() {
120    delete net.socketPools[options.flashId];
121    for(var id in sp.sockets) {
122      sp.sockets[id].destroy();
123    }
124    sp.sockets = {};
125    api.cleanup();
126  };
127
128  /**
129   * Creates a new socket.
130   *
131   * @param options:
132   *          connected: function(event) called when the socket connects.
133   *          closed: function(event) called when the socket closes.
134   *          data: function(event) called when socket data has arrived,
135   *            it can be read from the socket using receive().
136   *          error: function(event) called when a socket error occurs.
137   */
138   sp.createSocket = function(options) {
139     // default to empty options
140     options = options || {};
141
142     // create flash socket
143     var id = api.create();
144
145     // create javascript socket wrapper
146     var socket = {
147       id: id,
148       // set handlers
149       connected: options.connected || function(e){},
150       closed: options.closed || function(e){},
151       data: options.data || function(e){},
152       error: options.error || function(e){}
153     };
154
155     /**
156      * Destroys this socket.
157      */
158     socket.destroy = function() {
159       api.destroy(id);
160       delete sp.sockets[id];
161     };
162
163     /**
164      * Connects this socket.
165      *
166      * @param options:
167      *          host: the host to connect to.
168      *          port: the port to connect to.
169      *          policyPort: the policy port to use (if non-default), 0 to
170      *            use the flash default.
171      *          policyUrl: the policy file URL to use (instead of port).
172      */
173     socket.connect = function(options) {
174       // give precedence to policy URL over policy port
175       // if no policy URL and passed port isn't 0, use default port,
176       // otherwise use 0 for the port
177       var policyUrl = options.policyUrl || null;
178       var policyPort = 0;
179       if(policyUrl === null && options.policyPort !== 0) {
180         policyPort = options.policyPort || sp.policyPort;
181       }
182       api.connect(id, options.host, options.port, policyPort, policyUrl);
183     };
184
185     /**
186      * Closes this socket.
187      */
188     socket.close = function() {
189       api.close(id);
190       socket.closed({
191         id: socket.id,
192         type: 'close',
193         bytesAvailable: 0
194       });
195     };
196
197     /**
198      * Determines if the socket is connected or not.
199      *
200      * @return true if connected, false if not.
201      */
202     socket.isConnected = function() {
203       return api.isConnected(id);
204     };
205
206     /**
207      * Writes bytes to this socket.
208      *
209      * @param bytes the bytes (as a string) to write.
210      *
211      * @return true on success, false on failure.
212      */
213     socket.send = function(bytes) {
214       return api.send(id, forge.util.encode64(bytes));
215     };
216
217     /**
218      * Reads bytes from this socket (non-blocking). Fewer than the number
219      * of bytes requested may be read if enough bytes are not available.
220      *
221      * This method should be called from the data handler if there are
222      * enough bytes available. To see how many bytes are available, check
223      * the 'bytesAvailable' property on the event in the data handler or
224      * call the bytesAvailable() function on the socket. If the browser is
225      * msie, then the bytesAvailable() function should be used to avoid
226      * race conditions. Otherwise, using the property on the data handler's
227      * event may be quicker.
228      *
229      * @param count the maximum number of bytes to read.
230      *
231      * @return the bytes read (as a string) or null on error.
232      */
233     socket.receive = function(count) {
234       var rval = api.receive(id, count).rval;
235       return (rval === null) ? null : forge.util.decode64(rval);
236     };
237
238     /**
239      * Gets the number of bytes available for receiving on the socket.
240      *
241      * @return the number of bytes available for receiving.
242      */
243     socket.bytesAvailable = function() {
244       return api.getBytesAvailable(id);
245     };
246
247     // store and return socket
248     sp.sockets[id] = socket;
249     return socket;
250  };
251
252  return sp;
253};
254
255/**
256 * Destroys a flash socket pool.
257 *
258 * @param options:
259 *          flashId: the dom ID for the flash object element.
260 */
261net.destroySocketPool = function(options) {
262  if(options.flashId in net.socketPools) {
263    var sp = net.socketPools[options.flashId];
264    sp.destroy();
265  }
266};
267
268/**
269 * Creates a new socket.
270 *
271 * @param options:
272 *          flashId: the dom ID for the flash object element.
273 *          connected: function(event) called when the socket connects.
274 *          closed: function(event) called when the socket closes.
275 *          data: function(event) called when socket data has arrived, it
276 *            can be read from the socket using receive().
277 *          error: function(event) called when a socket error occurs.
278 *
279 * @return the created socket.
280 */
281net.createSocket = function(options) {
282  var socket = null;
283  if(options.flashId in net.socketPools) {
284    // get related socket pool
285    var sp = net.socketPools[options.flashId];
286    socket = sp.createSocket(options);
287  }
288  return socket;
289};
290
291} // end module implementation
292
293/* ########## Begin module wrapper ########## */
294var name = 'net';
295if(typeof define !== 'function') {
296  // NodeJS -> AMD
297  if(typeof module === 'object' && module.exports) {
298    var nodeJS = true;
299    define = function(ids, factory) {
300      factory(require, module);
301    };
302  }
303  // <script>
304  else {
305    if(typeof forge === 'undefined') {
306      forge = {};
307    }
308    return initModule(forge);
309  }
310}
311// AMD
312var deps;
313var defineFunc = function(require, module) {
314  module.exports = function(forge) {
315    var mods = deps.map(function(dep) {
316      return require(dep);
317    }).concat(initModule);
318    // handle circular dependencies
319    forge = forge || {};
320    forge.defined = forge.defined || {};
321    if(forge.defined[name]) {
322      return forge[name];
323    }
324    forge.defined[name] = true;
325    for(var i = 0; i < mods.length; ++i) {
326      mods[i](forge);
327    }
328    return forge[name];
329  };
330};
331var tmpDefine = define;
332define = function(ids, factory) {
333  deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2);
334  if(nodeJS) {
335    delete define;
336    return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0));
337  }
338  define = tmpDefine;
339  return define.apply(null, Array.prototype.slice.call(arguments, 0));
340};
341define(['require', 'module'], function() {
342  defineFunc.apply(null, Array.prototype.slice.call(arguments, 0));
343});
344})();