oracledb 6.0.3 → 6.1.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.
Files changed (61) hide show
  1. package/README.md +2 -2
  2. package/build/Release/oracledb-6.1.0-darwin-x64.node +0 -0
  3. package/build/Release/oracledb-6.1.0-darwin-x64.node-buildinfo.txt +1 -0
  4. package/build/Release/oracledb-6.1.0-js-buildinfo.txt +1 -0
  5. package/build/Release/oracledb-6.1.0-linux-arm64.node +0 -0
  6. package/build/Release/oracledb-6.1.0-linux-arm64.node-buildinfo.txt +1 -0
  7. package/build/Release/oracledb-6.1.0-linux-x64.node +0 -0
  8. package/build/Release/oracledb-6.1.0-linux-x64.node-buildinfo.txt +1 -0
  9. package/build/Release/oracledb-6.1.0-win32-x64.node +0 -0
  10. package/build/Release/oracledb-6.1.0-win32-x64.node-buildinfo.txt +1 -0
  11. package/examples/example.js +0 -1
  12. package/lib/aqQueue.js +40 -26
  13. package/lib/connection.js +15 -3
  14. package/lib/errors.js +10 -6
  15. package/lib/impl/connection.js +9 -0
  16. package/lib/impl/resultset.js +7 -4
  17. package/lib/oracledb.js +15 -12
  18. package/lib/pool.js +7 -1
  19. package/lib/sodaCollection.js +1 -1
  20. package/lib/thin/connection.js +92 -30
  21. package/lib/thin/pool.js +153 -68
  22. package/lib/thin/protocol/buffer.js +19 -1
  23. package/lib/thin/protocol/constants.js +3 -14
  24. package/lib/thin/protocol/encryptDecrypt.js +17 -17
  25. package/lib/thin/protocol/messages/auth.js +21 -23
  26. package/lib/thin/protocol/messages/base.js +22 -45
  27. package/lib/thin/protocol/messages/connectionCookie.js +76 -0
  28. package/lib/thin/protocol/messages/dataType.js +13 -9
  29. package/lib/thin/protocol/messages/execute.js +7 -7
  30. package/lib/thin/protocol/messages/index.js +2 -0
  31. package/lib/thin/protocol/messages/protocol.js +31 -20
  32. package/lib/thin/protocol/messages/withData.js +49 -43
  33. package/lib/thin/protocol/oson.js +4 -4
  34. package/lib/thin/protocol/packet.js +31 -10
  35. package/lib/thin/protocol/utils.js +2 -2
  36. package/lib/thin/resultSet.js +6 -6
  37. package/lib/thin/sqlnet/connStrategy.js +130 -5
  38. package/lib/thin/sqlnet/constants.js +2 -0
  39. package/lib/thin/sqlnet/ezConnectResolver.js +20 -19
  40. package/lib/thin/sqlnet/navNodes.js +32 -25
  41. package/lib/thin/sqlnet/networkSession.js +35 -30
  42. package/lib/thin/sqlnet/ntTcp.js +30 -14
  43. package/lib/thin/sqlnet/nvStrToNvPair.js +16 -16
  44. package/lib/thin/sqlnet/packet.js +9 -2
  45. package/lib/thin/sqlnet/paramParser.js +9 -9
  46. package/lib/thin/sqlnet/sessionAtts.js +4 -0
  47. package/lib/thin/statement.js +3 -3
  48. package/lib/thin/util.js +7 -8
  49. package/lib/transformer.js +3 -1
  50. package/lib/util.js +0 -13
  51. package/lib/version.js +2 -2
  52. package/package.json +1 -1
  53. package/build/Release/oracledb-6.0.3-darwin-x64.node +0 -0
  54. package/build/Release/oracledb-6.0.3-darwin-x64.node-buildinfo.txt +0 -1
  55. package/build/Release/oracledb-6.0.3-js-buildinfo.txt +0 -1
  56. package/build/Release/oracledb-6.0.3-linux-arm64.node +0 -0
  57. package/build/Release/oracledb-6.0.3-linux-arm64.node-buildinfo.txt +0 -1
  58. package/build/Release/oracledb-6.0.3-linux-x64.node +0 -0
  59. package/build/Release/oracledb-6.0.3-linux-x64.node-buildinfo.txt +0 -1
  60. package/build/Release/oracledb-6.0.3-win32-x64.node +0 -0
  61. package/build/Release/oracledb-6.0.3-win32-x64.node-buildinfo.txt +0 -1
@@ -31,6 +31,7 @@ const { Buffer } = require('buffer');
31
31
  const constants = require("./constants.js");
32
32
  const oson = require('./oson.js');
33
33
  const utils = require('./utils.js');
34
+ const errors = require("../../errors.js");
34
35
 
