From a1869fa87e874e81e7f1470687c8498ef35e1e95 Mon Sep 17 00:00:00 2001 From: Natalia Venditto Date: Mon, 8 Jul 2024 17:55:43 +0200 Subject: [PATCH] http: expose websockets PR-URL: https://github.com/nodejs/node/pull/53721 Reviewed-By: Matteo Collina Reviewed-By: Paolo Insogna Reviewed-By: James M Snell --- doc/api/http.md | 10 ++++++ lib/http.js | 36 +++++++++++++++++++++ test/parallel/test-http-import-websocket.js | 14 ++++++++ 3 files changed, 60 insertions(+) create mode 100644 test/parallel/test-http-import-websocket.js diff --git a/doc/api/http.md b/doc/api/http.md index 3557e22085f..478886676fa 100644 --- a/doc/api/http.md +++ b/doc/api/http.md @@ -4228,6 +4228,15 @@ added: Set the maximum number of idle HTTP parsers. +## `WebSocket` + + + +A browser-compatible implementation of [`WebSocket`][]. + [RFC 8187]: https://www.rfc-editor.org/rfc/rfc8187.txt [`'ERR_HTTP_CONTENT_LENGTH_MISMATCH'`]: errors.md#err_http_content_length_mismatch [`'checkContinue'`]: #event-checkcontinue @@ -4244,6 +4253,7 @@ Set the maximum number of idle HTTP parsers. [`Headers`]: globals.md#class-headers [`TypeError`]: errors.md#class-typeerror [`URL`]: url.md#the-whatwg-url-api +[`WebSocket`]: #websocket [`agent.createConnection()`]: #agentcreateconnectionoptions-callback [`agent.getName()`]: #agentgetnameoptions [`destroy()`]: #agentdestroy diff --git a/lib/http.js b/lib/http.js index 684bc2ebc02..96ea32cf1b1 100644 --- a/lib/http.js +++ b/lib/http.js @@ -42,6 +42,7 @@ const { ServerResponse, } = require('_http_server'); let maxHeaderSize; +let undici; /** * Returns a new instance of `http.Server`. @@ -114,6 +115,14 @@ function get(url, options, cb) { return req; } +/** + * Lazy loads WebSocket, CloseEvent and MessageEvent classes from undici + * @returns {object} An object containing WebSocket, CloseEvent, and MessageEvent classes. + */ +function lazyUndici() { + return undici ??= require('internal/deps/undici/undici'); +} + module.exports = { _connectionListener, METHODS: methods.toSorted(), @@ -160,3 +169,30 @@ ObjectDefineProperty(module.exports, 'globalAgent', { httpAgent.globalAgent = value; }, }); + +ObjectDefineProperty(module.exports, 'WebSocket', { + __proto__: null, + configurable: true, + enumerable: true, + get() { + return lazyUndici().WebSocket; + }, +}); + +ObjectDefineProperty(module.exports, 'CloseEvent', { + __proto__: null, + configurable: true, + enumerable: true, + get() { + return lazyUndici().CloseEvent; + }, +}); + +ObjectDefineProperty(module.exports, 'MessageEvent', { + __proto__: null, + configurable: true, + enumerable: true, + get() { + return lazyUndici().MessageEvent; + }, +}); diff --git a/test/parallel/test-http-import-websocket.js b/test/parallel/test-http-import-websocket.js new file mode 100644 index 00000000000..5026d65108f --- /dev/null +++ b/test/parallel/test-http-import-websocket.js @@ -0,0 +1,14 @@ +'use strict'; + +require('../common'); +const assert = require('assert'); +const { + WebSocket: NodeHttpWebSocket, + CloseEvent: NodeHttpCloseEvent, + MessageEvent: NodeHttpMessageEvent +} = require('node:http'); + +// Compare with global objects +assert.strictEqual(NodeHttpWebSocket, WebSocket); +assert.strictEqual(NodeHttpCloseEvent, CloseEvent); +assert.strictEqual(NodeHttpMessageEvent, MessageEvent);