@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.
Files changed (259) hide show
  1. package/build/src/browser.d.ts +0 -3
  2. package/build/src/browser.d.ts.map +1 -1
  3. package/build/src/browser.js +0 -3
  4. package/build/src/browser.js.map +1 -1
  5. package/build/src/index.d.ts +2 -5
  6. package/build/src/index.d.ts.map +1 -1
  7. package/build/src/index.js +2 -5
  8. package/build/src/index.js.map +1 -1
  9. package/build/src/lib/logging/DefaultLogger.d.ts +14 -0
  10. package/build/src/lib/logging/DefaultLogger.d.ts.map +1 -1
  11. package/build/src/lib/logging/DefaultLogger.js +27 -0
  12. package/build/src/lib/logging/DefaultLogger.js.map +1 -1
  13. package/build/src/lib/logging/index.d.ts +4 -0
  14. package/build/src/lib/logging/index.d.ts.map +1 -0
  15. package/build/src/lib/logging/index.js +10 -0
  16. package/build/src/lib/logging/index.js.map +1 -0
  17. package/build/src/models/ClientCertificate.d.ts +1 -1
  18. package/build/src/models/ClientCertificate.js.map +1 -1
  19. package/build/src/models/RequestConfig.d.ts +1 -1
  20. package/build/src/models/RequestConfig.js.map +1 -1
  21. package/build/src/models/SerializableError.d.ts +1 -1
  22. package/build/src/models/SerializableError.d.ts.map +1 -1
  23. package/build/src/models/SerializableError.js.map +1 -1
  24. package/build/src/proxy/RequestProxy.d.ts.map +1 -1
  25. package/build/src/proxy/RequestProxy.js +2 -2
  26. package/build/src/proxy/RequestProxy.js.map +1 -1
  27. package/build/src/runtime/http-engine/CoreEngine.d.ts +218 -139
  28. package/build/src/runtime/http-engine/CoreEngine.d.ts.map +1 -1
  29. package/build/src/runtime/http-engine/CoreEngine.js +716 -870
  30. package/build/src/runtime/http-engine/CoreEngine.js.map +1 -1
  31. package/build/src/runtime/http-engine/PayloadSupport.d.ts.map +1 -1
  32. package/build/src/runtime/http-engine/PayloadSupport.js +2 -1
  33. package/build/src/runtime/http-engine/PayloadSupport.js.map +1 -1
  34. package/build/src/runtime/http-engine/auth/AuthManager.d.ts +73 -0
  35. package/build/src/runtime/http-engine/auth/AuthManager.d.ts.map +1 -0
  36. package/build/src/runtime/http-engine/auth/AuthManager.js +186 -0
  37. package/build/src/runtime/http-engine/auth/AuthManager.js.map +1 -0
  38. package/build/src/runtime/http-engine/auth/index.d.ts +2 -0
  39. package/build/src/runtime/http-engine/auth/index.d.ts.map +1 -0
  40. package/build/src/runtime/http-engine/auth/index.js +2 -0
  41. package/build/src/runtime/http-engine/auth/index.js.map +1 -0
  42. package/build/src/runtime/http-engine/certificates/CertificateManager.d.ts +11 -0
  43. package/build/src/runtime/http-engine/certificates/CertificateManager.d.ts.map +1 -0
  44. package/build/src/runtime/http-engine/certificates/CertificateManager.js +76 -0
  45. package/build/src/runtime/http-engine/certificates/CertificateManager.js.map +1 -0
  46. package/build/src/runtime/http-engine/certificates/index.d.ts +2 -0
  47. package/build/src/runtime/http-engine/certificates/index.d.ts.map +1 -0
  48. package/build/src/runtime/http-engine/certificates/index.js +2 -0
  49. package/build/src/runtime/http-engine/certificates/index.js.map +1 -0
  50. package/build/src/runtime/http-engine/compression/CompressionManager.d.ts +25 -0
  51. package/build/src/runtime/http-engine/compression/CompressionManager.d.ts.map +1 -0
  52. package/build/src/runtime/http-engine/compression/CompressionManager.js +89 -0
  53. package/build/src/runtime/http-engine/compression/CompressionManager.js.map +1 -0
  54. package/build/src/runtime/http-engine/compression/index.d.ts +2 -0
  55. package/build/src/runtime/http-engine/compression/index.d.ts.map +1 -0
  56. package/build/src/runtime/http-engine/compression/index.js +2 -0
  57. package/build/src/runtime/http-engine/compression/index.js.map +1 -0
  58. package/build/src/runtime/http-engine/connections/ConnectionManager.d.ts +57 -0
  59. package/build/src/runtime/http-engine/connections/ConnectionManager.d.ts.map +1 -0
  60. package/build/src/runtime/http-engine/connections/ConnectionManager.js +78 -0
  61. package/build/src/runtime/http-engine/connections/ConnectionManager.js.map +1 -0
  62. package/build/src/runtime/http-engine/connections/DigestAuthHandler.d.ts +70 -0
  63. package/build/src/runtime/http-engine/connections/DigestAuthHandler.d.ts.map +1 -0
  64. package/build/src/runtime/http-engine/connections/DigestAuthHandler.js +184 -0
  65. package/build/src/runtime/http-engine/connections/DigestAuthHandler.js.map +1 -0
  66. package/build/src/runtime/http-engine/connections/DirectConnection.d.ts +22 -0
  67. package/build/src/runtime/http-engine/connections/DirectConnection.d.ts.map +1 -0
  68. package/build/src/runtime/http-engine/connections/DirectConnection.js +105 -0
  69. package/build/src/runtime/http-engine/connections/DirectConnection.js.map +1 -0
  70. package/build/src/runtime/http-engine/connections/ProxyAuthHandler.d.ts +60 -0
  71. package/build/src/runtime/http-engine/connections/ProxyAuthHandler.d.ts.map +1 -0
  72. package/build/src/runtime/http-engine/connections/ProxyAuthHandler.js +138 -0
  73. package/build/src/runtime/http-engine/connections/ProxyAuthHandler.js.map +1 -0
  74. package/build/src/runtime/http-engine/connections/ProxyConnection.d.ts +14 -0
  75. package/build/src/runtime/http-engine/connections/ProxyConnection.d.ts.map +1 -0
  76. package/build/src/runtime/http-engine/connections/ProxyConnection.js +47 -0
  77. package/build/src/runtime/http-engine/connections/ProxyConnection.js.map +1 -0
  78. package/build/src/runtime/http-engine/connections/TunnelConnection.d.ts +13 -0
  79. package/build/src/runtime/http-engine/connections/TunnelConnection.d.ts.map +1 -0
  80. package/build/src/runtime/http-engine/connections/TunnelConnection.js +175 -0
  81. package/build/src/runtime/http-engine/connections/TunnelConnection.js.map +1 -0
  82. package/build/src/runtime/http-engine/connections/index.d.ts +7 -0
  83. package/build/src/runtime/http-engine/connections/index.d.ts.map +1 -0
  84. package/build/src/runtime/http-engine/connections/index.js +7 -0
  85. package/build/src/runtime/http-engine/connections/index.js.map +1 -0
  86. package/build/src/runtime/http-engine/constants.d.ts +69 -0
  87. package/build/src/runtime/http-engine/constants.d.ts.map +1 -0
  88. package/build/src/runtime/http-engine/constants.js +90 -0
  89. package/build/src/runtime/http-engine/constants.js.map +1 -0
  90. package/build/src/runtime/http-engine/cookies/CookieProcessor.d.ts +5 -0
  91. package/build/src/runtime/http-engine/cookies/CookieProcessor.d.ts.map +1 -0
  92. package/build/src/runtime/http-engine/cookies/CookieProcessor.js +20 -0
  93. package/build/src/runtime/http-engine/cookies/CookieProcessor.js.map +1 -0
  94. package/build/src/runtime/http-engine/cookies/index.d.ts +2 -0
  95. package/build/src/runtime/http-engine/cookies/index.d.ts.map +1 -0
  96. package/build/src/runtime/http-engine/cookies/index.js +2 -0
  97. package/build/src/runtime/http-engine/cookies/index.js.map +1 -0
  98. package/build/src/runtime/http-engine/errors/HttpEngineErrors.d.ts +156 -0
  99. package/build/src/runtime/http-engine/errors/HttpEngineErrors.d.ts.map +1 -0
  100. package/build/src/runtime/http-engine/errors/HttpEngineErrors.js +227 -0
  101. package/build/src/runtime/http-engine/errors/HttpEngineErrors.js.map +1 -0
  102. package/build/src/runtime/http-engine/errors/index.d.ts +2 -0
  103. package/build/src/runtime/http-engine/errors/index.d.ts.map +1 -0
  104. package/build/src/runtime/http-engine/errors/index.js +2 -0
  105. package/build/src/runtime/http-engine/errors/index.js.map +1 -0
  106. package/build/src/runtime/http-engine/message/MessageBuilder.d.ts +66 -0
  107. package/build/src/runtime/http-engine/message/MessageBuilder.d.ts.map +1 -0
  108. package/build/src/runtime/http-engine/message/MessageBuilder.js +161 -0
  109. package/build/src/runtime/http-engine/message/MessageBuilder.js.map +1 -0
  110. package/build/src/runtime/http-engine/message/MessageProcessor.d.ts +27 -0
  111. package/build/src/runtime/http-engine/message/MessageProcessor.d.ts.map +1 -0
  112. package/build/src/runtime/http-engine/message/MessageProcessor.js +51 -0
  113. package/build/src/runtime/http-engine/message/MessageProcessor.js.map +1 -0
  114. package/build/src/runtime/http-engine/message/index.d.ts +3 -0
  115. package/build/src/runtime/http-engine/message/index.d.ts.map +1 -0
  116. package/build/src/runtime/http-engine/message/index.js +3 -0
  117. package/build/src/runtime/http-engine/message/index.js.map +1 -0
  118. package/build/src/runtime/http-engine/ntlm/NtlmAuth.d.ts +2 -8
  119. package/build/src/runtime/http-engine/ntlm/NtlmAuth.d.ts.map +1 -1
  120. package/build/src/runtime/http-engine/ntlm/NtlmAuth.js +11 -5
  121. package/build/src/runtime/http-engine/ntlm/NtlmAuth.js.map +1 -1
  122. package/build/src/runtime/http-engine/ntlm/NtlmMessage.js +6 -6
  123. package/build/src/runtime/http-engine/ntlm/NtlmMessage.js.map +1 -1
  124. package/build/src/runtime/http-engine/parsers/BodyParser.d.ts +39 -0
  125. package/build/src/runtime/http-engine/parsers/BodyParser.d.ts.map +1 -0
  126. package/build/src/runtime/http-engine/parsers/BodyParser.js +145 -0
  127. package/build/src/runtime/http-engine/parsers/BodyParser.js.map +1 -0
  128. package/build/src/runtime/http-engine/parsers/HeadersParser.d.ts +29 -0
  129. package/build/src/runtime/http-engine/parsers/HeadersParser.d.ts.map +1 -0
  130. package/build/src/runtime/http-engine/parsers/HeadersParser.js +88 -0
  131. package/build/src/runtime/http-engine/parsers/HeadersParser.js.map +1 -0
  132. package/build/src/runtime/http-engine/parsers/HttpResponseParser.d.ts +91 -0
  133. package/build/src/runtime/http-engine/parsers/HttpResponseParser.d.ts.map +1 -0
  134. package/build/src/runtime/http-engine/parsers/HttpResponseParser.js +236 -0
  135. package/build/src/runtime/http-engine/parsers/HttpResponseParser.js.map +1 -0
  136. package/build/src/runtime/http-engine/parsers/StatusParser.d.ts +20 -0
  137. package/build/src/runtime/http-engine/parsers/StatusParser.d.ts.map +1 -0
  138. package/build/src/runtime/http-engine/parsers/StatusParser.js +51 -0
  139. package/build/src/runtime/http-engine/parsers/StatusParser.js.map +1 -0
  140. package/build/src/runtime/http-engine/parsers/index.d.ts +5 -0
  141. package/build/src/runtime/http-engine/parsers/index.d.ts.map +1 -0
  142. package/build/src/runtime/http-engine/parsers/index.js +5 -0
  143. package/build/src/runtime/http-engine/parsers/index.js.map +1 -0
  144. package/build/src/runtime/http-engine/response/ResponseProcessor.d.ts +22 -0
  145. package/build/src/runtime/http-engine/response/ResponseProcessor.d.ts.map +1 -0
  146. package/build/src/runtime/http-engine/response/ResponseProcessor.js +25 -0
  147. package/build/src/runtime/http-engine/response/ResponseProcessor.js.map +1 -0
  148. package/build/src/runtime/http-engine/response/index.d.ts +2 -0
  149. package/build/src/runtime/http-engine/response/index.d.ts.map +1 -0
  150. package/build/src/runtime/http-engine/response/index.js +2 -0
  151. package/build/src/runtime/http-engine/response/index.js.map +1 -0
  152. package/build/src/runtime/http-engine/statistics/StatisticsProcessor.d.ts +7 -0
  153. package/build/src/runtime/http-engine/statistics/StatisticsProcessor.d.ts.map +1 -0
  154. package/build/src/runtime/http-engine/statistics/StatisticsProcessor.js +40 -0
  155. package/build/src/runtime/http-engine/statistics/StatisticsProcessor.js.map +1 -0
  156. package/build/src/runtime/http-engine/statistics/index.d.ts +2 -0
  157. package/build/src/runtime/http-engine/statistics/index.d.ts.map +1 -0
  158. package/build/src/runtime/http-engine/statistics/index.js +2 -0
  159. package/build/src/runtime/http-engine/statistics/index.js.map +1 -0
  160. package/build/src/runtime/http-engine/url/UrlProcessor.d.ts +24 -0
  161. package/build/src/runtime/http-engine/url/UrlProcessor.d.ts.map +1 -0
  162. package/build/src/runtime/http-engine/url/UrlProcessor.js +50 -0
  163. package/build/src/runtime/http-engine/url/UrlProcessor.js.map +1 -0
  164. package/build/src/runtime/http-engine/url/index.d.ts +2 -0
  165. package/build/src/runtime/http-engine/url/index.d.ts.map +1 -0
  166. package/build/src/runtime/http-engine/url/index.js +2 -0
  167. package/build/src/runtime/http-engine/url/index.js.map +1 -0
  168. package/build/src/runtime/http-runner/HttpRequestRunner.d.ts +3 -3
  169. package/build/src/runtime/http-runner/HttpRequestRunner.d.ts.map +1 -1
  170. package/build/src/runtime/http-runner/HttpRequestRunner.js.map +1 -1
  171. package/build/src/runtime/node/InteropInterfaces.d.ts +3 -3
  172. package/build/src/runtime/node/InteropInterfaces.d.ts.map +1 -1
  173. package/build/src/runtime/node/InteropInterfaces.js.map +1 -1
  174. package/build/src/runtime/node/ProjectRequestRunner.d.ts +2 -2
  175. package/build/src/runtime/node/ProjectRequestRunner.d.ts.map +1 -1
  176. package/build/src/runtime/node/ProjectRequestRunner.js.map +1 -1
  177. package/build/src/runtime/node/ProjectRunner.d.ts.map +1 -1
  178. package/build/src/runtime/node/ProjectRunner.js +2 -2
  179. package/build/src/runtime/node/ProjectRunner.js.map +1 -1
  180. package/build/tsconfig.tsbuildinfo +1 -1
  181. package/data/models/example-generator-api.json +6 -6
  182. package/package.json +2 -2
  183. package/src/lib/logging/DefaultLogger.ts +32 -0
  184. package/src/models/ClientCertificate.ts +1 -1
  185. package/src/models/RequestConfig.ts +1 -1
  186. package/src/models/SerializableError.ts +1 -1
  187. package/src/proxy/RequestProxy.ts +2 -2
  188. package/src/runtime/http-engine/CoreEngine.ts +858 -893
  189. package/src/runtime/http-engine/PayloadSupport.ts +2 -1
  190. package/src/runtime/http-engine/auth/AuthManager.ts +242 -0
  191. package/src/runtime/http-engine/certificates/CertificateManager.ts +74 -0
  192. package/src/runtime/http-engine/compression/CompressionManager.ts +99 -0
  193. package/src/runtime/http-engine/connections/ConnectionManager.ts +123 -0
  194. package/src/runtime/http-engine/connections/DigestAuthHandler.ts +238 -0
  195. package/src/runtime/http-engine/connections/DirectConnection.ts +134 -0
  196. package/src/runtime/http-engine/connections/ProxyAuthHandler.ts +179 -0
  197. package/src/runtime/http-engine/connections/ProxyConnection.ts +55 -0
  198. package/src/runtime/http-engine/connections/TunnelConnection.ts +192 -0
  199. package/src/runtime/http-engine/constants.ts +103 -0
  200. package/src/runtime/http-engine/cookies/CookieProcessor.ts +25 -0
  201. package/src/runtime/http-engine/errors/HttpEngineErrors.ts +319 -0
  202. package/src/runtime/http-engine/message/MessageBuilder.ts +201 -0
  203. package/src/runtime/http-engine/message/MessageProcessor.ts +73 -0
  204. package/src/runtime/http-engine/ntlm/NtlmAuth.ts +16 -13
  205. package/src/runtime/http-engine/ntlm/NtlmMessage.ts +6 -6
  206. package/src/runtime/http-engine/parsers/BodyParser.ts +171 -0
  207. package/src/runtime/http-engine/parsers/HeadersParser.ts +103 -0
  208. package/src/runtime/http-engine/parsers/HttpResponseParser.ts +280 -0
  209. package/src/runtime/http-engine/parsers/StatusParser.ts +69 -0
  210. package/src/runtime/http-engine/response/ResponseProcessor.ts +46 -0
  211. package/src/runtime/http-engine/statistics/StatisticsProcessor.ts +52 -0
  212. package/src/runtime/http-engine/url/UrlProcessor.ts +55 -0
  213. package/src/runtime/http-runner/HttpRequestRunner.ts +3 -3
  214. package/src/runtime/node/InteropInterfaces.ts +3 -3
  215. package/src/runtime/node/ProjectRequestRunner.ts +2 -2
  216. package/src/runtime/node/ProjectRunner.ts +2 -2
  217. package/tests/servers/ProxyServer.ts +32 -19
  218. package/tests/servers/express-routes/ApiEndpoint.ts +24 -0
  219. package/tests/servers/express-routes/BasicAuthRoute.ts +36 -0
  220. package/tests/servers/express-routes/BearerAuthRoute.ts +35 -0
  221. package/tests/servers/express-routes/NTLMRoute.ts +2 -3
  222. package/tests/servers/express-routes/PostApi.ts +15 -2
  223. package/tests/servers/express-routes/RedirectsApi.ts +12 -1
  224. package/tests/servers/express-routes/ResponsesApi.ts +1 -1
  225. package/tests/servers/express-routes/StreamApi.ts +19 -0
  226. package/tests/servers/oauth2mock/ServerMock.js +1 -1
  227. package/tests/unit/runtime/http-engine/HttpResponseParser.spec.ts +337 -0
  228. package/tests/unit/runtime/http-engine/abort.spec.ts +4 -5
  229. package/tests/unit/runtime/http-engine/auth.spec.ts +7 -58
  230. package/tests/unit/runtime/http-engine/certificates/CertificateManager.spec.ts +482 -0
  231. package/tests/unit/runtime/http-engine/certificates.spec.ts +2 -2
  232. package/tests/unit/runtime/http-engine/compression/CompressionManager.spec.ts +498 -0
  233. package/tests/unit/runtime/http-engine/compression.spec.ts +3 -72
  234. package/tests/unit/runtime/http-engine/connections/ConnectionManager.spec.ts +379 -0
  235. package/tests/unit/runtime/http-engine/connections/DigestAuthHandler.spec.ts +164 -0
  236. package/tests/unit/runtime/http-engine/core_engine.spec.ts +561 -0
  237. package/tests/unit/runtime/http-engine/engine_statuses.spec.ts +2 -2
  238. package/tests/unit/runtime/http-engine/events.spec.ts +2 -2
  239. package/tests/unit/runtime/http-engine/headers.spec.ts +2 -88
  240. package/tests/unit/runtime/http-engine/hosts.spec.ts +2 -2
  241. package/tests/unit/runtime/http-engine/http-get.spec.ts +2 -2
  242. package/tests/unit/runtime/http-engine/http-post.spec.ts +2 -2
  243. package/tests/unit/runtime/http-engine/logger.spec.ts +0 -8
  244. package/tests/unit/runtime/http-engine/message.spec.ts +2 -194
  245. package/tests/unit/runtime/http-engine/params.spec.ts +4 -4
  246. package/tests/unit/runtime/http-engine/proxy.spec.ts +15 -14
  247. package/tests/unit/runtime/http-engine/redirects.spec.ts +2 -2
  248. package/tests/unit/runtime/http-engine/responses.spec.ts +170 -277
  249. package/tests/unit/runtime/http-engine/timeout.spec.ts +3 -3
  250. package/tests/unit/runtime/http-engine/timings.spec.ts +2 -2
  251. package/tests/unit/runtime/proxy/HttpProjectProxy.spec.ts +25 -28
  252. package/tests/unit/runtime/runners/project_runner.spec.ts +2 -2
  253. package/tests/unit/runtime/runners/request_runner.spec.ts +2 -2
  254. package/build/src/runtime/http-engine/HttpEngine.d.ts +0 -311
  255. package/build/src/runtime/http-engine/HttpEngine.d.ts.map +0 -1
  256. package/build/src/runtime/http-engine/HttpEngine.js +0 -802
  257. package/build/src/runtime/http-engine/HttpEngine.js.map +0 -1
  258. package/src/runtime/http-engine/HttpEngine.ts +0 -952
  259. package/tests/unit/runtime/http-engine/connecting.spec.ts +0 -140
