Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NodeJS, WebSockets, upgrade head

I'm playing with NodeJS and WebSockets, there is the upgrade event with it's head parameter, as I understood from here that is basically data that directly trails the headers, but for my use case it's always empty so I don't really know what it means, I'd be glad if someone could provide a simple use case where the data parameter within the upgrade event isn't empty.

like image 329
Aviel Fedida Avatar asked Jan 01 '16 08:01

Aviel Fedida


1 Answers

Looking at the source that emits that upgrade event in the node repo, you'll see the following implementation:

  function socketOnData(d) {
    assert(!socket._paused);
    debug('SERVER socketOnData %d', d.length);
    var ret = parser.execute(d);

    onParserExecuteCommon(ret, d);
  }

  function onParserExecute(ret, d) {
    debug('SERVER socketOnParserExecute %d', ret);
    onParserExecuteCommon(ret, undefined);
  }

  function onParserExecuteCommon(ret, d) {
    if (ret instanceof Error) {
      debug('parse error');
      socket.destroy(ret);
    } else if (parser.incoming && parser.incoming.upgrade) {
      // Upgrade or CONNECT
      var bytesParsed = ret;
      var req = parser.incoming;
      debug('SERVER upgrade or connect', req.method);

      if (!d)
        d = parser.getCurrentBuffer();

      socket.removeListener('data', socketOnData);
      socket.removeListener('end', socketOnEnd);
      socket.removeListener('close', serverSocketCloseListener);
      unconsume(parser, socket);
      parser.finish();
      freeParser(parser, req, null);
      parser = null;

      var eventName = req.method === 'CONNECT' ? 'connect' : 'upgrade';
      if (EventEmitter.listenerCount(self, eventName) > 0) {
        debug('SERVER have listener for %s', eventName);
        var bodyHead = d.slice(bytesParsed, d.length);

        // TODO(isaacs): Need a way to reset a stream to fresh state
        // IE, not flowing, and not explicitly paused.
        socket._readableState.flowing = null;
        self.emit(eventName, req, socket, bodyHead);
...

The passed parameter, bodyHead, reflects the data from the passed parameter d on the socketOnData function, which is the default socket data event handler. On the other hand, it could be undefined if the onParserExecuteCommon was called from onParserExecute. I'd have to look through the source more to understand which cases would apply depending on how your server is implemented. Maybe you could enable the debug logs to see which methods are being called.

like image 147
Patrick Roberts Avatar answered Sep 24 '22 14:09

Patrick Roberts