annotate node_modules/socket.io/lib/index.js @ 101:52e44ee1c791 tip master

enabled all scores in autostart script
author Rob Canning <rc@kiben.net>
date Tue, 21 Apr 2015 16:20:57 +0100
parents cd921abc8887
children
rev   line source
rob@77 1
rob@77 2 /**
rob@77 3 * Module dependencies.
rob@77 4 */
rob@77 5
rob@77 6 var http = require('http');
rob@77 7 var read = require('fs').readFileSync;
rob@77 8 var parse = require('url').parse;
rob@77 9 var engine = require('engine.io');
rob@77 10 var client = require('socket.io-client');
rob@77 11 var clientVersion = require('socket.io-client/package').version;
rob@77 12 var Client = require('./client');
rob@77 13 var Namespace = require('./namespace');
rob@77 14 var Adapter = require('socket.io-adapter');
rob@77 15 var debug = require('debug')('socket.io:server');
rob@77 16 var url = require('url');
rob@77 17
rob@77 18 /**
rob@77 19 * Module exports.
rob@77 20 */
rob@77 21
rob@77 22 module.exports = Server;
rob@77 23
rob@77 24 /**
rob@77 25 * Socket.IO client source.
rob@77 26 */
rob@77 27
rob@77 28 var clientSource = read(require.resolve('socket.io-client/socket.io.js'), 'utf-8');
rob@77 29
rob@77 30 /**
rob@77 31 * Server constructor.
rob@77 32 *
rob@77 33 * @param {http.Server|Number|Object} http server, port or options
rob@77 34 * @param {Object} options
rob@77 35 * @api public
rob@77 36 */
rob@77 37
rob@77 38 function Server(srv, opts){
rob@77 39 if (!(this instanceof Server)) return new Server(srv, opts);
rob@77 40 if ('object' == typeof srv && !srv.listen) {
rob@77 41 opts = srv;
rob@77 42 srv = null;
rob@77 43 }
rob@77 44 opts = opts || {};
rob@77 45 this.nsps = {};
rob@77 46 this.path(opts.path || '/socket.io');
rob@77 47 this.serveClient(false !== opts.serveClient);
rob@77 48 this.adapter(opts.adapter || Adapter);
rob@77 49 this.origins(opts.origins || '*:*');
rob@77 50 this.sockets = this.of('/');
rob@77 51 if (srv) this.attach(srv, opts);
rob@77 52 }
rob@77 53
rob@77 54 /**
rob@77 55 * Server request verification function, that checks for allowed origins
rob@77 56 *
rob@77 57 * @param {http.IncomingMessage} request
rob@77 58 * @param {Function} callback to be called with the result: `fn(err, success)`
rob@77 59 */
rob@77 60
rob@77 61 Server.prototype.checkRequest = function(req, fn) {
rob@77 62 var origin = req.headers.origin || req.headers.referer;
rob@77 63
rob@77 64 // file:// URLs produce a null Origin which can't be authorized via echo-back
rob@77 65 if ('null' == origin) origin = '*';
rob@77 66
rob@77 67 if (this._origins.indexOf('*:*') !== -1) return fn(null, true);
rob@77 68 if (origin) {
rob@77 69 try {
rob@77 70 var parts = url.parse(origin);
rob@77 71 parts.port = parts.port || 80;
rob@77 72 var ok =
rob@77 73 ~this._origins.indexOf(parts.hostname + ':' + parts.port) ||
rob@77 74 ~this._origins.indexOf(parts.hostname + ':*') ||
rob@77 75 ~this._origins.indexOf('*:' + parts.port);
rob@77 76 return fn(null, !!ok);
rob@77 77 } catch (ex) {
rob@77 78 }
rob@77 79 }
rob@77 80 fn(null, false);
rob@77 81 };
rob@77 82
rob@77 83 /**
rob@77 84 * Sets/gets whether client code is being served.
rob@77 85 *
rob@77 86 * @param {Boolean} whether to serve client code
rob@77 87 * @return {Server|Boolean} self when setting or value when getting
rob@77 88 * @api public
rob@77 89 */
rob@77 90
rob@77 91 Server.prototype.serveClient = function(v){
rob@77 92 if (!arguments.length) return this._serveClient;
rob@77 93 this._serveClient = v;
rob@77 94 return this;
rob@77 95 };
rob@77 96
rob@77 97 /**
rob@77 98 * Old settings for backwards compatibility
rob@77 99 */
rob@77 100
rob@77 101 var oldSettings = {
rob@77 102 "transports": "transports",
rob@77 103 "heartbeat timeout": "pingTimeout",
rob@77 104 "heartbeat interval": "pingInterval",
rob@77 105 "destroy buffer size": "maxHttpBufferSize"
rob@77 106 };
rob@77 107
rob@77 108 /**
rob@77 109 * Backwards compatiblity.
rob@77 110 *
rob@77 111 * @api public
rob@77 112 */
rob@77 113
rob@77 114 Server.prototype.set = function(key, val){
rob@77 115 if ('authorization' == key && val) {
rob@77 116 this.use(function(socket, next) {
rob@77 117 val(socket.request, function(err, authorized) {
rob@77 118 if (err) return next(new Error(err));
rob@77 119 if (!authorized) return next(new Error('Not authorized'));
rob@77 120 next();
rob@77 121 });
rob@77 122 });
rob@77 123 } else if ('origins' == key && val) {
rob@77 124 this.origins(val);
rob@77 125 } else if ('resource' == key) {
rob@77 126 this.path(val);
rob@77 127 } else if (oldSettings[key] && this.eio[oldSettings[key]]) {
rob@77 128 this.eio[oldSettings[key]] = val;
rob@77 129 } else {
rob@77 130 console.error('Option %s is not valid. Please refer to the README.', key);
rob@77 131 }
rob@77 132
rob@77 133 return this;
rob@77 134 };
rob@77 135
rob@77 136 /**
rob@77 137 * Sets the client serving path.
rob@77 138 *
rob@77 139 * @param {String} pathname
rob@77 140 * @return {Server|String} self when setting or value when getting
rob@77 141 * @api public
rob@77 142 */
rob@77 143
rob@77 144 Server.prototype.path = function(v){
rob@77 145 if (!arguments.length) return this._path;
rob@77 146 this._path = v.replace(/\/$/, '');
rob@77 147 return this;
rob@77 148 };
rob@77 149
rob@77 150 /**
rob@77 151 * Sets the adapter for rooms.
rob@77 152 *
rob@77 153 * @param {Adapter} pathname
rob@77 154 * @return {Server|Adapter} self when setting or value when getting
rob@77 155 * @api public
rob@77 156 */
rob@77 157
rob@77 158 Server.prototype.adapter = function(v){
rob@77 159 if (!arguments.length) return this._adapter;
rob@77 160 this._adapter = v;
rob@77 161 for (var i in this.nsps) {
rob@77 162 if (this.nsps.hasOwnProperty(i)) {
rob@77 163 this.nsps[i].initAdapter();
rob@77 164 }
rob@77 165 }
rob@77 166 return this;
rob@77 167 };
rob@77 168
rob@77 169 /**
rob@77 170 * Sets the allowed origins for requests.
rob@77 171 *
rob@77 172 * @param {String} origins
rob@77 173 * @return {Server|Adapter} self when setting or value when getting
rob@77 174 * @api public
rob@77 175 */
rob@77 176
rob@77 177 Server.prototype.origins = function(v){
rob@77 178 if (!arguments.length) return this._origins;
rob@77 179
rob@77 180 this._origins = v;
rob@77 181 return this;
rob@77 182 };
rob@77 183
rob@77 184 /**
rob@77 185 * Attaches socket.io to a server or port.
rob@77 186 *
rob@77 187 * @param {http.Server|Number} server or port
rob@77 188 * @param {Object} options passed to engine.io
rob@77 189 * @return {Server} self
rob@77 190 * @api public
rob@77 191 */
rob@77 192
rob@77 193 Server.prototype.listen =
rob@77 194 Server.prototype.attach = function(srv, opts){
rob@77 195 if ('function' == typeof srv) {
rob@77 196 var msg = 'You are trying to attach socket.io to an express' +
rob@77 197 'request handler function. Please pass a http.Server instance.';
rob@77 198 throw new Error(msg);
rob@77 199 }
rob@77 200
rob@77 201 // handle a port as a string
rob@77 202 if (Number(srv) == srv) {
rob@77 203 srv = Number(srv);
rob@77 204 }
rob@77 205
rob@77 206 if ('number' == typeof srv) {
rob@77 207 debug('creating http server and binding to %d', srv);
rob@77 208 var port = srv;
rob@77 209 srv = http.Server(function(req, res){
rob@77 210 res.writeHead(404);
rob@77 211 res.end();
rob@77 212 });
rob@77 213 srv.listen(port);
rob@77 214 }
rob@77 215
rob@77 216 // set engine.io path to `/socket.io`
rob@77 217 opts = opts || {};
rob@77 218 opts.path = opts.path || '/socket.io';
rob@77 219 // set origins verification
rob@77 220 opts.allowRequest = this.checkRequest.bind(this);
rob@77 221
rob@77 222 // initialize engine
rob@77 223 debug('creating engine.io instance with opts %j', opts);
rob@77 224 this.eio = engine.attach(srv, opts);
rob@77 225
rob@77 226 // attach static file serving
rob@77 227 if (this._serveClient) this.attachServe(srv);
rob@77 228
rob@77 229 // bind to engine events
rob@77 230 this.bind(this.eio);
rob@77 231
rob@77 232 return this;
rob@77 233 };
rob@77 234
rob@77 235 /**
rob@77 236 * Attaches the static file serving.
rob@77 237 *
rob@77 238 * @param {Function|http.Server} http server
rob@77 239 * @api private
rob@77 240 */
rob@77 241
rob@77 242 Server.prototype.attachServe = function(srv){
rob@77 243 debug('attaching client serving req handler');
rob@77 244 var url = this._path + '/socket.io.js';
rob@77 245 var evs = srv.listeners('request').slice(0);
rob@77 246 var self = this;
rob@77 247 srv.removeAllListeners('request');
rob@77 248 srv.on('request', function(req, res) {
rob@77 249 if (0 == req.url.indexOf(url)) {
rob@77 250 self.serve(req, res);
rob@77 251 } else {
rob@77 252 for (var i = 0; i < evs.length; i++) {
rob@77 253 evs[i].call(srv, req, res);
rob@77 254 }
rob@77 255 }
rob@77 256 });
rob@77 257 };
rob@77 258
rob@77 259 /**
rob@77 260 * Handles a request serving `/socket.io.js`
rob@77 261 *
rob@77 262 * @param {http.Request} req
rob@77 263 * @param {http.Response} res
rob@77 264 * @api private
rob@77 265 */
rob@77 266
rob@77 267 Server.prototype.serve = function(req, res){
rob@77 268 if (req.headers.etag) {
rob@77 269 if (clientVersion == req.headers.etag) {
rob@77 270 debug('serve client 304');
rob@77 271 res.writeHead(304);
rob@77 272 res.end();
rob@77 273 return;
rob@77 274 }
rob@77 275 }
rob@77 276
rob@77 277 debug('serve client source');
rob@77 278 res.setHeader('Content-Type', 'application/javascript');
rob@77 279 res.setHeader('ETag', clientVersion);
rob@77 280 res.writeHead(200);
rob@77 281 res.end(clientSource);
rob@77 282 };
rob@77 283
rob@77 284 /**
rob@77 285 * Binds socket.io to an engine.io instance.
rob@77 286 *
rob@77 287 * @param {engine.Server} engine.io (or compatible) server
rob@77 288 * @return {Server} self
rob@77 289 * @api public
rob@77 290 */
rob@77 291
rob@77 292 Server.prototype.bind = function(engine){
rob@77 293 this.engine = engine;
rob@77 294 this.engine.on('connection', this.onconnection.bind(this));
rob@77 295 return this;
rob@77 296 };
rob@77 297
rob@77 298 /**
rob@77 299 * Called with each incoming transport connection.
rob@77 300 *
rob@77 301 * @param {engine.Socket} socket
rob@77 302 * @return {Server} self
rob@77 303 * @api public
rob@77 304 */
rob@77 305
rob@77 306 Server.prototype.onconnection = function(conn){
rob@77 307 debug('incoming connection with id %s', conn.id);
rob@77 308 var client = new Client(this, conn);
rob@77 309 client.connect('/');
rob@77 310 return this;
rob@77 311 };
rob@77 312
rob@77 313 /**
rob@77 314 * Looks up a namespace.
rob@77 315 *
rob@77 316 * @param {String} nsp name
rob@77 317 * @param {Function} optional, nsp `connection` ev handler
rob@77 318 * @api public
rob@77 319 */
rob@77 320
rob@77 321 Server.prototype.of = function(name, fn){
rob@77 322 if (!this.nsps[name]) {
rob@77 323 debug('initializing namespace %s', name);
rob@77 324 var nsp = new Namespace(this, name);
rob@77 325 this.nsps[name] = nsp;
rob@77 326 }
rob@77 327 if (fn) this.nsps[name].on('connect', fn);
rob@77 328 return this.nsps[name];
rob@77 329 };
rob@77 330
rob@77 331 /**
rob@77 332 * Expose main namespace (/).
rob@77 333 */
rob@77 334
rob@77 335 ['on', 'to', 'in', 'use', 'emit', 'send', 'write'].forEach(function(fn){
rob@77 336 Server.prototype[fn] = function(){
rob@77 337 var nsp = this.sockets[fn];
rob@77 338 return nsp.apply(this.sockets, arguments);
rob@77 339 };
rob@77 340 });
rob@77 341
rob@77 342 Namespace.flags.forEach(function(flag){
rob@77 343 Server.prototype.__defineGetter__(flag, function(name){
rob@77 344 this.flags.push(name);
rob@77 345 return this;
rob@77 346 });
rob@77 347 });
rob@77 348
rob@77 349 /**
rob@77 350 * BC with `io.listen`
rob@77 351 */
rob@77 352
rob@77 353 Server.listen = Server;