@@ -0,0 +1,192 @@
1
+ import net from 'net'
2
+ import tls from 'tls'
3
+ import https from 'https'
4
+ import http from 'http'
5
+ import { URL } from 'url'
6
+ import { TunnelConnectionOptions } from './ConnectionManager.js'
7
+ import { Headers } from '../../../lib/headers/Headers.js'
8
+ import { ProxyAuthHandler } from './ProxyAuthHandler.js'
9
+ import { HttpEngineErrorFactory } from '../errors/index.js'
10
+
11
+ /**
12
+ * Handles HTTPS tunneling through an HTTP proxy
13
+ */
14
+ export class TunnelConnection {
15
+ private options: TunnelConnectionOptions
16
+ private authHandler: ProxyAuthHandler
17
+
18
+ constructor(options: TunnelConnectionOptions) {
19
+ this.options = options
20
+ this.authHandler = new ProxyAuthHandler({
21
+ proxyUsername: options.proxyUsername,
22
+ proxyPassword: options.proxyPassword,
23
+ logger: options.logger,
24
+ })
25
+ }
26
+
27
+ async connect(): Promise<net.Socket> {
28
+ const { proxy, proxyIsSsl, targetHost, targetPort, logger, stats } = this.options
29
+
30
+ logger.debug('Creating a tunnel through the proxy...')
31
+
32
+ if (!proxy) {
33
+ throw HttpEngineErrorFactory.proxyConfigError('No proxy configuration found.')
34
+ }
35
+
36
+ let proxyUrl = proxy
37
+ if (proxyIsSsl && !proxyUrl.startsWith('https:')) {
38
+ proxyUrl = `https://${proxyUrl}`
39
+ } else if (!proxyIsSsl && !proxyUrl.startsWith('http:')) {
40
+ proxyUrl = `http://${proxyUrl}`
41
+ }
42
+
43
+ const proxyUri = new URL(proxyUrl)
44
+ const proxyPort = proxyUri.port || (proxyIsSsl ? 443 : 80)
45
+ const authority = `${targetHost}:${targetPort}`
46
+
47
+ const connectOptions: https.RequestOptions = {
48
+ host: proxyUri.hostname,
49
+ port: proxyPort,
50
+ method: 'CONNECT',
51
+ path: authority,
52
+ headers: {
53
+ host: authority,
54
+ },
55
+ }
56
+
57
+ if (proxyIsSsl) {
58
+ connectOptions.rejectUnauthorized = false
59
+ // @ts-expect-error This is correct!
60
+ connectOptions.requestOCSP = false
61
+ }
62
+
63
+ const lib = proxyIsSsl ? https : http
64
+
65
+ return new Promise((resolve, reject) => {
66
+ stats.connectionTime = Date.now()
67
+ try {
68
+ // Add proxy authorization if available
69
+ const auth = this.authHandler.generateAuthHeader()
70
+ if (auth) {
71
+ logger.debug('Adding proxy authorization.')
72
+ ;(connectOptions.headers as http.OutgoingHttpHeaders)['proxy-authorization'] = auth
73
+ }
74
+ logger.debug('Creating proxy tunnel...')
75
+ const connectRequest = lib.request(connectOptions)
76
+ logger.silly('Proxy tunnel created.')
77
+ connectRequest.once('socket', (socket: net.Socket) => {
78
+ logger.debug('Proxy tunnel socket created.')
79
+ socket.on('lookup', () => {
80
+ logger.debug('Proxy tunnel lookup.')
81
+ stats.lookupTime = Date.now()
82
+ })
83
+ })
84
+
85
+ connectRequest.on('error', (err) => {
86
+ logger.error('Error establishing proxy tunnel:', err)
87
+ reject(
88
+ HttpEngineErrorFactory.proxyError(
89
+ `Failed to establish proxy tunnel: ${err.message}`,
90
+ (err as Error & { code: string }).code ? Number((err as Error & { code: string }).code) : 111
91
+ )
92
+ )
93
+ })
94
+
95
+ connectRequest.on('connect', async (res: http.IncomingMessage, socket: net.Socket, head: Buffer) => {
96
+ const time = Date.now()
97
+ logger.debug('Proxy tunnel connected.')
98
+ stats.connectedTime = time
99
+ stats.secureStartTime = time
100
+ if (typeof stats.lookupTime === 'undefined') {
101
+ stats.lookupTime = time
102
+ }
103
+
104
+ if (res.statusCode === 401) {
105
+ // Handle proxy authentication required
106
+ logger.debug('Proxy tunnel not authorized. Closing.')
107
+ connectRequest.destroy()
108
+ reject(HttpEngineErrorFactory.proxyAuthRequired(res, head))
109
+ return
110
+ } else if (res.statusCode === 407) {
111
+ // Handle proxy authentication
112
+ logger.debug('Proxy tunnel authentication required. Trying to authenticate...')
113
+ try {
114
+ const retryResult = await this.handleProxyAuthentication(res)
115
+ if (retryResult) {
116
+ // Authentication succeeded and we should retry
117
+ connectRequest.destroy()
118
+ socket.destroy()
119
+
120
+ // Retry the connection with new authentication
121
+ try {
122
+ const retrySocket = await this.connect()
123
+ resolve(retrySocket)
124
+ } catch (retryError) {
125
+ reject(retryError)
126
+ }
127
+ return
128
+ } else {
129
+ // Authentication failed
130
+ logger.warn('Proxy authentication failed. Closing connection.')
131
+ connectRequest.destroy()
132
+ reject(HttpEngineErrorFactory.proxyAuthFailed())
133
+ return
134
+ }
135
+ } catch (error) {
136
+ logger.warn('Error handling proxy authentication:', error)
137
+ connectRequest.destroy()
138
+ reject(error)
139
+ }
140
+ return
141
+ } else if (res.statusCode !== 200) {
142
+ logger.debug(`The proxy tunnel ended with ${res.statusCode} status code. Erroring request.`)
143
+ connectRequest.destroy()
144
+ const errorMessage =
145
+ res.statusMessage || `Proxy tunnel establishment failed with status code ${res.statusCode}`
146
+ const e = HttpEngineErrorFactory.proxyError(errorMessage, res.statusCode)
147
+ reject(e)
148
+ return
149
+ }
150
+
151
+ logger.debug('Established a proxy tunnel.')
152
+ logger.debug('Upgrading connection to SSL...')
153
+ const tlsSocket = tls.connect({ socket, rejectUnauthorized: false }, () => {
154
+ logger.debug('Connection upgraded to SSL.')
155
+ resolve(tlsSocket)
156
+ })
157
+ tlsSocket.once('secureConnect', () => {
158
+ stats.secureConnectedTime = Date.now()
159
+ })
160
+ })
161
+
162
+ connectRequest.end()
163
+ } catch (error) {
164
+ reject(error)
165
+ }
166
+ })
167
+ }
168
+
169
+ private async handleProxyAuthentication(res: http.IncomingMessage): Promise<boolean> {
170
+ if (res.statusCode === 407) {
171
+ const headers = new Headers(res.headers)
172
+ const authHeader = headers.get('proxy-authenticate')
173
+
174
+ if (authHeader) {
175
+ try {
176
+ const authResponse = this.authHandler.handleChallenge(authHeader)
177
+ if (authResponse) {
178
+ this.options.logger.debug('Generated proxy authentication response')
179
+ this.authHandler.markAuthenticated()
180
+ return true // Indicate successful authentication
181
+ }
182
+ } catch (error) {
183
+ this.options.logger.error('Failed to handle proxy authentication:', error)
184
+ throw error
185
+ }
186
+ } else {
187
+ throw HttpEngineErrorFactory.proxyError('Proxy authentication required but no challenge provided', 407)
188
+ }
189
+ }
190
+ return false // Indicate failed authentication
191
+ }
192
+ }
@@ -0,0 +1,103 @@
1
+ /**
2
+ * HTTP constants used throughout the HTTP engine
3
+ */
4
+
5
+ // HTTP Status Code Ranges
6
+ export const REDIRECT_START = 300
7
+ export const REDIRECT_END = 399
8
+ export const CLIENT_ERROR_START = 400
9
+ export const CLIENT_ERROR_END = 499
10
+ export const SERVER_ERROR_START = 500
11
+ export const SERVER_ERROR_END = 599
12
+
13
+ // Specific Status Codes
14
+ export const STATUS_OK = 200
15
+ export const STATUS_MOVED_PERMANENTLY = 301
16
+ export const STATUS_FOUND = 302
17
+ export const STATUS_SEE_OTHER = 303
18
+ export const STATUS_NOT_MODIFIED = 304
19
+ export const STATUS_USE_PROXY = 305
20
+ export const STATUS_TEMPORARY_REDIRECT = 307
21
+ export const STATUS_PERMANENT_REDIRECT = 308
22
+ export const STATUS_UNAUTHORIZED = 401
23
+ export const STATUS_PROXY_AUTHENTICATION_REQUIRED = 407
24
+
25
+ // HTTP Methods
26
+ export const METHOD_GET = 'GET'
27
+ export const METHOD_HEAD = 'HEAD'
28
+ export const METHOD_POST = 'POST'
29
+ export const METHOD_PUT = 'PUT'
30
+ export const METHOD_DELETE = 'DELETE'
31
+ export const METHOD_PATCH = 'PATCH'
32
+ export const METHOD_OPTIONS = 'OPTIONS'
33
+ export const METHOD_TRACE = 'TRACE'
34
+ export const METHOD_CONNECT = 'CONNECT'
35
+
36
+ // HTTP Headers
37
+ export const HEADER_HOST = 'host'
38
+ export const HEADER_AUTHORIZATION = 'authorization'
39
+ export const HEADER_PROXY_AUTHORIZATION = 'proxy-authorization'
40
+ export const HEADER_CONNECTION = 'connection'
41
+ export const HEADER_CONTENT_LENGTH = 'content-length'
42
+ export const HEADER_TRANSFER_ENCODING = 'transfer-encoding'
43
+ export const HEADER_WWW_AUTHENTICATE = 'www-authenticate'
44
+ export const HEADER_PROXY_AUTHENTICATE = 'proxy-authenticate'
45
+
46
+ // HTTP Values
47
+ export const KEEP_ALIVE = 'keep-alive'
48
+ export const CHUNKED = 'chunked'
49
+ export const HTTP_VERSION = 'HTTP/1.1'
50
+
51
+ // Buffer Constants
52
+ export const CRLF = '\r\n'
53
+ export const CRLF_BUFFER = Buffer.from([13, 10, 13, 10]) // \r\n\r\n
54
+
55
+ // Timeout Constants
56
+ export const DEFAULT_TIMEOUT = 30000 // 30 seconds
57
+ export const DEFAULT_CONNECT_TIMEOUT = 10000 // 10 seconds
58
+
59
+ // Chunked Transfer Constants
60
+ export const CHUNK_SIZE_HEX_BASE = 16
61
+ export const MAX_CHUNK_SIZE = 0x1000000 // 16MB
62
+
63
+ // Authentication Constants
64
+ export const NTLM_PREFIX = 'NTLM '
65
+ export const BASIC_PREFIX = 'Basic '
66
+ export const DIGEST_PREFIX = 'Digest '
67
+
68
+ /**
69
+ * Check if a status code indicates a redirect
70
+ */
71
+ export function isRedirect(status: number): boolean {
72
+ return status >= REDIRECT_START && status <= REDIRECT_END
73
+ }
74
+
75
+ /**
76
+ * Check if a status code indicates a client error
77
+ */
78
+ export function isClientError(status: number): boolean {
79
+ return status >= CLIENT_ERROR_START && status <= CLIENT_ERROR_END
80
+ }
81
+
82
+ /**
83
+ * Check if a status code indicates a server error
84
+ */
85
+ export function isServerError(status: number): boolean {
86
+ return status >= SERVER_ERROR_START && status <= SERVER_ERROR_END
87
+ }
88
+
89
+ /**
90
+ * Check if a method should not have a body
91
+ */
92
+ export function isMethodWithoutBody(method: string): boolean {
93
+ const upperMethod = method.toUpperCase()
94
+ return upperMethod === METHOD_GET || upperMethod === METHOD_HEAD
95
+ }
96
+
97
+ /**
98
+ * Check if a method is safe (should not have side effects)
99
+ */
100
+ export function isSafeMethod(method: string): boolean {
101
+ const upperMethod = method.toUpperCase()
102
+ return upperMethod === METHOD_GET || upperMethod === METHOD_HEAD || upperMethod === METHOD_OPTIONS
103
+ }
@@ -0,0 +1,25 @@
1
+ import { Headers } from '../../../lib/headers/Headers.js'
2
+ import { CookieParser } from '../../../cookies/CookieParser.js'
3
+
4
+ /**
5
+ * Handles cookie exchange when redirecting the request.
6
+ */
7
+ export function processRedirectCookies(
8
+ responseCookies: string,
9
+ location: string,
10
+ requestUrl: string,
11
+ requestHeaders: string
12
+ ): string {
13
+ const received = CookieParser.parse(requestUrl, responseCookies)
14
+ const forwardCookies = CookieParser.filterCookies(received, location)
15
+ const headers = new Headers(requestHeaders)
16
+ headers.delete('cookie')
17
+ if (forwardCookies.length) {
18
+ const parts: string[] = []
19
+ forwardCookies.forEach((cookie) => {
20
+ parts.push(cookie.toString())
21
+ })
22
+ headers.set('cookie', parts.join('; '))
23
+ }
24
+ return headers.toString()
25
+ }
@@ -0,0 +1,319 @@
1
+ import type { IncomingMessage } from 'http'
2
+ import { SerializableError } from '../../../models/SerializableError.js'
3
+
4
+ /**
5
+ * Base class for all HTTP engine errors
6
+ */
7
+ export class HttpEngineError extends SerializableError {
8
+ readonly category: string
9
+
10
+ constructor(message: string, code?: number | string, category = 'general') {
11
+ super(message, code)
12
+ this.category = category
13
+ }
14
+ }
15
+
16
+ /**
17
+ * Connection-related errors
18
+ */
19
+ export class ConnectionError extends HttpEngineError {
20
+ readonly connectionType: 'direct' | 'proxy' | 'tunnel'
21
+
22
+ constructor(message: string, code?: number | string, connectionType: 'direct' | 'proxy' | 'tunnel' = 'direct') {
23
+ super(message, code, 'connection')
24
+ this.connectionType = connectionType
25
+ }
26
+ }
27
+
28
+ /**
29
+ * Authentication-related errors
30
+ */
31
+ export class AuthenticationError extends HttpEngineError {
32
+ readonly authType: 'request' | 'proxy' | 'digest' | 'basic' | 'ntlm'
33
+
34
+ constructor(
35
+ message: string,
36
+ code?: number | string,
37
+ authType: 'request' | 'proxy' | 'digest' | 'basic' | 'ntlm' = 'request'
38
+ ) {
39
+ super(message, code, 'authentication')
40
+ this.authType = authType
41
+ }
42
+ }
43
+
44
+ /**
45
+ * Message building errors
46
+ */
47
+ export class MessageBuilderError extends HttpEngineError {
48
+ readonly component: 'status' | 'headers' | 'body' | 'host'
49
+
50
+ constructor(message: string, code?: number | string, component: 'status' | 'headers' | 'body' | 'host' = 'headers') {
51
+ super(message, code, 'message')
52
+ this.component = component
53
+ }
54
+ }
55
+
56
+ /**
57
+ * Response parsing errors
58
+ */
59
+ export class ResponseParsingError extends HttpEngineError {
60
+ readonly parsingStage: 'status' | 'headers' | 'body' | 'chunked'
61
+
62
+ constructor(
63
+ message: string,
64
+ code?: number | string,
65
+ parsingStage: 'status' | 'headers' | 'body' | 'chunked' = 'headers'
66
+ ) {
67
+ super(message, code, 'parsing')
68
+ this.parsingStage = parsingStage
69
+ }
70
+ }
71
+
72
+ /**
73
+ * Timeout errors
74
+ */
75
+ export class TimeoutError extends HttpEngineError {
76
+ readonly timeoutType: 'connection' | 'request' | 'response'
77
+
78
+ constructor(message: string, code?: number | string, timeoutType: 'connection' | 'request' | 'response' = 'request') {
79
+ super(message, code, 'timeout')
80
+ this.timeoutType = timeoutType
81
+ }
82
+ }
83
+
84
+ /**
85
+ * Proxy-related errors
86
+ */
87
+ export class ProxyError extends HttpEngineError {
88
+ readonly proxyStage: 'connection' | 'authentication' | 'tunneling' | 'configuration'
89
+ override name = 'ProxyError'
90
+
91
+ constructor(
92
+ message: string,
93
+ code?: number | string,
94
+ proxyStage: 'connection' | 'authentication' | 'tunneling' | 'configuration' = 'connection'
95
+ ) {
96
+ super(message, code, 'proxy')
97
+ this.proxyStage = proxyStage
98
+ }
99
+ }
100
+
101
+ /**
102
+ * Proxy authentication error
103
+ */
104
+ export class ProxyAuthenticationError extends HttpEngineError {
105
+ override name = 'ProxyAuthenticationError'
106
+
107
+ constructor(
108
+ message: string,
109
+ code: number | string,
110
+ readonly response: IncomingMessage,
111
+ readonly head: Buffer
112
+ ) {
113
+ super(message, code, 'proxy')
114
+ }
115
+ }
116
+
117
+ /**
118
+ * Payload-related errors
119
+ */
120
+ export class PayloadError extends HttpEngineError {
121
+ readonly payloadType: 'serialization' | 'validation' | 'unsupported'
122
+
123
+ constructor(
124
+ message: string,
125
+ code?: number | string,
126
+ payloadType: 'serialization' | 'validation' | 'unsupported' = 'validation'
127
+ ) {
128
+ super(message, code, 'payload')
129
+ this.payloadType = payloadType
130
+ }
131
+ }
132
+
133
+ /**
134
+ * URL parsing errors
135
+ */
136
+ export class UrlParsingError extends HttpEngineError {
137
+ readonly url: string
138
+
139
+ constructor(message: string, url: string, code?: number | string) {
140
+ super(message, code, 'url')
141
+ this.url = url
142
+ }
143
+ }
144
+
145
+ /**
146
+ * Configuration errors
147
+ */
148
+ export class ConfigurationError extends HttpEngineError {
149
+ readonly configType: 'request' | 'proxy' | 'auth' | 'timeout'
150
+
151
+ constructor(
152
+ message: string,
153
+ code?: number | string,
154
+ configType: 'request' | 'proxy' | 'auth' | 'timeout' = 'request'
155
+ ) {
156
+ super(message, code, 'configuration')
157
+ this.configType = configType
158
+ }
159
+ }
160
+
161
+ /**
162
+ * Error factory for creating specific error types
163
+ */
164
+ // eslint-disable-next-line @typescript-eslint/no-extraneous-class
165
+ export class HttpEngineErrorFactory {
166
+ /**
167
+ * Create a connection error
168
+ */
169
+ static connectionError(
170
+ message: string,
171
+ code?: number | string,
172
+ connectionType?: 'direct' | 'proxy' | 'tunnel'
173
+ ): ConnectionError {
174
+ return new ConnectionError(message, code, connectionType)
175
+ }
176
+
177
+ /**
178
+ * Create an authentication error
179
+ */
180
+ static authenticationError(
181
+ message: string,
182
+ code?: number | string,
183
+ authType?: 'request' | 'proxy' | 'digest' | 'basic' | 'ntlm'
184
+ ): AuthenticationError {
185
+ return new AuthenticationError(message, code, authType)
186
+ }
187
+
188
+ /**
189
+ * Create a message builder error
190
+ */
191
+ static messageBuilderError(
192
+ message: string,
193
+ code?: number | string,
194
+ component?: 'status' | 'headers' | 'body' | 'host'
195
+ ): MessageBuilderError {
196
+ return new MessageBuilderError(message, code, component)
197
+ }
198
+
199
+ /**
200
+ * Create a response parsing error
201
+ */
202
+ static responseParsingError(
203
+ message: string,
204
+ code?: number | string,
205
+ parsingStage?: 'status' | 'headers' | 'body' | 'chunked'
206
+ ): ResponseParsingError {
207
+ return new ResponseParsingError(message, code, parsingStage)
208
+ }
209
+
210
+ /**
211
+ * Create a timeout error
212
+ */
213
+ static timeoutError(
214
+ message: string,
215
+ code?: number | string,
216
+ timeoutType?: 'connection' | 'request' | 'response'
217
+ ): TimeoutError {
218
+ return new TimeoutError(message, code, timeoutType)
219
+ }
220
+
221
+ /**
222
+ * Create a proxy error
223
+ */
224
+ static proxyError(
225
+ message: string,
226
+ code?: number | string,
227
+ proxyStage?: 'connection' | 'authentication' | 'tunneling' | 'configuration'
228
+ ): ProxyError {
229
+ return new ProxyError(message, code, proxyStage)
230
+ }
231
+
232
+ /**
233
+ * Create a payload error
234
+ */
235
+ static payloadError(
236
+ message: string,
237
+ code?: number | string,
238
+ payloadType?: 'serialization' | 'validation' | 'unsupported'
239
+ ): PayloadError {
240
+ return new PayloadError(message, code, payloadType)
241
+ }
242
+
243
+ /**
244
+ * Create a URL parsing error
245
+ */
246
+ static urlParsingError(message: string, url: string, code?: number | string): UrlParsingError {
247
+ return new UrlParsingError(message, url, code)
248
+ }
249
+
250
+ /**
251
+ * Create a configuration error
252
+ */
253
+ static configurationError(
254
+ message: string,
255
+ code?: number | string,
256
+ configType?: 'request' | 'proxy' | 'auth' | 'timeout'
257
+ ): ConfigurationError {
258
+ return new ConfigurationError(message, code, configType)
259
+ }
260
+
261
+ /**
262
+ * Convert a generic error to an HTTP engine error
263
+ */
264
+ static fromError(error: Error, category = 'general'): HttpEngineError {
265
+ if (error instanceof HttpEngineError) {
266
+ return error
267
+ }
268
+ return new HttpEngineError(error.message, undefined, category)
269
+ }
270
+
271
+ /**
272
+ * Create a connection timeout error
273
+ */
274
+ static connectionTimeout(timeoutMs: number): TimeoutError {
275
+ return new TimeoutError(`Connection timeout after ${timeoutMs}ms`, 408, 'connection')
276
+ }
277
+
278
+ /**
279
+ * Create a request timeout error
280
+ */
281
+ static requestTimeout(timeoutMs: number): TimeoutError {
282
+ return new TimeoutError(`Request timeout after ${timeoutMs}ms`, 408, 'request')
283
+ }
284
+
285
+ /**
286
+ * Create a proxy authentication error
287
+ */
288
+ static proxyAuthRequired(res: IncomingMessage, head: Buffer): ProxyAuthenticationError {
289
+ return new ProxyAuthenticationError('Proxy authentication required', 407, res, head)
290
+ }
291
+
292
+ /**
293
+ * Create a proxy authentication failed error
294
+ */
295
+ static proxyAuthFailed(): AuthenticationError {
296
+ return new AuthenticationError('Proxy authentication failed', 407, 'proxy')
297
+ }
298
+
299
+ /**
300
+ * Create a proxy configuration error
301
+ */
302
+ static proxyConfigError(message: string): ProxyError {
303
+ return new ProxyError(message, 400, 'configuration')
304
+ }
305
+
306
+ /**
307
+ * Create a payload serialization error
308
+ */
309
+ static payloadSerializationError(message: string): PayloadError {
310
+ return new PayloadError(message, 400, 'serialization')
311
+ }
312
+
313
+ /**
314
+ * Create an unsupported payload error
315
+ */
316
+ static unsupportedPayload(payloadType: string): PayloadError {
317
+ return new PayloadError(`Unsupported payload type: ${payloadType}`, 400, 'unsupported')
318
+ }
319
+ }