socket.io
socket.io copied to clipboard
Bad Request - TRANSPORT_MISMATCH - 400 response in browser - Apache Reverse Proxy
Describe the bug
In my browser I am seeing a 400 response when attempting the websocket connection, and on the socket.io server, with logging enabled, I am seeing error.code = 3, error.message = "Bad Request", and error.context = { name: "TRANSPORT_MISMATCH", transport: 'websocket', previousTransport: 'polling' }
. The socket.io server is sitting behind an Apache reverse proxy. The socket.io server has been packaged with the pkg
command. Long polling for the application works, but is undesired.
To Reproduce
Please fill the following code example:
Socket.IO server version: 4.4.1
Server
# In Apache Config
ProxyPass /somepath http://localhost:3000 Keepalive=On connectiontimeout=60 timeout=60
RewriteEngine on
RewriteCond %{HTTP:Upgrade} websocket [NC]
RewriteCond %{HTTP:Connection} upgrade [NC]
RewriteRule ^/?somepath(.*) "ws://localhost:3000/$1" [P,L]
ProxyTimeout 30
const express = require('express');
const app = express();
const http = require('http');
const server = http.createServer(app);
const { Server } = require('socket.io');
const { spawn } = require('child_process');
const process = require('process');
app.use(express.static('public'));
const io = new Server(server);
io.engine.on("connection_error", (err) => {
console.log(err.code); // the error code, for example 1
console.log(err.message); // the error message, for example "Session ID unknown"
console.log(err.context); // some additional error context
});
io.on('connection', (socket) => {
console.log('a user connected');
socket.on('disconnect', () => {
console.log('user disconnected');
});
});
// extraneous code redacted, mostly io.emit's to the connecting browser
server.listen(3000, '127.0.0.1', 0, () => {
console.log('Express+Socket.io server listening on *:3000');
});
Socket.IO client version: 4.4.1
Client
<script src="https://cdn.socket.io/4.4.1/socket.io.min.js" integrity="sha384-fKnu0iswBIqkjxrhQCTZ7qlLHOFEgNkRmK2vaO/LbTZSXdJfAu6ewRBdwHPhBo/H" crossorigin="anonymous"></script>
var socket = io("<DOMAIN>", { path: "/<PATH_INSIDE_PKG>/socket.io" });
socket.on('...', () => { console.log('here'); });
Expected behavior I anticipated that the websocket would connect, but it does not. There is polling happening, which is the solution I was trying to move away from. I don't know what I'm doing wrong.
Platform:
- Device: Linux server
- OS: RHEL 8
Additional context Apache Reverse Proxy -> Node + Express -> Socket.io Related line from Apache Error Log: [Thu Apr 14 15:07:13.835377 2022] [proxy_http:error] [pid 19XXXX:tid 140XXXX] (20014)Internal error (specific information not available): [client <MY_IP_ADDRESS>] AH01102: error reading status line from remote server localhost:3000 TLS is handled by Apache.
Did you ever figure out what was causing this issue? I'm running into the same thing when I try to put an app using socket.io behind an nginx reverse proxy.
@bassj Sorry, no, I never figured this out so I moved on to other work for the moment. When I come back to this I probably wont add the wrinkle of using pkg
to try and create a single binary out of the server. At that point I may see exactly the same issue that you are, but hopefully by then someone will have resolved this. Sorry searchers: another Internet dead end, for now.
Any movement on this? We're having the same issues using default settings for socket.io
We have a proxy setup using vite but cannot deploy to Heroku now.
Hi everyone! "TRANSPORT_MISMATCH" might mean that the server has received an invalid upgrade request. Is the proxy_wstunnel_module
module enabled?
References:
- https://socket.io/docs/v4/reverse-proxy/#apache-httpd)
- https://github.com/socketio/socket.io/tree/main/examples/cluster-httpd
- https://httpd.apache.org/docs/2.4/en/mod/mod_proxy_wstunnel.html
For future readers:
I'm going to close this, as I don't think that there is much we can do.
I wasn't able to reproduce with the example here: https://github.com/socketio/socket.io/tree/main/examples/cluster-httpd
There might be an issue in the httpd config.
Please reopen if needed.