diff --git a/cli/tests/unit/websocket_test.ts b/cli/tests/unit/websocket_test.ts index 7bc53495af..a31e71e047 100644 --- a/cli/tests/unit/websocket_test.ts +++ b/cli/tests/unit/websocket_test.ts @@ -365,3 +365,42 @@ Deno.test(async function websocketTlsSocketWorks() { await finished; }); + +// https://github.com/denoland/deno/issues/15340 +Deno.test( + async function websocketServerFieldInit() { + const ac = new AbortController(); + const listeningDeferred = Promise.withResolvers(); + + const server = Deno.serve({ + handler: (req) => { + const { socket, response } = Deno.upgradeWebSocket(req, { + idleTimeout: 0, + }); + socket.onopen = function () { + assert(typeof socket.url == "string"); + assert(socket.readyState == WebSocket.OPEN); + assert(socket.protocol == ""); + socket.close(); + }; + socket.onclose = () => ac.abort(); + return response; + }, + signal: ac.signal, + onListen: () => listeningDeferred.resolve(), + hostname: "localhost", + port: servePort, + }); + + await listeningDeferred.promise; + const deferred = Promise.withResolvers(); + const ws = new WebSocket(serveUrl); + assertEquals(ws.url, serveUrl); + ws.onerror = () => fail(); + ws.onclose = () => { + deferred.resolve(); + }; + + await Promise.all([deferred.promise, server.finished]); + }, +); diff --git a/ext/http/01_http.js b/ext/http/01_http.js index acaea5e7c0..309e44ee46 100644 --- a/ext/http/01_http.js +++ b/ext/http/01_http.js @@ -3,7 +3,6 @@ import { core, internals, primordials } from "ext:core/mod.js"; const { BadResourcePrototype, InterruptedPrototype, ops } = core; const { op_http_write } = Deno.core.ensureFastOps(); -import * as webidl from "ext:deno_webidl/00_webidl.js"; import { InnerBody } from "ext:deno_fetch/22_body.js"; import { Event, setEventTargetData } from "ext:deno_web/02_event.js"; import { BlobPrototype } from "ext:deno_web/09_file.js"; @@ -29,6 +28,7 @@ import { _role, _server, _serverHandleIdleTimeout, + createWebSocketBranded, SERVER, WebSocket, } from "ext:deno_websocket/01_websocket.js"; @@ -472,7 +472,7 @@ function upgradeWebSocket(request, options = {}) { } } - const socket = webidl.createBranded(WebSocket); + const socket = createWebSocketBranded(WebSocket); setEventTargetData(socket); socket[_server] = true; socket[_idleTimeoutDuration] = options.idleTimeout ?? 120; diff --git a/ext/websocket/01_websocket.js b/ext/websocket/01_websocket.js index 477f93b93d..2aea080716 100644 --- a/ext/websocket/01_websocket.js +++ b/ext/websocket/01_websocket.js @@ -582,6 +582,20 @@ defineEventHandler(WebSocket.prototype, "open"); webidl.configureInterface(WebSocket); const WebSocketPrototype = WebSocket.prototype; +function createWebSocketBranded() { + const socket = webidl.createBranded(WebSocket); + socket[_rid] = undefined; + socket[_role] = undefined; + socket[_readyState] = CONNECTING; + socket[_extensions] = ""; + socket[_protocol] = ""; + socket[_url] = ""; + socket[_binaryType] = "blob"; + socket[_idleTimeoutDuration] = 0; + socket[_idleTimeoutTimeout] = undefined; + return socket; +} + export { _eventLoop, _idleTimeoutDuration, @@ -592,6 +606,7 @@ export { _role, _server, _serverHandleIdleTimeout, + createWebSocketBranded, SERVER, WebSocket, };