35
36
  const TNS_BASE64_ALPHABET_ARRAY = Buffer.from("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", 'utf8');
36
37
 
@@ -324,23 +325,23 @@ class ReadPacket extends BaseBuffer {
324
325
 
325
326
  // Handle physical rowid
326
327
  if (buf && buf[0] === 1) {
327
- let rba = buf.readUInt32BE(1);
328
- let partitionID = buf.readUInt16BE(5);
329
- let blockNum = buf.readUInt32BE(7);
330
- let slotNum = buf.readUInt16BE(11);
328
+ const rba = buf.readUInt32BE(1);
329
+ const partitionID = buf.readUInt16BE(5);
330
+ const blockNum = buf.readUInt32BE(7);
331
+ const slotNum = buf.readUInt16BE(11);
331
332
  return utils.encodeRowID({rba, partitionID, blockNum, slotNum});
332
333
  }
333
334
 
334
335
  // handle logical rowid
335
336
  let outputLen = Math.floor(inputLen / 3) * 4;
336
- let remainder = inputLen % 3;
337
+ const remainder = inputLen % 3;
337
338
  if (remainder === 1) {
338
339
  outputLen += 1;
339
340
  } else if (remainder === 2) {
340
341
  outputLen += 3;
341
342
  }
342
343
 
343
- let outputValue = Buffer.alloc(outputLen);
344
+ const outputValue = Buffer.alloc(outputLen);
344
345
  inputLen -= 1;
345
346
  outputValue[0] = 42;
346
347
  outputOffset += 1;
@@ -385,16 +386,19 @@ class ReadPacket extends BaseBuffer {
385
386
  }
386
387
 
387
388
  readRowID() {
388
- let rba = this.readUB4();
389
- let partitionID = this.readUB2();
389
+ const rba = this.readUB4();
390
+ const partitionID = this.readUB2();
390
391
  this.skipUB1();
391
- let blockNum = this.readUB4();
392
- let slotNum = this.readUB2();
392
+ const blockNum = this.readUB4();
393
+ const slotNum = this.readUB2();
393
394
  return {rba, partitionID, blockNum, slotNum};
394
395
  }
395
396
 
396
397
  skipBytesChunked() {
397
398
  const numBytes = this.readUInt8();
399
+ if (numBytes === 0 || numBytes === constants.TNS_NULL_LENGTH_INDICATOR) {
400
+ return;
401
+ }
398
402
  if (numBytes !== constants.TNS_LONG_LENGTH_INDICATOR) {
399
403
  this.skipBytes(numBytes);
400
404
  } else {
@@ -407,6 +411,23 @@ class ReadPacket extends BaseBuffer {
407
411
  }
408
412
  }
409
413
 
414
+ readNullTerminatedBytes(maxSize = 50) {
415
+ let offset = 0;
416
+ const tmp = Buffer.allocUnsafe(maxSize);
417
+ while (offset < maxSize) {
418
+ tmp[offset] = this.readUInt8();
419
+ if (tmp[offset] === 0) {
420
+ break;
421
+ }
422
+ offset = offset + 1;
423
+ }
424
+ if (offset === maxSize) {
425
+ const reason = `Byte Arrray Exceeded MaxSize ${maxSize}`;
426
+ errors.throwErr(errors.ERR_INTERNAL, reason);
427
+ }
428
+ return tmp.subarray(0, offset + 1);
429
+ }
430
+
410
431
  }
411
432
 
412
433
 
@@ -43,7 +43,7 @@ function _convertBase64(result, value, size, offset) {
43
43
  function encodeRowID(rowID) {
44
44
  let offset = 0;
45
45
  if (rowID.rba !== 0 || rowID.partitionID !== 0 || rowID.blockNum !== 0 || rowID.slotNum != 0) {
46
- let result = Buffer.alloc(constants.TNS_MAX_ROWID_LENGTH);
46
+ const result = Buffer.alloc(constants.TNS_MAX_ROWID_LENGTH);
47
47
  offset = _convertBase64(result, rowID.rba, 6, offset);
48
48
  offset = _convertBase64(result, rowID.partitionID, 3, offset);
49
49
  offset = _convertBase64(result, rowID.blockNum, 6, offset);
@@ -59,7 +59,7 @@ function setObfuscatedValue(value) {
59
59
  const bytes = Buffer.from(value, 'utf8');
60
60
  const len = Buffer.byteLength(value);
61
61
 
62
- let arr = [];
62
+ const arr = [];
63
63
  for (let i = 0; i < len; i++) {
64
64
  arr.push(buf[i] ^ bytes[i]);
65
65
  }
@@ -68,10 +68,10 @@ class ThinResultSetImpl extends ResultSetImpl {
68
68
  // Returns rows fetched to the common layer in array format
69
69
  //---------------------------------------------------------------------------
70
70
  _processRows(numRowsFetched) {
71
- let rows = [];
72
- let bufferRowIndex = this.statement.bufferRowIndex;
71
+ const rows = [];
72
+ const bufferRowIndex = this.statement.bufferRowIndex;
73
73
  for (let row = bufferRowIndex; row < bufferRowIndex + numRowsFetched; row++) {
74
- let rowObj = [];
74
+ const rowObj = [];
75
75
  for (let col = 0; col < this.statement.numQueryVars; col++) {
76
76
  rowObj.push(this.statement.queryVars[col].values[row]);
77
77
  }
@@ -99,13 +99,13 @@ class ThinResultSetImpl extends ResultSetImpl {
99
99
  } else {
100
100
  // We fetch for the required number of row
101
101
  options.fetchArraySize = options.fetchArraySize - (this.statement.bufferRowCount - this.statement.bufferRowIndex);
102
- let prevBufferRowCount = this.statement.bufferRowCount;
102
+ const prevBufferRowCount = this.statement.bufferRowCount;
103
103
  if (this.statement.moreRowsToFetch && options.fetchArraySize > 0) {
104
104
  await this._fetchMoreRows(options);
105
105
  }
106
106
  options.fetchArraySize = numRows || this.options.fetchArraySize;
107
107
  if (prevBufferRowCount === this.statement.bufferRowCount) {
108
- let numRowsFetched = this.statement.bufferRowCount - this.statement.bufferRowIndex;
108
+ const numRowsFetched = this.statement.bufferRowCount - this.statement.bufferRowIndex;
109
109
  this.statement.bufferRowCount = 0;
110
110
  if (numRowsFetched > 0) {
111
111
  return this._processRows(numRowsFetched);
@@ -113,7 +113,7 @@ class ThinResultSetImpl extends ResultSetImpl {
113
113
  return [];
114
114
  }
115
115
  }
116
- let numRowsFetched = this.statement.bufferRowCount - this.statement.bufferRowIndex;
116
+ const numRowsFetched = this.statement.bufferRowCount - this.statement.bufferRowIndex;
117
117
  return this._processRows(numRowsFetched);
118
118
  }
119
119
 
@@ -54,6 +54,7 @@ class ConnectDescription {
54
54
  class ConnStrategy {
55
55
  constructor() {
56
56
  this.nextOptToTry = 0;
57
+ this.reorderDescriptionList = 0;
57
58
  this.retryCount = 0;
58
59
  this.lastRetryCounter = 0;
59
60
  this.lastRetryConnectDescription = 0;
@@ -95,9 +96,13 @@ class ConnStrategy {
95
96
  this.retryCount = config.retryCount;
96
97
  }
97
98
  }
99
+ if (!this.reorderDescriptionList) {
100
+ this.descriptionList = SOLE_INST_DHCACHE.reorderDescriptionList(this.descriptionList);
101
+ this.reorderDescriptionList = true;
102
+ }
98
103
  /* We try the address list at least once and upto (1 + retryCount) times */
99
104
  for (let d = this.lastRetryConnectDescription; d < this.descriptionList.length; d++) {
100
- let desc = this.descriptionList[d];
105
+ const desc = this.descriptionList[d];
101
106
  let cOpts = new Array();
102
107
  cOpts = desc.getConnectOptions();
103
108
  let delay = desc.delayInMillis;
@@ -108,8 +113,13 @@ class ConnStrategy {
108
113
  }
109
114
  }
110
115
  for (let i = this.lastRetryCounter; i <= this.retryCount; ++i) {
116
+ //Conn options must be reordered only when all options are tried
117
+ // i.e for retry and before the first try.
118
+ if (this.nextOptToTry == 0) {
119
+ cOpts = SOLE_INST_DHCACHE.reorderAddresses(cOpts);
120
+ }
111
121
  while (this.nextOptToTry < cOpts.length) {
112
- let copt = cOpts[this.nextOptToTry];
122
+ const copt = cOpts[this.nextOptToTry];
113
123
  this.lastRetryCounter = i;
114
124
  this.lastRetryConnectDescription = d;
115
125
  this.nextOptToTry++;
@@ -150,7 +160,7 @@ async function createNode(str) {
150
160
  else
151
161
  nvpair = str; //Already a NVPair
152
162
 
153
- let arg = nvpair.name.toUpperCase();
163
+ const arg = nvpair.name.toUpperCase();
154
164
  let navobj = null;
155
165
  switch (arg) {
156
166
  case "ADDRESS":
@@ -170,8 +180,123 @@ async function createNode(str) {
170
180
  `unknown top element ${arg}`);
171
181
  }
172
182
  navobj.initFromNVPair(nvpair);
173
- let cs = new ConnStrategy();
183
+ const cs = new ConnStrategy();
174
184
  await navobj.navigate(cs);
175
185
  return cs;
176
186
  }
177
- module.exports = { createNode };
187
+
188
+
189
+ class DownHostsCache {
190
+
191
+ constructor() {
192
+ // Timeout for each item in the cache
193
+ this.DOWN_HOSTS_TIMEOUT = 600;
194
+ // Minimum amount of time between each refresh
195
+ this.MIN_TIME_BETWEEN_REFRESH = 60;
196
+ // DownHostsCache Map
197
+ this.downHostsCacheMap = new Map();
198
+ // Last Refresh Time
199
+ this.lastRefreshTime = 0;
200
+ }
201
+
202
+ /**
203
+ * Add an address to the cache
204
+ *
205
+ * @param connOption
206
+ * address to be cached
207
+ * @return Map with address as key and time of insertion as value
208
+ */
209
+ markDownHost(addr) {
210
+ return this.downHostsCacheMap.set(addr, Date.now());
211
+ }
212
+
213
+ // Remove elements older than DownHostsTimeout
214
+ refreshCache() {
215
+ if (Date.now() - this.MIN_TIME_BETWEEN_REFRESH * 1000 > this.lastRefreshTime) {
216
+ this.downHostsCacheMap.forEach((value, key) => {
217
+ const entryTime = value;
218
+ if (entryTime != null && ((Date.now() - this.DOWN_HOSTS_TIMEOUT * 1000) > entryTime)) {
219
+ this.downHostsCacheMap.delete(key);
220
+ }
221
+ });
222
+ this.lastRefreshTime = Date.now();
223
+ }
224
+ }
225
+
226
+ /**
227
+ * Reorder addresses such that cached elements
228
+ * occur at the end of the array.
229
+ */
230
+ reorderAddresses(cOpts) {
231
+ this.refreshCache();
232
+
233
+ let topIdx = 0, btmIdx = cOpts.length - 1;
234
+
235
+ while (topIdx < btmIdx) {
236
+
237
+ // increment topIdx if the address is not cached
238
+ while (topIdx <= btmIdx
239
+ && !this.isDownHostsCached(cOpts[topIdx]))
240
+ topIdx++;
241
+
242
+ // decrement btmIdx if address is cached
243
+ while (btmIdx >= topIdx
244
+ && this.isDownHostsCached(cOpts[btmIdx]))
245
+ btmIdx--;
246
+
247
+ // swap cached with uncached
248
+ if (topIdx < btmIdx)
249
+ [cOpts[topIdx], cOpts[btmIdx]] = [cOpts[btmIdx], cOpts[topIdx]];
250
+
251
+ }
252
+ return cOpts;
253
+ }
254
+ /**
255
+ * Return if a desc is cached.
256
+ * A desc is cached if all the connection options(addresses)
257
+ * in that description are cached.
258
+ */
259
+ isDownDescCached(desc) {
260
+ const cOpts = desc.getConnectOptions();
261
+ for (let i = 0; i < cOpts.length; i++) {
262
+ if (!this.isDownHostsCached(cOpts[i]))
263
+ return false;
264
+ }
265
+ return true;
266
+ }
267
+ /**
268
+ * Reorder description list such that description with all connection options in downcache
269
+ * is pushed to the end of the description list
270
+ */
271
+ reorderDescriptionList(descs) {
272
+ this.refreshCache();
273
+
274
+ let topIdx = 0, btmIdx = descs.length - 1;
275
+
276
+ while (topIdx < btmIdx) {
277
+
278
+ // increment topIdx if the desc is not cached
279
+ while (topIdx <= btmIdx
280
+ && !this.isDownDescCached(descs[topIdx]))
281
+ topIdx++;
282
+
283
+ // decrement btmIdx if desc is cached
284
+ while (btmIdx >= topIdx
285
+ && this.isDownDescCached(descs[btmIdx]))
286
+ btmIdx--;
287
+
288
+ // swap cached with uncached
289
+ if (topIdx < btmIdx) {
290
+ [descs[topIdx], descs[btmIdx]] = [descs[btmIdx], descs[topIdx]];
291
+ }
292
+ }
293
+ return descs;
294
+ }
295
+ // Return if a host is cached
296
+ isDownHostsCached(copt) {
297
+ return this.downHostsCacheMap.has(copt.host);
298
+ }
299
+ }
300
+ // Single instance
301
+ const SOLE_INST_DHCACHE = new DownHostsCache();
302
+ module.exports = { createNode, SOLE_INST_DHCACHE };
@@ -107,6 +107,8 @@ module.exports = {
107
107
  NSGRAW : 0x1000, // I/O is direct to/from transport
108
108
  TNS_VERSION_DESIRED : 319,
109
109
  TNS_VERSION_MINIMUM : 300,
110
+ TNS_VERSION_MIN_UUID : 319,
111
+ TNS_UUID_OFFSET : 45,
110
112
 
111
113
  /* Accept Packet */
112
114
  NSPACVSN : 8, // connection version
@@ -71,7 +71,7 @@ const DESCRIPTION_PARAMS = ["ENABLE", "FAILOVER", "LOAD_BALANCE",
71
71
  class EZConnectResolver {
72
72
  constructor(url) {
73
73
  this.URL_PROPS_ALIAS = this.initializeUrlAlias();
74
- let jdbcUrlPrefix = url.indexOf('@');
74
+ const jdbcUrlPrefix = url.indexOf('@');
75
75
  if (jdbcUrlPrefix != -1) {
76
76
  this.url = url.substring(jdbcUrlPrefix + 1);
77
77
  this.urlPrefix = url.substring(0, jdbcUrlPrefix + 1);
@@ -125,7 +125,7 @@ class EZConnectResolver {
125
125
  // URL is in the following format
126
126
  // [protocol://]host1[,host13][:port1][,host2:port2][/service_name][:server][/instance_name]
127
127
 
128
- let urlWithoutWhiteSpaces = url.replace(/\s/g, "");
128
+ const urlWithoutWhiteSpaces = url.replace(/\s/g, "");
129
129
  let bool = 0;
130
130
  let protocol = null, hostInfo = null, serviceName = null, serverMode = null, instanceName = null;
131
131
  for (const match of urlWithoutWhiteSpaces.matchAll(EZ_URL_PATTERN)) {
@@ -153,7 +153,7 @@ class EZConnectResolver {
153
153
  const addressInfo =
154
154
  await this.buildAddressList(hostInfo, protocol, proxyHost, proxyPort);
155
155
 
156
- let connectionIdPrefix =
156
+ const connectionIdPrefix =
157
157
  this.urlProps.get("CONNECTION_ID_PREFIX");
158
158
  // Build the available information in TNS format.
159
159
  const parts = [];
@@ -214,7 +214,7 @@ class EZConnectResolver {
214
214
  proxyHost, proxyPort) {
215
215
  let shost = '';
216
216
  let ipcnt = 0;
217
- let builder = new Array();
217
+ const builder = new Array();
218
218
  let proxyInfo = '';
219
219
  if (proxyHost != null) {
220
220
  if (proxyPort != null) {
@@ -227,17 +227,17 @@ class EZConnectResolver {
227
227
  if (protocol == null) protocol = 'TCP';
228
228
  let naddr = 0;
229
229
  // ; groups the user into a ADDRESS_LIST
230
- let addressLists = hostInfo.split(";");
231
- for (let addressList in addressLists) {
230
+ const addressLists = hostInfo.split(";");
231
+ for (const addressList in addressLists) {
232
232
  let addressNodeCount = 0;
233
- let addressListBuilder = new Array();
233
+ const addressListBuilder = new Array();
234
234
  for (const match of addressLists[addressList].matchAll(HOSTNAMES_PATTERN)) {
235
- let hostnames = (match.groups.hostnames).split(',');
235
+ const hostnames = (match.groups.hostnames).split(',');
236
236
  let port = match.groups.port;
237
237
  if (port == null) {
238
238
  port = '1521' + '';
239
239
  }
240
- for (let hname in hostnames) {
240
+ for (const hname in hostnames) {
241
241
  addressListBuilder.push(this.getAddrStr(hostnames[hname], port, protocol, proxyInfo));
242
242
  shost = hostnames[hname];
243
243
  addressNodeCount++;
@@ -300,7 +300,7 @@ class EZConnectResolver {
300
300
  buildDescriptionParams() {
301
301
  if (this.urlProps.size === 0)
302
302
  return '';
303
- let builder = new Array();
303
+ const builder = new Array();
304
304
  this.urlProps.forEach(function(v, k) {
305
305
  if (DESCRIPTION_PARAMS.includes(k)) // Add only if it is a DESCRIPTION node parameter
306
306
  builder.push(`(${k}=${v})`);
@@ -318,10 +318,11 @@ class EZConnectResolver {
318
318
  if (protocol != null && protocol.toLowerCase() == "tcps") {
319
319
  // In EZConnect format if the DN match is not specified the enable it
320
320
  // by default for TCPS protocol.
321
- const serverDNMatch = this.urlProps.get("SSL_SERVER_DN_MATCH") || 'TRUE';
321
+ const serverDNMatch = this.urlProps.get("SSL_SERVER_DN_MATCH");
322
322
  const serverCertDN = this.urlProps.get("SSL_SERVER_CERT_DN");
323
323
  const walletDir = this.urlProps.get("MY_WALLET_DIRECTORY");
324
- securityInfo.push(`(SSL_SERVER_DN_MATCH=${serverDNMatch})`);
324
+ if (serverDNMatch != null)
325
+ securityInfo.push(`(SSL_SERVER_DN_MATCH=${serverDNMatch})`);
325
326
  if (serverCertDN != null)
326
327
  securityInfo.push(`(SSL_SERVER_CERT_DN=${serverCertDN}})`);
327
328
  if (walletDir != null)
@@ -342,8 +343,8 @@ class EZConnectResolver {
342
343
  * @return the parsed URL which does not contain the extended settings part.
343
344
  */
344
345
  parseExtendedSettings(urlStr) {
345
- let urlBytes = Array.from(urlStr.trim());
346
- let extendedSettingsIndex = this.findExtendedSettingPosition(urlBytes);
346
+ const urlBytes = Array.from(urlStr.trim());
347
+ const extendedSettingsIndex = this.findExtendedSettingPosition(urlBytes);
347
348
 
348
349
  if (extendedSettingsIndex == -1) {
349
350
  return urlStr; // No extended settings configuration found
@@ -360,7 +361,7 @@ class EZConnectResolver {
360
361
  parseExtendedProperties(urlChars, extIndex) {
361
362
  let key = null;
362
363
  let value = null;
363
- let token = new Array(urlChars.length);
364
+ const token = new Array(urlChars.length);
364
365
  let tokenIndx = 0;
365
366
  let indices = '';
366
367
  for (let i = extIndex; i < urlChars.length; i++) {
@@ -421,7 +422,7 @@ class EZConnectResolver {
421
422
  parseQuotedString(startIndex, urlChars, tokenIndex, token) {
422
423
  let i = startIndex + 1; // look for closing '"' from the next index
423
424
  while (i < urlChars.length) {
424
- let curChar = urlChars[i];
425
+ const curChar = urlChars[i];
425
426
  if (curChar == EXT_DOUBLE_QT) {
426
427
  // Got the " which ends the quoted block, so break the loop
427
428
  // Return the new indices, caller would resume from this new indices.
@@ -439,8 +440,8 @@ class EZConnectResolver {
439
440
  * @param value
440
441
  */
441
442
  addParam(key, value) {
442
- let aliasKeyName = key.toLowerCase();
443
- let propertyName = this.URL_PROPS_ALIAS.get(aliasKeyName);
443
+ const aliasKeyName = key.toLowerCase();
444
+ const propertyName = this.URL_PROPS_ALIAS.get(aliasKeyName);
444
445
  if (propertyName != null) {
445
446
  // if it is an URL alias then add to URL props
446
447
  this.urlProps.set(propertyName, value);
@@ -465,7 +466,7 @@ class EZConnectResolver {
465
466
  * @return url alias map
466
467
  */
467
468
  initializeUrlAlias() {
468
- let aliasMap = new Map();
469
+ const aliasMap = new Map();
469
470
  aliasMap.set("enable", "ENABLE");
470
471
  aliasMap.set("failover", "FAILOVER");
471
472
  aliasMap.set("load_balance", "LOAD_BALANCE");
@@ -58,7 +58,7 @@ class Address {
58
58
  * (ie, "(ADDRESS=(DESCRIPTION=...)) and ")
59
59
  */
60
60
  initFromString(s) {
61
- let nvp = createNVPair(s);
61
+ const nvp = createNVPair(s);
62
62
  this.initFromNVPair(nvp);
63
63
  }
64
64
 
@@ -70,11 +70,11 @@ class Address {
70
70
  initFromNVPair(nvp) {
71
71
  if (nvp == null || !(nvp.name.toUpperCase() == "ADDRESS"))
72
72
  errors.throwErr(errors.ERR_INVALID_CONNECT_STRING_SYNTAX);
73
- let protnvp = findNVPairRecurse(nvp, 'protocol');
74
- let portnvp = findNVPairRecurse(nvp, 'port');
75
- let hostnvp = findNVPairRecurse(nvp, 'host');
76
- let httpsProxyNVP = findNVPairRecurse(nvp, 'https_proxy');
77
- let httpsProxyPortNVP = findNVPairRecurse(nvp, 'https_proxy_port');
73
+ const protnvp = findNVPairRecurse(nvp, 'protocol');
74
+ const portnvp = findNVPairRecurse(nvp, 'port');
75
+ const hostnvp = findNVPairRecurse(nvp, 'host');
76
+ const httpsProxyNVP = findNVPairRecurse(nvp, 'https_proxy');
77
+ const httpsProxyPortNVP = findNVPairRecurse(nvp, 'https_proxy_port');
78
78
 
79
79
  if (portnvp)
80
80
  this.port = portnvp.atom;
@@ -121,7 +121,7 @@ class AddressList {
121
121
  * (ie, "(ADDRESS=(DESCRIPTION=...))")
122
122
  */
123
123
  initFromString(s) {
124
- let nvp = createNVPair(s);
124
+ const nvp = createNVPair(s);
125
125
  this.initFromNVPair(nvp);
126
126
  }
127
127
 
@@ -134,7 +134,7 @@ class AddressList {
134
134
  /* for each child of "ADDRESS_LIST", create child or set SR/LB/FO */
135
135
  this.children = [];
136
136
  let childnv, child;
137
- let listsize = nvp.getListSize();
137
+ const listsize = nvp.getListSize();
138
138
  if (listsize == 0) /* atom can not be valid */
139
139
  errors.throwErr(errors.ERR_INVALID_CONNECT_STRING_SYNTAX);
140
140
 
@@ -216,7 +216,7 @@ class Description {
216
216
  * Error thrown if invalid syntax (ie, "(ADDRESS=(DESCRIPTION=...))")
217
217
  */
218
218
  initFromString(s) {
219
- let nvp = createNVPair(s);
219
+ const nvp = createNVPair(s);
220
220
  this.initFromNVPair(nvp);
221
221
  }
222
222
 
@@ -227,7 +227,7 @@ class Description {
227
227
  */
228
228
  //errors.throwErr(errors.ERR_INVALID_CONNECT_STRING_SYNTAX);
229
229
  initFromNVPair(nvp) {
230
- let listsize = nvp.getListSize();
230
+ const listsize = nvp.getListSize();
231
231
  let childnv, child;
232
232
  if (listsize == 0) // atom can not be valid
233
233
  errors.throwErr(errors.ERR_INVALID_CONNECT_STRING_SYNTAX);
@@ -256,7 +256,7 @@ class Description {
256
256
  this.children.push(child);
257
257
  } else if (childnv.name.toUpperCase() == "CONNECT_DATA") {
258
258
  let tmpnv;
259
- let listsize = childnv.getListSize();
259
+ const listsize = childnv.getListSize();
260
260
  for (let i = 0; i < listsize; i++) {
261
261
  tmpnv = childnv.getListElement(i);
262
262
  if (tmpnv.name.toUpperCase() == "CONNECTION_ID_PREFIX") {
@@ -294,7 +294,7 @@ class Description {
294
294
  if (childnv.atom > 0)
295
295
  this.params.expireTime = childnv.atom;
296
296
  } else if (childnv.name.toUpperCase() == "SECURITY") {
297
- let listsize = childnv.getListSize();
297
+ const listsize = childnv.getListSize();
298
298
  let tmpnv;
299
299
  for (let i = 0; i < listsize; i++) {
300
300
  tmpnv = childnv.getListElement(i);
@@ -304,6 +304,10 @@ class Description {
304
304
  this.params.sslServerDNMatch = (tmpnv.atom.toLowerCase() == "yes"
305
305
  || tmpnv.atom.toLowerCase() == "on"
306
306
  || tmpnv.atom.toLowerCase() == "true");
307
+ } else if (tmpnv.name.toUpperCase() == "SSL_ALLOW_WEAK_DN_MATCH") {
308
+ this.params.sslAllowWeakDNMatch = (tmpnv.atom.toLowerCase() == "yes"
309
+ || tmpnv.atom.toLowerCase() == "on"
310
+ || tmpnv.atom.toLowerCase() == "true");
307
311
  } else if ((tmpnv.name.toUpperCase() == "WALLET_LOCATION") || (tmpnv.name.toUpperCase() == "MY_WALLET_DIRECTORY")) {
308
312
  this.params.walletLocation = tmpnv.atom;
309
313
  }
@@ -360,7 +364,7 @@ class DescriptionList {
360
364
  * (ie, "(ADDRESS=(DESCRIPTION=...))")
361
365
  */
362
366
  initFromString(s) {
363
- let nvp = createNVPair(s);
367
+ const nvp = createNVPair(s);
364
368
  this.initFromNVPair(nvp);
365
369
  }
366
370
 
@@ -370,7 +374,7 @@ class DescriptionList {
370
374
  * (ie, "(ADDRESS=(DESCRIPTION=...))")
371
375
  */
372
376
  initFromNVPair(nvp) {
373
- let listsize = nvp.getListSize();
377
+ const listsize = nvp.getListSize();
374
378
  let child, childnv;
375
379
  if (listsize == 0) /* atom can not be valid */
376
380
  errors.throwErr(errors.ERR_INVALID_CONNECT_STRING_SYNTAX);
@@ -482,8 +486,8 @@ class NavAddress extends Address {
482
486
  if (!net.isIP(this.host)) {
483
487
  try {
484
488
  addresses = await dnsPromises.lookup(this.host, options);
485
- for (let addr in addresses) {
486
- let co = new ConnOption();
489
+ for (const addr in addresses) {
490
+ const co = new ConnOption();
487
491
  co.hostname = this.host;
488
492
  co.port = this.port;
489
493
  co.protocol = this.prot;
@@ -503,7 +507,7 @@ class NavAddress extends Address {
503
507
  // do nothing
504
508
  }
505
509
  } else {
506
- let co = new ConnOption();
510
+ const co = new ConnOption();
507
511
  co.hostname = this.host;
508
512
  co.port = this.port;
509
513
  co.protocol = this.prot;
@@ -530,7 +534,7 @@ class NavAddress extends Address {
530
534
  * Address. Constructing a string is mainly needed when source route is ON.
531
535
  */
532
536
  addToString(cs) {
533
- let NVString = this.toString();
537
+ const NVString = this.toString();
534
538
  let cOpts = new Array();
535
539
  cOpts = cs.getcurrentDescription().getConnectOptions();
536
540
  for (let i = 0;i < cOpts.length; i++) {
@@ -589,7 +593,7 @@ class NavAddressList extends AddressList {
589
593
 
590
594
  }
591
595
  addToString(cs) {
592
- let NVString = this.toString();
596
+ const NVString = this.toString();
593
597
  let cOpts = new Array();
594
598
  cOpts = cs.getcurrentDescription().getConnectOptions();
595
599
  for (let i = 0;i < cOpts.length; i++) {
@@ -631,7 +635,7 @@ class NavAddressList extends AddressList {
631
635
 
632
636
  closeNVPair(cs) {
633
637
  let cOpts = new Array();
634
- let childS = this.getChildrenSize();
638
+ const childS = this.getChildrenSize();
635
639
  if (cs.getcurrentDescription() != null) {
636
640
  cOpts = cs.getcurrentDescription().getConnectOptions();
637
641
  let numChildren = 0;
@@ -682,7 +686,7 @@ class NavDescription extends Description {
682
686
  async navigate(cs) {
683
687
  cs.sBuf.length = 0; //reset
684
688
  cs.sBuf.push("(DESCRIPTION=");
685
- let desc = cs.newConnectionDescription(); //connectiondescription
689
+ const desc = cs.newConnectionDescription(); //connectiondescription
686
690
  if (this.retryCount != null) {
687
691
  cs.retryCount = this.getIntValue(this.retryCount, cs.retryCount);
688
692
  desc.retryCount = cs.retryCount;
@@ -711,7 +715,7 @@ class NavDescription extends Description {
711
715
  if ('enable' in this.params) {
712
716
  cs.sBuf.push("(ENABLE=" + this.params.enable + ")");
713
717
  }
714
- if (('sslServerCertDN' in this.params) || ('sslServerDNMatch' in this.params) || ('walletLocation' in this.params)) {
718
+ if (('sslServerCertDN' in this.params) || ('sslServerDNMatch' in this.params) || ('walletLocation' in this.params) || ('sslAllowWeakDNMatch' in this.params)) {
715
719
  cs.sBuf.push("(SECURITY=");
716
720
  if ('sslServerCertDN' in this.params) {
717
721
  cs.sBuf.push("(SSL_SERVER_CERT_DN=" + this.params.sslServerCertDN + ")");
@@ -719,6 +723,9 @@ class NavDescription extends Description {
719
723
  if ('sslServerDNMatch' in this.params) {
720
724
  cs.sBuf.push("(SSL_SERVER_DN_MATCH=" + this.params.sslServerDNMatch + ")");
721
725
  }
726
+ if ('sslAllowWeakDNMatch' in this.params) {
727
+ cs.sBuf.push("(SSL_ALLOW_WEAK_DN_MATCH=" + this.params.sslAllowWeakDNMatch + ")");
728
+ }
722
729
  if ('walletLocation' in this.params) {
723
730
  cs.sBuf.push("(WALLET_LOCATION=" + this.params.walletLocation + ")");
724
731
  }
@@ -834,10 +841,10 @@ class NavDescriptionList extends DescriptionList {
834
841
  */
835
842
  static setActiveChildren(children, failover, loadBalance) {
836
843
  let randNumber;
837
- let listSize = children.length;
844
+ const listSize = children.length;
838
845
  let tmpChildren = new Array();
839
- let rand = Math.floor(Math.random() * 10);
840
- let arr = new Array(listSize).fill(false);
846
+ const rand = Math.floor(Math.random() * 10);
847
+ const arr = new Array(listSize).fill(false);
841
848
 
842
849
  if (failover) {
843
850
  if (loadBalance) {