Home > Software design >  Permessage-Deflate Extension Breaks Socket.io WebSocket Communication (400 Bad Request)
Permessage-Deflate Extension Breaks Socket.io WebSocket Communication (400 Bad Request)

Time:03-26

I need to enable compression for websocket communication (using socketio). I did this by setting the perMessageDeflate to true which worked fine in my development environment and on a staging server (verified with Wireshark). However, on our production server the websocket connection fails and socketio (v4.4.1) falls back to polling. Both use nginx as a reverse proxy with the same configuration. Chromium console shows

WebSocket connection to 'wss://***/ws-test/socket.io/?EIO=4&transport=websocket&sid=9P4EelJhF0CcxvwNAAAE' failed: Error during WebSocket handshake: Unexpected response code: 400

I created a minimal sample that shows the same behaviour. Nodejs app on the server:

const express = require('express');
const app = express();
const http = require('http');
const server = http.createServer(app);
const { Server } = require("socket.io");

const io = new Server(server, {
    perMessageDeflate: true
});

app.get('/', (req, res) => {
    res.sendFile(__dirname   '/index.html');
});

server.listen(3001, () => {
    console.log('listening on *:3001');
});

Client:

    ...
    <script src="socket.io/socket.io.js"></script>
    <script>
      var socketio_path = window.location.pathname   'socket.io';
      var socket = io( { path: socketio_path } );
    </script>
</body>

The error 400 seems to come from the nodejs server, not from nginx. I enabled all kinds of logging but couldn't find any related messages. Software versions are also reasonably close and up-to-date: nginx 1.18.0 on both (staging and production), nodejs 14.19.0/14.18.1 (staging/prod). Do you have any ideas that could help making this work on the production server?

CodePudding user response:

It turned out, the issue is the Azure Application Gateway used on the production server. When it's bypassed, the websocket connection (with perMessageDeflate enabled) works fine.

Switching to a newer version of the Azure Application Gateway (v2 instead of v1) solved the issue in the end.

  • Related