Support symbols as key in UserData
Hello,
Starting from the Upgrade.js example, I tried storing the values I need (taken from some headers) under a symbol on the UserData object. The issue is the symbol is not present on the UserData in the 'open' handler, seems like only string properties are copied.
Could symbol properties also be propagated? I find this useful as using symbols won't pollute the ws object.
Thanks!
No properties are copied, the entire object you pass to res.upgrade(obj is passed by reference to the open handler. So it's the ideical object passed around
Than something weird happens along the way. I created a simple example that highlights the described issue:
"use strict";
const uWS = require("uWebSockets.js");
const symbol = Symbol("symbol");
const myData = {
data: "string-property",
[symbol]: "symbol-property"
};
uWS.App()
.ws("/", {
upgrade: (res, req, context) => {
res.upgrade(
myData,
req.getHeader("sec-websocket-key"),
req.getHeader("sec-websocket-protocol"),
req.getHeader("sec-websocket-extensions"),
context
);
},
open: (ws) => {
console.log("ws.data: ", ws.data);
console.log("ws.getUserData().data: ", ws.getUserData().data);
console.log("ws[symbol]: ", ws[symbol]);
console.log("ws.getUserData()[symbol]: ", ws.getUserData()[symbol]);
console.log("myData === ws.getUserData(): ", myData === ws.getUserData());
console.log("ws === ws.getUserData(): ", ws === ws.getUserData());
}
})
.listen(3000, (token) => {
console.log(token ? "Listening to port 3000" : "Failed to listen to port 3000");
});
When a client connects, the following logs are produced:
Listening to port 3000
ws.data: string-property
ws.getUserData().data: string-property
ws[symbol]: undefined
ws.getUserData()[symbol]: undefined
myData === ws.getUserData(): false
ws === ws.getUserData(): true
As you can see:
- string properties are accessible while symbol properties have undefined values
- the object returned by getUserData() is the Websocket instance itself but is different from the object passed to upgrade()
- the UserData properties are accessibile on the ws object, I'm guessing there is some prototype chaining involved
Ah, okay here is the issue https://github.com/uNetworking/uWebSockets.js/blob/da323442662b64c2b38e9585e044d7624e88d691/src/AppWrapper.h#L163
So, are you going to make the code even uglier, by iterating over userData->GetOwnPropertySymbols?
If I may, judgeing by what I can see in the C++ code, Object.assign should also be available in the header file and does the intended job in a single line.
Relax buddy. There is no Object::Assign
So, are you going to make the code even uglier, by iterating over userData->GetOwnPropertySymbols?
Indeed.