@push.rocks/smartproxy 20.0.1 → 21.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/changelog.md +26 -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 +33 -0
- package/dist_ts/detection/detectors/tls-detector.js +106 -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 -1
- package/dist_ts/index.js +3 -2
- 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/models/route-types.js +1 -1
- 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/index.d.ts +1 -2
- package/dist_ts/proxies/smart-proxy/utils/index.js +3 -4
- package/dist_ts/proxies/smart-proxy/utils/route-helpers.d.ts +112 -8
- package/dist_ts/proxies/smart-proxy/utils/route-helpers.js +231 -76
- 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 +17 -8
- package/readme.md +471 -2345
- 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 +120 -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 -2
- 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 -1
- package/ts/proxies/smart-proxy/models/route-types.ts +0 -1
- 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/index.ts +2 -13
- package/ts/proxies/smart-proxy/utils/route-helpers.ts +323 -86
- package/ts/tls/index.ts +8 -12
- package/ts/tls/sni/sni-handler.ts +3 -3
- package/ts/forwarding/config/forwarding-types.ts +0 -76
- package/ts/forwarding/config/index.ts +0 -26
- package/ts/forwarding/factory/forwarding-factory.ts +0 -189
- package/ts/forwarding/factory/index.ts +0 -5
- package/ts/forwarding/handlers/base-handler.ts +0 -155
- package/ts/forwarding/handlers/http-handler.ts +0 -163
- package/ts/forwarding/handlers/https-passthrough-handler.ts +0 -185
- package/ts/forwarding/handlers/https-terminate-to-http-handler.ts +0 -312
- package/ts/forwarding/handlers/https-terminate-to-https-handler.ts +0 -297
- package/ts/forwarding/handlers/index.ts +0 -9
- package/ts/forwarding/index.ts +0 -35
- package/ts/proxies/smart-proxy/utils/route-patterns.ts +0 -403
- /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
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP Protocol Constants
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* HTTP methods
|
|
7
|
+
*/
|
|
8
|
+
export const HTTP_METHODS = [
|
|
9
|
+
'GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS', 'CONNECT', 'TRACE'
|
|
10
|
+
] as const;
|
|
11
|
+
|
|
12
|
+
export type THttpMethod = typeof HTTP_METHODS[number];
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* HTTP version strings
|
|
16
|
+
*/
|
|
17
|
+
export const HTTP_VERSIONS = ['HTTP/1.0', 'HTTP/1.1', 'HTTP/2', 'HTTP/3'] as const;
|
|
18
|
+
|
|
19
|
+
export type THttpVersion = typeof HTTP_VERSIONS[number];
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* HTTP status codes
|
|
23
|
+
*/
|
|
24
|
+
export enum HttpStatus {
|
|
25
|
+
// 1xx Informational
|
|
26
|
+
CONTINUE = 100,
|
|
27
|
+
SWITCHING_PROTOCOLS = 101,
|
|
28
|
+
PROCESSING = 102,
|
|
29
|
+
EARLY_HINTS = 103,
|
|
30
|
+
|
|
31
|
+
// 2xx Success
|
|
32
|
+
OK = 200,
|
|
33
|
+
CREATED = 201,
|
|
34
|
+
ACCEPTED = 202,
|
|
35
|
+
NON_AUTHORITATIVE_INFORMATION = 203,
|
|
36
|
+
NO_CONTENT = 204,
|
|
37
|
+
RESET_CONTENT = 205,
|
|
38
|
+
PARTIAL_CONTENT = 206,
|
|
39
|
+
MULTI_STATUS = 207,
|
|
40
|
+
ALREADY_REPORTED = 208,
|
|
41
|
+
IM_USED = 226,
|
|
42
|
+
|
|
43
|
+
// 3xx Redirection
|
|
44
|
+
MULTIPLE_CHOICES = 300,
|
|
45
|
+
MOVED_PERMANENTLY = 301,
|
|
46
|
+
FOUND = 302,
|
|
47
|
+
SEE_OTHER = 303,
|
|
48
|
+
NOT_MODIFIED = 304,
|
|
49
|
+
USE_PROXY = 305,
|
|
50
|
+
TEMPORARY_REDIRECT = 307,
|
|
51
|
+
PERMANENT_REDIRECT = 308,
|
|
52
|
+
|
|
53
|
+
// 4xx Client Error
|
|
54
|
+
BAD_REQUEST = 400,
|
|
55
|
+
UNAUTHORIZED = 401,
|
|
56
|
+
PAYMENT_REQUIRED = 402,
|
|
57
|
+
FORBIDDEN = 403,
|
|
58
|
+
NOT_FOUND = 404,
|
|
59
|
+
METHOD_NOT_ALLOWED = 405,
|
|
60
|
+
NOT_ACCEPTABLE = 406,
|
|
61
|
+
PROXY_AUTHENTICATION_REQUIRED = 407,
|
|
62
|
+
REQUEST_TIMEOUT = 408,
|
|
63
|
+
CONFLICT = 409,
|
|
64
|
+
GONE = 410,
|
|
65
|
+
LENGTH_REQUIRED = 411,
|
|
66
|
+
PRECONDITION_FAILED = 412,
|
|
67
|
+
PAYLOAD_TOO_LARGE = 413,
|
|
68
|
+
URI_TOO_LONG = 414,
|
|
69
|
+
UNSUPPORTED_MEDIA_TYPE = 415,
|
|
70
|
+
RANGE_NOT_SATISFIABLE = 416,
|
|
71
|
+
EXPECTATION_FAILED = 417,
|
|
72
|
+
IM_A_TEAPOT = 418,
|
|
73
|
+
MISDIRECTED_REQUEST = 421,
|
|
74
|
+
UNPROCESSABLE_ENTITY = 422,
|
|
75
|
+
LOCKED = 423,
|
|
76
|
+
FAILED_DEPENDENCY = 424,
|
|
77
|
+
TOO_EARLY = 425,
|
|
78
|
+
UPGRADE_REQUIRED = 426,
|
|
79
|
+
PRECONDITION_REQUIRED = 428,
|
|
80
|
+
TOO_MANY_REQUESTS = 429,
|
|
81
|
+
REQUEST_HEADER_FIELDS_TOO_LARGE = 431,
|
|
82
|
+
UNAVAILABLE_FOR_LEGAL_REASONS = 451,
|
|
83
|
+
|
|
84
|
+
// 5xx Server Error
|
|
85
|
+
INTERNAL_SERVER_ERROR = 500,
|
|
86
|
+
NOT_IMPLEMENTED = 501,
|
|
87
|
+
BAD_GATEWAY = 502,
|
|
88
|
+
SERVICE_UNAVAILABLE = 503,
|
|
89
|
+
GATEWAY_TIMEOUT = 504,
|
|
90
|
+
HTTP_VERSION_NOT_SUPPORTED = 505,
|
|
91
|
+
VARIANT_ALSO_NEGOTIATES = 506,
|
|
92
|
+
INSUFFICIENT_STORAGE = 507,
|
|
93
|
+
LOOP_DETECTED = 508,
|
|
94
|
+
NOT_EXTENDED = 510,
|
|
95
|
+
NETWORK_AUTHENTICATION_REQUIRED = 511,
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* HTTP status text mapping
|
|
100
|
+
*/
|
|
101
|
+
export const HTTP_STATUS_TEXT: Record<HttpStatus, string> = {
|
|
102
|
+
// 1xx
|
|
103
|
+
[HttpStatus.CONTINUE]: 'Continue',
|
|
104
|
+
[HttpStatus.SWITCHING_PROTOCOLS]: 'Switching Protocols',
|
|
105
|
+
[HttpStatus.PROCESSING]: 'Processing',
|
|
106
|
+
[HttpStatus.EARLY_HINTS]: 'Early Hints',
|
|
107
|
+
|
|
108
|
+
// 2xx
|
|
109
|
+
[HttpStatus.OK]: 'OK',
|
|
110
|
+
[HttpStatus.CREATED]: 'Created',
|
|
111
|
+
[HttpStatus.ACCEPTED]: 'Accepted',
|
|
112
|
+
[HttpStatus.NON_AUTHORITATIVE_INFORMATION]: 'Non-Authoritative Information',
|
|
113
|
+
[HttpStatus.NO_CONTENT]: 'No Content',
|
|
114
|
+
[HttpStatus.RESET_CONTENT]: 'Reset Content',
|
|
115
|
+
[HttpStatus.PARTIAL_CONTENT]: 'Partial Content',
|
|
116
|
+
[HttpStatus.MULTI_STATUS]: 'Multi-Status',
|
|
117
|
+
[HttpStatus.ALREADY_REPORTED]: 'Already Reported',
|
|
118
|
+
[HttpStatus.IM_USED]: 'IM Used',
|
|
119
|
+
|
|
120
|
+
// 3xx
|
|
121
|
+
[HttpStatus.MULTIPLE_CHOICES]: 'Multiple Choices',
|
|
122
|
+
[HttpStatus.MOVED_PERMANENTLY]: 'Moved Permanently',
|
|
123
|
+
[HttpStatus.FOUND]: 'Found',
|
|
124
|
+
[HttpStatus.SEE_OTHER]: 'See Other',
|
|
125
|
+
[HttpStatus.NOT_MODIFIED]: 'Not Modified',
|
|
126
|
+
[HttpStatus.USE_PROXY]: 'Use Proxy',
|
|
127
|
+
[HttpStatus.TEMPORARY_REDIRECT]: 'Temporary Redirect',
|
|
128
|
+
[HttpStatus.PERMANENT_REDIRECT]: 'Permanent Redirect',
|
|
129
|
+
|
|
130
|
+
// 4xx
|
|
131
|
+
[HttpStatus.BAD_REQUEST]: 'Bad Request',
|
|
132
|
+
[HttpStatus.UNAUTHORIZED]: 'Unauthorized',
|
|
133
|
+
[HttpStatus.PAYMENT_REQUIRED]: 'Payment Required',
|
|
134
|
+
[HttpStatus.FORBIDDEN]: 'Forbidden',
|
|
135
|
+
[HttpStatus.NOT_FOUND]: 'Not Found',
|
|
136
|
+
[HttpStatus.METHOD_NOT_ALLOWED]: 'Method Not Allowed',
|
|
137
|
+
[HttpStatus.NOT_ACCEPTABLE]: 'Not Acceptable',
|
|
138
|
+
[HttpStatus.PROXY_AUTHENTICATION_REQUIRED]: 'Proxy Authentication Required',
|
|
139
|
+
[HttpStatus.REQUEST_TIMEOUT]: 'Request Timeout',
|
|
140
|
+
[HttpStatus.CONFLICT]: 'Conflict',
|
|
141
|
+
[HttpStatus.GONE]: 'Gone',
|
|
142
|
+
[HttpStatus.LENGTH_REQUIRED]: 'Length Required',
|
|
143
|
+
[HttpStatus.PRECONDITION_FAILED]: 'Precondition Failed',
|
|
144
|
+
[HttpStatus.PAYLOAD_TOO_LARGE]: 'Payload Too Large',
|
|
145
|
+
[HttpStatus.URI_TOO_LONG]: 'URI Too Long',
|
|
146
|
+
[HttpStatus.UNSUPPORTED_MEDIA_TYPE]: 'Unsupported Media Type',
|
|
147
|
+
[HttpStatus.RANGE_NOT_SATISFIABLE]: 'Range Not Satisfiable',
|
|
148
|
+
[HttpStatus.EXPECTATION_FAILED]: 'Expectation Failed',
|
|
149
|
+
[HttpStatus.IM_A_TEAPOT]: "I'm a teapot",
|
|
150
|
+
[HttpStatus.MISDIRECTED_REQUEST]: 'Misdirected Request',
|
|
151
|
+
[HttpStatus.UNPROCESSABLE_ENTITY]: 'Unprocessable Entity',
|
|
152
|
+
[HttpStatus.LOCKED]: 'Locked',
|
|
153
|
+
[HttpStatus.FAILED_DEPENDENCY]: 'Failed Dependency',
|
|
154
|
+
[HttpStatus.TOO_EARLY]: 'Too Early',
|
|
155
|
+
[HttpStatus.UPGRADE_REQUIRED]: 'Upgrade Required',
|
|
156
|
+
[HttpStatus.PRECONDITION_REQUIRED]: 'Precondition Required',
|
|
157
|
+
[HttpStatus.TOO_MANY_REQUESTS]: 'Too Many Requests',
|
|
158
|
+
[HttpStatus.REQUEST_HEADER_FIELDS_TOO_LARGE]: 'Request Header Fields Too Large',
|
|
159
|
+
[HttpStatus.UNAVAILABLE_FOR_LEGAL_REASONS]: 'Unavailable For Legal Reasons',
|
|
160
|
+
|
|
161
|
+
// 5xx
|
|
162
|
+
[HttpStatus.INTERNAL_SERVER_ERROR]: 'Internal Server Error',
|
|
163
|
+
[HttpStatus.NOT_IMPLEMENTED]: 'Not Implemented',
|
|
164
|
+
[HttpStatus.BAD_GATEWAY]: 'Bad Gateway',
|
|
165
|
+
[HttpStatus.SERVICE_UNAVAILABLE]: 'Service Unavailable',
|
|
166
|
+
[HttpStatus.GATEWAY_TIMEOUT]: 'Gateway Timeout',
|
|
167
|
+
[HttpStatus.HTTP_VERSION_NOT_SUPPORTED]: 'HTTP Version Not Supported',
|
|
168
|
+
[HttpStatus.VARIANT_ALSO_NEGOTIATES]: 'Variant Also Negotiates',
|
|
169
|
+
[HttpStatus.INSUFFICIENT_STORAGE]: 'Insufficient Storage',
|
|
170
|
+
[HttpStatus.LOOP_DETECTED]: 'Loop Detected',
|
|
171
|
+
[HttpStatus.NOT_EXTENDED]: 'Not Extended',
|
|
172
|
+
[HttpStatus.NETWORK_AUTHENTICATION_REQUIRED]: 'Network Authentication Required',
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Common HTTP headers
|
|
177
|
+
*/
|
|
178
|
+
export const HTTP_HEADERS = {
|
|
179
|
+
// Request headers
|
|
180
|
+
HOST: 'host',
|
|
181
|
+
USER_AGENT: 'user-agent',
|
|
182
|
+
ACCEPT: 'accept',
|
|
183
|
+
ACCEPT_LANGUAGE: 'accept-language',
|
|
184
|
+
ACCEPT_ENCODING: 'accept-encoding',
|
|
185
|
+
AUTHORIZATION: 'authorization',
|
|
186
|
+
CACHE_CONTROL: 'cache-control',
|
|
187
|
+
CONNECTION: 'connection',
|
|
188
|
+
CONTENT_TYPE: 'content-type',
|
|
189
|
+
CONTENT_LENGTH: 'content-length',
|
|
190
|
+
COOKIE: 'cookie',
|
|
191
|
+
|
|
192
|
+
// Response headers
|
|
193
|
+
SET_COOKIE: 'set-cookie',
|
|
194
|
+
LOCATION: 'location',
|
|
195
|
+
SERVER: 'server',
|
|
196
|
+
DATE: 'date',
|
|
197
|
+
EXPIRES: 'expires',
|
|
198
|
+
LAST_MODIFIED: 'last-modified',
|
|
199
|
+
ETAG: 'etag',
|
|
200
|
+
|
|
201
|
+
// CORS headers
|
|
202
|
+
ACCESS_CONTROL_ALLOW_ORIGIN: 'access-control-allow-origin',
|
|
203
|
+
ACCESS_CONTROL_ALLOW_METHODS: 'access-control-allow-methods',
|
|
204
|
+
ACCESS_CONTROL_ALLOW_HEADERS: 'access-control-allow-headers',
|
|
205
|
+
|
|
206
|
+
// Security headers
|
|
207
|
+
STRICT_TRANSPORT_SECURITY: 'strict-transport-security',
|
|
208
|
+
X_CONTENT_TYPE_OPTIONS: 'x-content-type-options',
|
|
209
|
+
X_FRAME_OPTIONS: 'x-frame-options',
|
|
210
|
+
X_XSS_PROTECTION: 'x-xss-protection',
|
|
211
|
+
CONTENT_SECURITY_POLICY: 'content-security-policy',
|
|
212
|
+
} as const;
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Get HTTP status text
|
|
216
|
+
*/
|
|
217
|
+
export function getStatusText(status: HttpStatus): string {
|
|
218
|
+
return HTTP_STATUS_TEXT[status] || 'Unknown';
|
|
219
|
+
}
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP Protocol Parser
|
|
3
|
+
* Generic HTTP parsing utilities
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { HTTP_METHODS, type THttpMethod, type THttpVersion } from './constants.js';
|
|
7
|
+
import type { IHttpRequestLine, IHttpHeader } from './types.js';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* HTTP parser utilities
|
|
11
|
+
*/
|
|
12
|
+
export class HttpParser {
|
|
13
|
+
/**
|
|
14
|
+
* Check if string is a valid HTTP method
|
|
15
|
+
*/
|
|
16
|
+
static isHttpMethod(str: string): str is THttpMethod {
|
|
17
|
+
return HTTP_METHODS.includes(str as THttpMethod);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Parse HTTP request line
|
|
22
|
+
*/
|
|
23
|
+
static parseRequestLine(line: string): IHttpRequestLine | null {
|
|
24
|
+
const parts = line.trim().split(' ');
|
|
25
|
+
|
|
26
|
+
if (parts.length !== 3) {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const [method, path, version] = parts;
|
|
31
|
+
|
|
32
|
+
// Validate method
|
|
33
|
+
if (!this.isHttpMethod(method)) {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Validate version
|
|
38
|
+
if (!version.startsWith('HTTP/')) {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return {
|
|
43
|
+
method: method as THttpMethod,
|
|
44
|
+
path,
|
|
45
|
+
version: version as THttpVersion
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Parse HTTP header line
|
|
51
|
+
*/
|
|
52
|
+
static parseHeaderLine(line: string): IHttpHeader | null {
|
|
53
|
+
const colonIndex = line.indexOf(':');
|
|
54
|
+
|
|
55
|
+
if (colonIndex === -1) {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const name = line.slice(0, colonIndex).trim();
|
|
60
|
+
const value = line.slice(colonIndex + 1).trim();
|
|
61
|
+
|
|
62
|
+
if (!name) {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return { name, value };
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Parse HTTP headers from lines
|
|
71
|
+
*/
|
|
72
|
+
static parseHeaders(lines: string[]): Record<string, string> {
|
|
73
|
+
const headers: Record<string, string> = {};
|
|
74
|
+
|
|
75
|
+
for (const line of lines) {
|
|
76
|
+
const header = this.parseHeaderLine(line);
|
|
77
|
+
if (header) {
|
|
78
|
+
// Convert header names to lowercase for consistency
|
|
79
|
+
headers[header.name.toLowerCase()] = header.value;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return headers;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Extract domain from Host header value
|
|
88
|
+
*/
|
|
89
|
+
static extractDomainFromHost(hostHeader: string): string {
|
|
90
|
+
// Remove port if present
|
|
91
|
+
const colonIndex = hostHeader.lastIndexOf(':');
|
|
92
|
+
if (colonIndex !== -1) {
|
|
93
|
+
// Check if it's not part of IPv6 address
|
|
94
|
+
const beforeColon = hostHeader.slice(0, colonIndex);
|
|
95
|
+
if (!beforeColon.includes(']')) {
|
|
96
|
+
return beforeColon;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return hostHeader;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Validate domain name
|
|
104
|
+
*/
|
|
105
|
+
static isValidDomain(domain: string): boolean {
|
|
106
|
+
// Basic domain validation
|
|
107
|
+
if (!domain || domain.length > 253) {
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Check for valid characters and structure
|
|
112
|
+
const domainRegex = /^(?!-)[A-Za-z0-9-]{1,63}(?<!-)(\.[A-Za-z0-9-]{1,63})*$/;
|
|
113
|
+
return domainRegex.test(domain);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Extract line from buffer
|
|
118
|
+
*/
|
|
119
|
+
static extractLine(buffer: Buffer, offset: number = 0): { line: string; nextOffset: number } | null {
|
|
120
|
+
// Look for CRLF
|
|
121
|
+
const crlfIndex = buffer.indexOf('\r\n', offset);
|
|
122
|
+
if (crlfIndex === -1) {
|
|
123
|
+
// Look for just LF
|
|
124
|
+
const lfIndex = buffer.indexOf('\n', offset);
|
|
125
|
+
if (lfIndex === -1) {
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return {
|
|
130
|
+
line: buffer.slice(offset, lfIndex).toString('utf8'),
|
|
131
|
+
nextOffset: lfIndex + 1
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return {
|
|
136
|
+
line: buffer.slice(offset, crlfIndex).toString('utf8'),
|
|
137
|
+
nextOffset: crlfIndex + 2
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Check if buffer contains printable ASCII
|
|
143
|
+
*/
|
|
144
|
+
static isPrintableAscii(buffer: Buffer, length?: number): boolean {
|
|
145
|
+
const checkLength = Math.min(length || buffer.length, buffer.length);
|
|
146
|
+
|
|
147
|
+
for (let i = 0; i < checkLength; i++) {
|
|
148
|
+
const byte = buffer[i];
|
|
149
|
+
// Allow printable ASCII (32-126) plus tab (9), LF (10), and CR (13)
|
|
150
|
+
if (byte < 32 || byte > 126) {
|
|
151
|
+
if (byte !== 9 && byte !== 10 && byte !== 13) {
|
|
152
|
+
return false;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return true;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Quick check if buffer starts with HTTP method
|
|
162
|
+
*/
|
|
163
|
+
static quickCheck(buffer: Buffer): boolean {
|
|
164
|
+
if (buffer.length < 3) {
|
|
165
|
+
return false;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Check common HTTP methods
|
|
169
|
+
const start = buffer.slice(0, 7).toString('ascii');
|
|
170
|
+
return start.startsWith('GET ') ||
|
|
171
|
+
start.startsWith('POST ') ||
|
|
172
|
+
start.startsWith('PUT ') ||
|
|
173
|
+
start.startsWith('DELETE ') ||
|
|
174
|
+
start.startsWith('HEAD ') ||
|
|
175
|
+
start.startsWith('OPTIONS') ||
|
|
176
|
+
start.startsWith('PATCH ') ||
|
|
177
|
+
start.startsWith('CONNECT') ||
|
|
178
|
+
start.startsWith('TRACE ');
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Parse query string
|
|
183
|
+
*/
|
|
184
|
+
static parseQueryString(queryString: string): Record<string, string> {
|
|
185
|
+
const params: Record<string, string> = {};
|
|
186
|
+
|
|
187
|
+
if (!queryString) {
|
|
188
|
+
return params;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// Remove leading '?' if present
|
|
192
|
+
if (queryString.startsWith('?')) {
|
|
193
|
+
queryString = queryString.slice(1);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const pairs = queryString.split('&');
|
|
197
|
+
for (const pair of pairs) {
|
|
198
|
+
const [key, value] = pair.split('=');
|
|
199
|
+
if (key) {
|
|
200
|
+
params[decodeURIComponent(key)] = value ? decodeURIComponent(value) : '';
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
return params;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Build query string from params
|
|
209
|
+
*/
|
|
210
|
+
static buildQueryString(params: Record<string, string>): string {
|
|
211
|
+
const pairs: string[] = [];
|
|
212
|
+
|
|
213
|
+
for (const [key, value] of Object.entries(params)) {
|
|
214
|
+
pairs.push(`${encodeURIComponent(key)}=${encodeURIComponent(value)}`);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
return pairs.length > 0 ? '?' + pairs.join('&') : '';
|
|
218
|
+
}
|
|
219
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP Protocol Type Definitions
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { THttpMethod, THttpVersion, HttpStatus } from './constants.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* HTTP request line structure
|
|
9
|
+
*/
|
|
10
|
+
export interface IHttpRequestLine {
|
|
11
|
+
method: THttpMethod;
|
|
12
|
+
path: string;
|
|
13
|
+
version: THttpVersion;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* HTTP response line structure
|
|
18
|
+
*/
|
|
19
|
+
export interface IHttpResponseLine {
|
|
20
|
+
version: THttpVersion;
|
|
21
|
+
status: HttpStatus;
|
|
22
|
+
statusText: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* HTTP header structure
|
|
27
|
+
*/
|
|
28
|
+
export interface IHttpHeader {
|
|
29
|
+
name: string;
|
|
30
|
+
value: string;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* HTTP message structure (base for request and response)
|
|
35
|
+
*/
|
|
36
|
+
export interface IHttpMessage {
|
|
37
|
+
headers: Record<string, string>;
|
|
38
|
+
body?: Buffer;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* HTTP request structure
|
|
43
|
+
*/
|
|
44
|
+
export interface IHttpRequest extends IHttpMessage {
|
|
45
|
+
method: THttpMethod;
|
|
46
|
+
path: string;
|
|
47
|
+
version: THttpVersion;
|
|
48
|
+
query?: Record<string, string>;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* HTTP response structure
|
|
53
|
+
*/
|
|
54
|
+
export interface IHttpResponse extends IHttpMessage {
|
|
55
|
+
status: HttpStatus;
|
|
56
|
+
statusText: string;
|
|
57
|
+
version: THttpVersion;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Parsed URL structure
|
|
62
|
+
*/
|
|
63
|
+
export interface IParsedUrl {
|
|
64
|
+
protocol?: string;
|
|
65
|
+
hostname?: string;
|
|
66
|
+
port?: number;
|
|
67
|
+
path?: string;
|
|
68
|
+
query?: string;
|
|
69
|
+
fragment?: string;
|
|
70
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Protocol-specific modules for smartproxy
|
|
3
|
+
*
|
|
4
|
+
* This directory contains generic protocol knowledge separated from
|
|
5
|
+
* smartproxy-specific implementation details.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export * as common from './common/index.js';
|
|
9
|
+
export * as tls from './tls/index.js';
|
|
10
|
+
export * as http from './http/index.js';
|
|
11
|
+
export * as proxy from './proxy/index.js';
|
|
12
|
+
export * as websocket from './websocket/index.js';
|