I have a service on a subdomain that is running Socket.io (v1.0.0). As part of the initial handshake and authorization OPTIONS request is sent once in a while (when there is a pending message that needs to be sent over XHR). The first 2 requests to establish the Socket ID and pass the authorization have the following headers:
GET /socket.io/?time=1411338676420&EIO=3&transport=polling&t=1411338676423-0 HTTP/1.1
...
Cookie: cluster_id=1382; SESSID=h13rh19hu9hf913hf912fh91
...
GET /socket.io/?time=1411338676420&EIO=3&transport=polling&t=1411338676576-1&sid=rV4pN-dcYPMTVgQUAAAH HTTP/1.1
...
Cookie: io=rV4pN-dcYPMTVgQUAAAH; cluster_id=1382; SESSID=h13rh19hu9hf913hf912fh91
...
Where io and cluster_id are set to sub.domain.com and SESSID is set for .domain.com. When the OPTIONS request is sent, the headers are the following:
OPTIONS /socket.io/?time=1411338676420&EIO=3&transport=polling&t=1411338676731-2&sid=rV4pN-dcYPMTVgQUAAAH HTTP/1.1
...
Access-Control-Request-Method: POST
Access-Control-Request-Headers: content-type
...
No Cookie header is passed, so the load balancer can't redirect the request to the correct "cluster", hence the request is sent to a random server, which results in a 400 error - unauthorized socket id.
The server replies like this to the OPTIONS request:
HTTP/1.1 400 Bad Request
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: https://domain.com
Set-Cookie: cluster_id=1024; path=/; HttpOnly
Is there a way around this (except having to add a custom parameter to the socket.io request with cluster_id value, so that the load balancer could pick it up (which is not a good idea - load balancers tend to convert the parameter into a number and use that to select the server from the list of available ones, hence when I add one more server to the cluster, most clients will be sent to the wrong server on their next request. Hence the cookie is the only way to go for me.
All browsers seem to do this to all OPTIONS requests like the one above. Is this a common interpretation of the HTTP specification?
had the same problem.
I solved it by adding a OPTIONS method handler in the balancer.
if(req.method == 'OPTIONS'){
res.setHeader('Access-Control-Allow-Credentials', true);
res.setHeader('Access-Control-Allow-Origin', req.headers.origin);
res.setHeader('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
res.end();
return;
}
The OPTIONS method request id handled by the balancer and it responds with CORS options. Cheers