react-native-nitro-net 0.5.1 → 0.5.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/android/libs/arm64-v8a/librust_c_net.so +0 -0
- package/android/libs/armeabi-v7a/librust_c_net.so +0 -0
- package/android/libs/x86/librust_c_net.so +0 -0
- package/android/libs/x86_64/librust_c_net.so +0 -0
- package/cpp/HybridNetDriver.hpp +17 -0
- package/cpp/NetManager.hpp +40 -69
- package/ios/Frameworks/RustCNet.xcframework/ios-arm64/RustCNet.framework/RustCNet +0 -0
- package/ios/Frameworks/RustCNet.xcframework/ios-arm64_x86_64-simulator/RustCNet.framework/RustCNet +0 -0
- package/lib/http.d.ts +3 -0
- package/lib/http.d.ts.map +1 -1
- package/lib/http.js +182 -61
- package/lib/net.d.ts +2 -3
- package/lib/net.d.ts.map +1 -1
- package/lib/net.js +61 -15
- package/package.json +2 -1
- package/react-native-nitro-net.podspec +2 -2
- package/src/http.ts +183 -59
- package/src/net.ts +62 -18
package/src/net.ts
CHANGED
|
@@ -91,6 +91,10 @@ function initWithConfig(config: NetConfig): void {
|
|
|
91
91
|
if (config.debug !== undefined) {
|
|
92
92
|
setVerbose(config.debug);
|
|
93
93
|
}
|
|
94
|
+
// Inject dispatcher for async events to avoid thread starvation/deadlocks
|
|
95
|
+
if ((Driver as any).installDispatcher) {
|
|
96
|
+
(Driver as any).installDispatcher();
|
|
97
|
+
}
|
|
94
98
|
Driver.initWithConfig(config);
|
|
95
99
|
}
|
|
96
100
|
|
|
@@ -296,6 +300,7 @@ export class Socket extends Duplex {
|
|
|
296
300
|
public autoSelectFamilyAttemptedAddresses: string[] = [];
|
|
297
301
|
private _autoSelectFamily: boolean = false;
|
|
298
302
|
private _timeout: number = 0;
|
|
303
|
+
private _nativeWriteCallbacks: Array<(error?: Error | null) => void> = [];
|
|
299
304
|
|
|
300
305
|
get localFamily(): string {
|
|
301
306
|
return this.localAddress && this.localAddress.includes(':') ? 'IPv6' : 'IPv4';
|
|
@@ -333,9 +338,8 @@ export class Socket extends Duplex {
|
|
|
333
338
|
this._setupEvents();
|
|
334
339
|
// Enable noDelay by default
|
|
335
340
|
this._driver.setNoDelay(true);
|
|
336
|
-
//
|
|
337
|
-
|
|
338
|
-
// Emit connect for server-side socket? No, it's already connected.
|
|
341
|
+
// For accepted server sockets, defer resume until after the server
|
|
342
|
+
// emits 'connection' so user handlers can attach first.
|
|
339
343
|
} else {
|
|
340
344
|
// New client socket
|
|
341
345
|
ensureInitialized();
|
|
@@ -355,8 +359,8 @@ export class Socket extends Duplex {
|
|
|
355
359
|
return this;
|
|
356
360
|
}
|
|
357
361
|
const ret = super.on(event, listener);
|
|
358
|
-
if (event === 'data' &&
|
|
359
|
-
debugLog(`Socket on('data'), flowing: ${(this as any).readableFlowing}`);
|
|
362
|
+
if (event === 'data' && (this as any).readableFlowing !== true) {
|
|
363
|
+
debugLog(`Socket on('data'), flowing: ${(this as any).readableFlowing}, paused: ${this.isPaused()}`);
|
|
360
364
|
this.resume();
|
|
361
365
|
}
|
|
362
366
|
return ret;
|
|
@@ -392,8 +396,10 @@ export class Socket extends Duplex {
|
|
|
392
396
|
if (data && data.byteLength > 0) {
|
|
393
397
|
const buffer = Buffer.from(data);
|
|
394
398
|
this.bytesRead += buffer.length;
|
|
395
|
-
|
|
396
|
-
|
|
399
|
+
this.push(buffer);
|
|
400
|
+
if (this.listenerCount('data') > 0 && (this as any).readableFlowing !== true) {
|
|
401
|
+
debugLog(`Socket onEvent(DATA) restoring flowing mode for attached 'data' listeners`);
|
|
402
|
+
this.resume();
|
|
397
403
|
}
|
|
398
404
|
}
|
|
399
405
|
break;
|
|
@@ -422,6 +428,11 @@ export class Socket extends Duplex {
|
|
|
422
428
|
this._connected = false;
|
|
423
429
|
this.connecting = false;
|
|
424
430
|
this.push(null); // EOF
|
|
431
|
+
if (!(this as any).allowHalfOpen && !this.writableEnded && !this.destroyed) {
|
|
432
|
+
// Match Node's default behavior: half-close the writable side
|
|
433
|
+
// when the peer finishes and allowHalfOpen is false.
|
|
434
|
+
this.end();
|
|
435
|
+
}
|
|
425
436
|
this.emit('close', this._hadError);
|
|
426
437
|
break;
|
|
427
438
|
case NetSocketEvent.DRAIN:
|
|
@@ -582,18 +593,20 @@ export class Socket extends Duplex {
|
|
|
582
593
|
return this;
|
|
583
594
|
}
|
|
584
595
|
|
|
585
|
-
end(cb?: () => void): this;
|
|
586
|
-
end(chunk: any, cb?: () => void): this;
|
|
587
|
-
end(chunk: any, encoding: string, cb?: () => void): this;
|
|
588
596
|
end(chunk?: any, encoding?: any, cb?: any): this {
|
|
589
|
-
debugLog(`Socket (localPort: ${this.localPort}) .end() called`);
|
|
590
597
|
if (typeof chunk === 'function') {
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
} else {
|
|
595
|
-
|
|
598
|
+
cb = chunk;
|
|
599
|
+
chunk = null;
|
|
600
|
+
encoding = null;
|
|
601
|
+
} else if (typeof encoding === 'function') {
|
|
602
|
+
cb = encoding;
|
|
603
|
+
encoding = null;
|
|
604
|
+
}
|
|
605
|
+
debugLog(`Socket (localPort: ${this.localPort}) .end() called`);
|
|
606
|
+
if (chunk != null) {
|
|
607
|
+
this.write(chunk, encoding);
|
|
596
608
|
}
|
|
609
|
+
super.end(cb);
|
|
597
610
|
return this;
|
|
598
611
|
}
|
|
599
612
|
|
|
@@ -601,6 +614,19 @@ export class Socket extends Duplex {
|
|
|
601
614
|
if (!this._driver) {
|
|
602
615
|
return callback(new Error('Socket not connected'));
|
|
603
616
|
}
|
|
617
|
+
if (!this._connected && this.connecting) {
|
|
618
|
+
const onConnect = () => {
|
|
619
|
+
this.removeListener('error', onError);
|
|
620
|
+
this._write(chunk, encoding, callback);
|
|
621
|
+
};
|
|
622
|
+
const onError = (err: Error) => {
|
|
623
|
+
this.removeListener('connect', onConnect);
|
|
624
|
+
callback(err);
|
|
625
|
+
};
|
|
626
|
+
this.once('connect', onConnect);
|
|
627
|
+
this.once('error', onError);
|
|
628
|
+
return;
|
|
629
|
+
}
|
|
604
630
|
try {
|
|
605
631
|
const buffer = (chunk instanceof Buffer) ? chunk : Buffer.from(chunk, encoding as any);
|
|
606
632
|
this.bytesWritten += buffer.length;
|
|
@@ -618,9 +644,24 @@ export class Socket extends Duplex {
|
|
|
618
644
|
}
|
|
619
645
|
|
|
620
646
|
_final(callback: (error?: Error | null) => void): void {
|
|
621
|
-
if (this._driver) {
|
|
622
|
-
|
|
647
|
+
if (!this._driver) {
|
|
648
|
+
return callback(null);
|
|
649
|
+
}
|
|
650
|
+
if (!this._connected && this.connecting) {
|
|
651
|
+
const onConnect = () => {
|
|
652
|
+
this.removeListener('error', onError);
|
|
653
|
+
this._final(callback);
|
|
654
|
+
};
|
|
655
|
+
const onError = () => {
|
|
656
|
+
this.removeListener('connect', onConnect);
|
|
657
|
+
callback(null); // Already destroyed/errored
|
|
658
|
+
};
|
|
659
|
+
this.once('connect', onConnect);
|
|
660
|
+
this.once('error', onError);
|
|
661
|
+
return;
|
|
623
662
|
}
|
|
663
|
+
debugLog(`Socket (localPort: ${this.localPort}) ._final() called, shutting down driver`);
|
|
664
|
+
this._driver.shutdown();
|
|
624
665
|
callback(null);
|
|
625
666
|
}
|
|
626
667
|
|
|
@@ -832,6 +873,9 @@ export class Server extends EventEmitter {
|
|
|
832
873
|
this._sockets.delete(socket);
|
|
833
874
|
});
|
|
834
875
|
this.emit('connection', socket);
|
|
876
|
+
// Start reading only after 'connection' handlers ran.
|
|
877
|
+
// This prevents dropping data when listeners are attached in the callback.
|
|
878
|
+
socket.resume();
|
|
835
879
|
}
|
|
836
880
|
}
|
|
837
881
|
break;
|