@api-client/core 0.18.11 → 0.18.13
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/build/src/browser.d.ts +0 -3
- package/build/src/browser.d.ts.map +1 -1
- package/build/src/browser.js +0 -3
- package/build/src/browser.js.map +1 -1
- package/build/src/index.d.ts +2 -5
- package/build/src/index.d.ts.map +1 -1
- package/build/src/index.js +2 -5
- package/build/src/index.js.map +1 -1
- package/build/src/lib/logging/DefaultLogger.d.ts +14 -0
- package/build/src/lib/logging/DefaultLogger.d.ts.map +1 -1
- package/build/src/lib/logging/DefaultLogger.js +27 -0
- package/build/src/lib/logging/DefaultLogger.js.map +1 -1
- package/build/src/lib/logging/index.d.ts +4 -0
- package/build/src/lib/logging/index.d.ts.map +1 -0
- package/build/src/lib/logging/index.js +10 -0
- package/build/src/lib/logging/index.js.map +1 -0
- package/build/src/modeling/DomainModel.d.ts.map +1 -1
- package/build/src/modeling/DomainModel.js +11 -4
- package/build/src/modeling/DomainModel.js.map +1 -1
- package/build/src/models/ClientCertificate.d.ts +1 -1
- package/build/src/models/ClientCertificate.js.map +1 -1
- package/build/src/models/RequestConfig.d.ts +1 -1
- package/build/src/models/RequestConfig.js.map +1 -1
- package/build/src/models/SerializableError.d.ts +1 -1
- package/build/src/models/SerializableError.d.ts.map +1 -1
- package/build/src/models/SerializableError.js.map +1 -1
- package/build/src/proxy/RequestProxy.d.ts.map +1 -1
- package/build/src/proxy/RequestProxy.js +2 -2
- package/build/src/proxy/RequestProxy.js.map +1 -1
- package/build/src/runtime/http-engine/CoreEngine.d.ts +218 -139
- package/build/src/runtime/http-engine/CoreEngine.d.ts.map +1 -1
- package/build/src/runtime/http-engine/CoreEngine.js +716 -870
- package/build/src/runtime/http-engine/CoreEngine.js.map +1 -1
- package/build/src/runtime/http-engine/PayloadSupport.d.ts.map +1 -1
- package/build/src/runtime/http-engine/PayloadSupport.js +2 -1
- package/build/src/runtime/http-engine/PayloadSupport.js.map +1 -1
- package/build/src/runtime/http-engine/auth/AuthManager.d.ts +73 -0
- package/build/src/runtime/http-engine/auth/AuthManager.d.ts.map +1 -0
- package/build/src/runtime/http-engine/auth/AuthManager.js +186 -0
- package/build/src/runtime/http-engine/auth/AuthManager.js.map +1 -0
- package/build/src/runtime/http-engine/auth/index.d.ts +2 -0
- package/build/src/runtime/http-engine/auth/index.d.ts.map +1 -0
- package/build/src/runtime/http-engine/auth/index.js +2 -0
- package/build/src/runtime/http-engine/auth/index.js.map +1 -0
- package/build/src/runtime/http-engine/certificates/CertificateManager.d.ts +11 -0
- package/build/src/runtime/http-engine/certificates/CertificateManager.d.ts.map +1 -0
- package/build/src/runtime/http-engine/certificates/CertificateManager.js +76 -0
- package/build/src/runtime/http-engine/certificates/CertificateManager.js.map +1 -0
- package/build/src/runtime/http-engine/certificates/index.d.ts +2 -0
- package/build/src/runtime/http-engine/certificates/index.d.ts.map +1 -0
- package/build/src/runtime/http-engine/certificates/index.js +2 -0
- package/build/src/runtime/http-engine/certificates/index.js.map +1 -0
- package/build/src/runtime/http-engine/compression/CompressionManager.d.ts +25 -0
- package/build/src/runtime/http-engine/compression/CompressionManager.d.ts.map +1 -0
- package/build/src/runtime/http-engine/compression/CompressionManager.js +89 -0
- package/build/src/runtime/http-engine/compression/CompressionManager.js.map +1 -0
- package/build/src/runtime/http-engine/compression/index.d.ts +2 -0
- package/build/src/runtime/http-engine/compression/index.d.ts.map +1 -0
- package/build/src/runtime/http-engine/compression/index.js +2 -0
- package/build/src/runtime/http-engine/compression/index.js.map +1 -0
- package/build/src/runtime/http-engine/connections/ConnectionManager.d.ts +57 -0
- package/build/src/runtime/http-engine/connections/ConnectionManager.d.ts.map +1 -0
- package/build/src/runtime/http-engine/connections/ConnectionManager.js +78 -0
- package/build/src/runtime/http-engine/connections/ConnectionManager.js.map +1 -0
- package/build/src/runtime/http-engine/connections/DigestAuthHandler.d.ts +70 -0
- package/build/src/runtime/http-engine/connections/DigestAuthHandler.d.ts.map +1 -0
- package/build/src/runtime/http-engine/connections/DigestAuthHandler.js +184 -0
- package/build/src/runtime/http-engine/connections/DigestAuthHandler.js.map +1 -0
- package/build/src/runtime/http-engine/connections/DirectConnection.d.ts +22 -0
- package/build/src/runtime/http-engine/connections/DirectConnection.d.ts.map +1 -0
- package/build/src/runtime/http-engine/connections/DirectConnection.js +105 -0
- package/build/src/runtime/http-engine/connections/DirectConnection.js.map +1 -0
- package/build/src/runtime/http-engine/connections/ProxyAuthHandler.d.ts +60 -0
- package/build/src/runtime/http-engine/connections/ProxyAuthHandler.d.ts.map +1 -0
- package/build/src/runtime/http-engine/connections/ProxyAuthHandler.js +138 -0
- package/build/src/runtime/http-engine/connections/ProxyAuthHandler.js.map +1 -0
- package/build/src/runtime/http-engine/connections/ProxyConnection.d.ts +14 -0
- package/build/src/runtime/http-engine/connections/ProxyConnection.d.ts.map +1 -0
- package/build/src/runtime/http-engine/connections/ProxyConnection.js +47 -0
- package/build/src/runtime/http-engine/connections/ProxyConnection.js.map +1 -0
- package/build/src/runtime/http-engine/connections/TunnelConnection.d.ts +13 -0
- package/build/src/runtime/http-engine/connections/TunnelConnection.d.ts.map +1 -0
- package/build/src/runtime/http-engine/connections/TunnelConnection.js +175 -0
- package/build/src/runtime/http-engine/connections/TunnelConnection.js.map +1 -0
- package/build/src/runtime/http-engine/connections/index.d.ts +7 -0
- package/build/src/runtime/http-engine/connections/index.d.ts.map +1 -0
- package/build/src/runtime/http-engine/connections/index.js +7 -0
- package/build/src/runtime/http-engine/connections/index.js.map +1 -0
- package/build/src/runtime/http-engine/constants.d.ts +69 -0
- package/build/src/runtime/http-engine/constants.d.ts.map +1 -0
- package/build/src/runtime/http-engine/constants.js +90 -0
- package/build/src/runtime/http-engine/constants.js.map +1 -0
- package/build/src/runtime/http-engine/cookies/CookieProcessor.d.ts +5 -0
- package/build/src/runtime/http-engine/cookies/CookieProcessor.d.ts.map +1 -0
- package/build/src/runtime/http-engine/cookies/CookieProcessor.js +20 -0
- package/build/src/runtime/http-engine/cookies/CookieProcessor.js.map +1 -0
- package/build/src/runtime/http-engine/cookies/index.d.ts +2 -0
- package/build/src/runtime/http-engine/cookies/index.d.ts.map +1 -0
- package/build/src/runtime/http-engine/cookies/index.js +2 -0
- package/build/src/runtime/http-engine/cookies/index.js.map +1 -0
- package/build/src/runtime/http-engine/errors/HttpEngineErrors.d.ts +156 -0
- package/build/src/runtime/http-engine/errors/HttpEngineErrors.d.ts.map +1 -0
- package/build/src/runtime/http-engine/errors/HttpEngineErrors.js +227 -0
- package/build/src/runtime/http-engine/errors/HttpEngineErrors.js.map +1 -0
- package/build/src/runtime/http-engine/errors/index.d.ts +2 -0
- package/build/src/runtime/http-engine/errors/index.d.ts.map +1 -0
- package/build/src/runtime/http-engine/errors/index.js +2 -0
- package/build/src/runtime/http-engine/errors/index.js.map +1 -0
- package/build/src/runtime/http-engine/message/MessageBuilder.d.ts +66 -0
- package/build/src/runtime/http-engine/message/MessageBuilder.d.ts.map +1 -0
- package/build/src/runtime/http-engine/message/MessageBuilder.js +161 -0
- package/build/src/runtime/http-engine/message/MessageBuilder.js.map +1 -0
- package/build/src/runtime/http-engine/message/MessageProcessor.d.ts +27 -0
- package/build/src/runtime/http-engine/message/MessageProcessor.d.ts.map +1 -0
- package/build/src/runtime/http-engine/message/MessageProcessor.js +51 -0
- package/build/src/runtime/http-engine/message/MessageProcessor.js.map +1 -0
- package/build/src/runtime/http-engine/message/index.d.ts +3 -0
- package/build/src/runtime/http-engine/message/index.d.ts.map +1 -0
- package/build/src/runtime/http-engine/message/index.js +3 -0
- package/build/src/runtime/http-engine/message/index.js.map +1 -0
- package/build/src/runtime/http-engine/ntlm/NtlmAuth.d.ts +2 -8
- package/build/src/runtime/http-engine/ntlm/NtlmAuth.d.ts.map +1 -1
- package/build/src/runtime/http-engine/ntlm/NtlmAuth.js +11 -5
- package/build/src/runtime/http-engine/ntlm/NtlmAuth.js.map +1 -1
- package/build/src/runtime/http-engine/ntlm/NtlmMessage.js +6 -6
- package/build/src/runtime/http-engine/ntlm/NtlmMessage.js.map +1 -1
- package/build/src/runtime/http-engine/parsers/BodyParser.d.ts +39 -0
- package/build/src/runtime/http-engine/parsers/BodyParser.d.ts.map +1 -0
- package/build/src/runtime/http-engine/parsers/BodyParser.js +145 -0
- package/build/src/runtime/http-engine/parsers/BodyParser.js.map +1 -0
- package/build/src/runtime/http-engine/parsers/HeadersParser.d.ts +29 -0
- package/build/src/runtime/http-engine/parsers/HeadersParser.d.ts.map +1 -0
- package/build/src/runtime/http-engine/parsers/HeadersParser.js +88 -0
- package/build/src/runtime/http-engine/parsers/HeadersParser.js.map +1 -0
- package/build/src/runtime/http-engine/parsers/HttpResponseParser.d.ts +91 -0
- package/build/src/runtime/http-engine/parsers/HttpResponseParser.d.ts.map +1 -0
- package/build/src/runtime/http-engine/parsers/HttpResponseParser.js +236 -0
- package/build/src/runtime/http-engine/parsers/HttpResponseParser.js.map +1 -0
- package/build/src/runtime/http-engine/parsers/StatusParser.d.ts +20 -0
- package/build/src/runtime/http-engine/parsers/StatusParser.d.ts.map +1 -0
- package/build/src/runtime/http-engine/parsers/StatusParser.js +51 -0
- package/build/src/runtime/http-engine/parsers/StatusParser.js.map +1 -0
- package/build/src/runtime/http-engine/parsers/index.d.ts +5 -0
- package/build/src/runtime/http-engine/parsers/index.d.ts.map +1 -0
- package/build/src/runtime/http-engine/parsers/index.js +5 -0
- package/build/src/runtime/http-engine/parsers/index.js.map +1 -0
- package/build/src/runtime/http-engine/response/ResponseProcessor.d.ts +22 -0
- package/build/src/runtime/http-engine/response/ResponseProcessor.d.ts.map +1 -0
- package/build/src/runtime/http-engine/response/ResponseProcessor.js +25 -0
- package/build/src/runtime/http-engine/response/ResponseProcessor.js.map +1 -0
- package/build/src/runtime/http-engine/response/index.d.ts +2 -0
- package/build/src/runtime/http-engine/response/index.d.ts.map +1 -0
- package/build/src/runtime/http-engine/response/index.js +2 -0
- package/build/src/runtime/http-engine/response/index.js.map +1 -0
- package/build/src/runtime/http-engine/statistics/StatisticsProcessor.d.ts +7 -0
- package/build/src/runtime/http-engine/statistics/StatisticsProcessor.d.ts.map +1 -0
- package/build/src/runtime/http-engine/statistics/StatisticsProcessor.js +40 -0
- package/build/src/runtime/http-engine/statistics/StatisticsProcessor.js.map +1 -0
- package/build/src/runtime/http-engine/statistics/index.d.ts +2 -0
- package/build/src/runtime/http-engine/statistics/index.d.ts.map +1 -0
- package/build/src/runtime/http-engine/statistics/index.js +2 -0
- package/build/src/runtime/http-engine/statistics/index.js.map +1 -0
- package/build/src/runtime/http-engine/url/UrlProcessor.d.ts +24 -0
- package/build/src/runtime/http-engine/url/UrlProcessor.d.ts.map +1 -0
- package/build/src/runtime/http-engine/url/UrlProcessor.js +50 -0
- package/build/src/runtime/http-engine/url/UrlProcessor.js.map +1 -0
- package/build/src/runtime/http-engine/url/index.d.ts +2 -0
- package/build/src/runtime/http-engine/url/index.d.ts.map +1 -0
- package/build/src/runtime/http-engine/url/index.js +2 -0
- package/build/src/runtime/http-engine/url/index.js.map +1 -0
- package/build/src/runtime/http-runner/HttpRequestRunner.d.ts +3 -3
- package/build/src/runtime/http-runner/HttpRequestRunner.d.ts.map +1 -1
- package/build/src/runtime/http-runner/HttpRequestRunner.js.map +1 -1
- package/build/src/runtime/node/InteropInterfaces.d.ts +3 -3
- package/build/src/runtime/node/InteropInterfaces.d.ts.map +1 -1
- package/build/src/runtime/node/InteropInterfaces.js.map +1 -1
- package/build/src/runtime/node/ProjectRequestRunner.d.ts +2 -2
- package/build/src/runtime/node/ProjectRequestRunner.d.ts.map +1 -1
- package/build/src/runtime/node/ProjectRequestRunner.js.map +1 -1
- package/build/src/runtime/node/ProjectRunner.d.ts.map +1 -1
- package/build/src/runtime/node/ProjectRunner.js +2 -2
- package/build/src/runtime/node/ProjectRunner.js.map +1 -1
- package/build/tsconfig.tsbuildinfo +1 -1
- package/data/models/example-generator-api.json +24 -24
- package/package.json +2 -2
- package/src/lib/logging/DefaultLogger.ts +32 -0
- package/src/modeling/DomainModel.ts +11 -4
- package/src/models/ClientCertificate.ts +1 -1
- package/src/models/RequestConfig.ts +1 -1
- package/src/models/SerializableError.ts +1 -1
- package/src/proxy/RequestProxy.ts +2 -2
- package/src/runtime/http-engine/CoreEngine.ts +858 -893
- package/src/runtime/http-engine/PayloadSupport.ts +2 -1
- package/src/runtime/http-engine/auth/AuthManager.ts +242 -0
- package/src/runtime/http-engine/certificates/CertificateManager.ts +74 -0
- package/src/runtime/http-engine/compression/CompressionManager.ts +99 -0
- package/src/runtime/http-engine/connections/ConnectionManager.ts +123 -0
- package/src/runtime/http-engine/connections/DigestAuthHandler.ts +238 -0
- package/src/runtime/http-engine/connections/DirectConnection.ts +134 -0
- package/src/runtime/http-engine/connections/ProxyAuthHandler.ts +179 -0
- package/src/runtime/http-engine/connections/ProxyConnection.ts +55 -0
- package/src/runtime/http-engine/connections/TunnelConnection.ts +192 -0
- package/src/runtime/http-engine/constants.ts +103 -0
- package/src/runtime/http-engine/cookies/CookieProcessor.ts +25 -0
- package/src/runtime/http-engine/errors/HttpEngineErrors.ts +319 -0
- package/src/runtime/http-engine/message/MessageBuilder.ts +201 -0
- package/src/runtime/http-engine/message/MessageProcessor.ts +73 -0
- package/src/runtime/http-engine/ntlm/NtlmAuth.ts +16 -13
- package/src/runtime/http-engine/ntlm/NtlmMessage.ts +6 -6
- package/src/runtime/http-engine/parsers/BodyParser.ts +171 -0
- package/src/runtime/http-engine/parsers/HeadersParser.ts +103 -0
- package/src/runtime/http-engine/parsers/HttpResponseParser.ts +280 -0
- package/src/runtime/http-engine/parsers/StatusParser.ts +69 -0
- package/src/runtime/http-engine/response/ResponseProcessor.ts +46 -0
- package/src/runtime/http-engine/statistics/StatisticsProcessor.ts +52 -0
- package/src/runtime/http-engine/url/UrlProcessor.ts +55 -0
- package/src/runtime/http-runner/HttpRequestRunner.ts +3 -3
- package/src/runtime/node/InteropInterfaces.ts +3 -3
- package/src/runtime/node/ProjectRequestRunner.ts +2 -2
- package/src/runtime/node/ProjectRunner.ts +2 -2
- package/tests/servers/ProxyServer.ts +32 -19
- package/tests/servers/express-routes/ApiEndpoint.ts +24 -0
- package/tests/servers/express-routes/BasicAuthRoute.ts +36 -0
- package/tests/servers/express-routes/BearerAuthRoute.ts +35 -0
- package/tests/servers/express-routes/NTLMRoute.ts +2 -3
- package/tests/servers/express-routes/PostApi.ts +15 -2
- package/tests/servers/express-routes/RedirectsApi.ts +12 -1
- package/tests/servers/express-routes/ResponsesApi.ts +1 -1
- package/tests/servers/express-routes/StreamApi.ts +19 -0
- package/tests/servers/oauth2mock/ServerMock.js +1 -1
- package/tests/unit/modeling/domain_model_entities.spec.ts +306 -1
- package/tests/unit/runtime/http-engine/HttpResponseParser.spec.ts +337 -0
- package/tests/unit/runtime/http-engine/abort.spec.ts +4 -5
- package/tests/unit/runtime/http-engine/auth.spec.ts +7 -58
- package/tests/unit/runtime/http-engine/certificates/CertificateManager.spec.ts +482 -0
- package/tests/unit/runtime/http-engine/certificates.spec.ts +2 -2
- package/tests/unit/runtime/http-engine/compression/CompressionManager.spec.ts +498 -0
- package/tests/unit/runtime/http-engine/compression.spec.ts +3 -72
- package/tests/unit/runtime/http-engine/connections/ConnectionManager.spec.ts +379 -0
- package/tests/unit/runtime/http-engine/connections/DigestAuthHandler.spec.ts +164 -0
- package/tests/unit/runtime/http-engine/core_engine.spec.ts +561 -0
- package/tests/unit/runtime/http-engine/engine_statuses.spec.ts +2 -2
- package/tests/unit/runtime/http-engine/events.spec.ts +2 -2
- package/tests/unit/runtime/http-engine/headers.spec.ts +2 -88
- package/tests/unit/runtime/http-engine/hosts.spec.ts +2 -2
- package/tests/unit/runtime/http-engine/http-get.spec.ts +2 -2
- package/tests/unit/runtime/http-engine/http-post.spec.ts +2 -2
- package/tests/unit/runtime/http-engine/logger.spec.ts +0 -8
- package/tests/unit/runtime/http-engine/message.spec.ts +2 -194
- package/tests/unit/runtime/http-engine/params.spec.ts +4 -4
- package/tests/unit/runtime/http-engine/proxy.spec.ts +15 -14
- package/tests/unit/runtime/http-engine/redirects.spec.ts +2 -2
- package/tests/unit/runtime/http-engine/responses.spec.ts +170 -277
- package/tests/unit/runtime/http-engine/timeout.spec.ts +3 -3
- package/tests/unit/runtime/http-engine/timings.spec.ts +2 -2
- package/tests/unit/runtime/proxy/HttpProjectProxy.spec.ts +25 -28
- package/tests/unit/runtime/runners/project_runner.spec.ts +2 -2
- package/tests/unit/runtime/runners/request_runner.spec.ts +2 -2
- package/build/src/runtime/http-engine/HttpEngine.d.ts +0 -311
- package/build/src/runtime/http-engine/HttpEngine.d.ts.map +0 -1
- package/build/src/runtime/http-engine/HttpEngine.js +0 -802
- package/build/src/runtime/http-engine/HttpEngine.js.map +0 -1
- package/src/runtime/http-engine/HttpEngine.ts +0 -952
- package/tests/unit/runtime/http-engine/connecting.spec.ts +0 -140
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
import crypto from 'node:crypto'
|
|
2
|
+
import { type Logger, type ILogObj } from '../../../lib/logging/index.js'
|
|
3
|
+
|
|
4
|
+
export interface DigestChallenge {
|
|
5
|
+
realm: string
|
|
6
|
+
nonce: string
|
|
7
|
+
qop?: string
|
|
8
|
+
algorithm?: string
|
|
9
|
+
opaque?: string
|
|
10
|
+
stale?: string
|
|
11
|
+
domain?: string
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface DigestResponse {
|
|
15
|
+
username: string
|
|
16
|
+
realm: string
|
|
17
|
+
nonce: string
|
|
18
|
+
uri: string
|
|
19
|
+
response: string
|
|
20
|
+
qop?: string
|
|
21
|
+
nc?: string
|
|
22
|
+
cnonce?: string
|
|
23
|
+
algorithm?: string
|
|
24
|
+
opaque?: string
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Handles HTTP Digest authentication according to RFC 2617
|
|
29
|
+
*/
|
|
30
|
+
export class DigestAuthHandler {
|
|
31
|
+
private logger: Logger<ILogObj>
|
|
32
|
+
private username: string
|
|
33
|
+
private password: string
|
|
34
|
+
private nc = 1
|
|
35
|
+
private cnonce: string
|
|
36
|
+
|
|
37
|
+
constructor(username: string, password: string, logger: Logger<ILogObj>) {
|
|
38
|
+
this.username = username
|
|
39
|
+
this.password = password
|
|
40
|
+
this.logger = logger
|
|
41
|
+
this.cnonce = this.generateCnonce()
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Parse a WWW-Authenticate or Proxy-Authenticate header
|
|
46
|
+
*/
|
|
47
|
+
parseChallenge(authenticateHeader: string): DigestChallenge {
|
|
48
|
+
const challenge: DigestChallenge = { realm: '', nonce: '' }
|
|
49
|
+
|
|
50
|
+
// Extract the method (Digest)
|
|
51
|
+
const methodMatch = authenticateHeader.match(/^(\w+)/)
|
|
52
|
+
if (!methodMatch || methodMatch[1].toLowerCase() !== 'digest') {
|
|
53
|
+
throw new Error('Not a Digest authentication challenge')
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Parse key-value pairs (both quoted and unquoted)
|
|
57
|
+
const paramRegex = /(\w+)=(?:"([^"]*)"|([^,\s]+))/g
|
|
58
|
+
let match
|
|
59
|
+
while ((match = paramRegex.exec(authenticateHeader)) !== null) {
|
|
60
|
+
const [, key, quotedValue, unquotedValue] = match
|
|
61
|
+
const value = quotedValue !== undefined ? quotedValue : unquotedValue
|
|
62
|
+
|
|
63
|
+
switch (key.toLowerCase()) {
|
|
64
|
+
case 'realm':
|
|
65
|
+
challenge.realm = value
|
|
66
|
+
break
|
|
67
|
+
case 'nonce':
|
|
68
|
+
challenge.nonce = value
|
|
69
|
+
break
|
|
70
|
+
case 'qop':
|
|
71
|
+
challenge.qop = value
|
|
72
|
+
break
|
|
73
|
+
case 'algorithm':
|
|
74
|
+
challenge.algorithm = value
|
|
75
|
+
break
|
|
76
|
+
case 'opaque':
|
|
77
|
+
challenge.opaque = value
|
|
78
|
+
break
|
|
79
|
+
case 'stale':
|
|
80
|
+
challenge.stale = value
|
|
81
|
+
break
|
|
82
|
+
case 'domain':
|
|
83
|
+
challenge.domain = value
|
|
84
|
+
break
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Validate required fields
|
|
89
|
+
if (!challenge.realm || !challenge.nonce) {
|
|
90
|
+
throw new Error('Invalid Digest challenge: missing realm or nonce')
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
this.logger.debug('Parsed Digest challenge:', challenge)
|
|
94
|
+
return challenge
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Generate a Digest authentication response
|
|
99
|
+
*/
|
|
100
|
+
generateResponse(challenge: DigestChallenge, method: string, uri: string): string {
|
|
101
|
+
const algorithm = challenge.algorithm?.toLowerCase() || 'md5'
|
|
102
|
+
const qop = challenge.qop?.toLowerCase()
|
|
103
|
+
|
|
104
|
+
// Generate HA1 = MD5(username:realm:password)
|
|
105
|
+
const ha1 = this.calculateHA1(challenge.realm, algorithm)
|
|
106
|
+
|
|
107
|
+
// Generate HA2 = MD5(method:uri)
|
|
108
|
+
const ha2 = this.calculateHA2(method, uri, algorithm)
|
|
109
|
+
|
|
110
|
+
let response: string
|
|
111
|
+
|
|
112
|
+
if (qop) {
|
|
113
|
+
// With quality of protection
|
|
114
|
+
const nc = this.formatNC(this.nc)
|
|
115
|
+
const cnonce = this.cnonce
|
|
116
|
+
|
|
117
|
+
if (qop === 'auth') {
|
|
118
|
+
// response = MD5(HA1:nonce:nc:cnonce:qop:HA2)
|
|
119
|
+
const responseInput = `${ha1}:${challenge.nonce}:${nc}:${cnonce}:${qop}:${ha2}`
|
|
120
|
+
response = crypto.createHash(algorithm).update(responseInput).digest('hex')
|
|
121
|
+
} else {
|
|
122
|
+
throw new Error(`Unsupported qop value: ${qop}`)
|
|
123
|
+
}
|
|
124
|
+
} else {
|
|
125
|
+
// Without quality of protection
|
|
126
|
+
// response = MD5(HA1:nonce:HA2)
|
|
127
|
+
const responseInput = `${ha1}:${challenge.nonce}:${ha2}`
|
|
128
|
+
response = crypto.createHash(algorithm).update(responseInput).digest('hex')
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Build the response header
|
|
132
|
+
const responseParams: DigestResponse = {
|
|
133
|
+
username: this.username,
|
|
134
|
+
realm: challenge.realm,
|
|
135
|
+
nonce: challenge.nonce,
|
|
136
|
+
uri,
|
|
137
|
+
response,
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
if (challenge.algorithm) {
|
|
141
|
+
responseParams.algorithm = challenge.algorithm
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
if (challenge.opaque) {
|
|
145
|
+
responseParams.opaque = challenge.opaque
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (qop) {
|
|
149
|
+
responseParams.qop = qop
|
|
150
|
+
responseParams.nc = this.formatNC(this.nc)
|
|
151
|
+
responseParams.cnonce = this.cnonce
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const responseHeader = this.buildResponseHeader(responseParams)
|
|
155
|
+
this.logger.debug('Generated Digest response:', responseHeader)
|
|
156
|
+
|
|
157
|
+
// Increment nonce count for next request
|
|
158
|
+
this.nc++
|
|
159
|
+
|
|
160
|
+
return responseHeader
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Calculate HA1 = MD5(username:realm:password)
|
|
165
|
+
*/
|
|
166
|
+
private calculateHA1(realm: string, algorithm: string): string {
|
|
167
|
+
const input = `${this.username}:${realm}:${this.password}`
|
|
168
|
+
return crypto.createHash(algorithm).update(input).digest('hex')
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Calculate HA2 = MD5(method:uri)
|
|
173
|
+
*/
|
|
174
|
+
private calculateHA2(method: string, uri: string, algorithm: string): string {
|
|
175
|
+
const input = `${method}:${uri}`
|
|
176
|
+
return crypto.createHash(algorithm).update(input).digest('hex')
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Generate a client nonce
|
|
181
|
+
*/
|
|
182
|
+
private generateCnonce(): string {
|
|
183
|
+
return crypto.randomBytes(16).toString('hex')
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Format nonce count as 8-digit hex string
|
|
188
|
+
*/
|
|
189
|
+
private formatNC(nc: number): string {
|
|
190
|
+
return nc.toString(16).padStart(8, '0')
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Build the Authorization header string
|
|
195
|
+
*/
|
|
196
|
+
private buildResponseHeader(params: DigestResponse): string {
|
|
197
|
+
const parts: string[] = ['Digest']
|
|
198
|
+
|
|
199
|
+
// Add required parameters
|
|
200
|
+
parts.push(`username="${params.username}"`)
|
|
201
|
+
parts.push(`realm="${params.realm}"`)
|
|
202
|
+
parts.push(`nonce="${params.nonce}"`)
|
|
203
|
+
parts.push(`uri="${params.uri}"`)
|
|
204
|
+
parts.push(`response="${params.response}"`)
|
|
205
|
+
|
|
206
|
+
// Add optional parameters
|
|
207
|
+
if (params.algorithm) {
|
|
208
|
+
parts.push(`algorithm="${params.algorithm}"`)
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
if (params.opaque) {
|
|
212
|
+
parts.push(`opaque="${params.opaque}"`)
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
if (params.qop) {
|
|
216
|
+
parts.push(`qop="${params.qop}"`)
|
|
217
|
+
parts.push(`nc="${params.nc}"`)
|
|
218
|
+
parts.push(`cnonce="${params.cnonce}"`)
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
return parts.join(', ')
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Reset the nonce count (useful for new sessions)
|
|
226
|
+
*/
|
|
227
|
+
reset(): void {
|
|
228
|
+
this.nc = 1
|
|
229
|
+
this.cnonce = this.generateCnonce()
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Check if a challenge is stale
|
|
234
|
+
*/
|
|
235
|
+
isStale(challenge: DigestChallenge): boolean {
|
|
236
|
+
return challenge.stale === 'true'
|
|
237
|
+
}
|
|
238
|
+
}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import net from 'net'
|
|
2
|
+
import tls from 'tls'
|
|
3
|
+
import { ConnectionOptions } from './ConnectionManager.js'
|
|
4
|
+
import type { HttpCertificate } from '../../../models/ClientCertificate.js'
|
|
5
|
+
import { addClientCertificate, checkServerIdentity } from '../certificates/index.js'
|
|
6
|
+
import { type Logger, type ILogObj } from '../../../lib/logging/index.js'
|
|
7
|
+
import type { RequestStats } from '../CoreEngine.js'
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Handles direct HTTP and HTTPS connections
|
|
11
|
+
*/
|
|
12
|
+
export class DirectConnection {
|
|
13
|
+
private options: ConnectionOptions
|
|
14
|
+
|
|
15
|
+
constructor(options: ConnectionOptions) {
|
|
16
|
+
this.options = options
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Establish a connection to the target host
|
|
21
|
+
*/
|
|
22
|
+
async connect(): Promise<net.Socket> {
|
|
23
|
+
const { host, port, timeout, validateCertificates, certificates, logger, stats } = this.options
|
|
24
|
+
|
|
25
|
+
let socket: net.Socket
|
|
26
|
+
// Check if this is an HTTPS connection based on port or protocol
|
|
27
|
+
const isHttps = port === 443 || port === 8443 || this.options.protocol === 'https:'
|
|
28
|
+
if (isHttps) {
|
|
29
|
+
socket = await this.createTlsConnection(host, port, validateCertificates, certificates, logger, stats)
|
|
30
|
+
} else {
|
|
31
|
+
socket = await this.createTcpConnection(host, port, logger, stats)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (timeout && timeout > 0) {
|
|
35
|
+
socket.setTimeout(timeout)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return socket
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Create a TCP connection for HTTP
|
|
43
|
+
*/
|
|
44
|
+
private createTcpConnection(
|
|
45
|
+
host: string,
|
|
46
|
+
port: number,
|
|
47
|
+
logger: Logger<ILogObj>,
|
|
48
|
+
stats: RequestStats
|
|
49
|
+
): Promise<net.Socket> {
|
|
50
|
+
logger.debug(`Opening HTTP connection to ${host} on port ${port}`)
|
|
51
|
+
return new Promise((resolve, reject) => {
|
|
52
|
+
stats.connectionTime = Date.now()
|
|
53
|
+
const isIp = net.isIP(host)
|
|
54
|
+
if (isIp) {
|
|
55
|
+
stats.lookupTime = Date.now()
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const client = net.createConnection(port, host, () => {
|
|
59
|
+
stats.connectedTime = Date.now()
|
|
60
|
+
logger.debug('HTTP connection established.')
|
|
61
|
+
resolve(client)
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
client.pause()
|
|
65
|
+
if (!isIp) {
|
|
66
|
+
client.once('lookup', () => {
|
|
67
|
+
stats.lookupTime = Date.now()
|
|
68
|
+
})
|
|
69
|
+
}
|
|
70
|
+
client.once('error', (err: Error) => reject(err))
|
|
71
|
+
})
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Create a TLS connection for HTTPS
|
|
76
|
+
*/
|
|
77
|
+
private createTlsConnection(
|
|
78
|
+
host: string,
|
|
79
|
+
port: number,
|
|
80
|
+
validateCertificates: boolean | undefined,
|
|
81
|
+
certificates: HttpCertificate[] | undefined,
|
|
82
|
+
logger: Logger<ILogObj>,
|
|
83
|
+
stats: RequestStats
|
|
84
|
+
): Promise<tls.TLSSocket> {
|
|
85
|
+
logger.debug('Opening an SSL connection...')
|
|
86
|
+
const options: tls.ConnectionOptions = {}
|
|
87
|
+
const isIp = net.isIP(host)
|
|
88
|
+
|
|
89
|
+
if (!isIp) {
|
|
90
|
+
options.servername = host
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (validateCertificates) {
|
|
94
|
+
options.checkServerIdentity = (hostname: string, cert: tls.PeerCertificate) => checkServerIdentity(hostname, cert)
|
|
95
|
+
} else {
|
|
96
|
+
options.rejectUnauthorized = false
|
|
97
|
+
options.checkServerIdentity = (): Error | undefined => {
|
|
98
|
+
return undefined
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Add client certificates if provided
|
|
103
|
+
if (Array.isArray(certificates)) {
|
|
104
|
+
certificates.forEach((cert) => addClientCertificate(cert, options))
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return new Promise((resolve, reject) => {
|
|
108
|
+
const time = Date.now()
|
|
109
|
+
stats.connectionTime = time
|
|
110
|
+
if (isIp) {
|
|
111
|
+
stats.lookupTime = time
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const client = tls.connect(port, host, options, () => {
|
|
115
|
+
logger.debug('SSL connection established.')
|
|
116
|
+
const connectTime = Date.now()
|
|
117
|
+
stats.connectedTime = connectTime
|
|
118
|
+
stats.secureStartTime = connectTime
|
|
119
|
+
resolve(client)
|
|
120
|
+
})
|
|
121
|
+
|
|
122
|
+
client.pause()
|
|
123
|
+
client.once('error', (e: Error) => reject(e))
|
|
124
|
+
if (!isIp) {
|
|
125
|
+
client.once('lookup', () => {
|
|
126
|
+
stats.lookupTime = Date.now()
|
|
127
|
+
})
|
|
128
|
+
}
|
|
129
|
+
client.once('secureConnect', () => {
|
|
130
|
+
stats.secureConnectedTime = Date.now()
|
|
131
|
+
})
|
|
132
|
+
})
|
|
133
|
+
}
|
|
134
|
+
}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import { SerializableError } from '../../../models/SerializableError.js'
|
|
2
|
+
import { type Logger, type ILogObj } from '../../../lib/logging/index.js'
|
|
3
|
+
import { DigestAuthHandler } from './DigestAuthHandler.js'
|
|
4
|
+
|
|
5
|
+
export interface ProxyAuthOptions {
|
|
6
|
+
proxyUsername?: string
|
|
7
|
+
proxyPassword?: string
|
|
8
|
+
/**
|
|
9
|
+
* The type of proxy authentication to use.
|
|
10
|
+
*/
|
|
11
|
+
proxyAuthorization?: 'Basic'
|
|
12
|
+
logger: Logger<ILogObj>
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface ProxyAuthChallenge {
|
|
16
|
+
method: string
|
|
17
|
+
realm?: string
|
|
18
|
+
nonce?: string
|
|
19
|
+
qop?: string
|
|
20
|
+
algorithm?: string
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Handles proxy authentication challenges and responses
|
|
25
|
+
*/
|
|
26
|
+
export class ProxyAuthHandler {
|
|
27
|
+
private options: ProxyAuthOptions
|
|
28
|
+
private authState: 'none' | 'challenged' | 'authenticated' = 'none'
|
|
29
|
+
private challenge?: ProxyAuthChallenge
|
|
30
|
+
private digestHandler?: DigestAuthHandler
|
|
31
|
+
|
|
32
|
+
constructor(options: ProxyAuthOptions) {
|
|
33
|
+
this.options = options
|
|
34
|
+
if (options.proxyUsername && options.proxyPassword) {
|
|
35
|
+
this.digestHandler = new DigestAuthHandler(options.proxyUsername, options.proxyPassword, options.logger)
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Check if we have proxy credentials configured
|
|
41
|
+
*/
|
|
42
|
+
hasCredentials(): boolean {
|
|
43
|
+
const { proxyUsername, proxyPassword, proxyAuthorization } = this.options
|
|
44
|
+
return !!(proxyUsername && proxyPassword) || !!proxyAuthorization
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Generate the initial proxy authorization header
|
|
49
|
+
*/
|
|
50
|
+
generateAuthHeader(): string | undefined {
|
|
51
|
+
const { proxyUsername, proxyPassword, proxyAuthorization } = this.options
|
|
52
|
+
|
|
53
|
+
if (!proxyUsername || !proxyPassword) {
|
|
54
|
+
return undefined
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (!proxyAuthorization || proxyAuthorization === 'Basic') {
|
|
58
|
+
// Basic authentication
|
|
59
|
+
const token = Buffer.from(`${proxyUsername}:${proxyPassword}`).toString('base64')
|
|
60
|
+
return `Basic ${token}`
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (proxyAuthorization === 'Digest') {
|
|
64
|
+
// For Digest auth, we need a challenge first
|
|
65
|
+
if (this.authState === 'none') {
|
|
66
|
+
// Initial request without auth header
|
|
67
|
+
return undefined
|
|
68
|
+
}
|
|
69
|
+
return this.generateDigestResponse()
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
throw new SerializableError(`Unsupported proxy authorization type: ${proxyAuthorization}`)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Handle a proxy authentication challenge
|
|
77
|
+
*/
|
|
78
|
+
handleChallenge(authenticateHeader: string): string | undefined {
|
|
79
|
+
this.authState = 'challenged'
|
|
80
|
+
this.challenge = this.parseChallenge(authenticateHeader)
|
|
81
|
+
this.options.logger.debug('Received proxy authentication challenge:', this.challenge)
|
|
82
|
+
|
|
83
|
+
if (this.challenge?.method === 'Basic') {
|
|
84
|
+
// For Basic auth, we can respond immediately
|
|
85
|
+
return this.generateAuthHeader()
|
|
86
|
+
} else if (this.challenge?.method === 'Digest') {
|
|
87
|
+
// For Digest auth, we need to generate a proper response
|
|
88
|
+
return this.generateDigestResponse()
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
throw new SerializableError(`Unsupported proxy authentication method: ${this.challenge?.method}`)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Parse the WWW-Authenticate or Proxy-Authenticate header
|
|
96
|
+
*/
|
|
97
|
+
private parseChallenge(authenticateHeader: string): ProxyAuthChallenge {
|
|
98
|
+
const challenge: ProxyAuthChallenge = { method: '' }
|
|
99
|
+
|
|
100
|
+
// Extract the method (Basic, Digest, etc.)
|
|
101
|
+
const methodMatch = authenticateHeader.match(/^(\w+)/)
|
|
102
|
+
if (methodMatch) {
|
|
103
|
+
challenge.method = methodMatch[1]
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Parse key-value pairs
|
|
107
|
+
const paramRegex = /(\w+)="([^"]*)"/g
|
|
108
|
+
let match
|
|
109
|
+
while ((match = paramRegex.exec(authenticateHeader)) !== null) {
|
|
110
|
+
const [, key, value] = match
|
|
111
|
+
switch (key.toLowerCase()) {
|
|
112
|
+
case 'realm':
|
|
113
|
+
challenge.realm = value
|
|
114
|
+
break
|
|
115
|
+
case 'nonce':
|
|
116
|
+
challenge.nonce = value
|
|
117
|
+
break
|
|
118
|
+
case 'qop':
|
|
119
|
+
challenge.qop = value
|
|
120
|
+
break
|
|
121
|
+
case 'algorithm':
|
|
122
|
+
challenge.algorithm = value
|
|
123
|
+
break
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return challenge
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Generate a Digest authentication response
|
|
132
|
+
*/
|
|
133
|
+
private generateDigestResponse(): string | undefined {
|
|
134
|
+
if (!this.digestHandler || !this.challenge) {
|
|
135
|
+
return undefined
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
try {
|
|
139
|
+
// Parse the full Digest challenge
|
|
140
|
+
const digestChallenge = this.digestHandler.parseChallenge(
|
|
141
|
+
`Digest realm="${this.challenge.realm}", nonce="${this.challenge.nonce}"${
|
|
142
|
+
this.challenge.qop ? `, qop="${this.challenge.qop}"` : ''
|
|
143
|
+
}${this.challenge.algorithm ? `, algorithm="${this.challenge.algorithm}"` : ''}`
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
// Generate the response for CONNECT method
|
|
147
|
+
const response = this.digestHandler.generateResponse(digestChallenge, 'CONNECT', '/')
|
|
148
|
+
return response
|
|
149
|
+
} catch (error) {
|
|
150
|
+
this.options.logger.error('Failed to generate Digest response:', error)
|
|
151
|
+
throw new SerializableError(`Digest authentication failed: ${(error as Error).message}`, 127)
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Check if authentication was successful
|
|
157
|
+
*/
|
|
158
|
+
isAuthenticated(): boolean {
|
|
159
|
+
return this.authState === 'authenticated'
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Mark authentication as successful
|
|
164
|
+
*/
|
|
165
|
+
markAuthenticated(): void {
|
|
166
|
+
this.authState = 'authenticated'
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Reset authentication state
|
|
171
|
+
*/
|
|
172
|
+
reset(): void {
|
|
173
|
+
this.authState = 'none'
|
|
174
|
+
this.challenge = undefined
|
|
175
|
+
if (this.digestHandler) {
|
|
176
|
+
this.digestHandler.reset()
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import net from 'net'
|
|
2
|
+
import { URL } from 'url'
|
|
3
|
+
import { ProxyConnectionOptions } from './ConnectionManager.js'
|
|
4
|
+
import { DirectConnection } from './DirectConnection.js'
|
|
5
|
+
import { SerializableError } from '../../../models/SerializableError.js'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Handles HTTP requests through a proxy server
|
|
9
|
+
*/
|
|
10
|
+
export class ProxyConnection {
|
|
11
|
+
private options: ProxyConnectionOptions
|
|
12
|
+
|
|
13
|
+
constructor(options: ProxyConnectionOptions) {
|
|
14
|
+
this.options = options
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Establish a connection to the proxy server
|
|
19
|
+
*/
|
|
20
|
+
async connect(): Promise<net.Socket> {
|
|
21
|
+
const { proxy, proxyIsSsl, logger } = this.options
|
|
22
|
+
|
|
23
|
+
logger.debug('Proxying an HTTP request...')
|
|
24
|
+
|
|
25
|
+
if (!proxy) {
|
|
26
|
+
throw new Error('No proxy configuration found.')
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
let proxyUrl = proxy
|
|
30
|
+
if (proxyIsSsl && !proxyUrl.startsWith('https:')) {
|
|
31
|
+
proxyUrl = `https://${proxyUrl}`
|
|
32
|
+
} else if (!proxyIsSsl && !proxyUrl.startsWith('http:')) {
|
|
33
|
+
proxyUrl = `http://${proxyUrl}`
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const proxyUri = new URL(proxyUrl)
|
|
37
|
+
const port = Number(proxyUri.port || (proxyIsSsl ? 443 : 80))
|
|
38
|
+
const host = proxyUri.hostname
|
|
39
|
+
|
|
40
|
+
// Create a direct connection to the proxy
|
|
41
|
+
const directConnection = new DirectConnection({
|
|
42
|
+
...this.options,
|
|
43
|
+
host,
|
|
44
|
+
port,
|
|
45
|
+
protocol: proxyIsSsl ? 'https:' : 'http:',
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
try {
|
|
49
|
+
return await directConnection.connect()
|
|
50
|
+
} catch (error) {
|
|
51
|
+
const err = error as Error & { code?: string }
|
|
52
|
+
throw new SerializableError(`Failed to connect to proxy: ${err.message}`, err.code ? Number(err.code) : 112)
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|