From 4ecbcd5e4f1d9fcd148d9c9d679841833f2014ba Mon Sep 17 00:00:00 2001 From: aricart Date: Mon, 4 Dec 2023 20:48:42 -0400 Subject: [PATCH] [FIX] fixed an issue affecting cluster updates when using ws:// protocol that updated gossiped servers as wss:// [BUMP] version, nbc to 1.19.0, and ci dependencies --- .github/workflows/natsws.yml | 4 ++-- .github/workflows/npm.yml | 4 ++-- package-lock.json | 28 ++++++++++++++-------------- package.json | 8 ++++---- src/connect.ts | 26 ++++++++++++++++++++++---- src/mod.ts | 4 ++-- src/nats-base-client.ts | 2 +- src/ws_transport.ts | 32 ++++++++++++++++---------------- 8 files changed, 63 insertions(+), 45 deletions(-) diff --git a/.github/workflows/natsws.yml b/.github/workflows/natsws.yml index cd573fe..6bf3ca8 100644 --- a/.github/workflows/natsws.yml +++ b/.github/workflows/natsws.yml @@ -14,7 +14,7 @@ jobs: strategy: matrix: node-version: [21.x] - deno-version: [1.36.4] + deno-version: [1.38.3] environment: CI runs-on: ubuntu-latest steps: @@ -31,7 +31,7 @@ jobs: with: deno-version: ${{ matrix.deno-version }} - name: Set NATS Server Version - run: echo "NATS_VERSION=v2.10.4" >> $GITHUB_ENV + run: echo "NATS_VERSION=v2.10.6" >> $GITHUB_ENV - name: Set CA run: echo "NODE_EXTRA_CA_CERTS=/home/runner/work/nats.ws/nats.ws/test/certs/ca.crt" >> $GITHUB_ENV - name: Get nats-server diff --git a/.github/workflows/npm.yml b/.github/workflows/npm.yml index 2efb504..146d112 100644 --- a/.github/workflows/npm.yml +++ b/.github/workflows/npm.yml @@ -8,8 +8,8 @@ jobs: test: strategy: matrix: - node-version: [20.x] - deno-version: [1.36.4] + node-version: [21.x] + deno-version: [1.38.3] runs-on: ubuntu-latest permissions: diff --git a/package-lock.json b/package-lock.json index 8022c6c..26487ba 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,22 +1,22 @@ { "name": "nats.ws", - "version": "1.19.0", + "version": "1.20.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "nats.ws", - "version": "1.19.0", + "version": "1.20.0", "license": "Apache-2.0", "devDependencies": { - "@types/node": "^20.6.x", + "@types/node": "^20.10.x", "ava": "^5.3.x", "minimist": "^1.2.8", - "nats-jwt": "^0.0.5", + "nats-jwt": "^0.0.7", "nyc": "^15.1.0", "shx": "^0.3.3", "tslint": "^6.1.3", - "typescript": "^5.2.x", + "typescript": "^5.3.x", "web-streams-polyfill": "^3.2.1", "websocket": "^1.0.34" }, @@ -570,9 +570,9 @@ } }, "node_modules/@types/node": { - "version": "20.8.10", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.10.tgz", - "integrity": "sha512-TlgT8JntpcbmKUFzjhsyhGfP2fsiz1Mv56im6enJ905xG1DAYesxJaeSbGqQmAw8OWPdhyJGhGSQGKRNJ45u9w==", + "version": "20.10.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.3.tgz", + "integrity": "sha512-XJavIpZqiXID5Yxnxv3RUDKTN5b81ddNC3ecsA0SoFXz/QU8OGBwZGMomiq0zw+uuqbL/krztv/DINAQ/EV4gg==", "dev": true, "dependencies": { "undici-types": "~5.26.4" @@ -2355,9 +2355,9 @@ "dev": true }, "node_modules/nats-jwt": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/nats-jwt/-/nats-jwt-0.0.5.tgz", - "integrity": "sha512-gmqBOdeVWhQSvZkruLevEt7adN5asBwPzUe4VYVJpdEuFjYINTUdPIx/YnOZgm2E+8EnzOgtJZySMUVXATkJUQ==", + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/nats-jwt/-/nats-jwt-0.0.7.tgz", + "integrity": "sha512-4TsK+EvmSufteQJwVnBw3mH0+R8RA/HwOUGZnox6mKh2y0xY9XaUKkoK42A5i/lugTM8jtPTELevr9GZZu6sKw==", "dev": true, "dependencies": { "nkeys.js": "1.0.5" @@ -3626,9 +3626,9 @@ } }, "node_modules/typescript": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", - "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.2.tgz", + "integrity": "sha512-6l+RyNy7oAHDfxC4FzSJcz9vnjTKxrLpDG5M2Vu4SHRVNg6xzqZp6LYSR9zjqQTu8DU/f5xwxUdADOkbrIX2gQ==", "dev": true, "bin": { "tsc": "bin/tsc", diff --git a/package.json b/package.json index c3ad3b4..f6a8ed2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nats.ws", - "version": "1.19.1", + "version": "1.20.0", "description": "WebSocket NATS client", "main": "./cjs/nats.js", "module": "./esm/nats.js", @@ -52,13 +52,13 @@ "nkeys.js": "1.0.5" }, "devDependencies": { - "@types/node": "^20.6.x", + "@types/node": "^20.10.x", "ava": "^5.3.x", "minimist": "^1.2.8", - "nats-jwt": "^0.0.5", + "nats-jwt": "^0.0.7", "shx": "^0.3.3", "tslint": "^6.1.3", - "typescript": "^5.2.x", + "typescript": "^5.3.x", "web-streams-polyfill": "^3.2.1", "websocket": "^1.0.34", "nyc": "^15.1.0" diff --git a/src/connect.ts b/src/connect.ts index a4cd78d..107820b 100644 --- a/src/connect.ts +++ b/src/connect.ts @@ -19,17 +19,29 @@ import { setTransportFactory, Transport, TransportFactory, -} from "https://raw.githubusercontent.com/nats-io/nats.deno/v1.18.0/nats-base-client/internal_mod.ts"; +} from "https://raw.githubusercontent.com/nats-io/nats.deno/v1.19.0/nats-base-client/internal_mod.ts"; import { WsTransport } from "./ws_transport.ts"; -export function wsUrlParseFn(u: string): string { +export function wsUrlParseFn(u: string, encrypted?: boolean): string { const ut = /^(.*:\/\/)(.*)/; if (!ut.test(u)) { - u = `https://${u}`; + // if we have no hint to encrypted and no protocol, assume encrypted + // else we fix the url from the update to match + if (typeof encrypted === "boolean") { + u = `${encrypted === true ? "https" : "http"}://${u}`; + } else { + u = `https://${u}`; + } } let url = new URL(u); const srcProto = url.protocol.toLowerCase(); + if (srcProto === "ws:") { + encrypted = false; + } + if (srcProto === "wss:") { + encrypted = true; + } if (srcProto !== "https:" && srcProto !== "http") { u = u.replace(/^(.*:\/\/)(.*)/gm, "$2"); url = new URL(`http://${u}`); @@ -48,10 +60,16 @@ export function wsUrlParseFn(u: string): string { port = url.port || "80"; protocol = "ws:"; break; - default: + case "https:": + case "wss:": + case "tls:": port = url.port || "443"; protocol = "wss:"; break; + default: + port = url.port || encrypted === true ? "443" : "80"; + protocol = encrypted === true ? "wss:" : "ws:"; + break; } return `${protocol}//${host}:${port}${path}${search}`; } diff --git a/src/mod.ts b/src/mod.ts index dd0c364..bc8a2c7 100644 --- a/src/mod.ts +++ b/src/mod.ts @@ -12,6 +12,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -export * from "https://raw.githubusercontent.com/nats-io/nats.deno/v1.18.0/nats-base-client/mod.ts"; -export * from "https://raw.githubusercontent.com/nats-io/nats.deno/v1.18.0/jetstream/mod.ts"; +export * from "https://raw.githubusercontent.com/nats-io/nats.deno/v1.19.0/nats-base-client/mod.ts"; +export * from "https://raw.githubusercontent.com/nats-io/nats.deno/v1.19.0/jetstream/mod.ts"; export { connect } from "./connect.ts"; diff --git a/src/nats-base-client.ts b/src/nats-base-client.ts index dac80da..1e92a61 100644 --- a/src/nats-base-client.ts +++ b/src/nats-base-client.ts @@ -13,4 +13,4 @@ * limitations under the License. */ // this import here to drive the build system -export * from "https://raw.githubusercontent.com/nats-io/nats.deno/v1.18.0/nats-base-client/internal_mod.ts"; +export * from "https://raw.githubusercontent.com/nats-io/nats.deno/v1.19.0/nats-base-client/internal_mod.ts"; diff --git a/src/ws_transport.ts b/src/ws_transport.ts index 3a731fd..e038b1e 100644 --- a/src/ws_transport.ts +++ b/src/ws_transport.ts @@ -19,7 +19,7 @@ import type { Server, ServerInfo, Transport, -} from "https://raw.githubusercontent.com/nats-io/nats.deno/v1.18.0/nats-base-client/internal_mod.ts"; +} from "https://raw.githubusercontent.com/nats-io/nats.deno/v1.19.0/nats-base-client/internal_mod.ts"; import { checkOptions, DataBuffer, @@ -30,9 +30,9 @@ import { INFO, NatsError, render, -} from "https://raw.githubusercontent.com/nats-io/nats.deno/v1.18.0/nats-base-client/internal_mod.ts"; +} from "https://raw.githubusercontent.com/nats-io/nats.deno/v1.19.0/nats-base-client/internal_mod.ts"; -const VERSION = "1.19.1"; +const VERSION = "1.20.0"; const LANG = "nats.ws"; export type WsSocketFactory = (u: string, opts: ConnectionOptions) => Promise<{ @@ -102,14 +102,14 @@ export class WsTransport implements Transport { this.socket.binaryType = "arraybuffer"; this.socket.onopen = () => { - if(this.isDiscarded()) { + if (this.isDiscarded()) { return; } // we don't do anything here... }; this.socket.onmessage = (me: MessageEvent) => { - if(this.isDiscarded()) { + if (this.isDiscarded()) { return; } this.yields.push(new Uint8Array(me.data)); @@ -144,7 +144,7 @@ export class WsTransport implements Transport { // @ts-ignore: CloseEvent is provided in browsers this.socket.onclose = (evt: CloseEvent) => { - if(this.isDiscarded()) { + if (this.isDiscarded()) { return; } this.socketClosed = true; @@ -158,7 +158,7 @@ export class WsTransport implements Transport { // @ts-ignore: signature can be any this.socket.onerror = (e: ErrorEvent | Event): void => { - if(this.isDiscarded()) { + if (this.isDiscarded()) { return; } const evt = e as ErrorEvent; @@ -181,8 +181,8 @@ export class WsTransport implements Transport { } private async _closed(err?: Error, internal = true): Promise { - if(this.isDiscarded()) { - return + if (this.isDiscarded()) { + return; } if (!this.connected) return; if (this.done) return; @@ -215,7 +215,7 @@ export class WsTransport implements Transport { async *iterate(): AsyncIterableIterator { while (true) { if (this.isDiscarded()) { - return + return; } if (this.yields.length === 0) { await this.signal; @@ -275,10 +275,10 @@ export class WsTransport implements Transport { // check to see if we are discarded, as the connection // may not have been closed, we attempt it here as well. - isDiscarded():boolean { - if(this.done) { + isDiscarded(): boolean { + if (this.done) { this.discard(); - return true + return true; } return false; } @@ -288,11 +288,11 @@ export class WsTransport implements Transport { // Firefox for example, will keep connections going, // so eventually if it succeeds, the client will have // an additional transport running. With this - discard () { + discard() { this.done = true; try { - this.socket?.close() - } catch(_err) { + this.socket?.close(); + } catch (_err) { // ignored } }