express-ws: Crash with fallback GET route

If you run the following test app:

var express = require('express');
var app = express();

require('express-ws')(app);

app.ws('/test', function(ws, req) {
  console.log('incoming connection');
});

app.get('/*', function(req, res, next){
  res.sendFile(__dirname + '/test.html');
});

app.listen(3000);

When you make a WebSocket request to ws://localhost:3000/invalidroute, the process crashes with the following exception:

http_outgoing.js:135
      this.outputSize += this._header.length;
                                     ^

TypeError: Cannot read property 'length' of null
    at ServerResponse.OutgoingMessage._send (_http_outgoing.js:135:38)
    at ServerResponse.OutgoingMessage.write (_http_outgoing.js:477:16)
    at ReadStream.ondata (_stream_readable.js:536:20)
    at emitOne (events.js:90:13)
    at ReadStream.emit (events.js:182:7)
    at readableAddChunk (_stream_readable.js:153:18)
    at ReadStream.Readable.push (_stream_readable.js:111:10)
    at onread (fs.js:1818:12)
    at FSReqWrap.wrapper [as oncomplete] (fs.js:614:17)

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 3
  • Comments: 15

Commits related to this issue

Most upvoted comments

Is there any workaround on this?

I’m working on a project that has a middleware to catch all paths that don’t match any route and return an HTML file.

To overcome the problem described in this issue, we added a check in the middleware to skip its action if the request contains the WebSocket header:

const frontendMiddleware = (req, res) => {
  if (req.header('sec-websocket-version') === undefined) {
    res.sendFile(path.join(FRONTEND_ROOT, 'build', 'index.html'))
  }
}

app.use(frontendMiddleware)

Ok I solved it

the * route (everything except /websocket)

router.get(/^.(?!websocket).*$/, (req, res) => {
	res.render('angular/index', { environment: app.get('env') });
});

move the websocket to /websocket

app.ws('/websocket', (ws, req) => {
    ...
});
webSocketServer = expressWs.getWss('/websocket');

@suhasdeshpande just make sure any wildcard routes you have defined do not match the ‘fake’ route.