react-native-nitro-net 0.2.0 → 0.3.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/README.md +70 -12
- 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/HybridHttpParser.hpp +67 -0
- package/cpp/HybridNetDriver.hpp +6 -0
- package/cpp/HybridNetServerDriver.hpp +7 -0
- package/cpp/HybridNetSocketDriver.hpp +27 -0
- package/cpp/NetBindings.hpp +15 -0
- package/ios/Frameworks/RustCNet.xcframework/Info.plist +5 -5
- 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/Net.nitro.d.ts +19 -0
- package/lib/http.d.ts +203 -0
- package/lib/http.js +1138 -0
- package/lib/https.d.ts +24 -0
- package/lib/https.js +144 -0
- package/lib/index.d.ts +46 -8
- package/lib/index.js +133 -26
- package/lib/tls.d.ts +21 -0
- package/lib/tls.js +74 -4
- package/nitrogen/generated/android/RustCNet+autolinking.cmake +2 -0
- package/nitrogen/generated/android/RustCNetOnLoad.cpp +2 -0
- package/nitrogen/generated/android/c++/JHybridHttpParserSpec.cpp +54 -0
- package/nitrogen/generated/android/c++/JHybridHttpParserSpec.hpp +65 -0
- package/nitrogen/generated/android/c++/JHybridNetDriverSpec.cpp +9 -0
- package/nitrogen/generated/android/c++/JHybridNetDriverSpec.hpp +1 -0
- package/nitrogen/generated/android/c++/JHybridNetServerDriverSpec.cpp +4 -0
- package/nitrogen/generated/android/c++/JHybridNetServerDriverSpec.hpp +1 -0
- package/nitrogen/generated/android/c++/JHybridNetSocketDriverSpec.cpp +9 -0
- package/nitrogen/generated/android/c++/JHybridNetSocketDriverSpec.hpp +2 -0
- package/nitrogen/generated/android/c++/JNetConfig.hpp +7 -3
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/net/HybridHttpParserSpec.kt +58 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/net/HybridNetDriverSpec.kt +4 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/net/HybridNetServerDriverSpec.kt +4 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/net/HybridNetSocketDriverSpec.kt +8 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/net/NetConfig.kt +6 -3
- package/nitrogen/generated/ios/RustCNet-Swift-Cxx-Bridge.cpp +17 -0
- package/nitrogen/generated/ios/RustCNet-Swift-Cxx-Bridge.hpp +26 -0
- package/nitrogen/generated/ios/RustCNet-Swift-Cxx-Umbrella.hpp +5 -0
- package/nitrogen/generated/ios/c++/HybridHttpParserSpecSwift.cpp +11 -0
- package/nitrogen/generated/ios/c++/HybridHttpParserSpecSwift.hpp +79 -0
- package/nitrogen/generated/ios/c++/HybridNetDriverSpecSwift.hpp +11 -0
- package/nitrogen/generated/ios/c++/HybridNetServerDriverSpecSwift.hpp +6 -0
- package/nitrogen/generated/ios/c++/HybridNetSocketDriverSpecSwift.hpp +14 -0
- package/nitrogen/generated/ios/swift/HybridHttpParserSpec.swift +56 -0
- package/nitrogen/generated/ios/swift/HybridHttpParserSpec_cxx.swift +131 -0
- package/nitrogen/generated/ios/swift/HybridNetDriverSpec.swift +1 -0
- package/nitrogen/generated/ios/swift/HybridNetDriverSpec_cxx.swift +15 -0
- package/nitrogen/generated/ios/swift/HybridNetServerDriverSpec.swift +1 -0
- package/nitrogen/generated/ios/swift/HybridNetServerDriverSpec_cxx.swift +11 -0
- package/nitrogen/generated/ios/swift/HybridNetSocketDriverSpec.swift +2 -0
- package/nitrogen/generated/ios/swift/HybridNetSocketDriverSpec_cxx.swift +36 -0
- package/nitrogen/generated/ios/swift/NetConfig.swift +19 -1
- package/nitrogen/generated/shared/c++/HybridHttpParserSpec.cpp +21 -0
- package/nitrogen/generated/shared/c++/HybridHttpParserSpec.hpp +63 -0
- package/nitrogen/generated/shared/c++/HybridNetDriverSpec.cpp +1 -0
- package/nitrogen/generated/shared/c++/HybridNetDriverSpec.hpp +4 -0
- package/nitrogen/generated/shared/c++/HybridNetServerDriverSpec.cpp +1 -0
- package/nitrogen/generated/shared/c++/HybridNetServerDriverSpec.hpp +1 -0
- package/nitrogen/generated/shared/c++/HybridNetSocketDriverSpec.cpp +2 -0
- package/nitrogen/generated/shared/c++/HybridNetSocketDriverSpec.hpp +2 -0
- package/nitrogen/generated/shared/c++/NetConfig.hpp +6 -2
- package/package.json +3 -3
- package/src/Net.nitro.ts +17 -0
- package/src/http.ts +1304 -0
- package/src/https.ts +127 -0
- package/src/index.ts +149 -18
- package/src/tls.ts +82 -6
package/lib/https.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import * as http from './http';
|
|
2
|
+
import * as tls from './tls';
|
|
3
|
+
import { IncomingMessage } from './http';
|
|
4
|
+
export declare class Server extends tls.Server {
|
|
5
|
+
private _httpConnections;
|
|
6
|
+
maxHeaderSize: number;
|
|
7
|
+
maxRequestsPerSocket: number;
|
|
8
|
+
headersTimeout: number;
|
|
9
|
+
requestTimeout: number;
|
|
10
|
+
keepAliveTimeout: number;
|
|
11
|
+
constructor(options?: any, requestListener?: (req: http.IncomingMessage, res: http.ServerResponse) => void);
|
|
12
|
+
setTimeout(ms: number, callback?: () => void): this;
|
|
13
|
+
}
|
|
14
|
+
export declare function createServer(options?: any, requestListener?: (req: http.IncomingMessage, res: http.ServerResponse) => void): Server;
|
|
15
|
+
export declare class ClientRequest extends http.ClientRequest {
|
|
16
|
+
constructor(options: any, callback?: (res: http.IncomingMessage) => void);
|
|
17
|
+
}
|
|
18
|
+
export declare function request(urlOrOptions: string | URL | http.RequestOptions, optionsOrCallback?: http.RequestOptions | ((res: http.IncomingMessage) => void), callback?: (res: http.IncomingMessage) => void): ClientRequest;
|
|
19
|
+
export declare function get(urlOrOptions: string | URL | http.RequestOptions, optionsOrCallback?: http.RequestOptions | ((res: http.IncomingMessage) => void), callback?: (res: http.IncomingMessage) => void): ClientRequest;
|
|
20
|
+
export declare class Agent extends http.Agent {
|
|
21
|
+
constructor(options?: any);
|
|
22
|
+
}
|
|
23
|
+
export declare const globalAgent: Agent;
|
|
24
|
+
export { IncomingMessage };
|
package/lib/https.js
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.IncomingMessage = exports.globalAgent = exports.Agent = exports.ClientRequest = exports.Server = void 0;
|
|
37
|
+
exports.createServer = createServer;
|
|
38
|
+
exports.request = request;
|
|
39
|
+
exports.get = get;
|
|
40
|
+
const http = __importStar(require("./http"));
|
|
41
|
+
const tls = __importStar(require("./tls"));
|
|
42
|
+
const http_1 = require("./http");
|
|
43
|
+
Object.defineProperty(exports, "IncomingMessage", { enumerable: true, get: function () { return http_1.IncomingMessage; } });
|
|
44
|
+
// ========== Server ==========
|
|
45
|
+
class Server extends tls.Server {
|
|
46
|
+
constructor(options, requestListener) {
|
|
47
|
+
if (typeof options === 'function') {
|
|
48
|
+
requestListener = options;
|
|
49
|
+
options = {};
|
|
50
|
+
}
|
|
51
|
+
super(options);
|
|
52
|
+
this._httpConnections = new Set();
|
|
53
|
+
this.maxHeaderSize = 16384;
|
|
54
|
+
this.maxRequestsPerSocket = 0;
|
|
55
|
+
this.headersTimeout = 60000;
|
|
56
|
+
this.requestTimeout = 300000;
|
|
57
|
+
this.keepAliveTimeout = 5000;
|
|
58
|
+
if (requestListener) {
|
|
59
|
+
this.on('request', requestListener);
|
|
60
|
+
}
|
|
61
|
+
// Initialize HTTP connection setup for secure connections
|
|
62
|
+
this.on('secureConnection', (socket) => {
|
|
63
|
+
// @ts-ignore - access internal http logic
|
|
64
|
+
http.Server.prototype._setupHttpConnection.call(this, socket);
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
setTimeout(ms, callback) {
|
|
68
|
+
// @ts-ignore - access netServer via super's internal or cast
|
|
69
|
+
this._netServer.setTimeout(ms, callback);
|
|
70
|
+
return this;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
exports.Server = Server;
|
|
74
|
+
function createServer(options, requestListener) {
|
|
75
|
+
return new Server(options, requestListener);
|
|
76
|
+
}
|
|
77
|
+
// ========== ClientRequest ==========
|
|
78
|
+
class ClientRequest extends http.ClientRequest {
|
|
79
|
+
constructor(options, callback) {
|
|
80
|
+
if (typeof options === 'string') {
|
|
81
|
+
options = new URL(options);
|
|
82
|
+
}
|
|
83
|
+
if (options instanceof URL) {
|
|
84
|
+
options = {
|
|
85
|
+
protocol: options.protocol,
|
|
86
|
+
hostname: options.hostname,
|
|
87
|
+
path: options.pathname + options.search,
|
|
88
|
+
port: options.port ? parseInt(options.port) : 443
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
options.protocol = 'https:';
|
|
92
|
+
super(options, callback);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
exports.ClientRequest = ClientRequest;
|
|
96
|
+
function request(urlOrOptions, optionsOrCallback, callback) {
|
|
97
|
+
let opts = {};
|
|
98
|
+
let cb = callback;
|
|
99
|
+
if (typeof urlOrOptions === 'string') {
|
|
100
|
+
const url = new URL(urlOrOptions);
|
|
101
|
+
opts = {
|
|
102
|
+
protocol: url.protocol,
|
|
103
|
+
hostname: url.hostname,
|
|
104
|
+
path: url.pathname + url.search,
|
|
105
|
+
port: url.port ? parseInt(url.port) : 443
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
else if (urlOrOptions instanceof URL) {
|
|
109
|
+
opts = {
|
|
110
|
+
protocol: urlOrOptions.protocol,
|
|
111
|
+
hostname: urlOrOptions.hostname,
|
|
112
|
+
path: urlOrOptions.pathname + urlOrOptions.search,
|
|
113
|
+
port: urlOrOptions.port ? parseInt(urlOrOptions.port) : 443
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
opts = { ...urlOrOptions };
|
|
118
|
+
}
|
|
119
|
+
if (typeof optionsOrCallback === 'function') {
|
|
120
|
+
cb = optionsOrCallback;
|
|
121
|
+
}
|
|
122
|
+
else if (optionsOrCallback) {
|
|
123
|
+
opts = { ...opts, ...optionsOrCallback };
|
|
124
|
+
}
|
|
125
|
+
opts.protocol = 'https:';
|
|
126
|
+
return new ClientRequest(opts, cb);
|
|
127
|
+
}
|
|
128
|
+
function get(urlOrOptions, optionsOrCallback, callback) {
|
|
129
|
+
const req = request(urlOrOptions, optionsOrCallback, callback);
|
|
130
|
+
req.end();
|
|
131
|
+
return req;
|
|
132
|
+
}
|
|
133
|
+
// ========== Agent ==========
|
|
134
|
+
class Agent extends http.Agent {
|
|
135
|
+
constructor(options) {
|
|
136
|
+
super(options);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
exports.Agent = Agent;
|
|
140
|
+
exports.globalAgent = new Agent({
|
|
141
|
+
keepAlive: true,
|
|
142
|
+
scheduling: 'lifo',
|
|
143
|
+
timeout: 5000,
|
|
144
|
+
});
|
package/lib/index.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ import type { NetSocketDriver, NetConfig } from './Net.nitro';
|
|
|
4
4
|
declare function isIP(input: string): number;
|
|
5
5
|
declare function isIPv4(input: string): boolean;
|
|
6
6
|
declare function isIPv6(input: string): boolean;
|
|
7
|
+
declare function isVerbose(): boolean;
|
|
7
8
|
declare function setVerbose(enabled: boolean): void;
|
|
8
9
|
declare function getDefaultAutoSelectFamily(): number;
|
|
9
10
|
declare function setDefaultAutoSelectFamily(family: number): void;
|
|
@@ -23,24 +24,56 @@ declare function setDefaultAutoSelectFamily(family: number): void;
|
|
|
23
24
|
* ```
|
|
24
25
|
*/
|
|
25
26
|
declare function initWithConfig(config: NetConfig): void;
|
|
27
|
+
export interface SocketAddressOptions {
|
|
28
|
+
address?: string;
|
|
29
|
+
family?: 'ipv4' | 'ipv6';
|
|
30
|
+
port?: number;
|
|
31
|
+
flowlabel?: number;
|
|
32
|
+
}
|
|
26
33
|
export declare class SocketAddress {
|
|
27
34
|
readonly address: string;
|
|
28
35
|
readonly family: 'ipv4' | 'ipv6';
|
|
29
36
|
readonly port: number;
|
|
30
37
|
readonly flowlabel: number;
|
|
31
|
-
constructor(options
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
38
|
+
constructor(options?: SocketAddressOptions);
|
|
39
|
+
/**
|
|
40
|
+
* Attempts to parse a string containing a socket address.
|
|
41
|
+
* Returns a SocketAddress if successful, or undefined if not.
|
|
42
|
+
*
|
|
43
|
+
* Supported formats:
|
|
44
|
+
* - `ip:port` (e.g., `127.0.0.1:8080`, `[::1]:8080`)
|
|
45
|
+
* - `ip` only (port defaults to 0)
|
|
46
|
+
*/
|
|
47
|
+
static parse(input: string): SocketAddress | undefined;
|
|
48
|
+
}
|
|
49
|
+
export interface BlockListRule {
|
|
50
|
+
type: 'address' | 'range' | 'subnet';
|
|
51
|
+
address?: string;
|
|
52
|
+
start?: string;
|
|
53
|
+
end?: string;
|
|
54
|
+
prefix?: number;
|
|
55
|
+
family: 'ipv4' | 'ipv6';
|
|
37
56
|
}
|
|
38
57
|
export declare class BlockList {
|
|
39
58
|
private _rules;
|
|
59
|
+
/** Returns an array of rules added to the blocklist. */
|
|
60
|
+
get rules(): BlockListRule[];
|
|
40
61
|
addAddress(address: string, family?: 'ipv4' | 'ipv6'): void;
|
|
41
62
|
addRange(start: string, end: string, family?: 'ipv4' | 'ipv6'): void;
|
|
42
63
|
addSubnet(net: string, prefix: number, family?: 'ipv4' | 'ipv6'): void;
|
|
43
64
|
check(address: string, family?: 'ipv4' | 'ipv6'): boolean;
|
|
65
|
+
/**
|
|
66
|
+
* Serializes the BlockList to a JSON-compatible format.
|
|
67
|
+
*/
|
|
68
|
+
toJSON(): BlockListRule[];
|
|
69
|
+
/**
|
|
70
|
+
* Creates a BlockList from a JSON array of rules.
|
|
71
|
+
*/
|
|
72
|
+
static fromJSON(json: BlockListRule[]): BlockList;
|
|
73
|
+
/**
|
|
74
|
+
* Checks if a given value is a BlockList instance.
|
|
75
|
+
*/
|
|
76
|
+
static isBlockList(value: unknown): value is BlockList;
|
|
44
77
|
}
|
|
45
78
|
export interface SocketOptions extends DuplexOptions {
|
|
46
79
|
fd?: any;
|
|
@@ -65,6 +98,7 @@ export declare class Socket extends Duplex {
|
|
|
65
98
|
bytesWritten: number;
|
|
66
99
|
autoSelectFamilyAttemptedAddresses: string[];
|
|
67
100
|
private _autoSelectFamily;
|
|
101
|
+
private _timeout;
|
|
68
102
|
get localFamily(): string;
|
|
69
103
|
get readyState(): string;
|
|
70
104
|
get pending(): boolean;
|
|
@@ -110,7 +144,7 @@ export declare class Socket extends Duplex {
|
|
|
110
144
|
* Use 'utf8', 'hex', etc.
|
|
111
145
|
*/
|
|
112
146
|
setEncoding(encoding: BufferEncoding): this;
|
|
113
|
-
get timeout(): number
|
|
147
|
+
get timeout(): number;
|
|
114
148
|
get bufferSize(): number;
|
|
115
149
|
resetAndDestroy(): this;
|
|
116
150
|
}
|
|
@@ -142,7 +176,9 @@ export declare function createConnection(options: any, connectionListener?: () =
|
|
|
142
176
|
export declare const connect: typeof createConnection;
|
|
143
177
|
export declare function createServer(options?: any, connectionListener?: (socket: Socket) => void): Server;
|
|
144
178
|
export * as tls from './tls';
|
|
145
|
-
export
|
|
179
|
+
export * as http from './http';
|
|
180
|
+
export * as https from './https';
|
|
181
|
+
export { isIP, isIPv4, isIPv6, getDefaultAutoSelectFamily, setDefaultAutoSelectFamily, isVerbose, setVerbose, initWithConfig, };
|
|
146
182
|
export type { NetConfig };
|
|
147
183
|
declare const _default: {
|
|
148
184
|
Socket: typeof Socket;
|
|
@@ -159,5 +195,7 @@ declare const _default: {
|
|
|
159
195
|
setDefaultAutoSelectFamily: typeof setDefaultAutoSelectFamily;
|
|
160
196
|
setVerbose: typeof setVerbose;
|
|
161
197
|
initWithConfig: typeof initWithConfig;
|
|
198
|
+
http: any;
|
|
199
|
+
https: any;
|
|
162
200
|
};
|
|
163
201
|
export default _default;
|
package/lib/index.js
CHANGED
|
@@ -33,7 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.tls = exports.connect = exports.Server = exports.Socket = exports.BlockList = exports.SocketAddress = void 0;
|
|
36
|
+
exports.https = exports.http = exports.tls = exports.connect = exports.Server = exports.Socket = exports.BlockList = exports.SocketAddress = void 0;
|
|
37
37
|
exports.createConnection = createConnection;
|
|
38
38
|
exports.createServer = createServer;
|
|
39
39
|
exports.isIP = isIP;
|
|
@@ -41,6 +41,7 @@ exports.isIPv4 = isIPv4;
|
|
|
41
41
|
exports.isIPv6 = isIPv6;
|
|
42
42
|
exports.getDefaultAutoSelectFamily = getDefaultAutoSelectFamily;
|
|
43
43
|
exports.setDefaultAutoSelectFamily = setDefaultAutoSelectFamily;
|
|
44
|
+
exports.isVerbose = isVerbose;
|
|
44
45
|
exports.setVerbose = setVerbose;
|
|
45
46
|
exports.initWithConfig = initWithConfig;
|
|
46
47
|
const readable_stream_1 = require("readable-stream");
|
|
@@ -74,14 +75,18 @@ function isIPv6(input) {
|
|
|
74
75
|
let _autoSelectFamilyDefault = 4; // Node default is usually 4/6 independent, but we mock it.
|
|
75
76
|
let _isVerbose = false;
|
|
76
77
|
let _isInitialized = false;
|
|
77
|
-
function
|
|
78
|
-
|
|
79
|
-
console.log(`[NET DEBUG] ${message}`);
|
|
80
|
-
}
|
|
78
|
+
function isVerbose() {
|
|
79
|
+
return _isVerbose;
|
|
81
80
|
}
|
|
82
81
|
function setVerbose(enabled) {
|
|
83
82
|
_isVerbose = enabled;
|
|
84
83
|
}
|
|
84
|
+
function debugLog(message) {
|
|
85
|
+
if (_isVerbose) {
|
|
86
|
+
const timestamp = new Date().toISOString().split('T')[1].split('Z')[0];
|
|
87
|
+
console.log(`[NET DEBUG ${timestamp}] ${message}`);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
85
90
|
function getDefaultAutoSelectFamily() {
|
|
86
91
|
return _autoSelectFamilyDefault;
|
|
87
92
|
}
|
|
@@ -116,29 +121,84 @@ function ensureInitialized() {
|
|
|
116
121
|
*/
|
|
117
122
|
function initWithConfig(config) {
|
|
118
123
|
_isInitialized = true;
|
|
124
|
+
if (config.debug !== undefined) {
|
|
125
|
+
setVerbose(config.debug);
|
|
126
|
+
}
|
|
119
127
|
Driver_1.Driver.initWithConfig(config);
|
|
120
128
|
}
|
|
121
|
-
// -----------------------------------------------------------------------------
|
|
122
|
-
// SocketAddress
|
|
123
|
-
// -----------------------------------------------------------------------------
|
|
124
|
-
// SocketAddress
|
|
125
|
-
// -----------------------------------------------------------------------------
|
|
126
129
|
class SocketAddress {
|
|
127
|
-
constructor(options) {
|
|
128
|
-
this.address = options.address;
|
|
129
|
-
this.family = options.family || (isIPv6(
|
|
130
|
-
this.port = options.port;
|
|
131
|
-
this.flowlabel = options.flowlabel
|
|
130
|
+
constructor(options = {}) {
|
|
131
|
+
this.address = options.address ?? (options.family === 'ipv6' ? '::' : '127.0.0.1');
|
|
132
|
+
this.family = options.family || (isIPv6(this.address) ? 'ipv6' : 'ipv4');
|
|
133
|
+
this.port = options.port ?? 0;
|
|
134
|
+
this.flowlabel = options.flowlabel ?? 0;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Attempts to parse a string containing a socket address.
|
|
138
|
+
* Returns a SocketAddress if successful, or undefined if not.
|
|
139
|
+
*
|
|
140
|
+
* Supported formats:
|
|
141
|
+
* - `ip:port` (e.g., `127.0.0.1:8080`, `[::1]:8080`)
|
|
142
|
+
* - `ip` only (port defaults to 0)
|
|
143
|
+
*/
|
|
144
|
+
static parse(input) {
|
|
145
|
+
if (!input || typeof input !== 'string')
|
|
146
|
+
return undefined;
|
|
147
|
+
let address;
|
|
148
|
+
let port = 0;
|
|
149
|
+
// Handle IPv6 bracket notation: [::1]:port
|
|
150
|
+
const ipv6Match = input.match(/^\[([^\]]+)\]:?(\d*)$/);
|
|
151
|
+
if (ipv6Match) {
|
|
152
|
+
address = ipv6Match[1];
|
|
153
|
+
port = ipv6Match[2] ? parseInt(ipv6Match[2], 10) : 0;
|
|
154
|
+
if (!isIPv6(address))
|
|
155
|
+
return undefined;
|
|
156
|
+
return new SocketAddress({ address, port, family: 'ipv6' });
|
|
157
|
+
}
|
|
158
|
+
// Handle IPv4 or IPv6 without brackets
|
|
159
|
+
const lastColon = input.lastIndexOf(':');
|
|
160
|
+
if (lastColon === -1) {
|
|
161
|
+
// No port, just IP
|
|
162
|
+
address = input;
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
// Determine if the colon is a port separator or part of IPv6
|
|
166
|
+
const potentialPort = input.slice(lastColon + 1);
|
|
167
|
+
const potentialAddr = input.slice(0, lastColon);
|
|
168
|
+
if (/^\d+$/.test(potentialPort) && (isIPv4(potentialAddr) || isIPv6(potentialAddr))) {
|
|
169
|
+
address = potentialAddr;
|
|
170
|
+
port = parseInt(potentialPort, 10);
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
// It's an IPv6 address without port
|
|
174
|
+
address = input;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
const family = isIPv6(address) ? 'ipv6' : (isIPv4(address) ? 'ipv4' : undefined);
|
|
178
|
+
if (!family)
|
|
179
|
+
return undefined;
|
|
180
|
+
return new SocketAddress({ address, port, family });
|
|
132
181
|
}
|
|
133
182
|
}
|
|
134
183
|
exports.SocketAddress = SocketAddress;
|
|
135
|
-
// -----------------------------------------------------------------------------
|
|
136
|
-
// BlockList
|
|
137
|
-
// -----------------------------------------------------------------------------
|
|
138
184
|
class BlockList {
|
|
139
185
|
constructor() {
|
|
140
186
|
this._rules = [];
|
|
141
187
|
}
|
|
188
|
+
/** Returns an array of rules added to the blocklist. */
|
|
189
|
+
get rules() {
|
|
190
|
+
return this._rules.map(r => {
|
|
191
|
+
if (r.type === 'address') {
|
|
192
|
+
return { type: 'address', address: r.data.address, family: r.data.family };
|
|
193
|
+
}
|
|
194
|
+
else if (r.type === 'range') {
|
|
195
|
+
return { type: 'range', start: r.data.start, end: r.data.end, family: r.data.family };
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
return { type: 'subnet', address: r.data.net, prefix: r.data.prefix, family: r.data.family };
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
}
|
|
142
202
|
addAddress(address, family) {
|
|
143
203
|
this._rules.push({ type: 'address', data: { address, family: family || (isIPv6(address) ? 'ipv6' : 'ipv4') } });
|
|
144
204
|
}
|
|
@@ -173,6 +233,36 @@ class BlockList {
|
|
|
173
233
|
}
|
|
174
234
|
return false;
|
|
175
235
|
}
|
|
236
|
+
/**
|
|
237
|
+
* Serializes the BlockList to a JSON-compatible format.
|
|
238
|
+
*/
|
|
239
|
+
toJSON() {
|
|
240
|
+
return this.rules;
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Creates a BlockList from a JSON array of rules.
|
|
244
|
+
*/
|
|
245
|
+
static fromJSON(json) {
|
|
246
|
+
const list = new BlockList();
|
|
247
|
+
for (const rule of json) {
|
|
248
|
+
if (rule.type === 'address' && rule.address) {
|
|
249
|
+
list.addAddress(rule.address, rule.family);
|
|
250
|
+
}
|
|
251
|
+
else if (rule.type === 'range' && rule.start && rule.end) {
|
|
252
|
+
list.addRange(rule.start, rule.end, rule.family);
|
|
253
|
+
}
|
|
254
|
+
else if (rule.type === 'subnet' && rule.address && rule.prefix !== undefined) {
|
|
255
|
+
list.addSubnet(rule.address, rule.prefix, rule.family);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
return list;
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Checks if a given value is a BlockList instance.
|
|
262
|
+
*/
|
|
263
|
+
static isBlockList(value) {
|
|
264
|
+
return value instanceof BlockList;
|
|
265
|
+
}
|
|
176
266
|
}
|
|
177
267
|
exports.BlockList = BlockList;
|
|
178
268
|
function ipv4ToLong(ip) {
|
|
@@ -205,7 +295,9 @@ class Socket extends readable_stream_1.Duplex {
|
|
|
205
295
|
super({
|
|
206
296
|
allowHalfOpen: options?.allowHalfOpen ?? false,
|
|
207
297
|
readable: options?.readable ?? true,
|
|
208
|
-
writable: options?.writable ?? true
|
|
298
|
+
writable: options?.writable ?? true,
|
|
299
|
+
// @ts-ignore
|
|
300
|
+
autoDestroy: false
|
|
209
301
|
});
|
|
210
302
|
this.connecting = false; // Changed from private _connecting
|
|
211
303
|
this._connected = false;
|
|
@@ -214,11 +306,14 @@ class Socket extends readable_stream_1.Duplex {
|
|
|
214
306
|
this.bytesWritten = 0;
|
|
215
307
|
this.autoSelectFamilyAttemptedAddresses = [];
|
|
216
308
|
this._autoSelectFamily = false;
|
|
309
|
+
this._timeout = 0;
|
|
217
310
|
if (options?.socketDriver) {
|
|
218
311
|
// Wrapping existing socket (from Server)
|
|
219
312
|
this._driver = options.socketDriver;
|
|
220
313
|
this._connected = true;
|
|
221
314
|
this._setupEvents();
|
|
315
|
+
// Enable noDelay by default
|
|
316
|
+
this._driver.setNoDelay(true);
|
|
222
317
|
// Resume the socket since it starts paused on server-accept
|
|
223
318
|
this.resume();
|
|
224
319
|
// Emit connect for server-side socket? No, it's already connected.
|
|
@@ -228,8 +323,10 @@ class Socket extends readable_stream_1.Duplex {
|
|
|
228
323
|
ensureInitialized();
|
|
229
324
|
this._driver = Driver_1.Driver.createSocket();
|
|
230
325
|
this._setupEvents();
|
|
231
|
-
//
|
|
232
|
-
this.
|
|
326
|
+
// Enable noDelay by default to match Node.js and reduce latency for small writes
|
|
327
|
+
this._driver.setNoDelay(true);
|
|
328
|
+
// Do NOT resume here - socket is not connected yet!
|
|
329
|
+
// resume() will be called after 'connect' event in _connect()
|
|
233
330
|
}
|
|
234
331
|
this.on('finish', () => {
|
|
235
332
|
// Writable side finished
|
|
@@ -268,6 +365,8 @@ class Socket extends readable_stream_1.Duplex {
|
|
|
268
365
|
this.connecting = false;
|
|
269
366
|
this._connected = true;
|
|
270
367
|
this._updateAddresses();
|
|
368
|
+
// Now that we're connected, start receiving data
|
|
369
|
+
this.resume();
|
|
271
370
|
this.emit('connect');
|
|
272
371
|
this.emit('ready');
|
|
273
372
|
break;
|
|
@@ -407,6 +506,7 @@ class Socket extends readable_stream_1.Duplex {
|
|
|
407
506
|
else {
|
|
408
507
|
this._autoSelectFamily = true;
|
|
409
508
|
}
|
|
509
|
+
debugLog(`Socket.connect: target=${host}:${port}, autoSelectFamily=${this._autoSelectFamily}`);
|
|
410
510
|
return this._connect(port, host, connectionListener, options.signal);
|
|
411
511
|
}
|
|
412
512
|
_connect(port, host, listener, signal) {
|
|
@@ -428,6 +528,7 @@ class Socket extends readable_stream_1.Duplex {
|
|
|
428
528
|
this.once('connect', () => signal.removeEventListener('abort', abortHandler));
|
|
429
529
|
this.once('close', () => signal.removeEventListener('abort', abortHandler));
|
|
430
530
|
}
|
|
531
|
+
debugLog(`Socket._connect: Calling driver.connect(${host}, ${port})`);
|
|
431
532
|
this._driver?.connect(host, port);
|
|
432
533
|
return this;
|
|
433
534
|
}
|
|
@@ -499,6 +600,7 @@ class Socket extends readable_stream_1.Duplex {
|
|
|
499
600
|
}
|
|
500
601
|
// Standard net.Socket methods
|
|
501
602
|
setTimeout(msecs, callback) {
|
|
603
|
+
this._timeout = msecs;
|
|
502
604
|
if (this._driver) {
|
|
503
605
|
this._driver.setTimeout(msecs);
|
|
504
606
|
}
|
|
@@ -521,12 +623,13 @@ class Socket extends readable_stream_1.Duplex {
|
|
|
521
623
|
* Resume reading after a call to pause().
|
|
522
624
|
*/
|
|
523
625
|
resume() {
|
|
524
|
-
const
|
|
525
|
-
|
|
626
|
+
const driver = this._driver;
|
|
627
|
+
const id = driver?.id;
|
|
628
|
+
debugLog(`Socket.resume() called, id: ${id === undefined ? 'none' : id}, destroyed: ${this.destroyed}`);
|
|
526
629
|
super.resume();
|
|
527
|
-
if (
|
|
630
|
+
if (driver) {
|
|
528
631
|
debugLog(`Socket.resume() calling driver.resume(), id: ${id}`);
|
|
529
|
-
|
|
632
|
+
driver.resume();
|
|
530
633
|
}
|
|
531
634
|
return this;
|
|
532
635
|
}
|
|
@@ -552,7 +655,7 @@ class Socket extends readable_stream_1.Duplex {
|
|
|
552
655
|
return this;
|
|
553
656
|
}
|
|
554
657
|
get timeout() {
|
|
555
|
-
return
|
|
658
|
+
return this._timeout;
|
|
556
659
|
}
|
|
557
660
|
get bufferSize() {
|
|
558
661
|
return 0; // Deprecated but often accessed
|
|
@@ -804,6 +907,8 @@ function createServer(options, connectionListener) {
|
|
|
804
907
|
return new Server(options, connectionListener);
|
|
805
908
|
}
|
|
806
909
|
exports.tls = __importStar(require("./tls"));
|
|
910
|
+
exports.http = __importStar(require("./http"));
|
|
911
|
+
exports.https = __importStar(require("./https"));
|
|
807
912
|
exports.default = {
|
|
808
913
|
Socket,
|
|
809
914
|
Server,
|
|
@@ -819,4 +924,6 @@ exports.default = {
|
|
|
819
924
|
setDefaultAutoSelectFamily,
|
|
820
925
|
setVerbose,
|
|
821
926
|
initWithConfig,
|
|
927
|
+
http: require('./http'),
|
|
928
|
+
https: require('./https'),
|
|
822
929
|
};
|
package/lib/tls.d.ts
CHANGED
|
@@ -26,6 +26,13 @@ export interface ConnectionOptions extends SocketOptions {
|
|
|
26
26
|
pfx?: string | ArrayBuffer;
|
|
27
27
|
passphrase?: string;
|
|
28
28
|
keylog?: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Custom hostname verification function.
|
|
31
|
+
* If provided, it will be called after the TLS handshake to verify the peer certificate.
|
|
32
|
+
* Return `undefined` if valid, or an `Error` if invalid.
|
|
33
|
+
* If not provided, the default `checkServerIdentity` is used.
|
|
34
|
+
*/
|
|
35
|
+
checkServerIdentity?: (hostname: string, cert: PeerCertificate) => Error | undefined;
|
|
29
36
|
}
|
|
30
37
|
export interface SecureContextOptions {
|
|
31
38
|
pfx?: string | ArrayBuffer;
|
|
@@ -70,6 +77,20 @@ export declare class TLSSocket extends Socket {
|
|
|
70
77
|
getSharedSigalgs(): string | undefined;
|
|
71
78
|
renegotiate(options: any, callback: (err: Error | null) => void): boolean;
|
|
72
79
|
disableRenegotiation(): void;
|
|
80
|
+
/**
|
|
81
|
+
* Enables trace output for this socket.
|
|
82
|
+
*/
|
|
83
|
+
enableTrace(): void;
|
|
84
|
+
/**
|
|
85
|
+
* Exports keying material for use by external protocols.
|
|
86
|
+
*
|
|
87
|
+
* @param length The number of bytes to return.
|
|
88
|
+
* @param label A label identifying the keying material.
|
|
89
|
+
* @param context An optional context.
|
|
90
|
+
* @returns Buffer containing keying material.
|
|
91
|
+
* @throws Error if export fails (e.g., TLS not connected).
|
|
92
|
+
*/
|
|
93
|
+
exportKeyingMaterial(length: number, label: string, context?: Buffer): Buffer;
|
|
73
94
|
constructor(socket: Socket, options?: ConnectionOptions);
|
|
74
95
|
constructor(options: ConnectionOptions);
|
|
75
96
|
connect(options: any, connectionListener?: () => void): this;
|