extra-headers still not supported in browser
gjuchault opened this issue · comments
It appears that those lines
engine.io-client/lib/socket.js
Lines 99 to 103 in 1519765
The way to use extraHeaders in Node is:
{
extraHeaders: { foo: 'bar' }
}
The way to use extraHeaders in Browser is (#536 (comment)):
{
transportOptions: {
polling: {
extraHeaders: { 'foo': 'bar' }
}
}
}
The documentation could definitely be improved here 👍
And what about websocket
protocol ?
Ah I see (for future reference, more testing and notes: https://trello.com/c/7oqnpaxT/88-verify-that-extraheaders-is-actually-still-100-fixed-for-browser-usage-in-socket-io-client-engine-io-client-and-if-so-1-update-t)
We have some code that looks for a "nosession" header in order to determine whether to log warnings or not when the cookie can't be used.
please see http://stackoverflow.com/a/4361358
@darrachequesne So I'm guessing maybe if we named it "Authorization" we'd have better luck? (I'll take that for a spin and post back-- just making sure that's the intended behavior.)
@gjuchault re what's documented now: https://github.com/socketio/engine.io-client/tree/be4c9067b548f3e27dd1889e4094aff5b6d9eecb#nodejs-with-extraheaders
Well, just for reference, in the browser and in React Native, looks like 'sec-websocket-protocol': 'foobar'
doesn't make it through:
transports: ['websocket'], // you need to explicitly tell it to use websockets
extraHeaders: {
// nosession: true,
// 'Sec-WebSocket-Protocol': 'foobar'
'sec-websocket-protocol': 'foobar'
}
From a node.js client, doing the same thing results in an error from the client:
TypeError: Cannot create property 'type' on string 'server sent a subprotocol even though none requested'
at WebSocket.onError (/Users/mike/code/react-native-socket-io-example/node_modules/engine.io-client/node_modules/ws/lib/WebSocket.js:450:16)
at emitOne (events.js:96:13)
at WebSocket.emit (events.js:188:7)
at ClientRequest.upgrade (/Users/mike/code/react-native-socket-io-example/node_modules/engine.io-client/node_modules/ws/lib/WebSocket.js:757:12)
at ClientRequest.g (events.js:291:16)
at emitThree (events.js:116:13)
at ClientRequest.emit (events.js:194:7)
at Socket.socketOnData (_http_client.js:394:11)
at emitOne (events.js:96:13)
at Socket.emit (events.js:188:7)
this is w/ socket.io@1.7.3 (engine.io@1.8.3)
I had the same results when embedding basic auth in the url (e.g. http:/foo:bar@localhost:1337
) and when including either of the two special headers as transport-specific websocket options:
Aside: for other folks finding this looking for an immediate answer, note that query
works just fine, as far as I can tell. In either case, be aware that you'll want to send a string -- because if you send false
, null
, or 0
, you'll get an ugly and (truthy) surprise (e.g. 'false'
, 'null'
, '0'
)
Update: extraHeaders
is supported in browsers as of v2.0.0, but only for the polling transport, because the browser Websocket API doesn't support adding extra headers to the handshake. As @mikermcneil mentions above, the best workaround for the websocket
transport is to use the query
option to pass whatever info you need in the handshake.
{
transports: ['polling'],
path: '/websocket',
transportOptions: {
polling: {
extraHeaders: {
'x-clientid': 'abc',
}
}
}
}
it works, you can print socket.handshake.headers['x-clientid'] on server.
you can send credentials like this
const socket = io({
auth: {
token: "abc"
}
});