@api-client/core 0.18.12 → 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/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 +6 -6
- package/package.json +2 -2
- package/src/lib/logging/DefaultLogger.ts +32 -0
- 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/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,379 @@
|
|
|
1
|
+
import { test } from '@japa/runner'
|
|
2
|
+
import net from 'net'
|
|
3
|
+
import {
|
|
4
|
+
ConnectionManager,
|
|
5
|
+
ConnectionOptions,
|
|
6
|
+
ProxyConnectionOptions,
|
|
7
|
+
TunnelConnectionOptions,
|
|
8
|
+
} from '../../../../../src/runtime/http-engine/connections/ConnectionManager.js'
|
|
9
|
+
import { DirectConnection } from '../../../../../src/runtime/http-engine/connections/DirectConnection.js'
|
|
10
|
+
import { ProxyConnection } from '../../../../../src/runtime/http-engine/connections/ProxyConnection.js'
|
|
11
|
+
import { TunnelConnection } from '../../../../../src/runtime/http-engine/connections/TunnelConnection.js'
|
|
12
|
+
import { createLogger, type Logger, type ILogObj } from '../../../../../src/lib/logging/index.js'
|
|
13
|
+
import { type RequestStats, type HttpEngineOptions } from '../../../../../src/runtime/http-engine/CoreEngine.js'
|
|
14
|
+
import { HttpCertificate } from '../../../../../src/models/ClientCertificate.js'
|
|
15
|
+
|
|
16
|
+
test.group('ConnectionManager', (group) => {
|
|
17
|
+
let connectionManager: ConnectionManager
|
|
18
|
+
let logger: Logger<ILogObj>
|
|
19
|
+
let stats: RequestStats
|
|
20
|
+
let createdSockets: net.Socket[] = []
|
|
21
|
+
|
|
22
|
+
group.each.setup(() => {
|
|
23
|
+
logger = createLogger()
|
|
24
|
+
stats = {}
|
|
25
|
+
connectionManager = new ConnectionManager(logger, stats)
|
|
26
|
+
createdSockets = []
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
group.each.teardown(() => {
|
|
30
|
+
// Clean up any sockets created during tests
|
|
31
|
+
for (const socket of createdSockets) {
|
|
32
|
+
if (!socket.destroyed) {
|
|
33
|
+
socket.destroy()
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
createdSockets = []
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
test('createDirectConnection should return DirectConnection instance', ({ assert }) => {
|
|
40
|
+
const options = {
|
|
41
|
+
host: 'example.com',
|
|
42
|
+
port: 80,
|
|
43
|
+
protocol: 'http:',
|
|
44
|
+
logger,
|
|
45
|
+
stats,
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const connection = connectionManager.createDirectConnection(options)
|
|
49
|
+
assert.instanceOf(connection, DirectConnection, 'creates DirectConnection instance')
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
test('createProxyConnection should return ProxyConnection instance', ({ assert }) => {
|
|
53
|
+
const options = {
|
|
54
|
+
host: 'example.com',
|
|
55
|
+
port: 80,
|
|
56
|
+
protocol: 'http:',
|
|
57
|
+
proxy: '127.0.0.1:8080',
|
|
58
|
+
proxyIsSsl: false,
|
|
59
|
+
targetUrl: 'http://example.com:80',
|
|
60
|
+
logger,
|
|
61
|
+
stats,
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const connection = connectionManager.createProxyConnection(options)
|
|
65
|
+
assert.instanceOf(connection, ProxyConnection, 'creates ProxyConnection instance')
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
test('createTunnelConnection should return TunnelConnection instance', ({ assert }) => {
|
|
69
|
+
const options = {
|
|
70
|
+
host: 'example.com',
|
|
71
|
+
port: 443,
|
|
72
|
+
protocol: 'https:',
|
|
73
|
+
proxy: '127.0.0.1:8080',
|
|
74
|
+
proxyIsSsl: false,
|
|
75
|
+
targetUrl: 'https://example.com:443',
|
|
76
|
+
targetHost: 'example.com',
|
|
77
|
+
targetPort: 443,
|
|
78
|
+
logger,
|
|
79
|
+
stats,
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const connection = connectionManager.createTunnelConnection(options)
|
|
83
|
+
assert.instanceOf(connection, TunnelConnection, 'creates TunnelConnection instance')
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
test('should create direct connection when no proxy is configured', async ({ assert }) => {
|
|
87
|
+
const mockSocket = new net.Socket()
|
|
88
|
+
createdSockets.push(mockSocket)
|
|
89
|
+
|
|
90
|
+
// Mock DirectConnection.connect to return our mock socket
|
|
91
|
+
const originalCreateDirectConnection = connectionManager.createDirectConnection
|
|
92
|
+
let capturedOptions: ConnectionOptions | undefined
|
|
93
|
+
|
|
94
|
+
connectionManager.createDirectConnection = (options) => {
|
|
95
|
+
capturedOptions = options
|
|
96
|
+
return {
|
|
97
|
+
connect: async () => mockSocket,
|
|
98
|
+
} as DirectConnection
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const engineOptions: HttpEngineOptions = {
|
|
102
|
+
timeout: 5000,
|
|
103
|
+
validateCertificates: true,
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const result = await connectionManager.createConnection('example.com', 80, 'http:', engineOptions)
|
|
107
|
+
|
|
108
|
+
assert.deepEqual(result, mockSocket, 'returns the socket from DirectConnection')
|
|
109
|
+
assert.equal(capturedOptions!.host, 'example.com', 'passes correct host')
|
|
110
|
+
assert.equal(capturedOptions!.port, 80, 'passes correct port')
|
|
111
|
+
assert.equal(capturedOptions!.protocol, 'http:', 'passes correct protocol')
|
|
112
|
+
assert.equal(capturedOptions!.timeout, 5000, 'passes timeout option')
|
|
113
|
+
assert.equal(capturedOptions!.validateCertificates, true, 'passes certificate validation option')
|
|
114
|
+
assert.equal(capturedOptions!.logger, logger, 'passes logger')
|
|
115
|
+
assert.equal(capturedOptions!.stats, stats, 'passes stats')
|
|
116
|
+
|
|
117
|
+
// Restore original method
|
|
118
|
+
connectionManager.createDirectConnection = originalCreateDirectConnection
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
test('should create proxy connection for HTTP through proxy', async ({ assert }) => {
|
|
122
|
+
const mockSocket = new net.Socket()
|
|
123
|
+
createdSockets.push(mockSocket)
|
|
124
|
+
|
|
125
|
+
// Mock ProxyConnection.connect to return our mock socket
|
|
126
|
+
const originalCreateProxyConnection = connectionManager.createProxyConnection
|
|
127
|
+
let capturedOptions: ProxyConnectionOptions | undefined
|
|
128
|
+
|
|
129
|
+
connectionManager.createProxyConnection = (options) => {
|
|
130
|
+
capturedOptions = options
|
|
131
|
+
return {
|
|
132
|
+
connect: async () => mockSocket,
|
|
133
|
+
} as ProxyConnection
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const engineOptions: HttpEngineOptions = {
|
|
137
|
+
proxy: '127.0.0.1:8080',
|
|
138
|
+
timeout: 5000,
|
|
139
|
+
validateCertificates: false,
|
|
140
|
+
proxyUsername: 'user',
|
|
141
|
+
proxyPassword: 'pass',
|
|
142
|
+
proxyAuthorization: 'Basic',
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const result = await connectionManager.createConnection('example.com', 80, 'http:', engineOptions)
|
|
146
|
+
|
|
147
|
+
assert.equal(result, mockSocket, 'returns the socket from ProxyConnection')
|
|
148
|
+
assert.equal(capturedOptions!.host, 'example.com', 'passes correct host')
|
|
149
|
+
assert.equal(capturedOptions!.port, 80, 'passes correct port')
|
|
150
|
+
assert.equal(capturedOptions!.protocol, 'http:', 'passes correct protocol')
|
|
151
|
+
assert.equal(capturedOptions!.proxy, '127.0.0.1:8080', 'passes proxy configuration')
|
|
152
|
+
assert.equal(capturedOptions!.proxyIsSsl, false, 'detects non-SSL proxy')
|
|
153
|
+
assert.equal(capturedOptions!.targetUrl, 'http://example.com:80', 'constructs target URL')
|
|
154
|
+
assert.equal(capturedOptions!.proxyUsername, 'user', 'passes proxy username')
|
|
155
|
+
assert.equal(capturedOptions!.proxyPassword, 'pass', 'passes proxy password')
|
|
156
|
+
assert.equal(capturedOptions!.proxyAuthorization, 'Basic', 'passes proxy authorization')
|
|
157
|
+
|
|
158
|
+
// Restore original method
|
|
159
|
+
connectionManager.createProxyConnection = originalCreateProxyConnection
|
|
160
|
+
})
|
|
161
|
+
|
|
162
|
+
test('should create tunnel connection for HTTPS through proxy', async ({ assert }) => {
|
|
163
|
+
const mockSocket = new net.Socket()
|
|
164
|
+
createdSockets.push(mockSocket)
|
|
165
|
+
|
|
166
|
+
// Mock TunnelConnection.connect to return our mock socket
|
|
167
|
+
const originalCreateTunnelConnection = connectionManager.createTunnelConnection
|
|
168
|
+
let capturedOptions: TunnelConnectionOptions | undefined
|
|
169
|
+
|
|
170
|
+
connectionManager.createTunnelConnection = (options) => {
|
|
171
|
+
capturedOptions = options
|
|
172
|
+
return {
|
|
173
|
+
connect: async () => mockSocket,
|
|
174
|
+
} as TunnelConnection
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
const engineOptions: HttpEngineOptions = {
|
|
178
|
+
proxy: 'https://proxy.example.com:8443',
|
|
179
|
+
timeout: 10000,
|
|
180
|
+
validateCertificates: true,
|
|
181
|
+
proxyUsername: 'admin',
|
|
182
|
+
proxyPassword: 'secret',
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
const result = await connectionManager.createConnection('secure.example.com', 443, 'https:', engineOptions)
|
|
186
|
+
|
|
187
|
+
assert.equal(result, mockSocket, 'returns the socket from TunnelConnection')
|
|
188
|
+
assert.equal(capturedOptions!.host, 'secure.example.com', 'passes correct host')
|
|
189
|
+
assert.equal(capturedOptions!.port, 443, 'passes correct port')
|
|
190
|
+
assert.equal(capturedOptions!.protocol, 'https:', 'passes correct protocol')
|
|
191
|
+
assert.equal(capturedOptions!.proxy, 'https://proxy.example.com:8443', 'passes proxy configuration')
|
|
192
|
+
assert.equal(capturedOptions!.proxyIsSsl, true, 'detects SSL proxy')
|
|
193
|
+
assert.equal(capturedOptions!.targetUrl, 'https://secure.example.com:443', 'constructs target URL')
|
|
194
|
+
assert.equal(capturedOptions!.targetHost, 'secure.example.com', 'passes target host')
|
|
195
|
+
assert.equal(capturedOptions!.targetPort, 443, 'passes target port')
|
|
196
|
+
assert.equal(capturedOptions!.proxyUsername, 'admin', 'passes proxy username')
|
|
197
|
+
assert.equal(capturedOptions!.proxyPassword, 'secret', 'passes proxy password')
|
|
198
|
+
|
|
199
|
+
// Restore original method
|
|
200
|
+
connectionManager.createTunnelConnection = originalCreateTunnelConnection
|
|
201
|
+
})
|
|
202
|
+
|
|
203
|
+
test('should detect SSL proxy correctly with https: scheme', async ({ assert }) => {
|
|
204
|
+
const mockSocket = new net.Socket()
|
|
205
|
+
createdSockets.push(mockSocket)
|
|
206
|
+
|
|
207
|
+
const originalCreateProxyConnection = connectionManager.createProxyConnection
|
|
208
|
+
let capturedOptions: ProxyConnectionOptions | undefined
|
|
209
|
+
|
|
210
|
+
connectionManager.createProxyConnection = (options) => {
|
|
211
|
+
capturedOptions = options
|
|
212
|
+
return {
|
|
213
|
+
connect: async () => mockSocket,
|
|
214
|
+
} as ProxyConnection
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
const engineOptions: HttpEngineOptions = {
|
|
218
|
+
proxy: 'https://secure-proxy.example.com:8443',
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
await connectionManager.createConnection('example.com', 80, 'http:', engineOptions)
|
|
222
|
+
|
|
223
|
+
assert.equal(capturedOptions!.proxyIsSsl, true, 'correctly identifies SSL proxy')
|
|
224
|
+
|
|
225
|
+
// Restore original method
|
|
226
|
+
connectionManager.createProxyConnection = originalCreateProxyConnection
|
|
227
|
+
})
|
|
228
|
+
|
|
229
|
+
test('should detect non-SSL proxy correctly without https: scheme', async ({ assert }) => {
|
|
230
|
+
const mockSocket = new net.Socket()
|
|
231
|
+
createdSockets.push(mockSocket)
|
|
232
|
+
|
|
233
|
+
const originalCreateProxyConnection = connectionManager.createProxyConnection
|
|
234
|
+
let capturedOptions: ProxyConnectionOptions | undefined
|
|
235
|
+
|
|
236
|
+
connectionManager.createProxyConnection = (options) => {
|
|
237
|
+
capturedOptions = options
|
|
238
|
+
return {
|
|
239
|
+
connect: async () => mockSocket,
|
|
240
|
+
} as ProxyConnection
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
const engineOptions: HttpEngineOptions = {
|
|
244
|
+
proxy: '192.168.1.100:3128',
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
const socket = await connectionManager.createConnection('example.com', 80, 'http:', engineOptions)
|
|
248
|
+
createdSockets.push(socket)
|
|
249
|
+
|
|
250
|
+
assert.equal(capturedOptions!.proxyIsSsl, false, 'correctly identifies non-SSL proxy')
|
|
251
|
+
|
|
252
|
+
// Restore original method
|
|
253
|
+
connectionManager.createProxyConnection = originalCreateProxyConnection
|
|
254
|
+
})
|
|
255
|
+
|
|
256
|
+
test('should pass client certificates to connection options', async ({ assert }) => {
|
|
257
|
+
const mockSocket = new net.Socket()
|
|
258
|
+
createdSockets.push(mockSocket)
|
|
259
|
+
const mockCertificates: HttpCertificate[] = [
|
|
260
|
+
{
|
|
261
|
+
key: 'abcd1234',
|
|
262
|
+
kind: 'Core#Certificate',
|
|
263
|
+
name: 'test-cert',
|
|
264
|
+
cert: { data: Buffer.from('cert-data') },
|
|
265
|
+
certKey: { data: Buffer.from('key-data'), passphrase: 'secret' },
|
|
266
|
+
type: 'pem',
|
|
267
|
+
},
|
|
268
|
+
]
|
|
269
|
+
|
|
270
|
+
const originalCreateDirectConnection = connectionManager.createDirectConnection
|
|
271
|
+
let capturedOptions: ConnectionOptions | undefined
|
|
272
|
+
|
|
273
|
+
connectionManager.createDirectConnection = (options) => {
|
|
274
|
+
capturedOptions = options
|
|
275
|
+
return {
|
|
276
|
+
connect: async () => mockSocket,
|
|
277
|
+
} as DirectConnection
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
const engineOptions: HttpEngineOptions = {
|
|
281
|
+
certificates: mockCertificates,
|
|
282
|
+
validateCertificates: false,
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
await connectionManager.createConnection('client-cert.example.com', 443, 'https:', engineOptions)
|
|
286
|
+
|
|
287
|
+
assert.equal(capturedOptions!.certificates, mockCertificates, 'passes client certificates')
|
|
288
|
+
assert.equal(capturedOptions!.validateCertificates, false, 'passes certificate validation setting')
|
|
289
|
+
|
|
290
|
+
// Restore original method
|
|
291
|
+
connectionManager.createDirectConnection = originalCreateDirectConnection
|
|
292
|
+
})
|
|
293
|
+
|
|
294
|
+
test('should handle undefined optional parameters', async ({ assert }) => {
|
|
295
|
+
const mockSocket = new net.Socket()
|
|
296
|
+
createdSockets.push(mockSocket)
|
|
297
|
+
|
|
298
|
+
const originalCreateDirectConnection = connectionManager.createDirectConnection
|
|
299
|
+
let capturedOptions: ConnectionOptions | undefined
|
|
300
|
+
|
|
301
|
+
connectionManager.createDirectConnection = (options) => {
|
|
302
|
+
capturedOptions = options
|
|
303
|
+
return {
|
|
304
|
+
connect: async () => mockSocket,
|
|
305
|
+
} as DirectConnection
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
const engineOptions: HttpEngineOptions = {}
|
|
309
|
+
|
|
310
|
+
await connectionManager.createConnection('example.com', 80, 'http:', engineOptions)
|
|
311
|
+
|
|
312
|
+
assert.isUndefined(capturedOptions!.timeout, 'handles undefined timeout')
|
|
313
|
+
assert.isUndefined(capturedOptions!.validateCertificates, 'handles undefined certificate validation')
|
|
314
|
+
assert.isUndefined(capturedOptions!.certificates, 'handles undefined certificates')
|
|
315
|
+
|
|
316
|
+
// Restore original method
|
|
317
|
+
connectionManager.createDirectConnection = originalCreateDirectConnection
|
|
318
|
+
})
|
|
319
|
+
|
|
320
|
+
test('should handle custom ports correctly', async ({ assert }) => {
|
|
321
|
+
const mockSocket = new net.Socket()
|
|
322
|
+
createdSockets.push(mockSocket)
|
|
323
|
+
|
|
324
|
+
const originalCreateProxyConnection = connectionManager.createProxyConnection
|
|
325
|
+
let capturedOptions: ProxyConnectionOptions | undefined
|
|
326
|
+
|
|
327
|
+
connectionManager.createProxyConnection = (options) => {
|
|
328
|
+
capturedOptions = options
|
|
329
|
+
return {
|
|
330
|
+
connect: async () => mockSocket,
|
|
331
|
+
} as ProxyConnection
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
const engineOptions: HttpEngineOptions = {
|
|
335
|
+
proxy: '127.0.0.1:8080',
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
await connectionManager.createConnection('api.example.com', 8090, 'http:', engineOptions)
|
|
339
|
+
|
|
340
|
+
assert.equal(capturedOptions!.targetUrl, 'http://api.example.com:8090', 'constructs URL with custom port')
|
|
341
|
+
|
|
342
|
+
// Restore original method
|
|
343
|
+
connectionManager.createProxyConnection = originalCreateProxyConnection
|
|
344
|
+
})
|
|
345
|
+
|
|
346
|
+
test('should create working connection through proxy', async ({ assert, httpConfig }) => {
|
|
347
|
+
const engineOptions: HttpEngineOptions = {
|
|
348
|
+
proxy: `127.0.0.1:${httpConfig.proxyHttpPort}`,
|
|
349
|
+
timeout: 5000,
|
|
350
|
+
validateCertificates: false,
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
// Try to create a real connection through the proxy
|
|
354
|
+
const socket = await connectionManager.createConnection('httpbin.org', 80, 'http:', engineOptions)
|
|
355
|
+
createdSockets.push(socket)
|
|
356
|
+
|
|
357
|
+
assert.ok(socket, 'creates a real socket')
|
|
358
|
+
assert.instanceOf(socket, net.Socket, 'returns a net.Socket instance')
|
|
359
|
+
|
|
360
|
+
// Note: socket will be cleaned up in teardown
|
|
361
|
+
}).timeout(10000)
|
|
362
|
+
|
|
363
|
+
test('should create working HTTPS tunnel through proxy', async ({ assert, httpConfig }) => {
|
|
364
|
+
const engineOptions: HttpEngineOptions = {
|
|
365
|
+
proxy: `https://127.0.0.1:${httpConfig.proxyHttpsPort}`,
|
|
366
|
+
timeout: 5000,
|
|
367
|
+
validateCertificates: false,
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
// Try to create a real HTTPS tunnel through the proxy
|
|
371
|
+
const socket = await connectionManager.createConnection('httpbin.org', 443, 'https:', engineOptions)
|
|
372
|
+
createdSockets.push(socket)
|
|
373
|
+
|
|
374
|
+
assert.ok(socket, 'creates a real socket')
|
|
375
|
+
assert.instanceOf(socket, net.Socket, 'returns a net.Socket instance')
|
|
376
|
+
|
|
377
|
+
// Note: socket will be cleaned up in teardown
|
|
378
|
+
}).timeout(10000)
|
|
379
|
+
})
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { test } from '@japa/runner'
|
|
2
|
+
import { DigestAuthHandler } from '../../../../../src/runtime/http-engine/connections/DigestAuthHandler.js'
|
|
3
|
+
import { createLogger, type Logger, type ILogObj } from '../../../../../src/lib/logging/index.js'
|
|
4
|
+
|
|
5
|
+
test.group('DigestAuthHandler', (group) => {
|
|
6
|
+
let handler: DigestAuthHandler
|
|
7
|
+
let logger: Logger<ILogObj>
|
|
8
|
+
|
|
9
|
+
group.each.setup(() => {
|
|
10
|
+
logger = createLogger()
|
|
11
|
+
handler = new DigestAuthHandler('testuser', 'testpass', logger)
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
test('should parse a basic Digest challenge', ({ assert }) => {
|
|
15
|
+
const challenge = handler.parseChallenge(
|
|
16
|
+
'Digest realm="testrealm", nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093", algorithm=MD5'
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
assert.equal(challenge.realm, 'testrealm')
|
|
20
|
+
assert.equal(challenge.nonce, 'dcd98b7102dd2f0e8b11d0f600bfb0c093')
|
|
21
|
+
assert.equal(challenge.algorithm, 'MD5')
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
test('should parse a challenge with qop', ({ assert }) => {
|
|
25
|
+
const challenge = handler.parseChallenge(
|
|
26
|
+
'Digest realm="testrealm", nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093", qop="auth"'
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
assert.equal(challenge.realm, 'testrealm')
|
|
30
|
+
assert.equal(challenge.nonce, 'dcd98b7102dd2f0e8b11d0f600bfb0c093')
|
|
31
|
+
assert.equal(challenge.qop, 'auth')
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
test('should throw error for non-Digest challenge', ({ assert }) => {
|
|
35
|
+
assert.throws(() => {
|
|
36
|
+
handler.parseChallenge('Basic realm="testrealm"')
|
|
37
|
+
}, 'Not a Digest authentication challenge')
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
test('should throw error for invalid challenge', ({ assert }) => {
|
|
41
|
+
assert.throws(() => {
|
|
42
|
+
handler.parseChallenge('Digest realm="testrealm"')
|
|
43
|
+
}, 'Invalid Digest challenge: missing realm or nonce')
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
test('should generate response without qop', ({ assert }) => {
|
|
47
|
+
const challenge = handler.parseChallenge(
|
|
48
|
+
'Digest realm="testrealm", nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093", algorithm=MD5'
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
const response = handler.generateResponse(challenge, 'CONNECT', '/')
|
|
52
|
+
|
|
53
|
+
assert.include(response, 'Digest')
|
|
54
|
+
assert.include(response, 'username="testuser"')
|
|
55
|
+
assert.include(response, 'realm="testrealm"')
|
|
56
|
+
assert.include(response, 'nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093"')
|
|
57
|
+
assert.include(response, 'uri="/"')
|
|
58
|
+
assert.include(response, 'response=')
|
|
59
|
+
assert.include(response, 'algorithm="MD5"')
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
test('should generate response with qop', ({ assert }) => {
|
|
63
|
+
const challenge = handler.parseChallenge(
|
|
64
|
+
'Digest realm="testrealm", nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093", qop="auth", algorithm=MD5'
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
const response = handler.generateResponse(challenge, 'CONNECT', '/')
|
|
68
|
+
|
|
69
|
+
assert.include(response, 'Digest')
|
|
70
|
+
assert.include(response, 'username="testuser"')
|
|
71
|
+
assert.include(response, 'realm="testrealm"')
|
|
72
|
+
assert.include(response, 'nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093"')
|
|
73
|
+
assert.include(response, 'uri="/"')
|
|
74
|
+
assert.include(response, 'response=')
|
|
75
|
+
assert.include(response, 'qop="auth"')
|
|
76
|
+
assert.include(response, 'nc=')
|
|
77
|
+
assert.include(response, 'cnonce=')
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
test('should handle opaque parameter', ({ assert }) => {
|
|
81
|
+
const challenge = handler.parseChallenge(
|
|
82
|
+
'Digest realm="testrealm", nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093", ' +
|
|
83
|
+
'opaque="5ccc069c403ebaf9f0171e9517f40e41"'
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
const response = handler.generateResponse(challenge, 'CONNECT', '/')
|
|
87
|
+
|
|
88
|
+
assert.include(response, 'opaque="5ccc069c403ebaf9f0171e9517f40e41"')
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
test('should throw error for unsupported qop', ({ assert }) => {
|
|
92
|
+
const challenge = handler.parseChallenge(
|
|
93
|
+
'Digest realm="testrealm", nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093", qop="auth-int"'
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
assert.throws(() => {
|
|
97
|
+
handler.generateResponse(challenge, 'CONNECT', '/')
|
|
98
|
+
}, 'Unsupported qop value: auth-int')
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
test('should increment nonce count for each request', ({ assert }) => {
|
|
102
|
+
const challenge = handler.parseChallenge(
|
|
103
|
+
'Digest realm="testrealm", nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093", qop="auth"'
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
const response1 = handler.generateResponse(challenge, 'CONNECT', '/')
|
|
107
|
+
const response2 = handler.generateResponse(challenge, 'CONNECT', '/')
|
|
108
|
+
|
|
109
|
+
// Extract nc values
|
|
110
|
+
const nc1Match = response1.match(/nc="([^"]+)"/)
|
|
111
|
+
const nc2Match = response2.match(/nc="([^"]+)"/)
|
|
112
|
+
|
|
113
|
+
assert.isNotNull(nc1Match)
|
|
114
|
+
assert.isNotNull(nc2Match)
|
|
115
|
+
assert.equal(nc1Match![1], '00000001')
|
|
116
|
+
assert.equal(nc2Match![1], '00000002')
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
test('should reset nonce count and generate new cnonce', ({ assert }) => {
|
|
120
|
+
const challenge = handler.parseChallenge(
|
|
121
|
+
'Digest realm="testrealm", nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093", qop="auth"'
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
const response1 = handler.generateResponse(challenge, 'CONNECT', '/')
|
|
125
|
+
handler.reset()
|
|
126
|
+
const response2 = handler.generateResponse(challenge, 'CONNECT', '/')
|
|
127
|
+
|
|
128
|
+
// Extract nc and cnonce values
|
|
129
|
+
const nc1Match = response1.match(/nc="([^"]+)"/)
|
|
130
|
+
const nc2Match = response2.match(/nc="([^"]+)"/)
|
|
131
|
+
const cnonce1Match = response1.match(/cnonce="([^"]+)"/)
|
|
132
|
+
const cnonce2Match = response2.match(/cnonce="([^"]+)"/)
|
|
133
|
+
|
|
134
|
+
assert.equal(nc1Match![1], '00000001')
|
|
135
|
+
assert.equal(nc2Match![1], '00000001') // Reset to 1
|
|
136
|
+
assert.notEqual(cnonce1Match![1], cnonce2Match![1]) // Different cnonce
|
|
137
|
+
})
|
|
138
|
+
|
|
139
|
+
test('should detect stale challenges', ({ assert }) => {
|
|
140
|
+
const staleChallenge = handler.parseChallenge(
|
|
141
|
+
'Digest realm="testrealm", nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093", stale=true'
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
const freshChallenge = handler.parseChallenge(
|
|
145
|
+
'Digest realm="testrealm", nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093", stale=false'
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
assert.isTrue(handler.isStale(staleChallenge))
|
|
149
|
+
assert.isFalse(handler.isStale(freshChallenge))
|
|
150
|
+
})
|
|
151
|
+
|
|
152
|
+
test('should calculate correct HA1', ({ assert }) => {
|
|
153
|
+
// This test verifies the MD5 calculation is correct
|
|
154
|
+
// HA1 = MD5(username:realm:password)
|
|
155
|
+
const challenge = handler.parseChallenge('Digest realm="testrealm", nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093"')
|
|
156
|
+
|
|
157
|
+
const response = handler.generateResponse(challenge, 'CONNECT', '/')
|
|
158
|
+
const responseMatch = response.match(/response="([^"]+)"/)
|
|
159
|
+
|
|
160
|
+
assert.isNotNull(responseMatch)
|
|
161
|
+
// The response should be a valid MD5 hash
|
|
162
|
+
assert.match(responseMatch![1], /^[a-f0-9]{32}$/)
|
|
163
|
+
})
|
|
164
|
+
})
|