Skip to content

Commit c884320

Browse files
committed
fix: switch from websocket library to ws to avoid native dep issues
1 parent ce0f965 commit c884320

File tree

7 files changed

+92
-103
lines changed

7 files changed

+92
-103
lines changed

node-client/package-lock.json

Lines changed: 27 additions & 50 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

node-client/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
"shelljs": "^0.8.2",
5454
"tslib": "^1.9.3",
5555
"underscore": "^1.9.1",
56-
"websocket": "^1.0.28"
56+
"ws": "^6.1.0"
5757
},
5858
"devDependencies": {
5959
"@types/base-64": "^0.1.2",
@@ -65,9 +65,9 @@
6565
"@types/node": "^10.12.0",
6666
"@types/request": "^2.47.1",
6767
"@types/underscore": "^1.8.9",
68-
"@types/websocket": "0.0.40",
68+
"@types/ws": "^6.0.1",
6969
"chai": "^4.2.0",
70-
"jasmine": "^3.2.0",
70+
"jasmine": "^3.3.0",
7171
"mocha": "^5.2.0",
7272
"mock-fs": "^4.7.0",
7373
"nyc": "^13.1.0",

node-client/src/attach_test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { expect } from 'chai';
22
import { ReadableStreamBuffer, WritableStreamBuffer } from 'stream-buffers';
33
import { anyFunction, anything, capture, instance, mock, verify, when } from 'ts-mockito';
4-
import ws = require('websocket');
4+
import WebSocket = require('ws');
55

66
import { Attach } from './attach';
77
import { KubeConfig } from './config';
@@ -64,7 +64,7 @@ describe('Attach', () => {
6464
const path = `/api/v1/namespaces/${namespace}/pods/${pod}/attach`;
6565
const args = `container=${container}&stderr=true&stdin=true&stdout=true&tty=false`;
6666

67-
const fakeConn: ws.connection = mock(ws.connection);
67+
const fakeConn: WebSocket = mock(WebSocket);
6868
when(fakeWebSocket.connect(`${path}?${args}`, null, anyFunction())).thenResolve(fakeConn);
6969

7070
await attach.attach(

node-client/src/exec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import querystring = require('querystring');
22
import stream = require('stream');
3-
import ws = require('websocket');
3+
import WebSocket = require('ws');
44

55
import { KubeConfig } from './config';
66
import { WebSocketHandler, WebSocketInterface } from './web-socket-handler';
@@ -19,7 +19,7 @@ export class Exec {
1919
// TODO: make command an array and support multiple args
2020
public async exec(namespace: string, podName: string, containerName: string, command: string,
2121
stdout: stream.Writable | any, stderr: stream.Writable | any, stdin: stream.Readable | any,
22-
tty: boolean): Promise<ws.connection> {
22+
tty: boolean): Promise<WebSocket> {
2323
const query = {
2424
stdout: stdout != null,
2525
stderr: stderr != null,

node-client/src/exec_test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { expect } from 'chai';
22
import { ReadableStreamBuffer, WritableStreamBuffer } from 'stream-buffers';
33
import { anyFunction, capture, instance, mock, verify, when } from 'ts-mockito';
4-
import ws = require('websocket');
4+
import WebSocket = require('ws');
55

66
import { KubeConfig } from './config';
77
import { Exec } from './exec';
@@ -65,7 +65,7 @@ describe('Exec', () => {
6565
const path = `/api/v1/namespaces/${namespace}/pods/${pod}/exec`;
6666
const args = `stdout=true&stderr=true&stdin=true&tty=false&command=${cmd}&container=${container}`;
6767

68-
const fakeConn: ws.connection = mock(ws.connection);
68+
const fakeConn: WebSocket = mock(WebSocket);
6969
when(fakeWebSocket.connect(`${path}?${args}`, null, anyFunction())).thenResolve(fakeConn);
7070

7171
await exec.exec(

node-client/src/portforward.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import querystring = require('querystring');
22
import stream = require('stream');
3-
import ws = require('websocket');
3+
import WebSocket = require('ws');
44

55
import { KubeConfig } from './config';
66
import { WebSocketHandler, WebSocketInterface } from './web-socket-handler';
@@ -20,9 +20,12 @@ export class PortForward {
2020
}
2121

2222
// TODO: support multiple ports for real...
23-
public async portForward(namespace: string, podName: string, targetPorts: number[],
24-
output: stream.Writable, err: stream.Writable,
25-
input: stream.Readable): Promise<ws.connection> {
23+
public async portForward(
24+
namespace: string, podName: string, targetPorts: number[],
25+
output: stream.Writable, err: stream.Writable,
26+
input: stream.Readable,
27+
): Promise<WebSocket> {
28+
2629
if (targetPorts.length === 0) {
2730
throw new Error('You must provide at least one port to forward to.');
2831
}

node-client/src/web-socket-handler.ts

Lines changed: 49 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
import https = require('https');
21
import stream = require('stream');
3-
import ws = require('websocket');
2+
import WebSocket = require('ws');
43

54
import { V1Status } from './api';
65
import { KubeConfig } from './config';
@@ -13,9 +12,11 @@ const protocols = [
1312
];
1413

1514
export interface WebSocketInterface {
16-
connect(path: string,
17-
textHandler: ((text: string) => boolean) | null,
18-
binaryHandler: ((stream: number, buff: Buffer) => boolean) | null): Promise<ws.connection>;
15+
connect(
16+
path: string,
17+
textHandler: ((text: string) => boolean) | null,
18+
binaryHandler: ((stream: number, buff: Buffer) => boolean) | null,
19+
): Promise<WebSocket>;
1920
}
2021

2122
export class WebSocketHandler implements WebSocketInterface {
@@ -24,8 +25,10 @@ export class WebSocketHandler implements WebSocketInterface {
2425
public static readonly StderrStream = 2;
2526
public static readonly StatusStream = 3;
2627

27-
public static handleStandardStreams(streamNum: number, buff: Buffer,
28-
stdout: stream.Writable, stderr: stream.Writable): V1Status | null {
28+
public static handleStandardStreams(
29+
streamNum: number, buff: Buffer,
30+
stdout: stream.Writable, stderr: stream.Writable,
31+
): V1Status | null {
2932
if (buff.length < 1) {
3033
return null;
3134
}
@@ -48,8 +51,11 @@ export class WebSocketHandler implements WebSocketInterface {
4851
return null;
4952
}
5053

51-
public static handleStandardInput(conn: ws.connection,
52-
stdin: stream.Readable | any, streamNum: number = 0): boolean {
54+
public static handleStandardInput(
55+
ws: WebSocket,
56+
stdin: stream.Readable | any,
57+
streamNum: number = 0,
58+
): boolean {
5359
stdin.on('data', (data) => {
5460
const buff = Buffer.alloc(data.length + 1);
5561
buff.writeInt8(streamNum, 0);
@@ -58,11 +64,11 @@ export class WebSocketHandler implements WebSocketInterface {
5864
} else {
5965
buff.write(data, 1);
6066
}
61-
conn.send(buff);
67+
ws.send(buff);
6268
});
6369

6470
stdin.on('end', () => {
65-
conn.close();
71+
ws.close();
6672
});
6773
// Keep the stream open
6874
return true;
@@ -82,9 +88,11 @@ export class WebSocketHandler implements WebSocketInterface {
8288
* @param binaryHandler Callback for binary data over the web socket.
8389
* Returns true if the connection should be kept alive, false to disconnect.
8490
*/
85-
public connect(path: string,
86-
textHandler: ((text: string) => boolean) | null,
87-
binaryHandler: ((stream: number, buff: Buffer) => boolean) | null): Promise<ws.connection> {
91+
public connect(
92+
path: string,
93+
textHandler: ((text: string) => boolean) | null,
94+
binaryHandler: ((stream: number, buff: Buffer) => boolean) | null,
95+
): Promise<WebSocket> {
8896

8997
const cluster = this.config.getCurrentCluster();
9098
if (!cluster) {
@@ -96,37 +104,38 @@ export class WebSocketHandler implements WebSocketInterface {
96104
const proto = ssl ? 'wss' : 'ws';
97105
const uri = `${proto}://${target}${path}`;
98106

99-
const opts: https.RequestOptions = {};
107+
const opts: WebSocket.ClientOptions = {};
100108
// TODO: This doesn't set insecureSSL if skipTLSVerify is set...
101109
this.config.applytoHTTPSOptions(opts);
102110

103-
const client = new ws.client({ tlsOptions: opts });
104-
105111
return new Promise((resolve, reject) => {
106-
client.on('connect', (connection) => {
107-
connection.on('message', (message: ws.IMessage) => {
108-
if (message.type === 'utf8' && message.utf8Data) {
109-
if (textHandler) {
110-
if (!textHandler(message.utf8Data)) {
111-
connection.close();
112-
}
113-
}
114-
} else if (message.type === 'binary' && message.binaryData) {
115-
if (binaryHandler) {
116-
const streamNum = message.binaryData.readInt8(0);
117-
if (!binaryHandler(streamNum, message.binaryData.slice(1))) {
118-
connection.close();
119-
}
120-
}
112+
const client = new WebSocket(uri, opts);
113+
let resolved = false;
114+
115+
client.onopen = () => {
116+
resolved = true;
117+
resolve(client);
118+
};
119+
120+
client.onerror = (err) => {
121+
if (!resolved) {
122+
reject(err);
123+
}
124+
};
125+
126+
client.onmessage = ({ data }: { data: WebSocket.Data }) => {
127+
// TODO: support ArrayBuffer and Buffer[] data types?
128+
if (typeof data === 'string') {
129+
if (textHandler && !textHandler(data)) {
130+
client.close();
131+
}
132+
} else if (data instanceof Buffer) {
133+
const streamNum = data.readInt8(0);
134+
if (binaryHandler && !binaryHandler(streamNum, data.slice(1))) {
135+
client.close();
121136
}
122-
});
123-
resolve(connection);
124-
});
125-
126-
client.on('connectFailed', (err) => {
127-
reject(err);
128-
});
129-
client.connect(uri, protocols);
137+
}
138+
};
130139
});
131140
}
132141
}

0 commit comments

Comments
 (0)