diff --git a/package.json b/package.json index 406e23b8..f5e0cd73 100644 --- a/package.json +++ b/package.json @@ -42,14 +42,14 @@ "@types/express": "^4.17.8", "@types/http-proxy": "^1.17.4", "@types/js-yaml": "^4.0.0", - "@types/node": "^14.17.1", + "@types/node": "^16.0.0", "@types/pem": "^1.9.5", "@types/proxy-from-env": "^1.0.1", "@types/safe-compare": "^1.1.0", "@types/semver": "^7.1.0", "@types/split2": "^3.2.0", "@types/trusted-types": "^2.0.2", - "@types/ws": "^8.0.0", + "@types/ws": "^8.5.3", "@typescript-eslint/eslint-plugin": "^5.23.0", "@typescript-eslint/parser": "^5.23.0", "audit-ci": "^6.0.0", @@ -85,7 +85,8 @@ "node-fetch": "^2.6.7", "nanoid": "^3.1.31", "minimist": "npm:minimist-lite@2.2.1", - "glob-parent": "^6.0.1" + "glob-parent": "^6.0.1", + "@types/node": "^16.0.0" }, "dependencies": { "@coder/logger": "1.1.16", diff --git a/src/node/routes/vscode.ts b/src/node/routes/vscode.ts index 961b46c0..e8c45129 100644 --- a/src/node/routes/vscode.ts +++ b/src/node/routes/vscode.ts @@ -127,7 +127,10 @@ export class CodeServerRouteWrapper { private $proxyWebsocket = async (req: WebsocketRequest) => { const wrappedSocket = await this._socketProxyProvider.createProxy(req.ws) - this._codeServerMain.handleUpgrade(req, wrappedSocket) + // This should actually accept a duplex stream but it seems Code has not + // been updated to match the Node 16 types so cast for now. There does not + // appear to be any code specific to sockets so this should be fine. + this._codeServerMain.handleUpgrade(req, wrappedSocket as net.Socket) req.ws.resume() } diff --git a/src/node/socket.ts b/src/node/socket.ts index a56d9566..194d28e0 100644 --- a/src/node/socket.ts +++ b/src/node/socket.ts @@ -1,6 +1,7 @@ import { promises as fs } from "fs" import * as net from "net" import * as path from "path" +import * as stream from "stream" import * as tls from "tls" import { Emitter } from "../common/emitter" import { generateUuid } from "../common/util" @@ -27,10 +28,13 @@ export class SocketProxyProvider { } /** - * Create a socket proxy for TLS sockets. If it's not a TLS socket the - * original socket is returned. This will spawn a proxy server on demand. + * Create a socket proxy for TLS sockets. If it is not a TLS socket the + * original socket or stream is returned. This will spawn a proxy server on + * demand. */ - public async createProxy(socket: net.Socket): Promise { + public async createProxy(socket: tls.TLSSocket | net.Socket): Promise + public async createProxy(socket: stream.Duplex): Promise + public async createProxy(socket: tls.TLSSocket | net.Socket | stream.Duplex): Promise { if (!(socket instanceof tls.TLSSocket)) { return socket } diff --git a/src/node/wsRouter.ts b/src/node/wsRouter.ts index 0c60a5fa..2f6f18ba 100644 --- a/src/node/wsRouter.ts +++ b/src/node/wsRouter.ts @@ -8,13 +8,14 @@ export const handleUpgrade = (app: express.Express, server: http.Server): void = server.on("upgrade", (req, socket, head) => { socket.pause() - req.ws = socket - req.head = head - req._ws_handled = false + const wreq = req as InternalWebsocketRequest + wreq.ws = socket + wreq.head = head + wreq._ws_handled = false // Send the request off to be handled by Express. - ;(app as any).handle(req, new http.ServerResponse(req), () => { - if (!req._ws_handled) { + ;(app as any).handle(wreq, new http.ServerResponse(wreq), () => { + if (!wreq._ws_handled) { socket.end("HTTP/1.1 404 Not Found\r\n\r\n") } }) diff --git a/test/unit/node/update.test.ts b/test/unit/node/update.test.ts index d315e977..50d88dee 100644 --- a/test/unit/node/update.test.ts +++ b/test/unit/node/update.test.ts @@ -67,7 +67,7 @@ describe("update", () => { // Anything else is a 404. response.writeHead(404) - response.end("not found") + return response.end("not found") }) let _settings: SettingsProvider | undefined diff --git a/typings/pluginapi.d.ts b/typings/pluginapi.d.ts index 2397d668..829709b2 100644 --- a/typings/pluginapi.d.ts +++ b/typings/pluginapi.d.ts @@ -5,7 +5,7 @@ import { field, Level, Logger } from "@coder/logger" import * as express from "express" import * as expressCore from "express-serve-static-core" import ProxyServer from "http-proxy" -import * as net from "net" +import * as stream from "stream" import Websocket from "ws" /** @@ -97,7 +97,7 @@ export declare class HttpError extends Error { } export interface WebsocketRequest extends express.Request { - ws: net.Socket + ws: stream.Duplex head: Buffer } diff --git a/yarn.lock b/yarn.lock index 2d513045..cb876382 100644 --- a/yarn.lock +++ b/yarn.lock @@ -369,9 +369,9 @@ "@types/express" "*" "@types/express-serve-static-core@^4.17.18": - version "4.17.19" - resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.19.tgz#00acfc1632e729acac4f1530e9e16f6dd1508a1d" - integrity sha512-DJOSHzX7pCiSElWaGR8kCprwibCB/3yW6vcT8VG3P0SJjnv19gnWG/AZMfM60Xj/YJIp/YCaDHyvzsFVeniARA== + version "4.17.30" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.30.tgz#0f2f99617fa8f9696170c46152ccf7500b34ac04" + integrity sha512-gstzbTWro2/nFed1WXtf+TtrpwxH7Ggs4RLYTLbeVgIkUQOI3WG/JKjgeOU1zXDvezllupjrf8OPIdvTbIaVOQ== dependencies: "@types/node" "*" "@types/qs" "*" @@ -426,10 +426,10 @@ resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.1.tgz#283f669ff76d7b8260df8ab7a4262cc83d988256" integrity sha512-fZQQafSREFyuZcdWFAExYjBiCL7AUCdgsk80iO0q4yihYYdcIiH28CcuPTGFgLOCC8RlW49GSQxdHwZP+I7CNg== -"@types/node@*", "@types/node@^14.17.1": - version "14.17.6" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.17.6.tgz#cc61c8361c89e70c468cda464d1fa3dd7e5ebd62" - integrity sha512-iBxsxU7eswQDGhlr3AiamBxOssaYxbM+NKXVil8jg9yFXvrfEFbDumLD/2dMTB+zYyg7w+Xjt8yuxfdbUHAtcQ== +"@types/node@*", "@types/node@^16.0.0": + version "16.11.41" + resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.41.tgz#88eb485b1bfdb4c224d878b7832239536aa2f813" + integrity sha512-mqoYK2TnVjdkGk8qXAVGc/x9nSaTpSrFaGFm43BUH3IdoBV0nta6hYaGmdOvIMlbHJbUEVen3gvwpwovAZKNdQ== "@types/normalize-package-data@^2.4.0": version "2.4.0" @@ -500,10 +500,10 @@ resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.3.tgz#9c088679876f374eb5983f150d4787aa6fb32d7e" integrity sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ== -"@types/ws@^8.0.0": - version "8.2.0" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.2.0.tgz#75faefbe2328f3b833cb8dc640658328990d04f3" - integrity sha512-cyeefcUCgJlEk+hk2h3N+MqKKsPViQgF5boi9TTHSK+PoR9KWBb/C5ccPcDyAqgsbAYHTwulch725DV84+pSpg== +"@types/ws@^8.5.3": + version "8.5.3" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.3.tgz#7d25a1ffbecd3c4f2d35068d0b283c037003274d" + integrity sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w== dependencies: "@types/node" "*"