From aee468cf2d6f852314c249be10543f0077153bf8 Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Mon, 30 Sep 2024 16:29:29 -0700 Subject: [PATCH] Remove use of `Module['websocket']`. NFC We can still receive the initial value for websocket from the Module object but there is not need to continue to access it via the Module object. --- src/library_sockfs.js | 112 +++++++++++++++++++----------------------- 1 file changed, 50 insertions(+), 62 deletions(-) diff --git a/src/library_sockfs.js b/src/library_sockfs.js index e781b6dc31aff..a63955b64a7a5 100644 --- a/src/library_sockfs.js +++ b/src/library_sockfs.js @@ -10,37 +10,35 @@ addToLibrary({ }, $SOCKFS__deps: ['$FS'], $SOCKFS: { +#if expectToReceiveOnModule('websocket') + websocketArgs: {}, +#endif + callbacks: {}, + on(event, callback) { + SOCKFS.callbacks[event] = callback; + }, + emit(event, param) { + SOCKFS.callbacks[event]?.(param); + }, mount(mount) { - // If Module['websocket'] has already been defined (e.g. for configuring - // the subprotocol/url) use that, if not initialise it to a new object. - Module['websocket'] = (Module['websocket'] && - ('object' === typeof Module['websocket'])) ? Module['websocket'] : {}; - +#if expectToReceiveOnModule('websocket') + // The incomming Module['websocket'] can be used for configuring + // configuring subprotocol/url, etc + SOCKFS.websocketArgs = {{{ makeModuleReceiveExpr('websocket', '{}') }}}; // Add the Event registration mechanism to the exported websocket configuration // object so we can register network callbacks from native JavaScript too. // For more documentation see system/include/emscripten/emscripten.h - Module['websocket']._callbacks = {}; - Module['websocket']['on'] = /** @this{Object} */ function(event, callback) { - if ('function' === typeof callback) { - this._callbacks[event] = callback; - } - return this; - }; - - Module['websocket'].emit = /** @this{Object} */ function(event, param) { - if ('function' === typeof this._callbacks[event]) { - this._callbacks[event].call(this, param); - } - }; + (Module['websocket'] ??= {})['on'] = SOCKFS.on; +#endif - // If debug is enabled register simple default logging callbacks for each Event. #if SOCKET_DEBUG - Module['websocket']['on']('error', (error) => dbg('websocket: error ' + error)); - Module['websocket']['on']('open', (fd) => dbg('websocket: open fd = ' + fd)); - Module['websocket']['on']('listen', (fd) => dbg('websocket: listen fd = ' + fd)); - Module['websocket']['on']('connection', (fd) => dbg('websocket: connection fd = ' + fd)); - Module['websocket']['on']('message', (fd) => dbg('websocket: message fd = ' + fd)); - Module['websocket']['on']('close', (fd) => dbg('websocket: close fd = ' + fd)); + // If debug is enabled register simple default logging callbacks for each Event. + SOCKFS.on('error', (error) => dbg('websocket: error ' + error)); + SOCKFS.on('open', (fd) => dbg('websocket: open fd = ' + fd)); + SOCKFS.on('listen', (fd) => dbg('websocket: listen fd = ' + fd)); + SOCKFS.on('connection', (fd) => dbg('websocket: connection fd = ' + fd)); + SOCKFS.on('message', (fd) => dbg('websocket: message fd = ' + fd)); + SOCKFS.on('close', (fd) => dbg('websocket: close fd = ' + fd)); #endif return FS.createNode(null, '/', {{{ cDefs.S_IFDIR }}} | 511 /* 0777 */, 0); @@ -169,36 +167,32 @@ addToLibrary({ } else { // create the actual websocket object and connect try { - // runtimeConfig gets set to true if WebSocket runtime configuration is available. - var runtimeConfig = (Module['websocket'] && ('object' === typeof Module['websocket'])); - // The default value is 'ws://' the replace is needed because the compiler replaces '//' comments with '#' // comments without checking context, so we'd end up with ws:#, the replace swaps the '#' for '//' again. var url = '{{{ WEBSOCKET_URL }}}'.replace('#', '//'); + // Make the WebSocket subprotocol (Sec-WebSocket-Protocol) default to binary if no configuration is set. + var subProtocols = '{{{ WEBSOCKET_SUBPROTOCOL }}}'; // The default value is 'binary' + // The default WebSocket options + var opts = undefined; - if (runtimeConfig) { - if ('string' === typeof Module['websocket']['url']) { - url = Module['websocket']['url']; // Fetch runtime WebSocket URL config. - } +#if expectToReceiveOnModule('websocket') + // Fetch runtime WebSocket URL config. + if (SOCKFS.websocketArgs['url']) { + url = SOCKFS.websocketArgs['url']; } + // Fetch runtime WebSocket subprotocol config. + if (SOCKFS.websocketArgs['subprotocol']) { + subProtocols = SOCKFS.websocketArgs['subprotocol']; + } else if (SOCKFS.websocketArgs['subprotocol'] === null) { + subProtocols = 'null' + } +#endif if (url === 'ws://' || url === 'wss://') { // Is the supplied URL config just a prefix, if so complete it. var parts = addr.split('/'); url = url + parts[0] + ":" + port + "/" + parts.slice(1).join('/'); } - // Make the WebSocket subprotocol (Sec-WebSocket-Protocol) default to binary if no configuration is set. - var subProtocols = '{{{ WEBSOCKET_SUBPROTOCOL }}}'; // The default value is 'binary' - - if (runtimeConfig) { - if ('string' === typeof Module['websocket']['subprotocol']) { - subProtocols = Module['websocket']['subprotocol']; // Fetch runtime WebSocket subprotocol config. - } - } - - // The default WebSocket options - var opts = undefined; - if (subProtocols !== 'null') { // The regex trims the string (removes spaces at the beginning and end, then splits the string by // , into an Array. Whitespace removal is important for Websockify and ws. @@ -207,12 +201,6 @@ addToLibrary({ opts = subProtocols; } - // some webservers (azure) does not support subprotocol header - if (runtimeConfig && null === Module['websocket']['subprotocol']) { - subProtocols = 'null'; - opts = undefined; - } - #if SOCKET_DEBUG dbg('websocket: connect: ' + url + ', ' + subProtocols.toString()); #endif @@ -280,8 +268,8 @@ addToLibrary({ dbg('websocket: handle open'); #endif - Module['websocket'].emit('open', sock.stream.fd); sock.connecting = false; + SOCKFS.emit('open', sock.stream.fd); try { var queued = peer.msg_send_queue.shift(); @@ -334,7 +322,7 @@ addToLibrary({ } sock.recv_queue.push({ addr: peer.addr, port: peer.port, data: data }); - Module['websocket'].emit('message', sock.stream.fd); + SOCKFS.emit('message', sock.stream.fd); }; if (ENVIRONMENT_IS_NODE) { @@ -346,7 +334,7 @@ addToLibrary({ handleMessage((new Uint8Array(data)).buffer); // copy from node Buffer -> ArrayBuffer }); peer.socket.on('close', function() { - Module['websocket'].emit('close', sock.stream.fd); + SOCKFS.emit('close', sock.stream.fd); }); peer.socket.on('error', function(error) { // Although the ws library may pass errors that may be more descriptive than @@ -354,13 +342,13 @@ addToLibrary({ // ENOTFOUND on getaddrinfo seems to be node.js specific, so using ECONNREFUSED // is still probably the most useful thing to do. sock.error = {{{ cDefs.ECONNREFUSED }}}; // Used in getsockopt for SOL_SOCKET/SO_ERROR test. - Module['websocket'].emit('error', [sock.stream.fd, sock.error, 'ECONNREFUSED: Connection refused']); + SOCKFS.emit('error', [sock.stream.fd, sock.error, 'ECONNREFUSED: Connection refused']); // don't throw }); } else { peer.socket.onopen = handleOpen; peer.socket.onclose = function() { - Module['websocket'].emit('close', sock.stream.fd); + SOCKFS.emit('close', sock.stream.fd); }; peer.socket.onmessage = function peer_socket_onmessage(event) { handleMessage(event.data); @@ -369,7 +357,7 @@ addToLibrary({ // The WebSocket spec only allows a 'simple event' to be thrown on error, // so we only really know as much as ECONNREFUSED. sock.error = {{{ cDefs.ECONNREFUSED }}}; // Used in getsockopt for SOL_SOCKET/SO_ERROR test. - Module['websocket'].emit('error', [sock.stream.fd, sock.error, 'ECONNREFUSED: Connection refused']); + SOCKFS.emit('error', [sock.stream.fd, sock.error, 'ECONNREFUSED: Connection refused']); }; } }, @@ -525,7 +513,7 @@ addToLibrary({ port: sock.sport // TODO support backlog }); - Module['websocket'].emit('listen', sock.stream.fd); // Send Event with listen fd. + SOCKFS.emit('listen', sock.stream.fd); // Send Event with listen fd. sock.server.on('connection', function(ws) { #if SOCKET_DEBUG @@ -541,17 +529,17 @@ addToLibrary({ // push to queue for accept to pick up sock.pending.push(newsock); - Module['websocket'].emit('connection', newsock.stream.fd); + SOCKFS.emit('connection', newsock.stream.fd); } else { // create a peer on the listen socket so calling sendto // with the listen socket and an address will resolve // to the correct client SOCKFS.websocket_sock_ops.createPeer(sock, ws); - Module['websocket'].emit('connection', sock.stream.fd); + SOCKFS.emit('connection', sock.stream.fd); } }); sock.server.on('close', function() { - Module['websocket'].emit('close', sock.stream.fd); + SOCKFS.emit('close', sock.stream.fd); sock.server = null; }); sock.server.on('error', function(error) { @@ -562,7 +550,7 @@ addToLibrary({ // occur in a well written app as errors should get trapped in the compiled // app's own getaddrinfo call. sock.error = {{{ cDefs.EHOSTUNREACH }}}; // Used in getsockopt for SOL_SOCKET/SO_ERROR test. - Module['websocket'].emit('error', [sock.stream.fd, sock.error, 'EHOSTUNREACH: Host is unreachable']); + SOCKFS.emit('error', [sock.stream.fd, sock.error, 'EHOSTUNREACH: Host is unreachable']); // don't throw }); #endif // ENVIRONMENT_MAY_BE_NODE @@ -763,7 +751,7 @@ addToLibrary({ // FIXME(sbc): This has no corresponding Pop so will currently keep the // runtime alive indefinitely. {{{ runtimeKeepalivePush() }}} - Module['websocket']['on'](event, callback ? _callback : null); + SOCKFS.on(event, callback ? _callback : null); }, emscripten_set_socket_error_callback__deps: ['$_setNetworkCallback'], emscripten_set_socket_error_callback: (userData, callback) => {