oracledb 6.0.1 → 6.0.3
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/README.md +18 -19
- package/SECURITY.md +1 -1
- package/build/Release/{oracledb-6.0.1-darwin-x64.node → oracledb-6.0.3-darwin-x64.node} +0 -0
- package/build/Release/oracledb-6.0.3-darwin-x64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.0.3-js-buildinfo.txt +1 -0
- package/build/Release/{oracledb-6.0.1-linux-arm64.node → oracledb-6.0.3-linux-arm64.node} +0 -0
- package/build/Release/oracledb-6.0.3-linux-arm64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.0.3-linux-x64.node-buildinfo.txt +1 -0
- package/build/Release/{oracledb-6.0.1-win32-x64.node → oracledb-6.0.3-win32-x64.node} +0 -0
- package/build/Release/oracledb-6.0.3-win32-x64.node-buildinfo.txt +1 -0
- package/lib/connection.js +1 -0
- package/lib/errors.js +5 -4
- package/lib/pool.js +4 -1
- package/lib/settings.js +1 -1
- package/lib/thin/dbObject.js +17 -5
- package/lib/thin/lob.js +2 -2
- package/lib/thin/pool.js +10 -12
- package/lib/thin/protocol/buffer.js +9 -9
- package/lib/thin/protocol/constants.js +5 -4
- package/lib/thin/protocol/encryptDecrypt.js +24 -12
- package/lib/thin/protocol/messages/auth.js +7 -9
- package/lib/thin/protocol/messages/base.js +10 -10
- package/lib/thin/protocol/messages/execute.js +5 -5
- package/lib/thin/protocol/messages/lobOp.js +3 -3
- package/lib/thin/protocol/messages/withData.js +20 -18
- package/lib/thin/protocol/packet.js +31 -27
- package/lib/thin/protocol/protocol.js +12 -7
- package/lib/thin/sqlnet/connStrategy.js +4 -2
- package/lib/thin/sqlnet/ezConnectResolver.js +9 -5
- package/lib/thin/sqlnet/navNodes.js +3 -3
- package/lib/thin/sqlnet/networkSession.js +10 -10
- package/lib/thin/sqlnet/ntTcp.js +38 -25
- package/lib/thin/sqlnet/packet.js +8 -8
- package/lib/thin/sqlnet/paramParser.js +5 -8
- package/lib/thin/statement.js +1 -0
- package/lib/thin/util.js +21 -0
- package/lib/version.js +1 -1
- package/package.json +1 -1
- package/build/Release/oracledb-6.0.1-darwin-x64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.0.1-js-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.0.1-linux-arm64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.0.1-linux-x64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.0.1-win32-x64.node-buildinfo.txt +0 -1
- /package/build/Release/{oracledb-6.0.1-linux-x64.node → oracledb-6.0.3-linux-x64.node} +0 -0
|
@@ -139,7 +139,7 @@ class MessageWithData extends Message {
|
|
|
139
139
|
|
|
140
140
|
let numBytes = buf.readUB4();
|
|
141
141
|
if (numBytes > 0) {
|
|
142
|
-
buf.
|
|
142
|
+
buf.skipBytesChunked(); // current date
|
|
143
143
|
}
|
|
144
144
|
buf.skipUB4(); // dcbflag
|
|
145
145
|
buf.skipUB4(); // dcbmdbz
|
|
@@ -147,7 +147,7 @@ class MessageWithData extends Message {
|
|
|
147
147
|
buf.skipUB4(); // dcbmxpr
|
|
148
148
|
numBytes = buf.readUB4();
|
|
149
149
|
if (numBytes > 0) {
|
|
150
|
-
buf.
|
|
150
|
+
buf.skipBytesChunked();
|
|
151
151
|
}
|
|
152
152
|
|
|
153
153
|
this.resultSetsToSetup.push(resultSet);
|
|
@@ -173,7 +173,7 @@ class MessageWithData extends Message {
|
|
|
173
173
|
let oid;
|
|
174
174
|
let numBytes = buf.readUB4(); // OID
|
|
175
175
|
if (numBytes > 0) {
|
|
176
|
-
oid = buf.readBytesWithLength();
|
|
176
|
+
oid = Buffer.from(buf.readBytesWithLength());
|
|
177
177
|
}
|
|
178
178
|
buf.skipUB2(); // version
|
|
179
179
|
buf.skipUB2(); // character set id
|
|
@@ -190,17 +190,17 @@ class MessageWithData extends Message {
|
|
|
190
190
|
let name;
|
|
191
191
|
numBytes = buf.readUB4();
|
|
192
192
|
if (numBytes > 0) {
|
|
193
|
-
name = buf.readStr(constants.
|
|
193
|
+
name = buf.readStr(constants.CSFRM_IMPLICIT);
|
|
194
194
|
}
|
|
195
195
|
let schema;
|
|
196
196
|
numBytes = buf.readUB4();
|
|
197
197
|
if (numBytes > 0) {
|
|
198
|
-
schema = buf.readStr(constants.
|
|
198
|
+
schema = buf.readStr(constants.CSFRM_IMPLICIT);
|
|
199
199
|
}
|
|
200
200
|
numBytes = buf.readUB4();
|
|
201
201
|
let typeName;
|
|
202
202
|
if (numBytes > 0) {
|
|
203
|
-
typeName = buf.readStr(constants.
|
|
203
|
+
typeName = buf.readStr(constants.CSFRM_IMPLICIT);
|
|
204
204
|
}
|
|
205
205
|
buf.skipUB2(); // column position
|
|
206
206
|
buf.skipUB4(); // uds flag
|
|
@@ -316,10 +316,11 @@ class MessageWithData extends Message {
|
|
|
316
316
|
processIOVector(buf) {
|
|
317
317
|
let numBytes;
|
|
318
318
|
buf.skipUB1(); // flag
|
|
319
|
-
const
|
|
320
|
-
|
|
319
|
+
const temp16 = buf.readUB2(); // num requests
|
|
320
|
+
const temp32 = buf.readUB4(); // iter num
|
|
321
|
+
const numBinds = temp32 * 256 + temp16;
|
|
321
322
|
buf.skipUB4(); // num iters this time
|
|
322
|
-
buf.
|
|
323
|
+
buf.skipUB2(); // uac buffer length
|
|
323
324
|
numBytes = buf.readUB2(); // bit vector for fast fetch
|
|
324
325
|
if (numBytes > 0) {
|
|
325
326
|
buf.skipBytes(numBytes);
|
|
@@ -355,7 +356,7 @@ class MessageWithData extends Message {
|
|
|
355
356
|
oraTypeNum === constants.TNS_DATA_TYPE_CHAR ||
|
|
356
357
|
oraTypeNum === constants.TNS_DATA_TYPE_LONG
|
|
357
358
|
) {
|
|
358
|
-
if (csfrm === constants.
|
|
359
|
+
if (csfrm === constants.CSFRM_NCHAR) {
|
|
359
360
|
buf.caps.checkNCharsetId();
|
|
360
361
|
}
|
|
361
362
|
colValue = buf.readStr(csfrm);
|
|
@@ -378,9 +379,9 @@ class MessageWithData extends Message {
|
|
|
378
379
|
const useLocalTime = (oraTypeNum === constants.TNS_DATA_TYPE_DATE ||
|
|
379
380
|
oraTypeNum === constants.TNS_DATA_TYPE_TIMESTAMP);
|
|
380
381
|
colValue = buf.readOracleDate(useLocalTime);
|
|
381
|
-
}
|
|
382
|
+
} else if (oraTypeNum === constants.TNS_DATA_TYPE_ROWID) {
|
|
382
383
|
if (!this.inFetch) {
|
|
383
|
-
colValue = buf.readStr(constants.
|
|
384
|
+
colValue = buf.readStr(constants.CSFRM_IMPLICIT);
|
|
384
385
|
} else {
|
|
385
386
|
let numBytes = buf.readUInt8();
|
|
386
387
|
if (isNullLength(numBytes)) {
|
|
@@ -392,7 +393,7 @@ class MessageWithData extends Message {
|
|
|
392
393
|
}
|
|
393
394
|
} else if (oraTypeNum === constants.TNS_DATA_TYPE_UROWID) {
|
|
394
395
|
if (!this.inFetch) {
|
|
395
|
-
colValue = buf.readStr(constants.
|
|
396
|
+
colValue = buf.readStr(constants.CSFRM_IMPLICIT);
|
|
396
397
|
} else {
|
|
397
398
|
colValue = buf.readURowID();
|
|
398
399
|
}
|
|
@@ -478,7 +479,7 @@ class MessageWithData extends Message {
|
|
|
478
479
|
for (let i = 0; i < numParams; i++) {
|
|
479
480
|
numBytes = buf.readUB2(); // key
|
|
480
481
|
if (numBytes > 0) {
|
|
481
|
-
keyTextValue = buf.readStr(constants.
|
|
482
|
+
keyTextValue = buf.readStr(constants.CSFRM_IMPLICIT);
|
|
482
483
|
}
|
|
483
484
|
numBytes = buf.readUB2(); // value
|
|
484
485
|
if (numBytes > 0) {
|
|
@@ -546,6 +547,7 @@ class MessageWithData extends Message {
|
|
|
546
547
|
variable.maxSize = constants.TNS_MAX_LONG_LENGTH;
|
|
547
548
|
}
|
|
548
549
|
resultSet.statement.requiresDefine = true;
|
|
550
|
+
resultSet.statement.noPrefetch = true;
|
|
549
551
|
}
|
|
550
552
|
}
|
|
551
553
|
}
|
|
@@ -563,7 +565,7 @@ class MessageWithData extends Message {
|
|
|
563
565
|
|
|
564
566
|
if (this.statement.isQuery) {
|
|
565
567
|
this.inFetch = true;
|
|
566
|
-
if (this.statement.queryVars)
|
|
568
|
+
if (this.statement.queryVars) {
|
|
567
569
|
this.outVariables = [];
|
|
568
570
|
for (let i = 0; i < this.statement.queryVars.length; i++) {
|
|
569
571
|
this.outVariables.push(this.statement.queryVars[i]);
|
|
@@ -582,7 +584,7 @@ class MessageWithData extends Message {
|
|
|
582
584
|
}
|
|
583
585
|
|
|
584
586
|
getBitVector(buf, numBytes) {
|
|
585
|
-
this.bitVector = buf.readBytes(numBytes);
|
|
587
|
+
this.bitVector = Buffer.from(buf.readBytes(numBytes));
|
|
586
588
|
}
|
|
587
589
|
|
|
588
590
|
processBindParams(buf, params) {
|
|
@@ -607,7 +609,7 @@ class MessageWithData extends Message {
|
|
|
607
609
|
// NCHAR, NVARCHAR reports ORA-01460: unimplemented or unreasonable
|
|
608
610
|
// conversion requested if maxSize is not multiplied by the
|
|
609
611
|
// bufferSizeFactor
|
|
610
|
-
if (variable.type._csfrm === constants.
|
|
612
|
+
if (variable.type._csfrm === constants.CSFRM_NCHAR) {
|
|
611
613
|
maxSize *= variable.type._bufferSizeFactor;
|
|
612
614
|
}
|
|
613
615
|
if ([constants.TNS_DATA_TYPE_ROWID, constants.TNS_DATA_TYPE_UROWID].includes(oraTypeNum)) {
|
|
@@ -731,7 +733,7 @@ class MessageWithData extends Message {
|
|
|
731
733
|
oraTypeNum === constants.TNS_DATA_TYPE_LONG ||
|
|
732
734
|
oraTypeNum === constants.TNS_DATA_TYPE_RAW ||
|
|
733
735
|
oraTypeNum === constants.TNS_DATA_TYPE_LONG_RAW) {
|
|
734
|
-
if (variable.type._csfrm === constants.
|
|
736
|
+
if (variable.type._csfrm === constants.CSFRM_NCHAR) {
|
|
735
737
|
buf.caps.checkNCharsetId();
|
|
736
738
|
value = Buffer.from(value, constants.TNS_ENCODING_UTF16).swap16();
|
|
737
739
|
} else {
|
|
@@ -220,12 +220,17 @@ class ReadPacket extends BaseBuffer {
|
|
|
220
220
|
}
|
|
221
221
|
|
|
222
222
|
// the requested bytes are split across multiple packets; if a chunked read
|
|
223
|
-
// is
|
|
224
|
-
//
|
|
225
|
-
|
|
226
|
-
|
|
223
|
+
// is in progress, a chunk is acquired that will accommodate the requested
|
|
224
|
+
// bytes; otherwise, a separate buffer will be allocated to accommodate the
|
|
225
|
+
// requested bytes
|
|
226
|
+
let buf;
|
|
227
|
+
if (inChunkedRead) {
|
|
228
|
+
buf = this.chunkedBytesBuf.getBuf(numBytes);
|
|
229
|
+
} else {
|
|
230
|
+
buf = Buffer.alloc(numBytes);
|
|
227
231
|
}
|
|
228
|
-
|
|
232
|
+
|
|
233
|
+
// copy the bytes to the buffer from the remainder of this packet
|
|
229
234
|
let offset = 0;
|
|
230
235
|
this.buf.copy(buf, offset, this.pos, this.pos + numBytesLeft);
|
|
231
236
|
offset += numBytesLeft;
|
|
@@ -241,10 +246,7 @@ class ReadPacket extends BaseBuffer {
|
|
|
241
246
|
numBytes -= numSplitBytes;
|
|
242
247
|
}
|
|
243
248
|
|
|
244
|
-
|
|
245
|
-
if (!inChunkedRead) {
|
|
246
|
-
return this.chunkedBytesBuf.endChunkedRead();
|
|
247
|
-
}
|
|
249
|
+
return buf;
|
|
248
250
|
|
|
249
251
|
}
|
|
250
252
|
|
|
@@ -252,46 +254,48 @@ class ReadPacket extends BaseBuffer {
|
|
|
252
254
|
* Receives a packet from the adapter.
|
|
253
255
|
*/
|
|
254
256
|
receivePacket() {
|
|
255
|
-
if (this.
|
|
257
|
+
if (this.savedPacketPos === this.savedPackets.length) {
|
|
256
258
|
const packet = this.nsi.syncRecvPacket();
|
|
257
|
-
if (!packet)
|
|
259
|
+
if (!packet || this.nsi.isBreak)
|
|
258
260
|
throw new utils.OutOfPacketsError();
|
|
259
|
-
this.
|
|
261
|
+
this.savedPackets.push(packet);
|
|
260
262
|
}
|
|
261
|
-
this.startPacket(this.
|
|
263
|
+
this.startPacket(this.savedPackets[this.savedPacketPos++]);
|
|
262
264
|
}
|
|
263
265
|
|
|
264
266
|
restorePoint() {
|
|
265
|
-
this.
|
|
266
|
-
this.startPacket(this.
|
|
267
|
+
this.savedPacketPos = 0;
|
|
268
|
+
this.startPacket(this.savedPackets[this.savedPacketPos++]);
|
|
267
269
|
this.pos = this.savedPos;
|
|
268
270
|
}
|
|
269
271
|
|
|
270
272
|
savePoint() {
|
|
271
|
-
if (this.
|
|
272
|
-
this.
|
|
273
|
+
if (this.savedPackets) {
|
|
274
|
+
this.savedPackets = this.savedPackets.splice(this.savedPacketPos - 1);
|
|
273
275
|
} else {
|
|
274
|
-
this.
|
|
276
|
+
this.savedPackets = [this.packet];
|
|
275
277
|
}
|
|
276
|
-
this.
|
|
278
|
+
this.savedPacketPos = 1;
|
|
277
279
|
this.savedPos = this.pos;
|
|
278
280
|
}
|
|
279
281
|
|
|
280
|
-
startPacket(
|
|
281
|
-
this.
|
|
282
|
+
startPacket(packet) {
|
|
283
|
+
this.packet = packet;
|
|
284
|
+
this.buf = packet.buf;
|
|
282
285
|
this.pos = 10; // skip packet heaader and data flags
|
|
283
|
-
this.size = buf.length;
|
|
286
|
+
this.size = packet.buf.length;
|
|
287
|
+
this.packetNum = packet.num;
|
|
284
288
|
}
|
|
285
289
|
|
|
286
290
|
async waitForPackets() {
|
|
287
291
|
const packet = await this.nsi.recvPacket();
|
|
288
|
-
if (!this.
|
|
289
|
-
this.
|
|
290
|
-
this.
|
|
292
|
+
if (!this.savedPackets) {
|
|
293
|
+
this.savedPackets = [packet];
|
|
294
|
+
this.savedPacketPos = 0;
|
|
291
295
|
} else {
|
|
292
|
-
this.
|
|
296
|
+
this.savedPackets.push(packet);
|
|
293
297
|
}
|
|
294
|
-
this.startPacket(this.
|
|
298
|
+
this.startPacket(this.savedPackets[this.savedPacketPos++]);
|
|
295
299
|
}
|
|
296
300
|
|
|
297
301
|
/**
|
|
@@ -71,6 +71,7 @@ class Protocol {
|
|
|
71
71
|
while (true) { // eslint-disable-line
|
|
72
72
|
if (this.nsi.isBreak) {
|
|
73
73
|
await this.resetMessage();
|
|
74
|
+
delete this.readBuf.savedBuffers;
|
|
74
75
|
await this.readBuf.waitForPackets();
|
|
75
76
|
}
|
|
76
77
|
try {
|
|
@@ -78,8 +79,10 @@ class Protocol {
|
|
|
78
79
|
break;
|
|
79
80
|
} catch (err) {
|
|
80
81
|
if (err instanceof utils.OutOfPacketsError) {
|
|
81
|
-
|
|
82
|
-
|
|
82
|
+
if (!this.nsi.isBreak) {
|
|
83
|
+
await this.readBuf.waitForPackets();
|
|
84
|
+
this.readBuf.restorePoint();
|
|
85
|
+
}
|
|
83
86
|
continue;
|
|
84
87
|
}
|
|
85
88
|
throw (err);
|
|
@@ -108,7 +111,7 @@ class Protocol {
|
|
|
108
111
|
this.writeBuf.endRequest();
|
|
109
112
|
}
|
|
110
113
|
|
|
111
|
-
async _recoverFromError(message) {
|
|
114
|
+
async _recoverFromError(caughtErr, message) {
|
|
112
115
|
/*
|
|
113
116
|
* We have NJS error(protocol related) detected during packet write/read
|
|
114
117
|
* operation. Issue a break and reset to clear channel . We receive the
|
|
@@ -121,10 +124,12 @@ class Protocol {
|
|
|
121
124
|
await this.readBuf.waitForPackets();
|
|
122
125
|
message.decode(this.readBuf);
|
|
123
126
|
} catch (err) { // Recovery failed
|
|
124
|
-
// TODO: throw different error indicating that reset failed, probably
|
|
125
|
-
// put inside resetMessage()
|
|
126
127
|
this.nsi.disconnect();
|
|
127
|
-
errors.
|
|
128
|
+
const newErr = errors.getErr(errors.ERR_CONNECTION_CLOSED);
|
|
129
|
+
caughtErr.message = newErr.message +
|
|
130
|
+
"\nError recovery failed: " + err.message +
|
|
131
|
+
"\nOriginal error: " + caughtErr.message;
|
|
132
|
+
throw caughtErr;
|
|
128
133
|
}
|
|
129
134
|
}
|
|
130
135
|
|
|
@@ -150,7 +155,7 @@ class Protocol {
|
|
|
150
155
|
} catch (err) {
|
|
151
156
|
if (!this.connInProgress &&
|
|
152
157
|
err.code !== errors.ERR_CONNECTION_CLOSED_CODE) {
|
|
153
|
-
await this._recoverFromError(message);
|
|
158
|
+
await this._recoverFromError(err, message);
|
|
154
159
|
}
|
|
155
160
|
throw err;
|
|
156
161
|
} finally {
|
|
@@ -28,8 +28,7 @@
|
|
|
28
28
|
|
|
29
29
|
const { NavAddress, NavAddressList, NavDescription, NavDescriptionList } = require("./navNodes.js");
|
|
30
30
|
const { createNVPair } = require("./nvStrToNvPair.js");
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
const errors = require("../../errors.js");
|
|
33
32
|
|
|
34
33
|
/**
|
|
35
34
|
* Class that holds all possible attributes under Description
|
|
@@ -166,6 +165,9 @@ async function createNode(str) {
|
|
|
166
165
|
case "DESCRIPTION_LIST":
|
|
167
166
|
navobj = new NavDescriptionList();
|
|
168
167
|
break;
|
|
168
|
+
default:
|
|
169
|
+
errors.throwErr(errors.ERR_INVALID_CONNECT_STRING_PARAMETERS,
|
|
170
|
+
`unknown top element ${arg}`);
|
|
169
171
|
}
|
|
170
172
|
navobj.initFromNVPair(nvpair);
|
|
171
173
|
let cs = new ConnStrategy();
|
|
@@ -39,8 +39,7 @@ Test Case in oracle_private/ezconnectTest.js
|
|
|
39
39
|
const HOSTNAMES_PATTERN = new RegExp("((?=(?<hostnames>(((\\[[A-z0-9:]+\\])|([A-z0-9][A-z0-9._-]+))[,]?)+)))\\k<hostnames>(:(?<port>\\d+)?)?", 'g');
|
|
40
40
|
|
|
41
41
|
// The EZConnect pattern without the extended settings part.
|
|
42
|
-
const EZ_URL_PATTERN = new RegExp("^((?<protocol>
|
|
43
|
-
+ "(//)?"
|
|
42
|
+
const EZ_URL_PATTERN = new RegExp("^(((?<protocol>[A-z0-9]+):)?//)?"
|
|
44
43
|
+ "(?<hostinfo>(" + HOSTNAMES_PATTERN.source + "(?=([,]|[;]|[/]|[:]|$))([,]|[;])?)+)"
|
|
45
44
|
+ "(/(?<servicename>[A-z0-9][A-z0-9,-.]+)?)"
|
|
46
45
|
+ "?(:(?<servermode>dedicated|shared|pooled))"
|
|
@@ -145,8 +144,9 @@ class EZConnectResolver {
|
|
|
145
144
|
if (protocol == null) {
|
|
146
145
|
if (!(url.includes("//")))
|
|
147
146
|
protocol = 'TCP';
|
|
147
|
+
} else if (protocol.toLowerCase() != 'tcp' && protocol.toLowerCase() != 'tcps') {
|
|
148
|
+
errors.throwErr(errors.ERR_INVALID_EZCONNECT_SYNTAX, 'Unsupported protocol in thin mode', protocol);
|
|
148
149
|
}
|
|
149
|
-
|
|
150
150
|
// Try to get the proxy information from URL properties
|
|
151
151
|
const proxyHost = this.urlProps.get("HTTPS_PROXY");
|
|
152
152
|
const proxyPort = this.urlProps.get("HTTPS_PROXY_PORT");
|
|
@@ -216,8 +216,12 @@ class EZConnectResolver {
|
|
|
216
216
|
let ipcnt = 0;
|
|
217
217
|
let builder = new Array();
|
|
218
218
|
let proxyInfo = '';
|
|
219
|
-
if (proxyHost != null
|
|
220
|
-
|
|
219
|
+
if (proxyHost != null) {
|
|
220
|
+
if (proxyPort != null) {
|
|
221
|
+
proxyInfo = `(HTTPS_PROXY=${proxyHost})(HTTPS_PROXY_PORT=${proxyPort})`;
|
|
222
|
+
} else {
|
|
223
|
+
proxyInfo = `(HTTPS_PROXY=${proxyHost})`;
|
|
224
|
+
}
|
|
221
225
|
}
|
|
222
226
|
|
|
223
227
|
if (protocol == null) protocol = 'TCP';
|
|
@@ -32,6 +32,7 @@ const os = require("os");
|
|
|
32
32
|
const net = require('net');
|
|
33
33
|
const dns = require('dns');
|
|
34
34
|
const dnsPromises = dns.promises;
|
|
35
|
+
const cInfo = require("../util.js").CLIENT_INFO;
|
|
35
36
|
|
|
36
37
|
const SchemaObjectFactoryInterface = {
|
|
37
38
|
ADDR:0,
|
|
@@ -443,7 +444,6 @@ const NavSchemaObject = {
|
|
|
443
444
|
LB: "(LOAD_BALANCE=yes)",
|
|
444
445
|
NFO: "(FAILOVER=false)",
|
|
445
446
|
CD: "(CONNECT_DATA=",
|
|
446
|
-
CID: `(CID=(PROGRAM=nodejs)(HOST=${os.hostname()})(USER=${os.userInfo().username}))`,
|
|
447
447
|
CONID: "(CONNECTION_ID="
|
|
448
448
|
};
|
|
449
449
|
const options = {
|
|
@@ -770,10 +770,10 @@ class NavDescription extends Description {
|
|
|
770
770
|
if (this.connectData == null) {
|
|
771
771
|
this.connectData = "(SERVICE_NAME=)";
|
|
772
772
|
}
|
|
773
|
-
|
|
773
|
+
const cid = `(CID=(PROGRAM=${cInfo.program})(HOST=${cInfo.hostName})(USER=${cInfo.userName}))`;
|
|
774
774
|
cOpts[i].CNdata.push(NavSchemaObject.CD);
|
|
775
775
|
cOpts[i].CNdata.push(this.connectData);
|
|
776
|
-
cOpts[i].CNdata.push(
|
|
776
|
+
cOpts[i].CNdata.push(cid);
|
|
777
777
|
cOpts[i].CNdata.push(")");
|
|
778
778
|
|
|
779
779
|
if (this.SID != null) {
|
|
@@ -165,6 +165,9 @@ class NetworkSession {
|
|
|
165
165
|
* Make the transport level connection
|
|
166
166
|
*/
|
|
167
167
|
async transportConnect(address) {
|
|
168
|
+
if (address.protocol.toUpperCase() == 'TCP' && address.httpsProxy) {
|
|
169
|
+
errors.throwErr(errors.ERR_INVALID_CONNECT_STRING_PARAMETERS, 'https proxy requires protocol as', 'tcps ');
|
|
170
|
+
}
|
|
168
171
|
if (address.protocol && (address.protocol.toUpperCase() == 'TCP' || address.protocol.toUpperCase() == 'TCPS')) {
|
|
169
172
|
this.ntAdapter = new NTTCP(this.sAtts.nt);
|
|
170
173
|
} else {
|
|
@@ -173,8 +176,8 @@ class NetworkSession {
|
|
|
173
176
|
await this.ntAdapter.connect(address);
|
|
174
177
|
this.ntAdapter.startRead();
|
|
175
178
|
this.sAtts.ntCha = this.ntAdapter.cha;
|
|
176
|
-
this.sndDatapkt = new Packet.DataPacket(this.sAtts.
|
|
177
|
-
this.rcvDatapkt = new Packet.DataPacket(this.sAtts.
|
|
179
|
+
this.sndDatapkt = new Packet.DataPacket(this.sAtts.largeSDU);
|
|
180
|
+
this.rcvDatapkt = new Packet.DataPacket(this.sAtts.largeSDU);
|
|
178
181
|
}
|
|
179
182
|
|
|
180
183
|
/**
|
|
@@ -280,17 +283,16 @@ class NetworkSession {
|
|
|
280
283
|
}
|
|
281
284
|
|
|
282
285
|
connectPkt = new Packet.ConnectPacket(redirConnData, this.sAtts, constants.NSPFRDR);
|
|
286
|
+
this.sndDatapkt = new Packet.DataPacket(this.sAtts.largeSDU);
|
|
283
287
|
this._sendConnect(connectPkt);
|
|
284
288
|
}
|
|
285
289
|
}
|
|
286
290
|
|
|
287
291
|
/* Accepted */
|
|
288
292
|
this.connected = true;
|
|
289
|
-
this.
|
|
290
|
-
this.
|
|
291
|
-
this.
|
|
292
|
-
this.sndDatapkt = new Packet.DataPacket(this.sAtts.sdu, this.sAtts.largeSDU);
|
|
293
|
-
this.sndDatapkt.createPacket();
|
|
293
|
+
this.cData = null;
|
|
294
|
+
this.sndDatapkt = new Packet.DataPacket(this.sAtts.largeSDU);
|
|
295
|
+
this.sndDatapkt.createPacket(constants.NSPDADAT); //Currently only used for disconnect
|
|
294
296
|
this.sndDatapkt.offset = this.sndDatapkt.dataPtr;
|
|
295
297
|
this.sndDatapkt.len = this.sndDatapkt.bufLen;
|
|
296
298
|
this.markerPkt = new Packet.MarkerPacket(this.sAtts.largeSDU);
|
|
@@ -466,7 +468,7 @@ class NetworkSession {
|
|
|
466
468
|
let bytesCopied = 0;
|
|
467
469
|
|
|
468
470
|
this.sndDatapkt.dataLen = this.sndDatapkt.offset;
|
|
469
|
-
if (this.sndDatapkt.dataLen < this.sndDatapkt.bufLen) {
|
|
471
|
+
if (this.sndDatapkt.dataLen < this.sndDatapkt.bufLen || !this.sndDatapkt.bufLen) {
|
|
470
472
|
bytesCopied = this.sndDatapkt.fillBuf(userBuf, offset, len);
|
|
471
473
|
len -= bytesCopied;
|
|
472
474
|
offset += bytesCopied;
|
|
@@ -591,7 +593,6 @@ class NetworkSession {
|
|
|
591
593
|
let error = 0;
|
|
592
594
|
if (this.controlPkt.errno) { /* Control pkt already read */
|
|
593
595
|
error = this.controlPkt.errno;
|
|
594
|
-
this.controlPkt.clear(); /* Clear error */
|
|
595
596
|
return (error);
|
|
596
597
|
} else if (!this.getOption(constants.HEALTHCHECK)) {
|
|
597
598
|
return errors.ERR_CONNECTION_CLOSED;
|
|
@@ -602,7 +603,6 @@ class NetworkSession {
|
|
|
602
603
|
if (packet.type == constants.NSPTCNL) {
|
|
603
604
|
this.controlPkt.fromPacket(packet);
|
|
604
605
|
error = this.controlPkt.errno;
|
|
605
|
-
this.controlPkt.clear(); /* Clear error */
|
|
606
606
|
return (error);
|
|
607
607
|
} else {
|
|
608
608
|
this.ntAdapter.packets.unshift(packet); /* Push packet back */
|
package/lib/thin/sqlnet/ntTcp.js
CHANGED
|
@@ -47,6 +47,8 @@ const TCPCHA = 1 << 1 | /* ASYNC support */
|
|
|
47
47
|
1 << 9 | /* Full Duplex support */
|
|
48
48
|
1 << 12; /* SIGPIPE Support */
|
|
49
49
|
|
|
50
|
+
let streamNum = 1;
|
|
51
|
+
|
|
50
52
|
/**
|
|
51
53
|
* Network Transport TCP/TCPS adapter
|
|
52
54
|
* @param {Address} address Destination Address
|
|
@@ -63,6 +65,8 @@ class NTTCP {
|
|
|
63
65
|
this.numPacketsSinceLastWait = 0;
|
|
64
66
|
this.secure = false;
|
|
65
67
|
this.largeSDU = false;
|
|
68
|
+
this.streamNum = streamNum++;
|
|
69
|
+
this.packetNum = 1;
|
|
66
70
|
}
|
|
67
71
|
|
|
68
72
|
/**
|
|
@@ -240,7 +244,8 @@ class NTTCP {
|
|
|
240
244
|
}
|
|
241
245
|
this.stream = null;
|
|
242
246
|
this.connected = false;
|
|
243
|
-
this.
|
|
247
|
+
this.drainWaiter = null;
|
|
248
|
+
this.readWaiter = null;
|
|
244
249
|
}
|
|
245
250
|
|
|
246
251
|
/**
|
|
@@ -318,21 +323,19 @@ class NTTCP {
|
|
|
318
323
|
send(buf) {
|
|
319
324
|
this.checkErr();
|
|
320
325
|
if (process.env.NODE_ORACLEDB_DEBUG_PACKETS)
|
|
321
|
-
this.printPacket(
|
|
326
|
+
this.printPacket(`Sending packet ${this.packetNum} on stream ${this.streamNum}`, buf);
|
|
322
327
|
const result = this.stream.write(buf, (err) => {
|
|
323
328
|
if (err) {
|
|
324
329
|
this.savedErr = err;
|
|
325
330
|
this.err = true;
|
|
326
|
-
|
|
327
|
-
this.waiter();
|
|
328
|
-
this.waiter = null;
|
|
329
|
-
}
|
|
331
|
+
this._notifyWaiters();
|
|
330
332
|
}
|
|
331
333
|
});
|
|
332
334
|
if (!result) {
|
|
333
335
|
this.needsDrain = true;
|
|
334
336
|
}
|
|
335
337
|
this.numPacketsSinceLastWait++;
|
|
338
|
+
this.packetNum++;
|
|
336
339
|
}
|
|
337
340
|
|
|
338
341
|
/**
|
|
@@ -353,11 +356,7 @@ class NTTCP {
|
|
|
353
356
|
this.checkErr();
|
|
354
357
|
if (this.needsDrain) {
|
|
355
358
|
await new Promise((resolve) => {
|
|
356
|
-
this.
|
|
357
|
-
this.stream.once('drain', () => {
|
|
358
|
-
resolve();
|
|
359
|
-
this.waiter = null;
|
|
360
|
-
});
|
|
359
|
+
this.drainWaiter = resolve;
|
|
361
360
|
});
|
|
362
361
|
this.checkErr();
|
|
363
362
|
} else {
|
|
@@ -400,15 +399,16 @@ class NTTCP {
|
|
|
400
399
|
const packet = {
|
|
401
400
|
buf: tempBuf.subarray(0, len),
|
|
402
401
|
type: tempBuf[4],
|
|
403
|
-
flags: tempBuf[5]
|
|
402
|
+
flags: tempBuf[5],
|
|
403
|
+
num : this.packetNum++
|
|
404
404
|
};
|
|
405
405
|
this.packets.push(packet);
|
|
406
|
-
if (this.
|
|
407
|
-
this.
|
|
408
|
-
this.
|
|
406
|
+
if (this.readWaiter) {
|
|
407
|
+
this.readWaiter();
|
|
408
|
+
this.readWaiter = null;
|
|
409
409
|
}
|
|
410
410
|
if (process.env.NODE_ORACLEDB_DEBUG_PACKETS)
|
|
411
|
-
this.printPacket(
|
|
411
|
+
this.printPacket(`Receiving packet ${packet.num} on stream ${this.streamNum}`, packet.buf);
|
|
412
412
|
|
|
413
413
|
// if the packet consumed all of the bytes (most common scenario), then
|
|
414
414
|
// simply clear the temporary buffer; otherwise, retain whatever bytes
|
|
@@ -442,7 +442,7 @@ class NTTCP {
|
|
|
442
442
|
if (this.packets.length === 0) {
|
|
443
443
|
this.checkErr();
|
|
444
444
|
await new Promise((resolve) => {
|
|
445
|
-
this.
|
|
445
|
+
this.readWaiter = resolve;
|
|
446
446
|
this.numPacketsSinceLastWait = 0;
|
|
447
447
|
});
|
|
448
448
|
this.checkErr();
|
|
@@ -478,26 +478,25 @@ class NTTCP {
|
|
|
478
478
|
this.stream.on('error', (err) => {
|
|
479
479
|
this.savedErr = err;
|
|
480
480
|
this.err = true;
|
|
481
|
-
|
|
482
|
-
this.waiter();
|
|
483
|
-
this.waiter = null;
|
|
484
|
-
}
|
|
481
|
+
this._notifyWaiters();
|
|
485
482
|
});
|
|
486
483
|
|
|
487
484
|
this.stream.on('end', () => {
|
|
488
485
|
this.err = true;
|
|
489
|
-
|
|
490
|
-
this.waiter();
|
|
491
|
-
this.waiter = null;
|
|
492
|
-
}
|
|
486
|
+
this._notifyWaiters();
|
|
493
487
|
});
|
|
494
488
|
|
|
495
489
|
this.stream.on('close', () => {
|
|
496
490
|
this.connected = false;
|
|
491
|
+
this._notifyWaiters();
|
|
497
492
|
});
|
|
498
493
|
|
|
499
494
|
this.stream.on('drain', () => {
|
|
500
495
|
this.needsDrain = false;
|
|
496
|
+
if (this.drainWaiter) {
|
|
497
|
+
this.drainWaiter();
|
|
498
|
+
this.drainWaiter = null;
|
|
499
|
+
}
|
|
501
500
|
});
|
|
502
501
|
|
|
503
502
|
}
|
|
@@ -522,6 +521,20 @@ class NTTCP {
|
|
|
522
521
|
}
|
|
523
522
|
}
|
|
524
523
|
|
|
524
|
+
/**
|
|
525
|
+
* Notify the waiters (drain and read) and reset them, if applicable.
|
|
526
|
+
*/
|
|
527
|
+
_notifyWaiters() {
|
|
528
|
+
if (this.drainWaiter) {
|
|
529
|
+
this.drainWaiter();
|
|
530
|
+
this.drainWaiter = null;
|
|
531
|
+
}
|
|
532
|
+
if (this.readWaiter) {
|
|
533
|
+
this.readWaiter();
|
|
534
|
+
this.readWaiter = null;
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
|
|
525
538
|
}
|
|
526
539
|
|
|
527
540
|
module.exports = NTTCP;
|
|
@@ -52,7 +52,7 @@ function ConnectPacket(connectData, sAtts, flags = 0) {
|
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
/* Building Connect Packet */
|
|
55
|
-
this.buf = Buffer.
|
|
55
|
+
this.buf = Buffer.allocUnsafe(size).fill(0);
|
|
56
56
|
this.buf.writeUInt16BE(size, constants.NSPHDLEN);
|
|
57
57
|
this.buf.writeUInt8(flags, constants.NSPHDFLGS);
|
|
58
58
|
this.buf.writeUInt8(constants.NSPTCN, constants.NSPHDTYP);
|
|
@@ -142,24 +142,24 @@ function ConnectPacket(connectData, sAtts, flags = 0) {
|
|
|
142
142
|
* @param {int} size of Data Packet
|
|
143
143
|
* @param {boolean} isLargeSDU Large SDU
|
|
144
144
|
*/
|
|
145
|
-
function DataPacket(
|
|
145
|
+
function DataPacket(isLargeSDU) {
|
|
146
146
|
this.dataPtr = 0; /* data offset start */
|
|
147
147
|
this.dataLen = 0; /* data offset end */
|
|
148
|
-
this.bufLen = size; /* Length of buffer */
|
|
149
148
|
this.offset = 0; /* Offset for buffer read/write (fastpath) */
|
|
150
149
|
this.len = 0; /* Length of buffer read/write (fastpath) */
|
|
150
|
+
this.bufLen = 0; /* Length of buffer */
|
|
151
151
|
|
|
152
152
|
/**
|
|
153
153
|
* Create the Data Packet(Internal)
|
|
154
154
|
*/
|
|
155
|
-
this.createPacket = function() {
|
|
155
|
+
this.createPacket = function(len) {
|
|
156
156
|
/* Building Data Packet */
|
|
157
157
|
this.dataPtr = constants.NSPDADAT;
|
|
158
158
|
this.dataLen = constants.NSPDADAT;
|
|
159
|
-
|
|
160
|
-
this.buf = Buffer.alloc(size);
|
|
159
|
+
this.buf = Buffer.allocUnsafe(len).fill(0);
|
|
161
160
|
this.buf.writeUInt8(0, constants.NSPHDFLGS);
|
|
162
161
|
this.buf.writeUInt8(constants.NSPTDA, constants.NSPHDTYP);
|
|
162
|
+
this.bufLen = len; /* Length of buffer */
|
|
163
163
|
};
|
|
164
164
|
|
|
165
165
|
/**
|
|
@@ -173,7 +173,7 @@ function DataPacket(size, isLargeSDU) {
|
|
|
173
173
|
let bytes2Copy;
|
|
174
174
|
|
|
175
175
|
if (!this.buf) {
|
|
176
|
-
this.createPacket();
|
|
176
|
+
this.createPacket(len + constants.NSPDADAT); //Currently NS data packets are being used only in the connect/disconnect phase
|
|
177
177
|
}
|
|
178
178
|
|
|
179
179
|
if (len > this.bufLen - this.dataLen) {
|
|
@@ -377,7 +377,7 @@ function ControlPacket() {
|
|
|
377
377
|
} else if (err1 == NSESENDMESG) {
|
|
378
378
|
this.errno = err1;
|
|
379
379
|
this.notifLen = err2;
|
|
380
|
-
this.notif = Buffer.
|
|
380
|
+
this.notif = Buffer.allocUnsafe(err2 + 1).fill(0);
|
|
381
381
|
this.buf.copy(this.notif, 0, constants.NSPCTLDAT + 12, constants.NSPCTLDAT + 12 + err2);
|
|
382
382
|
} else {
|
|
383
383
|
this.errno = err1;
|