@push.rocks/smartproxy 21.0.0 → 21.1.1
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/changelog.md +18 -0
- package/dist_ts/core/utils/proxy-protocol.d.ts +5 -17
- package/dist_ts/core/utils/proxy-protocol.js +13 -97
- package/dist_ts/core/utils/websocket-utils.d.ts +6 -7
- package/dist_ts/core/utils/websocket-utils.js +10 -66
- package/dist_ts/detection/detectors/http-detector-v2.d.ts +33 -0
- package/dist_ts/detection/detectors/http-detector-v2.js +87 -0
- package/dist_ts/detection/detectors/http-detector.d.ts +33 -0
- package/dist_ts/detection/detectors/http-detector.js +89 -0
- package/dist_ts/detection/detectors/quick-detector.d.ts +28 -0
- package/dist_ts/detection/detectors/quick-detector.js +131 -0
- package/dist_ts/detection/detectors/routing-extractor.d.ts +28 -0
- package/dist_ts/detection/detectors/routing-extractor.js +122 -0
- package/dist_ts/detection/detectors/tls-detector-v2.d.ts +33 -0
- package/dist_ts/detection/detectors/tls-detector-v2.js +80 -0
- package/dist_ts/detection/detectors/tls-detector.d.ts +55 -0
- package/dist_ts/detection/detectors/tls-detector.js +206 -0
- package/dist_ts/detection/index.d.ts +17 -0
- package/dist_ts/detection/index.js +22 -0
- package/dist_ts/detection/models/detection-types.d.ts +87 -0
- package/dist_ts/detection/models/detection-types.js +5 -0
- package/dist_ts/detection/models/interfaces.d.ts +97 -0
- package/dist_ts/detection/models/interfaces.js +5 -0
- package/dist_ts/detection/protocol-detector-v2.d.ts +46 -0
- package/dist_ts/detection/protocol-detector-v2.js +116 -0
- package/dist_ts/detection/protocol-detector.d.ts +74 -0
- package/dist_ts/detection/protocol-detector.js +173 -0
- package/dist_ts/detection/utils/buffer-utils.d.ts +61 -0
- package/dist_ts/detection/utils/buffer-utils.js +127 -0
- package/dist_ts/detection/utils/fragment-manager.d.ts +31 -0
- package/dist_ts/detection/utils/fragment-manager.js +53 -0
- package/dist_ts/detection/utils/parser-utils.d.ts +42 -0
- package/dist_ts/detection/utils/parser-utils.js +63 -0
- package/dist_ts/index.d.ts +2 -0
- package/dist_ts/index.js +3 -1
- package/dist_ts/protocols/common/fragment-handler.d.ts +73 -0
- package/dist_ts/protocols/common/fragment-handler.js +117 -0
- package/dist_ts/protocols/common/index.d.ts +7 -0
- package/dist_ts/protocols/common/index.js +8 -0
- package/dist_ts/protocols/common/types.d.ts +68 -0
- package/dist_ts/protocols/common/types.js +7 -0
- package/dist_ts/protocols/http/constants.d.ts +119 -0
- package/dist_ts/protocols/http/constants.js +200 -0
- package/dist_ts/protocols/http/index.d.ts +7 -0
- package/dist_ts/protocols/http/index.js +8 -0
- package/dist_ts/protocols/http/parser.d.ts +58 -0
- package/dist_ts/protocols/http/parser.js +184 -0
- package/dist_ts/protocols/http/types.d.ts +62 -0
- package/dist_ts/protocols/http/types.js +5 -0
- package/dist_ts/protocols/index.d.ts +11 -0
- package/dist_ts/protocols/index.js +12 -0
- package/dist_ts/protocols/proxy/index.d.ts +6 -0
- package/dist_ts/protocols/proxy/index.js +7 -0
- package/dist_ts/protocols/proxy/parser.d.ts +44 -0
- package/dist_ts/protocols/proxy/parser.js +153 -0
- package/dist_ts/protocols/proxy/types.d.ts +47 -0
- package/dist_ts/protocols/proxy/types.js +6 -0
- package/dist_ts/protocols/tls/alerts/index.d.ts +4 -0
- package/dist_ts/protocols/tls/alerts/index.js +5 -0
- package/dist_ts/protocols/tls/alerts/tls-alert.d.ts +150 -0
- package/dist_ts/protocols/tls/alerts/tls-alert.js +226 -0
- package/dist_ts/protocols/tls/constants.d.ts +122 -0
- package/dist_ts/protocols/tls/constants.js +135 -0
- package/dist_ts/protocols/tls/index.d.ts +12 -0
- package/dist_ts/protocols/tls/index.js +27 -0
- package/dist_ts/protocols/tls/parser.d.ts +53 -0
- package/dist_ts/protocols/tls/parser.js +294 -0
- package/dist_ts/protocols/tls/sni/client-hello-parser.d.ts +100 -0
- package/dist_ts/protocols/tls/sni/client-hello-parser.js +463 -0
- package/dist_ts/protocols/tls/sni/index.d.ts +5 -0
- package/dist_ts/protocols/tls/sni/index.js +6 -0
- package/dist_ts/protocols/tls/sni/sni-extraction.d.ts +58 -0
- package/dist_ts/protocols/tls/sni/sni-extraction.js +275 -0
- package/dist_ts/protocols/tls/types.d.ts +65 -0
- package/dist_ts/protocols/tls/types.js +5 -0
- package/dist_ts/protocols/tls/utils/index.d.ts +4 -0
- package/dist_ts/protocols/tls/utils/index.js +5 -0
- package/dist_ts/protocols/tls/utils/tls-utils.d.ts +158 -0
- package/dist_ts/protocols/tls/utils/tls-utils.js +187 -0
- package/dist_ts/protocols/websocket/constants.d.ts +55 -0
- package/dist_ts/protocols/websocket/constants.js +58 -0
- package/dist_ts/protocols/websocket/index.d.ts +7 -0
- package/dist_ts/protocols/websocket/index.js +8 -0
- package/dist_ts/protocols/websocket/types.d.ts +47 -0
- package/dist_ts/protocols/websocket/types.js +5 -0
- package/dist_ts/protocols/websocket/utils.d.ts +25 -0
- package/dist_ts/protocols/websocket/utils.js +103 -0
- package/dist_ts/proxies/http-proxy/models/http-types.d.ts +25 -27
- package/dist_ts/proxies/http-proxy/models/http-types.js +24 -44
- package/dist_ts/proxies/smart-proxy/models/interfaces.d.ts +5 -0
- package/dist_ts/proxies/smart-proxy/route-connection-handler.js +81 -61
- package/dist_ts/proxies/smart-proxy/tls-manager.js +2 -1
- package/dist_ts/proxies/smart-proxy/utils/route-helpers.d.ts +2 -0
- package/dist_ts/proxies/smart-proxy/utils/route-helpers.js +61 -52
- package/dist_ts/tls/index.d.ts +5 -7
- package/dist_ts/tls/index.js +8 -11
- package/dist_ts/tls/sni/client-hello-parser.js +3 -2
- package/dist_ts/tls/sni/sni-handler.js +4 -4
- package/dist_ts/tls/utils/tls-utils.d.ts +1 -110
- package/dist_ts/tls/utils/tls-utils.js +4 -116
- package/package.json +1 -1
- package/readme.plan.md +0 -0
- package/ts/core/utils/proxy-protocol.ts +14 -131
- package/ts/core/utils/websocket-utils.ts +12 -60
- package/ts/detection/detectors/http-detector.ts +114 -0
- package/ts/detection/detectors/quick-detector.ts +148 -0
- package/ts/detection/detectors/routing-extractor.ts +147 -0
- package/ts/detection/detectors/tls-detector.ts +252 -0
- package/ts/detection/index.ts +25 -0
- package/ts/detection/models/detection-types.ts +102 -0
- package/ts/detection/models/interfaces.ts +115 -0
- package/ts/detection/protocol-detector.ts +230 -0
- package/ts/detection/utils/buffer-utils.ts +141 -0
- package/ts/detection/utils/fragment-manager.ts +64 -0
- package/ts/detection/utils/parser-utils.ts +77 -0
- package/ts/index.ts +3 -1
- package/ts/protocols/common/fragment-handler.ts +163 -0
- package/ts/protocols/common/index.ts +8 -0
- package/ts/protocols/common/types.ts +76 -0
- package/ts/protocols/http/constants.ts +219 -0
- package/ts/protocols/http/index.ts +8 -0
- package/ts/protocols/http/parser.ts +219 -0
- package/ts/protocols/http/types.ts +70 -0
- package/ts/protocols/index.ts +12 -0
- package/ts/protocols/proxy/index.ts +7 -0
- package/ts/protocols/proxy/parser.ts +183 -0
- package/ts/protocols/proxy/types.ts +53 -0
- package/ts/{tls → protocols/tls}/alerts/tls-alert.ts +1 -1
- package/ts/protocols/tls/index.ts +37 -0
- package/ts/protocols/tls/sni/index.ts +6 -0
- package/ts/{tls → protocols/tls}/utils/tls-utils.ts +1 -1
- package/ts/protocols/websocket/constants.ts +60 -0
- package/ts/protocols/websocket/index.ts +8 -0
- package/ts/protocols/websocket/types.ts +53 -0
- package/ts/protocols/websocket/utils.ts +98 -0
- package/ts/proxies/http-proxy/models/http-types.ts +29 -46
- package/ts/proxies/smart-proxy/models/interfaces.ts +7 -0
- package/ts/proxies/smart-proxy/route-connection-handler.ts +91 -68
- package/ts/proxies/smart-proxy/tls-manager.ts +1 -0
- package/ts/proxies/smart-proxy/utils/route-helpers.ts +72 -56
- package/ts/tls/index.ts +8 -12
- package/ts/tls/sni/sni-handler.ts +3 -3
- /package/ts/{tls → protocols/tls}/alerts/index.ts +0 -0
- /package/ts/{tls → protocols/tls}/sni/client-hello-parser.ts +0 -0
- /package/ts/{tls → protocols/tls}/sni/sni-extraction.ts +0 -0
- /package/ts/{tls → protocols/tls}/utils/index.ts +0 -0
package/changelog.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2025-07-22 - 21.1.1 - fix(detection)
|
|
4
|
+
Fix SNI detection in TLS detector
|
|
5
|
+
|
|
6
|
+
- Restored proper TLS detector implementation with ClientHello parsing
|
|
7
|
+
- Fixed imports to use new protocols module locations
|
|
8
|
+
- Added missing detectWithContext method for fragmented detection
|
|
9
|
+
- Fixed method names to match BufferAccumulator interface
|
|
10
|
+
- Removed unused import readUInt24BE
|
|
11
|
+
|
|
12
|
+
## 2025-07-21 - 21.1.0 - feat(protocols)
|
|
13
|
+
Refactor protocol utilities into centralized protocols module
|
|
14
|
+
|
|
15
|
+
- Moved TLS utilities from `ts/tls/` to `ts/protocols/tls/`
|
|
16
|
+
- Created centralized protocol modules for HTTP, WebSocket, Proxy, and TLS
|
|
17
|
+
- Core utilities now delegate to protocol modules for parsing and utilities
|
|
18
|
+
- Maintains backward compatibility through re-exports in original locations
|
|
19
|
+
- Improves code organization and separation of concerns
|
|
20
|
+
|
|
3
21
|
## 2025-07-22 - 21.0.0 - BREAKING_CHANGE(forwarding)
|
|
4
22
|
Remove legacy forwarding module
|
|
5
23
|
|
|
@@ -1,24 +1,12 @@
|
|
|
1
1
|
import * as plugins from '../../plugins.js';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
*/
|
|
5
|
-
export interface IProxyInfo {
|
|
6
|
-
protocol: 'TCP4' | 'TCP6' | 'UNKNOWN';
|
|
7
|
-
sourceIP: string;
|
|
8
|
-
sourcePort: number;
|
|
9
|
-
destinationIP: string;
|
|
10
|
-
destinationPort: number;
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* Interface for parse result including remaining data
|
|
14
|
-
*/
|
|
15
|
-
export interface IProxyParseResult {
|
|
16
|
-
proxyInfo: IProxyInfo | null;
|
|
17
|
-
remainingData: Buffer;
|
|
18
|
-
}
|
|
2
|
+
import { type IProxyInfo, type IProxyParseResult } from '../../protocols/proxy/index.js';
|
|
3
|
+
export type { IProxyInfo, IProxyParseResult } from '../../protocols/proxy/index.js';
|
|
19
4
|
/**
|
|
20
5
|
* Parser for PROXY protocol v1 (text format)
|
|
21
6
|
* Spec: https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt
|
|
7
|
+
*
|
|
8
|
+
* This class now delegates to the protocol parser but adds
|
|
9
|
+
* smartproxy-specific features like socket reading and logging
|
|
22
10
|
*/
|
|
23
11
|
export declare class ProxyProtocolParser {
|
|
24
12
|
static readonly PROXY_V1_SIGNATURE = "PROXY ";
|
|
@@ -1,121 +1,37 @@
|
|
|
1
1
|
import * as plugins from '../../plugins.js';
|
|
2
2
|
import { logger } from './logger.js';
|
|
3
|
+
import { ProxyProtocolParser as ProtocolParser } from '../../protocols/proxy/index.js';
|
|
3
4
|
/**
|
|
4
5
|
* Parser for PROXY protocol v1 (text format)
|
|
5
6
|
* Spec: https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt
|
|
7
|
+
*
|
|
8
|
+
* This class now delegates to the protocol parser but adds
|
|
9
|
+
* smartproxy-specific features like socket reading and logging
|
|
6
10
|
*/
|
|
7
11
|
export class ProxyProtocolParser {
|
|
8
|
-
static { this.PROXY_V1_SIGNATURE =
|
|
9
|
-
static { this.MAX_HEADER_LENGTH =
|
|
10
|
-
static { this.HEADER_TERMINATOR =
|
|
12
|
+
static { this.PROXY_V1_SIGNATURE = ProtocolParser.PROXY_V1_SIGNATURE; }
|
|
13
|
+
static { this.MAX_HEADER_LENGTH = ProtocolParser.MAX_HEADER_LENGTH; }
|
|
14
|
+
static { this.HEADER_TERMINATOR = ProtocolParser.HEADER_TERMINATOR; }
|
|
11
15
|
/**
|
|
12
16
|
* Parse PROXY protocol v1 header from buffer
|
|
13
17
|
* Returns proxy info and remaining data after header
|
|
14
18
|
*/
|
|
15
19
|
static parse(data) {
|
|
16
|
-
//
|
|
17
|
-
|
|
18
|
-
return {
|
|
19
|
-
proxyInfo: null,
|
|
20
|
-
remainingData: data
|
|
21
|
-
};
|
|
22
|
-
}
|
|
23
|
-
// Find header terminator
|
|
24
|
-
const headerEndIndex = data.indexOf(this.HEADER_TERMINATOR);
|
|
25
|
-
if (headerEndIndex === -1) {
|
|
26
|
-
// Header incomplete, need more data
|
|
27
|
-
if (data.length > this.MAX_HEADER_LENGTH) {
|
|
28
|
-
// Header too long, invalid
|
|
29
|
-
throw new Error('PROXY protocol header exceeds maximum length');
|
|
30
|
-
}
|
|
31
|
-
return {
|
|
32
|
-
proxyInfo: null,
|
|
33
|
-
remainingData: data
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
// Extract header line
|
|
37
|
-
const headerLine = data.toString('ascii', 0, headerEndIndex);
|
|
38
|
-
const remainingData = data.slice(headerEndIndex + 2); // Skip \r\n
|
|
39
|
-
// Parse header
|
|
40
|
-
const parts = headerLine.split(' ');
|
|
41
|
-
if (parts.length < 2) {
|
|
42
|
-
throw new Error(`Invalid PROXY protocol header format: ${headerLine}`);
|
|
43
|
-
}
|
|
44
|
-
const [signature, protocol] = parts;
|
|
45
|
-
// Validate protocol
|
|
46
|
-
if (!['TCP4', 'TCP6', 'UNKNOWN'].includes(protocol)) {
|
|
47
|
-
throw new Error(`Invalid PROXY protocol: ${protocol}`);
|
|
48
|
-
}
|
|
49
|
-
// For UNKNOWN protocol, ignore addresses
|
|
50
|
-
if (protocol === 'UNKNOWN') {
|
|
51
|
-
return {
|
|
52
|
-
proxyInfo: {
|
|
53
|
-
protocol: 'UNKNOWN',
|
|
54
|
-
sourceIP: '',
|
|
55
|
-
sourcePort: 0,
|
|
56
|
-
destinationIP: '',
|
|
57
|
-
destinationPort: 0
|
|
58
|
-
},
|
|
59
|
-
remainingData
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
// For TCP4/TCP6, we need all 6 parts
|
|
63
|
-
if (parts.length !== 6) {
|
|
64
|
-
throw new Error(`Invalid PROXY protocol header format: ${headerLine}`);
|
|
65
|
-
}
|
|
66
|
-
const [, , srcIP, dstIP, srcPort, dstPort] = parts;
|
|
67
|
-
// Validate and parse ports
|
|
68
|
-
const sourcePort = parseInt(srcPort, 10);
|
|
69
|
-
const destinationPort = parseInt(dstPort, 10);
|
|
70
|
-
if (isNaN(sourcePort) || sourcePort < 0 || sourcePort > 65535) {
|
|
71
|
-
throw new Error(`Invalid source port: ${srcPort}`);
|
|
72
|
-
}
|
|
73
|
-
if (isNaN(destinationPort) || destinationPort < 0 || destinationPort > 65535) {
|
|
74
|
-
throw new Error(`Invalid destination port: ${dstPort}`);
|
|
75
|
-
}
|
|
76
|
-
// Validate IP addresses
|
|
77
|
-
const protocolType = protocol;
|
|
78
|
-
if (!this.isValidIP(srcIP, protocolType)) {
|
|
79
|
-
throw new Error(`Invalid source IP for ${protocol}: ${srcIP}`);
|
|
80
|
-
}
|
|
81
|
-
if (!this.isValidIP(dstIP, protocolType)) {
|
|
82
|
-
throw new Error(`Invalid destination IP for ${protocol}: ${dstIP}`);
|
|
83
|
-
}
|
|
84
|
-
return {
|
|
85
|
-
proxyInfo: {
|
|
86
|
-
protocol: protocol,
|
|
87
|
-
sourceIP: srcIP,
|
|
88
|
-
sourcePort,
|
|
89
|
-
destinationIP: dstIP,
|
|
90
|
-
destinationPort
|
|
91
|
-
},
|
|
92
|
-
remainingData
|
|
93
|
-
};
|
|
20
|
+
// Delegate to protocol parser
|
|
21
|
+
return ProtocolParser.parse(data);
|
|
94
22
|
}
|
|
95
23
|
/**
|
|
96
24
|
* Generate PROXY protocol v1 header
|
|
97
25
|
*/
|
|
98
26
|
static generate(info) {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
}
|
|
102
|
-
const header = `PROXY ${info.protocol} ${info.sourceIP} ${info.destinationIP} ${info.sourcePort} ${info.destinationPort}\r\n`;
|
|
103
|
-
if (header.length > this.MAX_HEADER_LENGTH) {
|
|
104
|
-
throw new Error('Generated PROXY protocol header exceeds maximum length');
|
|
105
|
-
}
|
|
106
|
-
return Buffer.from(header, 'ascii');
|
|
27
|
+
// Delegate to protocol parser
|
|
28
|
+
return ProtocolParser.generate(info);
|
|
107
29
|
}
|
|
108
30
|
/**
|
|
109
31
|
* Validate IP address format
|
|
110
32
|
*/
|
|
111
33
|
static isValidIP(ip, protocol) {
|
|
112
|
-
|
|
113
|
-
return plugins.net.isIPv4(ip);
|
|
114
|
-
}
|
|
115
|
-
else if (protocol === 'TCP6') {
|
|
116
|
-
return plugins.net.isIPv6(ip);
|
|
117
|
-
}
|
|
118
|
-
return false;
|
|
34
|
+
return ProtocolParser.isValidIP(ip, protocol);
|
|
119
35
|
}
|
|
120
36
|
/**
|
|
121
37
|
* Attempt to read a complete PROXY protocol header from a socket
|
|
@@ -198,4 +114,4 @@ export class ProxyProtocolParser {
|
|
|
198
114
|
});
|
|
199
115
|
}
|
|
200
116
|
}
|
|
201
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
117
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJveHktcHJvdG9jb2wuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90cy9jb3JlL3V0aWxzL3Byb3h5LXByb3RvY29sLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sa0JBQWtCLENBQUM7QUFDNUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUNyQyxPQUFPLEVBQUUsbUJBQW1CLElBQUksY0FBYyxFQUEyQyxNQUFNLGdDQUFnQyxDQUFDO0FBS2hJOzs7Ozs7R0FNRztBQUNILE1BQU0sT0FBTyxtQkFBbUI7YUFDZCx1QkFBa0IsR0FBRyxjQUFjLENBQUMsa0JBQWtCLENBQUM7YUFDdkQsc0JBQWlCLEdBQUcsY0FBYyxDQUFDLGlCQUFpQixDQUFDO2FBQ3JELHNCQUFpQixHQUFHLGNBQWMsQ0FBQyxpQkFBaUIsQ0FBQztJQUVyRTs7O09BR0c7SUFDSCxNQUFNLENBQUMsS0FBSyxDQUFDLElBQVk7UUFDdkIsOEJBQThCO1FBQzlCLE9BQU8sY0FBYyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNwQyxDQUFDO0lBRUQ7O09BRUc7SUFDSCxNQUFNLENBQUMsUUFBUSxDQUFDLElBQWdCO1FBQzlCLDhCQUE4QjtRQUM5QixPQUFPLGNBQWMsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDdkMsQ0FBQztJQUVEOztPQUVHO0lBQ0ssTUFBTSxDQUFDLFNBQVMsQ0FBQyxFQUFVLEVBQUUsUUFBcUM7UUFDeEUsT0FBTyxjQUFjLENBQUMsU0FBUyxDQUFDLEVBQUUsRUFBRSxRQUFRLENBQUMsQ0FBQztJQUNoRCxDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsTUFBTSxDQUFDLEtBQUssQ0FBQyxjQUFjLENBQUMsTUFBMEIsRUFBRSxVQUFrQixJQUFJO1FBQzVFLE9BQU8sSUFBSSxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRTtZQUM3QixJQUFJLE1BQU0s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
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* WebSocket utility functions
|
|
3
|
+
*
|
|
4
|
+
* This module provides smartproxy-specific WebSocket utilities
|
|
5
|
+
* and re-exports protocol utilities from the protocols module
|
|
3
6
|
*/
|
|
4
|
-
|
|
5
|
-
* Type for WebSocket RawData that can be different types in different environments
|
|
6
|
-
* This matches the ws library's type definition
|
|
7
|
-
*/
|
|
8
|
-
export type RawData = Buffer | ArrayBuffer | Buffer[] | any;
|
|
7
|
+
export type { RawData } from '../../protocols/websocket/index.js';
|
|
9
8
|
/**
|
|
10
9
|
* Get the length of a WebSocket message regardless of its type
|
|
11
10
|
* (handles all possible WebSocket message data types)
|
|
@@ -13,11 +12,11 @@ export type RawData = Buffer | ArrayBuffer | Buffer[] | any;
|
|
|
13
12
|
* @param data - The data message from WebSocket (could be any RawData type)
|
|
14
13
|
* @returns The length of the data in bytes
|
|
15
14
|
*/
|
|
16
|
-
export declare function getMessageSize(data: RawData): number;
|
|
15
|
+
export declare function getMessageSize(data: import('../../protocols/websocket/index.js').RawData): number;
|
|
17
16
|
/**
|
|
18
17
|
* Convert any raw WebSocket data to Buffer for consistent handling
|
|
19
18
|
*
|
|
20
19
|
* @param data - The data message from WebSocket (could be any RawData type)
|
|
21
20
|
* @returns A Buffer containing the data
|
|
22
21
|
*/
|
|
23
|
-
export declare function toBuffer(data: RawData): Buffer;
|
|
22
|
+
export declare function toBuffer(data: import('../../protocols/websocket/index.js').RawData): Buffer;
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* WebSocket utility functions
|
|
3
|
+
*
|
|
4
|
+
* This module provides smartproxy-specific WebSocket utilities
|
|
5
|
+
* and re-exports protocol utilities from the protocols module
|
|
3
6
|
*/
|
|
7
|
+
// Import and re-export from protocols
|
|
8
|
+
import { getMessageSize as protocolGetMessageSize, toBuffer as protocolToBuffer } from '../../protocols/websocket/index.js';
|
|
4
9
|
/**
|
|
5
10
|
* Get the length of a WebSocket message regardless of its type
|
|
6
11
|
* (handles all possible WebSocket message data types)
|
|
@@ -9,40 +14,8 @@
|
|
|
9
14
|
* @returns The length of the data in bytes
|
|
10
15
|
*/
|
|
11
16
|
export function getMessageSize(data) {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
return Buffer.from(data, 'utf8').length;
|
|
15
|
-
}
|
|
16
|
-
else if (data instanceof Buffer) {
|
|
17
|
-
// For Node.js Buffer
|
|
18
|
-
return data.length;
|
|
19
|
-
}
|
|
20
|
-
else if (data instanceof ArrayBuffer) {
|
|
21
|
-
// For ArrayBuffer
|
|
22
|
-
return data.byteLength;
|
|
23
|
-
}
|
|
24
|
-
else if (Array.isArray(data)) {
|
|
25
|
-
// For array of buffers, sum their lengths
|
|
26
|
-
return data.reduce((sum, chunk) => {
|
|
27
|
-
if (chunk instanceof Buffer) {
|
|
28
|
-
return sum + chunk.length;
|
|
29
|
-
}
|
|
30
|
-
else if (chunk instanceof ArrayBuffer) {
|
|
31
|
-
return sum + chunk.byteLength;
|
|
32
|
-
}
|
|
33
|
-
return sum;
|
|
34
|
-
}, 0);
|
|
35
|
-
}
|
|
36
|
-
else {
|
|
37
|
-
// For other types, try to determine the size or return 0
|
|
38
|
-
try {
|
|
39
|
-
return Buffer.from(data).length;
|
|
40
|
-
}
|
|
41
|
-
catch (e) {
|
|
42
|
-
console.warn('Could not determine message size', e);
|
|
43
|
-
return 0;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
17
|
+
// Delegate to protocol implementation
|
|
18
|
+
return protocolGetMessageSize(data);
|
|
46
19
|
}
|
|
47
20
|
/**
|
|
48
21
|
* Convert any raw WebSocket data to Buffer for consistent handling
|
|
@@ -51,36 +24,7 @@ export function getMessageSize(data) {
|
|
|
51
24
|
* @returns A Buffer containing the data
|
|
52
25
|
*/
|
|
53
26
|
export function toBuffer(data) {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
}
|
|
57
|
-
else if (data instanceof Buffer) {
|
|
58
|
-
return data;
|
|
59
|
-
}
|
|
60
|
-
else if (data instanceof ArrayBuffer) {
|
|
61
|
-
return Buffer.from(data);
|
|
62
|
-
}
|
|
63
|
-
else if (Array.isArray(data)) {
|
|
64
|
-
// For array of buffers, concatenate them
|
|
65
|
-
return Buffer.concat(data.map(chunk => {
|
|
66
|
-
if (chunk instanceof Buffer) {
|
|
67
|
-
return chunk;
|
|
68
|
-
}
|
|
69
|
-
else if (chunk instanceof ArrayBuffer) {
|
|
70
|
-
return Buffer.from(chunk);
|
|
71
|
-
}
|
|
72
|
-
return Buffer.from(chunk);
|
|
73
|
-
}));
|
|
74
|
-
}
|
|
75
|
-
else {
|
|
76
|
-
// For other types, try to convert to Buffer or return empty Buffer
|
|
77
|
-
try {
|
|
78
|
-
return Buffer.from(data);
|
|
79
|
-
}
|
|
80
|
-
catch (e) {
|
|
81
|
-
console.warn('Could not convert message to Buffer', e);
|
|
82
|
-
return Buffer.alloc(0);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
27
|
+
// Delegate to protocol implementation
|
|
28
|
+
return protocolToBuffer(data);
|
|
85
29
|
}
|
|
86
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
30
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2Vic29ja2V0LXV0aWxzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdHMvY29yZS91dGlscy93ZWJzb2NrZXQtdXRpbHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7O0dBS0c7QUFFSCxzQ0FBc0M7QUFDdEMsT0FBTyxFQUFFLGNBQWMsSUFBSSxzQkFBc0IsRUFBRSxRQUFRLElBQUksZ0JBQWdCLEVBQUUsTUFBTSxvQ0FBb0MsQ0FBQztBQUc1SDs7Ozs7O0dBTUc7QUFDSCxNQUFNLFVBQVUsY0FBYyxDQUFDLElBQTBEO0lBQ3ZGLHNDQUFzQztJQUN0QyxPQUFPLHNCQUFzQixDQUFDLElBQUksQ0FBQyxDQUFDO0FBQ3RDLENBQUM7QUFFRDs7Ozs7R0FLRztBQUNILE1BQU0sVUFBVSxRQUFRLENBQUMsSUFBMEQ7SUFDakYsc0NBQXNDO0lBQ3RDLE9BQU8sZ0JBQWdCLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDaEMsQ0FBQyJ9
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP Protocol Detector V2
|
|
3
|
+
*
|
|
4
|
+
* Simplified HTTP detection using the new architecture
|
|
5
|
+
*/
|
|
6
|
+
import type { IProtocolDetector } from '../models/interfaces.js';
|
|
7
|
+
import type { IDetectionResult, IDetectionOptions } from '../models/detection-types.js';
|
|
8
|
+
import type { IConnectionContext } from '../../protocols/common/types.js';
|
|
9
|
+
import { DetectionFragmentManager } from '../utils/fragment-manager.js';
|
|
10
|
+
/**
|
|
11
|
+
* Simplified HTTP detector
|
|
12
|
+
*/
|
|
13
|
+
export declare class HttpDetectorV2 implements IProtocolDetector {
|
|
14
|
+
private quickDetector;
|
|
15
|
+
private fragmentManager;
|
|
16
|
+
constructor(fragmentManager: DetectionFragmentManager);
|
|
17
|
+
/**
|
|
18
|
+
* Check if buffer can be handled by this detector
|
|
19
|
+
*/
|
|
20
|
+
canHandle(buffer: Buffer): boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Get minimum bytes needed for detection
|
|
23
|
+
*/
|
|
24
|
+
getMinimumBytes(): number;
|
|
25
|
+
/**
|
|
26
|
+
* Detect HTTP protocol from buffer
|
|
27
|
+
*/
|
|
28
|
+
detect(buffer: Buffer, options?: IDetectionOptions): IDetectionResult | null;
|
|
29
|
+
/**
|
|
30
|
+
* Handle fragmented detection
|
|
31
|
+
*/
|
|
32
|
+
detectWithContext(buffer: Buffer, context: IConnectionContext, options?: IDetectionOptions): IDetectionResult | null;
|
|
33
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP Protocol Detector V2
|
|
3
|
+
*
|
|
4
|
+
* Simplified HTTP detection using the new architecture
|
|
5
|
+
*/
|
|
6
|
+
import { QuickProtocolDetector } from './quick-detector.js';
|
|
7
|
+
import { RoutingExtractor } from './routing-extractor.js';
|
|
8
|
+
import { DetectionFragmentManager } from '../utils/fragment-manager.js';
|
|
9
|
+
/**
|
|
10
|
+
* Simplified HTTP detector
|
|
11
|
+
*/
|
|
12
|
+
export class HttpDetectorV2 {
|
|
13
|
+
constructor(fragmentManager) {
|
|
14
|
+
this.quickDetector = new QuickProtocolDetector();
|
|
15
|
+
this.fragmentManager = fragmentManager;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Check if buffer can be handled by this detector
|
|
19
|
+
*/
|
|
20
|
+
canHandle(buffer) {
|
|
21
|
+
const result = this.quickDetector.quickDetect(buffer);
|
|
22
|
+
return result.protocol === 'http' && result.confidence > 50;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Get minimum bytes needed for detection
|
|
26
|
+
*/
|
|
27
|
+
getMinimumBytes() {
|
|
28
|
+
return 4; // "GET " minimum
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Detect HTTP protocol from buffer
|
|
32
|
+
*/
|
|
33
|
+
detect(buffer, options) {
|
|
34
|
+
// Quick detection first
|
|
35
|
+
const quickResult = this.quickDetector.quickDetect(buffer);
|
|
36
|
+
if (quickResult.protocol !== 'http' || quickResult.confidence < 50) {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
// If we don't need full headers, we can return early
|
|
40
|
+
if (quickResult.confidence >= 95 && !options?.extractFullHeaders) {
|
|
41
|
+
return {
|
|
42
|
+
protocol: 'http',
|
|
43
|
+
connectionInfo: {
|
|
44
|
+
protocol: 'http',
|
|
45
|
+
method: quickResult.metadata?.method
|
|
46
|
+
},
|
|
47
|
+
isComplete: true
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
// Extract routing information if needed
|
|
51
|
+
const routing = RoutingExtractor.extract(buffer, 'http');
|
|
52
|
+
// Check if we have complete headers
|
|
53
|
+
const headersEnd = buffer.indexOf('\r\n\r\n');
|
|
54
|
+
const isComplete = headersEnd !== -1;
|
|
55
|
+
return {
|
|
56
|
+
protocol: 'http',
|
|
57
|
+
connectionInfo: {
|
|
58
|
+
protocol: 'http',
|
|
59
|
+
domain: routing?.domain,
|
|
60
|
+
path: routing?.path,
|
|
61
|
+
method: quickResult.metadata?.method
|
|
62
|
+
},
|
|
63
|
+
isComplete,
|
|
64
|
+
bytesNeeded: isComplete ? undefined : buffer.length + 512 // Need more for headers
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Handle fragmented detection
|
|
69
|
+
*/
|
|
70
|
+
detectWithContext(buffer, context, options) {
|
|
71
|
+
const handler = this.fragmentManager.getHandler('http');
|
|
72
|
+
const connectionId = DetectionFragmentManager.createConnectionId(context);
|
|
73
|
+
// Add fragment
|
|
74
|
+
const result = handler.addFragment(connectionId, buffer);
|
|
75
|
+
if (result.error) {
|
|
76
|
+
handler.complete(connectionId);
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
// Try detection on accumulated buffer
|
|
80
|
+
const detectResult = this.detect(result.buffer, options);
|
|
81
|
+
if (detectResult && detectResult.isComplete) {
|
|
82
|
+
handler.complete(connectionId);
|
|
83
|
+
}
|
|
84
|
+
return detectResult;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaHR0cC1kZXRlY3Rvci12Mi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3RzL2RldGVjdGlvbi9kZXRlY3RvcnMvaHR0cC1kZXRlY3Rvci12Mi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7OztHQUlHO0FBTUgsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDNUQsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDMUQsT0FBTyxFQUFFLHdCQUF3QixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFFeEU7O0dBRUc7QUFDSCxNQUFNLE9BQU8sY0FBYztJQUl6QixZQUFZLGVBQXlDO1FBSDdDLGtCQUFhLEdBQUcsSUFBSSxxQkFBcUIsRUFBRSxDQUFDO1FBSWxELElBQUksQ0FBQyxlQUFlLEdBQUcsZUFBZSxDQUFDO0lBQ3pDLENBQUM7SUFFRDs7T0FFRztJQUNILFNBQVMsQ0FBQyxNQUFjO1FBQ3RCLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3RELE9BQU8sTUFBTSxDQUFDLFFBQVEsS0FBSyxNQUFNLElBQUksTUFBTSxDQUFDLFVBQVUsR0FBRyxFQUFFLENBQUM7SUFDOUQsQ0FBQztJQUVEOztPQUVHO0lBQ0gsZUFBZTtRQUNiLE9BQU8sQ0FBQyxDQUFDLENBQUMsaUJBQWlCO0lBQzdCLENBQUM7SUFFRDs7T0FFRztJQUNILE1BQU0sQ0FBQyxNQUFjLEVBQUUsT0FBMkI7UUFDaEQsd0JBQXdCO1FBQ3hCLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBRTNELElBQUksV0FBVyxDQUFDLFFBQVEsS0FBSyxNQUFNLElBQUksV0FBVyxDQUFDLFVBQVUsR0FBRyxFQUFFLEVBQUUsQ0FBQztZQUNuRSxPQUFPLElBQUksQ0FBQztRQUNkLENBQUM7UUFFRCxxREFBcUQ7UUFDckQsSUFBSSxXQUFXLENBQUMsVUFBVSxJQUFJLEVBQUUsSUFBSSxDQUFDLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxDQUFDO1lBQ2pFLE9BQU87Z0JBQ0wsUUFBUSxFQUFFLE1BQU07Z0JBQ2hCLGNBQWMsRUFBRTtvQkFDZCxRQUFRLEVBQUUsTUFBTTtvQkFDaEIsTUFBTSxFQUFFLFdBQVcsQ0FBQyxRQUFRLEVBQUUsTUFBcUI7aUJBQ3BEO2dCQUNELFVBQVUsRUFBRSxJQUFJO2FBQ2pCLENBQUM7UUFDSixDQUFDO1FBRUQsd0NBQXdDO1FBQ3hDLE1BQU0sT0FBTyxHQUFHLGdCQUFnQixDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFFekQsb0NBQW9DO1FBQ3BDLE1BQU0sVUFBVSxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDOUMsTUFBTSxVQUFVLEdBQUcsVUFBVSxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBRXJDLE9BQU87WUFDTCxRQUFRLEVBQUUsTUFBTTtZQUNoQixjQUFjLEVBQUU7Z0JBQ2QsUUFBUSxFQUFFLE1BQU07Z0JBQ2hCLE1BQU0sRUFBRSxPQUFPLEVBQUUsTUFBTTtnQkFDdkIsSUFBSSxFQUFFLE9BQU8sRUFBRSxJQUFJO2dCQUNuQixNQUFNLEVBQUUsV0FBVyxDQUFDLFFBQVEsRUFBRSxNQUFxQjthQUNwRDtZQUNELFVBQVU7WUFDVixXQUFXLEVBQUUsVUFBVSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxNQUFNLEdBQUcsR0FBRyxDQUFDLHdCQUF3QjtTQUNuRixDQUFDO0lBQ0osQ0FBQztJQUVEOztPQUVHO0lBQ0gsaUJBQWlCLENBQ2YsTUFBYyxFQUNkLE9BQTJCLEVBQzNCLE9BQTJCO1FBRTNCLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3hELE1BQU0sWUFBWSxHQUFHLHdCQUF3QixDQUFDLGtCQUFrQixDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBRTFFLGVBQWU7UUFDZixNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsV0FBVyxDQUFDLFlBQVksRUFBRSxNQUFNLENBQUMsQ0FBQztRQUV6RCxJQUFJLE1BQU0sQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNqQixPQUFPLENBQUMsUUFBUSxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQy9CLE9BQU8sSUFBSSxDQUFDO1FBQ2QsQ0FBQztRQUVELHNDQUFzQztRQUN0QyxNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxNQUFPLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFFMUQsSUFBSSxZQUFZLElBQUksWUFBWSxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBQzVDLE9BQU8sQ0FBQyxRQUFRLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDakMsQ0FBQztRQUVELE9BQU8sWUFBWSxDQUFDO0lBQ3RCLENBQUM7Q0FDRiJ9
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP Protocol Detector
|
|
3
|
+
*
|
|
4
|
+
* Simplified HTTP detection using the new architecture
|
|
5
|
+
*/
|
|
6
|
+
import type { IProtocolDetector } from '../models/interfaces.js';
|
|
7
|
+
import type { IDetectionResult, IDetectionOptions } from '../models/detection-types.js';
|
|
8
|
+
import type { IConnectionContext } from '../../protocols/common/types.js';
|
|
9
|
+
import { DetectionFragmentManager } from '../utils/fragment-manager.js';
|
|
10
|
+
/**
|
|
11
|
+
* Simplified HTTP detector
|
|
12
|
+
*/
|
|
13
|
+
export declare class HttpDetector implements IProtocolDetector {
|
|
14
|
+
private quickDetector;
|
|
15
|
+
private fragmentManager;
|
|
16
|
+
constructor(fragmentManager?: DetectionFragmentManager);
|
|
17
|
+
/**
|
|
18
|
+
* Check if buffer can be handled by this detector
|
|
19
|
+
*/
|
|
20
|
+
canHandle(buffer: Buffer): boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Get minimum bytes needed for detection
|
|
23
|
+
*/
|
|
24
|
+
getMinimumBytes(): number;
|
|
25
|
+
/**
|
|
26
|
+
* Detect HTTP protocol from buffer
|
|
27
|
+
*/
|
|
28
|
+
detect(buffer: Buffer, options?: IDetectionOptions): IDetectionResult | null;
|
|
29
|
+
/**
|
|
30
|
+
* Handle fragmented detection
|
|
31
|
+
*/
|
|
32
|
+
detectWithContext(buffer: Buffer, context: IConnectionContext, options?: IDetectionOptions): IDetectionResult | null;
|
|
33
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP Protocol Detector
|
|
3
|
+
*
|
|
4
|
+
* Simplified HTTP detection using the new architecture
|
|
5
|
+
*/
|
|
6
|
+
import { QuickProtocolDetector } from './quick-detector.js';
|
|
7
|
+
import { RoutingExtractor } from './routing-extractor.js';
|
|
8
|
+
import { DetectionFragmentManager } from '../utils/fragment-manager.js';
|
|
9
|
+
/**
|
|
10
|
+
* Simplified HTTP detector
|
|
11
|
+
*/
|
|
12
|
+
export class HttpDetector {
|
|
13
|
+
constructor(fragmentManager) {
|
|
14
|
+
this.quickDetector = new QuickProtocolDetector();
|
|
15
|
+
this.fragmentManager = fragmentManager || new DetectionFragmentManager();
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Check if buffer can be handled by this detector
|
|
19
|
+
*/
|
|
20
|
+
canHandle(buffer) {
|
|
21
|
+
const result = this.quickDetector.quickDetect(buffer);
|
|
22
|
+
return result.protocol === 'http' && result.confidence > 50;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Get minimum bytes needed for detection
|
|
26
|
+
*/
|
|
27
|
+
getMinimumBytes() {
|
|
28
|
+
return 4; // "GET " minimum
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Detect HTTP protocol from buffer
|
|
32
|
+
*/
|
|
33
|
+
detect(buffer, options) {
|
|
34
|
+
// Quick detection first
|
|
35
|
+
const quickResult = this.quickDetector.quickDetect(buffer);
|
|
36
|
+
if (quickResult.protocol !== 'http' || quickResult.confidence < 50) {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
// Extract routing information
|
|
40
|
+
const routing = RoutingExtractor.extract(buffer, 'http');
|
|
41
|
+
// If we don't need full headers, we can return early
|
|
42
|
+
if (quickResult.confidence >= 95 && !options?.extractFullHeaders) {
|
|
43
|
+
return {
|
|
44
|
+
protocol: 'http',
|
|
45
|
+
connectionInfo: {
|
|
46
|
+
protocol: 'http',
|
|
47
|
+
method: quickResult.metadata?.method,
|
|
48
|
+
domain: routing?.domain,
|
|
49
|
+
path: routing?.path
|
|
50
|
+
},
|
|
51
|
+
isComplete: true
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
// Check if we have complete headers
|
|
55
|
+
const headersEnd = buffer.indexOf('\r\n\r\n');
|
|
56
|
+
const isComplete = headersEnd !== -1;
|
|
57
|
+
return {
|
|
58
|
+
protocol: 'http',
|
|
59
|
+
connectionInfo: {
|
|
60
|
+
protocol: 'http',
|
|
61
|
+
domain: routing?.domain,
|
|
62
|
+
path: routing?.path,
|
|
63
|
+
method: quickResult.metadata?.method
|
|
64
|
+
},
|
|
65
|
+
isComplete,
|
|
66
|
+
bytesNeeded: isComplete ? undefined : buffer.length + 512 // Need more for headers
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Handle fragmented detection
|
|
71
|
+
*/
|
|
72
|
+
detectWithContext(buffer, context, options) {
|
|
73
|
+
const handler = this.fragmentManager.getHandler('http');
|
|
74
|
+
const connectionId = DetectionFragmentManager.createConnectionId(context);
|
|
75
|
+
// Add fragment
|
|
76
|
+
const result = handler.addFragment(connectionId, buffer);
|
|
77
|
+
if (result.error) {
|
|
78
|
+
handler.complete(connectionId);
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
// Try detection on accumulated buffer
|
|
82
|
+
const detectResult = this.detect(result.buffer, options);
|
|
83
|
+
if (detectResult && detectResult.isComplete) {
|
|
84
|
+
handler.complete(connectionId);
|
|
85
|
+
}
|
|
86
|
+
return detectResult;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaHR0cC1kZXRlY3Rvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3RzL2RldGVjdGlvbi9kZXRlY3RvcnMvaHR0cC1kZXRlY3Rvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7OztHQUlHO0FBTUgsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDNUQsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDMUQsT0FBTyxFQUFFLHdCQUF3QixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFFeEU7O0dBRUc7QUFDSCxNQUFNLE9BQU8sWUFBWTtJQUl2QixZQUFZLGVBQTBDO1FBSDlDLGtCQUFhLEdBQUcsSUFBSSxxQkFBcUIsRUFBRSxDQUFDO1FBSWxELElBQUksQ0FBQyxlQUFlLEdBQUcsZUFBZSxJQUFJLElBQUksd0JBQXdCLEVBQUUsQ0FBQztJQUMzRSxDQUFDO0lBRUQ7O09BRUc7SUFDSCxTQUFTLENBQUMsTUFBYztRQUN0QixNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUN0RCxPQUFPLE1BQU0sQ0FBQyxRQUFRLEtBQUssTUFBTSxJQUFJLE1BQU0sQ0FBQyxVQUFVLEdBQUcsRUFBRSxDQUFDO0lBQzlELENBQUM7SUFFRDs7T0FFRztJQUNILGVBQWU7UUFDYixPQUFPLENBQUMsQ0FBQyxDQUFDLGlCQUFpQjtJQUM3QixDQUFDO0lBRUQ7O09BRUc7SUFDSCxNQUFNLENBQUMsTUFBYyxFQUFFLE9BQTJCO1FBQ2hELHdCQUF3QjtRQUN4QixNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUUzRCxJQUFJLFdBQVcsQ0FBQyxRQUFRLEtBQUssTUFBTSxJQUFJLFdBQVcsQ0FBQyxVQUFVLEdBQUcsRUFBRSxFQUFFLENBQUM7WUFDbkUsT0FBTyxJQUFJLENBQUM7UUFDZCxDQUFDO1FBRUQsOEJBQThCO1FBQzlCLE1BQU0sT0FBTyxHQUFHLGdCQUFnQixDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFFekQscURBQXFEO1FBQ3JELElBQUksV0FBVyxDQUFDLFVBQVUsSUFBSSxFQUFFLElBQUksQ0FBQyxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsQ0FBQztZQUNqRSxPQUFPO2dCQUNMLFFBQVEsRUFBRSxNQUFNO2dCQUNoQixjQUFjLEVBQUU7b0JBQ2QsUUFBUSxFQUFFLE1BQU07b0JBQ2hCLE1BQU0sRUFBRSxXQUFXLENBQUMsUUFBUSxFQUFFLE1BQXFCO29CQUNuRCxNQUFNLEVBQUUsT0FBTyxFQUFFLE1BQU07b0JBQ3ZCLElBQUksRUFBRSxPQUFPLEVBQUUsSUFBSTtpQkFDcEI7Z0JBQ0QsVUFBVSxFQUFFLElBQUk7YUFDakIsQ0FBQztRQUNKLENBQUM7UUFFRCxvQ0FBb0M7UUFDcEMsTUFBTSxVQUFVLEdBQUcsTUFBTSxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUM5QyxNQUFNLFVBQVUsR0FBRyxVQUFVLEtBQUssQ0FBQyxDQUFDLENBQUM7UUFFckMsT0FBTztZQUNMLFFBQVEsRUFBRSxNQUFNO1lBQ2hCLGNBQWMsRUFBRTtnQkFDZCxRQUFRLEVBQUUsTUFBTTtnQkFDaEIsTUFBTSxFQUFFLE9BQU8sRUFBRSxNQUFNO2dCQUN2QixJQUFJLEVBQUUsT0FBTyxFQUFFLElBQUk7Z0JBQ25CLE1BQU0sRUFBRSxXQUFXLENBQUMsUUFBUSxFQUFFLE1BQXFCO2FBQ3BEO1lBQ0QsVUFBVTtZQUNWLFdBQVcsRUFBRSxVQUFVLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLE1BQU0sR0FBRyxHQUFHLENBQUMsd0JBQXdCO1NBQ25GLENBQUM7SUFDSixDQUFDO0lBRUQ7O09BRUc7SUFDSCxpQkFBaUIsQ0FDZixNQUFjLEVBQ2QsT0FBMkIsRUFDM0IsT0FBMkI7UUFFM0IsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDeEQsTUFBTSxZQUFZLEdBQUcsd0JBQXdCLENBQUMsa0JBQWtCLENBQUMsT0FBTyxDQUFDLENBQUM7UUFFMUUsZUFBZTtRQUNmLE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyxXQUFXLENBQUMsWUFBWSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBRXpELElBQUksTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ2pCLE9BQU8sQ0FBQyxRQUFRLENBQUMsWUFBWSxDQUFDLENBQUM7WUFDL0IsT0FBTyxJQUFJLENBQUM7UUFDZCxDQUFDO1FBRUQsc0NBQXNDO1FBQ3RDLE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLE1BQU8sRUFBRSxPQUFPLENBQUMsQ0FBQztRQUUxRCxJQUFJLFlBQVksSUFBSSxZQUFZLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDNUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUNqQyxDQUFDO1FBRUQsT0FBTyxZQUFZLENBQUM7SUFDdEIsQ0FBQztDQUNGIn0=
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Quick Protocol Detector
|
|
3
|
+
*
|
|
4
|
+
* Lightweight protocol identification based on minimal bytes
|
|
5
|
+
* No parsing, just identification
|
|
6
|
+
*/
|
|
7
|
+
import type { IProtocolDetector, IProtocolDetectionResult } from '../../protocols/common/types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Quick protocol detector for fast identification
|
|
10
|
+
*/
|
|
11
|
+
export declare class QuickProtocolDetector implements IProtocolDetector {
|
|
12
|
+
/**
|
|
13
|
+
* Check if this detector can handle the data
|
|
14
|
+
*/
|
|
15
|
+
canHandle(data: Buffer): boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Perform quick detection based on first few bytes
|
|
18
|
+
*/
|
|
19
|
+
quickDetect(data: Buffer): IProtocolDetectionResult;
|
|
20
|
+
/**
|
|
21
|
+
* Check if data looks like TLS
|
|
22
|
+
*/
|
|
23
|
+
private checkTls;
|
|
24
|
+
/**
|
|
25
|
+
* Check if data looks like HTTP
|
|
26
|
+
*/
|
|
27
|
+
private checkHttp;
|
|
28
|
+
}
|