@novnc/novnc 1.0.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AUTHORS +13 -0
- package/LICENSE.txt +2 -1
- package/README.md +69 -3
- package/core/base64.js +35 -41
- package/core/decoders/copyrect.js +22 -0
- package/core/decoders/hextile.js +137 -0
- package/core/decoders/raw.js +56 -0
- package/core/decoders/rre.js +44 -0
- package/core/decoders/tight.js +315 -0
- package/core/decoders/tightpng.js +27 -0
- package/core/deflator.js +85 -0
- package/core/des.js +90 -95
- package/core/display.js +254 -297
- package/core/encodings.js +7 -3
- package/core/inflator.js +48 -20
- package/core/input/domkeytable.js +21 -24
- package/core/input/fixedkeys.js +3 -1
- package/core/input/gesturehandler.js +567 -0
- package/core/input/keyboard.js +194 -120
- package/core/input/keysym.js +2 -0
- package/core/input/keysymdef.js +3 -3
- package/core/input/util.js +53 -12
- package/core/input/vkeys.js +2 -1
- package/core/rfb.js +1937 -1496
- package/core/util/browser.js +80 -29
- package/core/util/cursor.js +253 -0
- package/core/util/element.js +32 -0
- package/core/util/events.js +59 -55
- package/core/util/eventtarget.js +25 -30
- package/core/util/int.js +15 -0
- package/core/util/logging.js +21 -16
- package/core/util/polyfill.js +15 -8
- package/core/util/strings.js +21 -8
- package/core/websock.js +145 -167
- package/docs/API.md +31 -10
- package/lib/base64.js +115 -0
- package/lib/decoders/copyrect.js +44 -0
- package/lib/decoders/hextile.js +173 -0
- package/lib/decoders/raw.js +78 -0
- package/lib/decoders/rre.js +65 -0
- package/lib/decoders/tight.js +350 -0
- package/lib/decoders/tightpng.js +67 -0
- package/lib/deflator.js +99 -0
- package/lib/des.js +314 -0
- package/lib/display.js +733 -0
- package/lib/encodings.js +64 -0
- package/lib/inflator.js +87 -0
- package/lib/input/domkeytable.js +282 -0
- package/lib/input/fixedkeys.js +123 -0
- package/lib/input/gesturehandler.js +642 -0
- package/lib/input/keyboard.js +429 -0
- package/lib/input/keysym.js +1135 -0
- package/lib/input/keysymdef.js +1354 -0
- package/lib/input/util.js +304 -0
- package/lib/input/vkeys.js +127 -0
- package/lib/input/xtscancodes.js +505 -0
- package/lib/rfb.js +3448 -0
- package/lib/util/browser.js +131 -0
- package/lib/util/cursor.js +314 -0
- package/lib/util/element.js +43 -0
- package/lib/util/events.js +142 -0
- package/lib/util/eventtarget.js +64 -0
- package/lib/util/int.js +22 -0
- package/lib/util/logging.js +79 -0
- package/lib/util/polyfill.js +72 -0
- package/lib/util/strings.js +38 -0
- package/lib/vendor/pako/lib/utils/common.js +67 -0
- package/lib/vendor/pako/lib/zlib/adler32.js +33 -0
- package/lib/vendor/pako/lib/zlib/constants.js +51 -0
- package/lib/vendor/pako/lib/zlib/crc32.js +42 -0
- package/lib/vendor/pako/lib/zlib/deflate.js +2159 -0
- package/lib/vendor/pako/lib/zlib/gzheader.js +53 -0
- package/lib/vendor/pako/lib/zlib/inffast.js +445 -0
- package/lib/vendor/pako/lib/zlib/inflate.js +2114 -0
- package/lib/vendor/pako/lib/zlib/inftrees.js +418 -0
- package/lib/vendor/pako/lib/zlib/messages.js +36 -0
- package/lib/vendor/pako/lib/zlib/trees.js +1499 -0
- package/lib/vendor/pako/lib/zlib/zstream.js +46 -0
- package/lib/vendor/promise.js +255 -0
- package/lib/websock.js +374 -0
- package/package.json +48 -28
- package/vendor/pako/lib/zlib/deflate.js +30 -30
- package/vendor/pako/lib/zlib/inflate.js +17 -17
- package/core/input/mouse.js +0 -280
- package/docs/API-internal.md +0 -125
- package/docs/EMBEDDING.md +0 -83
- package/docs/VERSION +0 -1
package/core/websock.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* Websock: high-performance binary WebSockets
|
|
3
|
-
* Copyright (C)
|
|
3
|
+
* Copyright (C) 2019 The noVNC Authors
|
|
4
4
|
* Licensed under MPL 2.0 (see LICENSE.txt)
|
|
5
5
|
*
|
|
6
6
|
* Websock is similar to the standard WebSocket object but with extra
|
|
@@ -14,143 +14,121 @@
|
|
|
14
14
|
|
|
15
15
|
import * as Log from './util/logging.js';
|
|
16
16
|
|
|
17
|
-
export default function Websock() {
|
|
18
|
-
"use strict";
|
|
19
|
-
|
|
20
|
-
this._websocket = null; // WebSocket object
|
|
21
|
-
|
|
22
|
-
this._rQi = 0; // Receive queue index
|
|
23
|
-
this._rQlen = 0; // Next write position in the receive queue
|
|
24
|
-
this._rQbufferSize = 1024 * 1024 * 4; // Receive queue buffer size (4 MiB)
|
|
25
|
-
this._rQmax = this._rQbufferSize / 8;
|
|
26
|
-
// called in init: this._rQ = new Uint8Array(this._rQbufferSize);
|
|
27
|
-
this._rQ = null; // Receive queue
|
|
28
|
-
|
|
29
|
-
this._sQbufferSize = 1024 * 10; // 10 KiB
|
|
30
|
-
// called in init: this._sQ = new Uint8Array(this._sQbufferSize);
|
|
31
|
-
this._sQlen = 0;
|
|
32
|
-
this._sQ = null; // Send queue
|
|
33
|
-
|
|
34
|
-
this._eventHandlers = {
|
|
35
|
-
'message': function () {},
|
|
36
|
-
'open': function () {},
|
|
37
|
-
'close': function () {},
|
|
38
|
-
'error': function () {}
|
|
39
|
-
};
|
|
40
|
-
};
|
|
41
|
-
|
|
42
17
|
// this has performance issues in some versions Chromium, and
|
|
43
18
|
// doesn't gain a tremendous amount of performance increase in Firefox
|
|
44
19
|
// at the moment. It may be valuable to turn it on in the future.
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
20
|
+
// Also copyWithin() for TypedArrays is not supported in IE 11 or
|
|
21
|
+
// Safari 13 (at the moment we want to support Safari 11).
|
|
22
|
+
const ENABLE_COPYWITHIN = false;
|
|
23
|
+
const MAX_RQ_GROW_SIZE = 40 * 1024 * 1024; // 40 MiB
|
|
24
|
+
|
|
25
|
+
export default class Websock {
|
|
26
|
+
constructor() {
|
|
27
|
+
this._websocket = null; // WebSocket object
|
|
28
|
+
|
|
29
|
+
this._rQi = 0; // Receive queue index
|
|
30
|
+
this._rQlen = 0; // Next write position in the receive queue
|
|
31
|
+
this._rQbufferSize = 1024 * 1024 * 4; // Receive queue buffer size (4 MiB)
|
|
32
|
+
// called in init: this._rQ = new Uint8Array(this._rQbufferSize);
|
|
33
|
+
this._rQ = null; // Receive queue
|
|
34
|
+
|
|
35
|
+
this._sQbufferSize = 1024 * 10; // 10 KiB
|
|
36
|
+
// called in init: this._sQ = new Uint8Array(this._sQbufferSize);
|
|
37
|
+
this._sQlen = 0;
|
|
38
|
+
this._sQ = null; // Send queue
|
|
39
|
+
|
|
40
|
+
this._eventHandlers = {
|
|
41
|
+
message: () => {},
|
|
42
|
+
open: () => {},
|
|
43
|
+
close: () => {},
|
|
44
|
+
error: () => {}
|
|
60
45
|
};
|
|
61
46
|
}
|
|
62
|
-
})();
|
|
63
47
|
|
|
64
|
-
Websock.prototype = {
|
|
65
48
|
// Getters and Setters
|
|
66
|
-
|
|
49
|
+
get sQ() {
|
|
67
50
|
return this._sQ;
|
|
68
|
-
}
|
|
51
|
+
}
|
|
69
52
|
|
|
70
|
-
|
|
53
|
+
get rQ() {
|
|
71
54
|
return this._rQ;
|
|
72
|
-
}
|
|
55
|
+
}
|
|
73
56
|
|
|
74
|
-
|
|
57
|
+
get rQi() {
|
|
75
58
|
return this._rQi;
|
|
76
|
-
}
|
|
59
|
+
}
|
|
77
60
|
|
|
78
|
-
|
|
61
|
+
set rQi(val) {
|
|
79
62
|
this._rQi = val;
|
|
80
|
-
}
|
|
63
|
+
}
|
|
81
64
|
|
|
82
65
|
// Receive Queue
|
|
83
|
-
rQlen
|
|
66
|
+
get rQlen() {
|
|
84
67
|
return this._rQlen - this._rQi;
|
|
85
|
-
}
|
|
68
|
+
}
|
|
86
69
|
|
|
87
|
-
rQpeek8
|
|
70
|
+
rQpeek8() {
|
|
88
71
|
return this._rQ[this._rQi];
|
|
89
|
-
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
rQskipBytes(bytes) {
|
|
75
|
+
this._rQi += bytes;
|
|
76
|
+
}
|
|
90
77
|
|
|
91
|
-
rQshift8
|
|
92
|
-
return this.
|
|
93
|
-
}
|
|
78
|
+
rQshift8() {
|
|
79
|
+
return this._rQshift(1);
|
|
80
|
+
}
|
|
94
81
|
|
|
95
|
-
|
|
96
|
-
this.
|
|
97
|
-
}
|
|
82
|
+
rQshift16() {
|
|
83
|
+
return this._rQshift(2);
|
|
84
|
+
}
|
|
98
85
|
|
|
99
|
-
|
|
100
|
-
this.
|
|
101
|
-
}
|
|
86
|
+
rQshift32() {
|
|
87
|
+
return this._rQshift(4);
|
|
88
|
+
}
|
|
102
89
|
|
|
103
90
|
// TODO(directxman12): test performance with these vs a DataView
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
return
|
|
121
|
-
}
|
|
91
|
+
_rQshift(bytes) {
|
|
92
|
+
let res = 0;
|
|
93
|
+
for (let byte = bytes - 1; byte >= 0; byte--) {
|
|
94
|
+
res += this._rQ[this._rQi++] << (byte * 8);
|
|
95
|
+
}
|
|
96
|
+
return res;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
rQshiftStr(len) {
|
|
100
|
+
if (typeof(len) === 'undefined') { len = this.rQlen; }
|
|
101
|
+
let str = "";
|
|
102
|
+
// Handle large arrays in steps to avoid long strings on the stack
|
|
103
|
+
for (let i = 0; i < len; i += 4096) {
|
|
104
|
+
let part = this.rQshiftBytes(Math.min(4096, len - i));
|
|
105
|
+
str += String.fromCharCode.apply(null, part);
|
|
106
|
+
}
|
|
107
|
+
return str;
|
|
108
|
+
}
|
|
122
109
|
|
|
123
|
-
rQshiftBytes
|
|
124
|
-
if (typeof(len) === 'undefined') { len = this.rQlen
|
|
110
|
+
rQshiftBytes(len) {
|
|
111
|
+
if (typeof(len) === 'undefined') { len = this.rQlen; }
|
|
125
112
|
this._rQi += len;
|
|
126
113
|
return new Uint8Array(this._rQ.buffer, this._rQi - len, len);
|
|
127
|
-
}
|
|
114
|
+
}
|
|
128
115
|
|
|
129
|
-
rQshiftTo
|
|
130
|
-
if (len === undefined) { len = this.rQlen
|
|
116
|
+
rQshiftTo(target, len) {
|
|
117
|
+
if (len === undefined) { len = this.rQlen; }
|
|
131
118
|
// TODO: make this just use set with views when using a ArrayBuffer to store the rQ
|
|
132
119
|
target.set(new Uint8Array(this._rQ.buffer, this._rQi, len));
|
|
133
120
|
this._rQi += len;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
rQwhole: function () {
|
|
137
|
-
return new Uint8Array(this._rQ.buffer, 0, this._rQlen);
|
|
138
|
-
},
|
|
121
|
+
}
|
|
139
122
|
|
|
140
|
-
rQslice
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
} else {
|
|
144
|
-
return new Uint8Array(this._rQ.buffer, this._rQi + start, this._rQlen - this._rQi - start);
|
|
145
|
-
}
|
|
146
|
-
},
|
|
123
|
+
rQslice(start, end = this.rQlen) {
|
|
124
|
+
return new Uint8Array(this._rQ.buffer, this._rQi + start, end - start);
|
|
125
|
+
}
|
|
147
126
|
|
|
148
127
|
// Check to see if we must wait for 'num' bytes (default to FBU.bytes)
|
|
149
128
|
// to be available in the receive queue. Return true if we need to
|
|
150
129
|
// wait (and possibly print a debug message), otherwise false.
|
|
151
|
-
rQwait
|
|
152
|
-
|
|
153
|
-
if (rQlen < num) {
|
|
130
|
+
rQwait(msg, num, goback) {
|
|
131
|
+
if (this.rQlen < num) {
|
|
154
132
|
if (goback) {
|
|
155
133
|
if (this._rQi < goback) {
|
|
156
134
|
throw new Error("rQwait cannot backup " + goback + " bytes");
|
|
@@ -160,58 +138,55 @@ Websock.prototype = {
|
|
|
160
138
|
return true; // true means need more data
|
|
161
139
|
}
|
|
162
140
|
return false;
|
|
163
|
-
}
|
|
141
|
+
}
|
|
164
142
|
|
|
165
143
|
// Send Queue
|
|
166
144
|
|
|
167
|
-
flush
|
|
145
|
+
flush() {
|
|
168
146
|
if (this._sQlen > 0 && this._websocket.readyState === WebSocket.OPEN) {
|
|
169
|
-
this._websocket.send(this.
|
|
147
|
+
this._websocket.send(this._encodeMessage());
|
|
170
148
|
this._sQlen = 0;
|
|
171
149
|
}
|
|
172
|
-
}
|
|
150
|
+
}
|
|
173
151
|
|
|
174
|
-
send
|
|
152
|
+
send(arr) {
|
|
175
153
|
this._sQ.set(arr, this._sQlen);
|
|
176
154
|
this._sQlen += arr.length;
|
|
177
155
|
this.flush();
|
|
178
|
-
}
|
|
156
|
+
}
|
|
179
157
|
|
|
180
|
-
|
|
181
|
-
this.send(str.split('').map(
|
|
182
|
-
|
|
183
|
-
}));
|
|
184
|
-
},
|
|
158
|
+
sendString(str) {
|
|
159
|
+
this.send(str.split('').map(chr => chr.charCodeAt(0)));
|
|
160
|
+
}
|
|
185
161
|
|
|
186
162
|
// Event Handlers
|
|
187
|
-
off
|
|
188
|
-
this._eventHandlers[evt] =
|
|
189
|
-
}
|
|
163
|
+
off(evt) {
|
|
164
|
+
this._eventHandlers[evt] = () => {};
|
|
165
|
+
}
|
|
190
166
|
|
|
191
|
-
on
|
|
167
|
+
on(evt, handler) {
|
|
192
168
|
this._eventHandlers[evt] = handler;
|
|
193
|
-
}
|
|
169
|
+
}
|
|
194
170
|
|
|
195
|
-
|
|
171
|
+
_allocateBuffers() {
|
|
196
172
|
this._rQ = new Uint8Array(this._rQbufferSize);
|
|
197
173
|
this._sQ = new Uint8Array(this._sQbufferSize);
|
|
198
|
-
}
|
|
174
|
+
}
|
|
199
175
|
|
|
200
|
-
init
|
|
201
|
-
this.
|
|
176
|
+
init() {
|
|
177
|
+
this._allocateBuffers();
|
|
202
178
|
this._rQi = 0;
|
|
203
179
|
this._websocket = null;
|
|
204
|
-
}
|
|
180
|
+
}
|
|
205
181
|
|
|
206
|
-
open
|
|
207
|
-
var ws_schema = uri.match(/^([a-z]+):\/\//)[1];
|
|
182
|
+
open(uri, protocols) {
|
|
208
183
|
this.init();
|
|
209
184
|
|
|
210
185
|
this._websocket = new WebSocket(uri, protocols);
|
|
211
186
|
this._websocket.binaryType = 'arraybuffer';
|
|
212
187
|
|
|
213
|
-
this._websocket.onmessage = this.
|
|
214
|
-
this._websocket.onopen = (
|
|
188
|
+
this._websocket.onmessage = this._recvMessage.bind(this);
|
|
189
|
+
this._websocket.onopen = () => {
|
|
215
190
|
Log.Debug('>> WebSock.onopen');
|
|
216
191
|
if (this._websocket.protocol) {
|
|
217
192
|
Log.Info("Server choose sub-protocol: " + this._websocket.protocol);
|
|
@@ -219,20 +194,20 @@ Websock.prototype = {
|
|
|
219
194
|
|
|
220
195
|
this._eventHandlers.open();
|
|
221
196
|
Log.Debug("<< WebSock.onopen");
|
|
222
|
-
}
|
|
223
|
-
this._websocket.onclose = (
|
|
197
|
+
};
|
|
198
|
+
this._websocket.onclose = (e) => {
|
|
224
199
|
Log.Debug(">> WebSock.onclose");
|
|
225
200
|
this._eventHandlers.close(e);
|
|
226
201
|
Log.Debug("<< WebSock.onclose");
|
|
227
|
-
}
|
|
228
|
-
this._websocket.onerror = (
|
|
202
|
+
};
|
|
203
|
+
this._websocket.onerror = (e) => {
|
|
229
204
|
Log.Debug(">> WebSock.onerror: " + e);
|
|
230
205
|
this._eventHandlers.error(e);
|
|
231
206
|
Log.Debug("<< WebSock.onerror: " + e);
|
|
232
|
-
}
|
|
233
|
-
}
|
|
207
|
+
};
|
|
208
|
+
}
|
|
234
209
|
|
|
235
|
-
close
|
|
210
|
+
close() {
|
|
236
211
|
if (this._websocket) {
|
|
237
212
|
if ((this._websocket.readyState === WebSocket.OPEN) ||
|
|
238
213
|
(this._websocket.readyState === WebSocket.CONNECTING)) {
|
|
@@ -240,77 +215,80 @@ Websock.prototype = {
|
|
|
240
215
|
this._websocket.close();
|
|
241
216
|
}
|
|
242
217
|
|
|
243
|
-
this._websocket.onmessage =
|
|
218
|
+
this._websocket.onmessage = () => {};
|
|
244
219
|
}
|
|
245
|
-
}
|
|
220
|
+
}
|
|
246
221
|
|
|
247
222
|
// private methods
|
|
248
|
-
|
|
223
|
+
_encodeMessage() {
|
|
249
224
|
// Put in a binary arraybuffer
|
|
250
225
|
// according to the spec, you can send ArrayBufferViews with the send method
|
|
251
226
|
return new Uint8Array(this._sQ.buffer, 0, this._sQlen);
|
|
252
|
-
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// We want to move all the unread data to the start of the queue,
|
|
230
|
+
// e.g. compacting.
|
|
231
|
+
// The function also expands the receive que if needed, and for
|
|
232
|
+
// performance reasons we combine these two actions to avoid
|
|
233
|
+
// unneccessary copying.
|
|
234
|
+
_expandCompactRQ(minFit) {
|
|
235
|
+
// if we're using less than 1/8th of the buffer even with the incoming bytes, compact in place
|
|
236
|
+
// instead of resizing
|
|
237
|
+
const requiredBufferSize = (this._rQlen - this._rQi + minFit) * 8;
|
|
238
|
+
const resizeNeeded = this._rQbufferSize < requiredBufferSize;
|
|
253
239
|
|
|
254
|
-
_expand_compact_rQ: function (min_fit) {
|
|
255
|
-
var resizeNeeded = min_fit || this._rQlen - this._rQi > this._rQbufferSize / 2;
|
|
256
240
|
if (resizeNeeded) {
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
} else {
|
|
261
|
-
// otherwise, make sure we satisy rQlen - rQi + min_fit < rQbufferSize / 8
|
|
262
|
-
this._rQbufferSize = (this._rQlen - this._rQi + min_fit) * 8;
|
|
263
|
-
}
|
|
241
|
+
// Make sure we always *at least* double the buffer size, and have at least space for 8x
|
|
242
|
+
// the current amount of data
|
|
243
|
+
this._rQbufferSize = Math.max(this._rQbufferSize * 2, requiredBufferSize);
|
|
264
244
|
}
|
|
265
245
|
|
|
266
246
|
// we don't want to grow unboundedly
|
|
267
247
|
if (this._rQbufferSize > MAX_RQ_GROW_SIZE) {
|
|
268
248
|
this._rQbufferSize = MAX_RQ_GROW_SIZE;
|
|
269
|
-
if (this._rQbufferSize - this.
|
|
270
|
-
throw new
|
|
249
|
+
if (this._rQbufferSize - this.rQlen < minFit) {
|
|
250
|
+
throw new Error("Receive Queue buffer exceeded " + MAX_RQ_GROW_SIZE + " bytes, and the new message could not fit");
|
|
271
251
|
}
|
|
272
252
|
}
|
|
273
253
|
|
|
274
254
|
if (resizeNeeded) {
|
|
275
|
-
|
|
276
|
-
this._rQmax = this._rQbufferSize / 8;
|
|
255
|
+
const oldRQbuffer = this._rQ.buffer;
|
|
277
256
|
this._rQ = new Uint8Array(this._rQbufferSize);
|
|
278
|
-
this._rQ.set(new Uint8Array(
|
|
257
|
+
this._rQ.set(new Uint8Array(oldRQbuffer, this._rQi, this._rQlen - this._rQi));
|
|
279
258
|
} else {
|
|
280
259
|
if (ENABLE_COPYWITHIN) {
|
|
281
|
-
this._rQ.copyWithin(0, this._rQi);
|
|
260
|
+
this._rQ.copyWithin(0, this._rQi, this._rQlen);
|
|
282
261
|
} else {
|
|
283
|
-
this._rQ.set(new Uint8Array(this._rQ.buffer, this._rQi));
|
|
262
|
+
this._rQ.set(new Uint8Array(this._rQ.buffer, this._rQi, this._rQlen - this._rQi));
|
|
284
263
|
}
|
|
285
264
|
}
|
|
286
265
|
|
|
287
266
|
this._rQlen = this._rQlen - this._rQi;
|
|
288
267
|
this._rQi = 0;
|
|
289
|
-
}
|
|
268
|
+
}
|
|
290
269
|
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
270
|
+
// push arraybuffer values onto the end of the receive que
|
|
271
|
+
_DecodeMessage(data) {
|
|
272
|
+
const u8 = new Uint8Array(data);
|
|
294
273
|
if (u8.length > this._rQbufferSize - this._rQlen) {
|
|
295
|
-
this.
|
|
274
|
+
this._expandCompactRQ(u8.length);
|
|
296
275
|
}
|
|
297
276
|
this._rQ.set(u8, this._rQlen);
|
|
298
277
|
this._rQlen += u8.length;
|
|
299
|
-
}
|
|
278
|
+
}
|
|
300
279
|
|
|
301
|
-
|
|
302
|
-
this.
|
|
303
|
-
if (this.rQlen
|
|
280
|
+
_recvMessage(e) {
|
|
281
|
+
this._DecodeMessage(e.data);
|
|
282
|
+
if (this.rQlen > 0) {
|
|
304
283
|
this._eventHandlers.message();
|
|
305
|
-
// Compact the receive queue
|
|
306
284
|
if (this._rQlen == this._rQi) {
|
|
285
|
+
// All data has now been processed, this means we
|
|
286
|
+
// can reset the receive queue.
|
|
307
287
|
this._rQlen = 0;
|
|
308
288
|
this._rQi = 0;
|
|
309
|
-
} else if (this._rQlen > this._rQmax) {
|
|
310
|
-
this._expand_compact_rQ();
|
|
311
289
|
}
|
|
312
290
|
} else {
|
|
313
291
|
Log.Debug("Ignoring empty message");
|
|
314
292
|
}
|
|
315
293
|
}
|
|
316
|
-
}
|
|
294
|
+
}
|
package/docs/API.md
CHANGED
|
@@ -24,13 +24,7 @@ protocol stream.
|
|
|
24
24
|
`focusOnClick`
|
|
25
25
|
- Is a `boolean` indicating if keyboard focus should automatically be
|
|
26
26
|
moved to the remote session when a `mousedown` or `touchstart`
|
|
27
|
-
event is received.
|
|
28
|
-
|
|
29
|
-
`touchButton`
|
|
30
|
-
- Is a `long` controlling the button mask that should be simulated
|
|
31
|
-
when a touch event is recieved. Uses the same values as
|
|
32
|
-
[`MouseEvent.button`](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/button).
|
|
33
|
-
Is set to `1` by default.
|
|
27
|
+
event is received. Enabled by default.
|
|
34
28
|
|
|
35
29
|
`clipViewport`
|
|
36
30
|
- Is a `boolean` indicating if the remote session should be clipped
|
|
@@ -53,6 +47,30 @@ protocol stream.
|
|
|
53
47
|
should be sent whenever the container changes dimensions. Disabled
|
|
54
48
|
by default.
|
|
55
49
|
|
|
50
|
+
`showDotCursor`
|
|
51
|
+
- Is a `boolean` indicating whether a dot cursor should be shown
|
|
52
|
+
instead of a zero-sized or fully-transparent cursor if the server
|
|
53
|
+
sets such invisible cursor. Disabled by default.
|
|
54
|
+
|
|
55
|
+
`background`
|
|
56
|
+
- Is a valid CSS [background](https://developer.mozilla.org/en-US/docs/Web/CSS/background)
|
|
57
|
+
style value indicating which background style should be applied
|
|
58
|
+
to the element containing the remote session screen. The default value is `rgb(40, 40, 40)`
|
|
59
|
+
(solid gray color).
|
|
60
|
+
|
|
61
|
+
`qualityLevel`
|
|
62
|
+
- Is an `int` in range `[0-9]` controlling the desired JPEG quality.
|
|
63
|
+
Value `0` implies low quality and `9` implies high quality.
|
|
64
|
+
Default value is `6`.
|
|
65
|
+
|
|
66
|
+
`compressionLevel`
|
|
67
|
+
- Is an `int` in range `[0-9]` controlling the desired compression
|
|
68
|
+
level. Value `0` means no compression. Level 1 uses a minimum of CPU
|
|
69
|
+
resources and achieves weak compression ratios, while level 9 offers
|
|
70
|
+
best compression but is slow in terms of CPU consumption on the server
|
|
71
|
+
side. Use high levels with very slow network connections.
|
|
72
|
+
Default value is `2`.
|
|
73
|
+
|
|
56
74
|
`capabilities` *Read only*
|
|
57
75
|
- Is an `Object` indicating which optional extensions are available
|
|
58
76
|
on the server. Some methods may only be called if the corresponding
|
|
@@ -137,7 +155,7 @@ connection to a specified VNC server.
|
|
|
137
155
|
|
|
138
156
|
##### Syntax
|
|
139
157
|
|
|
140
|
-
|
|
158
|
+
let rfb = new RFB( target, url [, options] );
|
|
141
159
|
|
|
142
160
|
###### Parameters
|
|
143
161
|
|
|
@@ -176,6 +194,10 @@ connection to a specified VNC server.
|
|
|
176
194
|
- A `DOMString` specifying the ID to provide to any VNC repeater
|
|
177
195
|
encountered.
|
|
178
196
|
|
|
197
|
+
`wsProtocols`
|
|
198
|
+
- An `Array` of `DOMString`s specifying the sub-protocols to use
|
|
199
|
+
in the WebSocket connection. Empty by default.
|
|
200
|
+
|
|
179
201
|
#### connect
|
|
180
202
|
|
|
181
203
|
The `connect` event is fired after all the handshaking with the server
|
|
@@ -360,5 +382,4 @@ to the remote server.
|
|
|
360
382
|
###### Parameters
|
|
361
383
|
|
|
362
384
|
**`text`**
|
|
363
|
-
- A `DOMString` specifying the clipboard data to send.
|
|
364
|
-
characters from ISO 8859-1 are supported.
|
|
385
|
+
- A `DOMString` specifying the clipboard data to send.
|
package/lib/base64.js
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
|
|
4
|
+
|
|
5
|
+
Object.defineProperty(exports, "__esModule", {
|
|
6
|
+
value: true
|
|
7
|
+
});
|
|
8
|
+
exports.default = void 0;
|
|
9
|
+
|
|
10
|
+
var Log = _interopRequireWildcard(require("./util/logging.js"));
|
|
11
|
+
|
|
12
|
+
function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; }
|
|
13
|
+
|
|
14
|
+
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
15
|
+
|
|
16
|
+
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
17
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
18
|
+
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
19
|
+
// From: http://hg.mozilla.org/mozilla-central/raw-file/ec10630b1a54/js/src/devtools/jint/sunspider/string-base64.js
|
|
20
|
+
var _default = {
|
|
21
|
+
/* Convert data (an array of integers) to a Base64 string. */
|
|
22
|
+
toBase64Table: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='.split(''),
|
|
23
|
+
base64Pad: '=',
|
|
24
|
+
encode: function encode(data) {
|
|
25
|
+
"use strict";
|
|
26
|
+
|
|
27
|
+
var result = '';
|
|
28
|
+
var length = data.length;
|
|
29
|
+
var lengthpad = length % 3; // Convert every three bytes to 4 ascii characters.
|
|
30
|
+
|
|
31
|
+
for (var i = 0; i < length - 2; i += 3) {
|
|
32
|
+
result += this.toBase64Table[data[i] >> 2];
|
|
33
|
+
result += this.toBase64Table[((data[i] & 0x03) << 4) + (data[i + 1] >> 4)];
|
|
34
|
+
result += this.toBase64Table[((data[i + 1] & 0x0f) << 2) + (data[i + 2] >> 6)];
|
|
35
|
+
result += this.toBase64Table[data[i + 2] & 0x3f];
|
|
36
|
+
} // Convert the remaining 1 or 2 bytes, pad out to 4 characters.
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
var j = length - lengthpad;
|
|
40
|
+
|
|
41
|
+
if (lengthpad === 2) {
|
|
42
|
+
result += this.toBase64Table[data[j] >> 2];
|
|
43
|
+
result += this.toBase64Table[((data[j] & 0x03) << 4) + (data[j + 1] >> 4)];
|
|
44
|
+
result += this.toBase64Table[(data[j + 1] & 0x0f) << 2];
|
|
45
|
+
result += this.toBase64Table[64];
|
|
46
|
+
} else if (lengthpad === 1) {
|
|
47
|
+
result += this.toBase64Table[data[j] >> 2];
|
|
48
|
+
result += this.toBase64Table[(data[j] & 0x03) << 4];
|
|
49
|
+
result += this.toBase64Table[64];
|
|
50
|
+
result += this.toBase64Table[64];
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return result;
|
|
54
|
+
},
|
|
55
|
+
|
|
56
|
+
/* Convert Base64 data to a string */
|
|
57
|
+
|
|
58
|
+
/* eslint-disable comma-spacing */
|
|
59
|
+
toBinaryTable: [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, 0, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1],
|
|
60
|
+
|
|
61
|
+
/* eslint-enable comma-spacing */
|
|
62
|
+
decode: function decode(data) {
|
|
63
|
+
var offset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
|
|
64
|
+
var dataLength = data.indexOf('=') - offset;
|
|
65
|
+
|
|
66
|
+
if (dataLength < 0) {
|
|
67
|
+
dataLength = data.length - offset;
|
|
68
|
+
}
|
|
69
|
+
/* Every four characters is 3 resulting numbers */
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
var resultLength = (dataLength >> 2) * 3 + Math.floor(dataLength % 4 / 1.5);
|
|
73
|
+
var result = new Array(resultLength); // Convert one by one.
|
|
74
|
+
|
|
75
|
+
var leftbits = 0; // number of bits decoded, but yet to be appended
|
|
76
|
+
|
|
77
|
+
var leftdata = 0; // bits decoded, but yet to be appended
|
|
78
|
+
|
|
79
|
+
for (var idx = 0, i = offset; i < data.length; i++) {
|
|
80
|
+
var c = this.toBinaryTable[data.charCodeAt(i) & 0x7f];
|
|
81
|
+
var padding = data.charAt(i) === this.base64Pad; // Skip illegal characters and whitespace
|
|
82
|
+
|
|
83
|
+
if (c === -1) {
|
|
84
|
+
Log.Error("Illegal character code " + data.charCodeAt(i) + " at position " + i);
|
|
85
|
+
continue;
|
|
86
|
+
} // Collect data into leftdata, update bitcount
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
leftdata = leftdata << 6 | c;
|
|
90
|
+
leftbits += 6; // If we have 8 or more bits, append 8 bits to the result
|
|
91
|
+
|
|
92
|
+
if (leftbits >= 8) {
|
|
93
|
+
leftbits -= 8; // Append if not padding.
|
|
94
|
+
|
|
95
|
+
if (!padding) {
|
|
96
|
+
result[idx++] = leftdata >> leftbits & 0xff;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
leftdata &= (1 << leftbits) - 1;
|
|
100
|
+
}
|
|
101
|
+
} // If there are any bits left, the base64 string was corrupted
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
if (leftbits) {
|
|
105
|
+
var err = new Error('Corrupted base64 string');
|
|
106
|
+
err.name = 'Base64-Error';
|
|
107
|
+
throw err;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return result;
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
/* End of Base64 namespace */
|
|
114
|
+
|
|
115
|
+
exports.default = _default;
|