Node js + Sails js + websocket app crashing every few hours

Problem

I am having a problem similar to socket.io issue using sails.js. Every once in a while (once per day, or even few hours, it varies), a visitor to the web site/app will crash Node, seemingly due to the way his websocket client tries to connect. Anyway, here's the crash log:

debug: Lowering sails...

/Volumes/Two/Sites/lsdfinder/node_modules/sails/node_modules/express/node_modules/connect/lib/utils.js:216
  return 0 == str.indexOf('s:')
                  ^
TypeError: Cannot call method 'indexOf' of undefined
    at exports.parseSignedCookie (/Volumes/Two/Sites/lsdfinder/node_modules/sails/node_modules/express/node_modules/connect/lib/utils.js:216:19)
    at Manager.socketAttemptingToConnect (/Volumes/Two/Sites/lsdfinder/node_modules/sails/lib/hooks/sockets/authorization.js:35:26)
    at Manager.authorize (/Volumes/Two/Sites/lsdfinder/node_modules/sails/node_modules/socket.io/lib/manager.js:910:31)
    at Manager.handleHandshake (/Volumes/Two/Sites/lsdfinder/node_modules/sails/node_modules/socket.io/lib/manager.js:786:8)
    at Manager.handleRequest (/Volumes/Two/Sites/lsdfinder/node_modules/sails/node_modules/socket.io/lib/manager.js:593:12)
    at Server.<anonymous> (/Volumes/Two/Sites/lsdfinder/node_modules/sails/node_modules/socket.io/lib/manager.js:119:10)
    at Server.EventEmitter.emit (events.js:98:17)
    at HTTPParser.parser.onIncoming (http.js:2076:12)
    at HTTPParser.parserOnHeadersComplete [as onHeadersComplete] (http.js:120:23)
    at Socket.socket.ondata (http.js:1966:22)
9 Oct 10:42:24 - [nodemon] app crashed - waiting for file changes before starting...

In config/sockets.js, authorization is set to true. Not sure what else to do, where to fix this. Any suggestions? I can read the Sails docs too, but this appears to be a problem in Express/Connect, no? Thanks.

...René

Problem courtesy of: René Fournier

Solution

The problem is that once every so often, a client will connect that has no cookies. Sails.js is using util.parseSignedCookie() from Connect without checking for errors, and therefore an error is thrown. This is what it looks like in Sails:

if (handshake.headers.cookie) {
  handshake.cookie = cookie.parse(handshake.headers.cookie);
  handshake.sessionID = parseSignedCookie(handshake.cookie[sails.config.session.key], sails.config.session.secret);
}

If you take a look into the cookieParser() middleware of Connect, you can see error checking is required:

if (cookies) {
  try {
    req.cookies = cookie.parse(cookies);
    if (secret) {
      req.signedCookies = utils.parseSignedCookies(req.cookies, secret);
      req.signedCookies = utils.parseJSONCookies(req.signedCookies);
    }
    req.cookies = utils.parseJSONCookies(req.cookies);
  } catch (err) {
    err.status = 400;
    return next(err);
  }
}

I've created a Gist here that fixes the problem, and will submit a pull request to Sails.js when I have the time. The Gist uses Connect's cookieParser() middleware to automatically handle errors. If you want to use this, modify this file in your modules folder:

node_modules/sails/lib/hooks/sockets/authorization.js
Solution courtesy of: hexacyanide

Discussion

If you are doing a crossdomain request, you could turn off authorization.

In *site_dir/config/sockets.js* set authorization to false. One way of doing it. You can also call your api with something like this

bash **http://localhost:1337?cookie=smokeybear**

Its is in the comments on the sockets.js file.

Discussion courtesy of: CASoetan

This recipe can be found in it's original form on Stack Over Flow.