From 8b557c2707f0a9868f52d5c59fcf4a1b6c99cbb4 Mon Sep 17 00:00:00 2001 From: Salman Muin Kayser Chishti Date: Thu, 31 Jul 2025 23:37:22 +0100 Subject: [PATCH 01/14] support node 24 --- package.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 17d616c..2bfd716 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,9 @@ "name": "@actions/http-client", "version": "2.2.3", "description": "Actions Http Client", + "engines": { + "node": ">=24.0.0" + }, "keywords": [ "github", "actions", @@ -39,7 +42,7 @@ "url": "https://github.com/actions/toolkit/issues" }, "devDependencies": { - "@types/node": "20.7.1", + "@types/node": "24.1.0", "@types/tunnel": "0.0.3", "proxy": "^2.1.1", "@types/proxy": "^1.0.1" From 71b2ce5ec179fb0b381a7f4cc1ad685e261ad8ef Mon Sep 17 00:00:00 2001 From: Salman Muin Kayser Chishti Date: Thu, 31 Jul 2025 23:48:44 +0100 Subject: [PATCH 02/14] updates --- package-lock.json | 41 ++++++++++++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9002158..ac04c7e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,10 +13,13 @@ "undici": "^5.28.5" }, "devDependencies": { - "@types/node": "20.7.1", + "@types/node": "24.1.0", "@types/proxy": "^1.0.1", "@types/tunnel": "0.0.3", "proxy": "^2.1.1" + }, + "engines": { + "node": ">=24.0.0" } }, "node_modules/@fastify/busboy": { @@ -28,10 +31,14 @@ } }, "node_modules/@types/node": { - "version": "20.7.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.7.1.tgz", - "integrity": "sha512-LT+OIXpp2kj4E2S/p91BMe+VgGX2+lfO+XTpfXhh+bCk2LkQtHZSub8ewFBMGP5ClysPjTDFa4sMI8Q3n4T0wg==", - "dev": true + "version": "24.1.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.1.0.tgz", + "integrity": "sha512-ut5FthK5moxFKH2T1CUOC6ctR67rQRvvHdFLCD2Ql6KXmMuCrjsSsRI9UsLCm9M18BMwClv4pn327UvB7eeO1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~7.8.0" + } }, "node_modules/@types/proxy": { "version": "1.0.2", @@ -226,6 +233,13 @@ "engines": { "node": ">=14.0" } + }, + "node_modules/undici-types": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.8.0.tgz", + "integrity": "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==", + "dev": true, + "license": "MIT" } }, "dependencies": { @@ -235,10 +249,13 @@ "integrity": "sha512-JUFJad5lv7jxj926GPgymrWQxxjPYuJNiNjNMzqT+HiuP6Vl3dk5xzG+8sTX96np0ZAluvaMzPsjhHZ5rNuNQQ==" }, "@types/node": { - "version": "20.7.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.7.1.tgz", - "integrity": "sha512-LT+OIXpp2kj4E2S/p91BMe+VgGX2+lfO+XTpfXhh+bCk2LkQtHZSub8ewFBMGP5ClysPjTDFa4sMI8Q3n4T0wg==", - "dev": true + "version": "24.1.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.1.0.tgz", + "integrity": "sha512-ut5FthK5moxFKH2T1CUOC6ctR67rQRvvHdFLCD2Ql6KXmMuCrjsSsRI9UsLCm9M18BMwClv4pn327UvB7eeO1w==", + "dev": true, + "requires": { + "undici-types": "~7.8.0" + } }, "@types/proxy": { "version": "1.0.2", @@ -388,6 +405,12 @@ "requires": { "@fastify/busboy": "^2.0.0" } + }, + "undici-types": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.8.0.tgz", + "integrity": "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==", + "dev": true } } } From 8229643fe90e1c30d0a7097155ea6fbb8ea3322c Mon Sep 17 00:00:00 2001 From: Salman Muin Kayser Chishti Date: Fri, 1 Aug 2025 11:50:25 +0100 Subject: [PATCH 03/14] update for types --- src/index.ts | 67 +++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 58 insertions(+), 9 deletions(-) diff --git a/src/index.ts b/src/index.ts index 6ee9ae4..17f5fde 100644 --- a/src/index.ts +++ b/src/index.ts @@ -275,9 +275,8 @@ export class HttpClient { Headers.Accept, MediaTypes.ApplicationJson ) - additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader( + additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultContentTypeHeader( additionalHeaders, - Headers.ContentType, MediaTypes.ApplicationJson ) const res: HttpClientResponse = await this.post( @@ -299,9 +298,8 @@ export class HttpClient { Headers.Accept, MediaTypes.ApplicationJson ) - additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader( + additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultContentTypeHeader( additionalHeaders, - Headers.ContentType, MediaTypes.ApplicationJson ) const res: HttpClientResponse = await this.put( @@ -323,9 +321,8 @@ export class HttpClient { Headers.Accept, MediaTypes.ApplicationJson ) - additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader( + additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultContentTypeHeader( additionalHeaders, - Headers.ContentType, MediaTypes.ApplicationJson ) const res: HttpClientResponse = await this.patch( @@ -632,12 +629,64 @@ export class HttpClient { additionalHeaders: http.OutgoingHttpHeaders, header: string, _default: string - ): string | number | string[] { + ): string | string[] { + let clientHeader: string | string[] | undefined + if (this.requestOptions && this.requestOptions.headers) { + const headerValue = lowercaseKeys(this.requestOptions.headers)[header] + if (headerValue) { + clientHeader = typeof headerValue === 'number' ? headerValue.toString() : headerValue + } + } + + const additionalValue = additionalHeaders[header] + + if (additionalValue !== undefined) { + return typeof additionalValue === 'number' ? additionalValue.toString() : additionalValue + } + + if (clientHeader !== undefined) { + return clientHeader + } + + return _default + } + + private _getExistingOrDefaultContentTypeHeader( + additionalHeaders: http.OutgoingHttpHeaders, + _default: string + ): string { let clientHeader: string | undefined if (this.requestOptions && this.requestOptions.headers) { - clientHeader = lowercaseKeys(this.requestOptions.headers)[header] + const headerValue = lowercaseKeys(this.requestOptions.headers)[Headers.ContentType] + if (headerValue) { + if (typeof headerValue === 'number') { + clientHeader = String(headerValue) + } else if (Array.isArray(headerValue)) { + clientHeader = headerValue.join(', ') + } else { + clientHeader = headerValue + } + } } - return additionalHeaders[header] || clientHeader || _default + + const additionalValue = additionalHeaders[Headers.ContentType] + + // Return the first non-undefined value, converting numbers or arrays to strings if necessary + if (additionalValue !== undefined) { + if (typeof additionalValue === 'number') { + return String(additionalValue) + } else if (Array.isArray(additionalValue)) { + return additionalValue.join(', ') + } else { + return additionalValue + } + } + + if (clientHeader !== undefined) { + return clientHeader + } + + return _default } private _getAgent(parsedUrl: URL): http.Agent { From 09705524bbaa04900917036f6a8410107ed2e745 Mon Sep 17 00:00:00 2001 From: Salman Muin Kayser Chishti Date: Wed, 6 Aug 2025 12:57:10 +0100 Subject: [PATCH 04/14] format --- src/index.ts | 56 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 24 deletions(-) diff --git a/src/index.ts b/src/index.ts index 17f5fde..553384c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -275,10 +275,11 @@ export class HttpClient { Headers.Accept, MediaTypes.ApplicationJson ) - additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultContentTypeHeader( - additionalHeaders, - MediaTypes.ApplicationJson - ) + additionalHeaders[Headers.ContentType] = + this._getExistingOrDefaultContentTypeHeader( + additionalHeaders, + MediaTypes.ApplicationJson + ) const res: HttpClientResponse = await this.post( requestUrl, data, @@ -298,10 +299,11 @@ export class HttpClient { Headers.Accept, MediaTypes.ApplicationJson ) - additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultContentTypeHeader( - additionalHeaders, - MediaTypes.ApplicationJson - ) + additionalHeaders[Headers.ContentType] = + this._getExistingOrDefaultContentTypeHeader( + additionalHeaders, + MediaTypes.ApplicationJson + ) const res: HttpClientResponse = await this.put( requestUrl, data, @@ -321,10 +323,11 @@ export class HttpClient { Headers.Accept, MediaTypes.ApplicationJson ) - additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultContentTypeHeader( - additionalHeaders, - MediaTypes.ApplicationJson - ) + additionalHeaders[Headers.ContentType] = + this._getExistingOrDefaultContentTypeHeader( + additionalHeaders, + MediaTypes.ApplicationJson + ) const res: HttpClientResponse = await this.patch( requestUrl, data, @@ -634,30 +637,35 @@ export class HttpClient { if (this.requestOptions && this.requestOptions.headers) { const headerValue = lowercaseKeys(this.requestOptions.headers)[header] if (headerValue) { - clientHeader = typeof headerValue === 'number' ? headerValue.toString() : headerValue + clientHeader = + typeof headerValue === 'number' ? headerValue.toString() : headerValue } } - + const additionalValue = additionalHeaders[header] - + if (additionalValue !== undefined) { - return typeof additionalValue === 'number' ? additionalValue.toString() : additionalValue + return typeof additionalValue === 'number' + ? additionalValue.toString() + : additionalValue } - + if (clientHeader !== undefined) { return clientHeader } - + return _default } - + private _getExistingOrDefaultContentTypeHeader( additionalHeaders: http.OutgoingHttpHeaders, _default: string ): string { let clientHeader: string | undefined if (this.requestOptions && this.requestOptions.headers) { - const headerValue = lowercaseKeys(this.requestOptions.headers)[Headers.ContentType] + const headerValue = lowercaseKeys(this.requestOptions.headers)[ + Headers.ContentType + ] if (headerValue) { if (typeof headerValue === 'number') { clientHeader = String(headerValue) @@ -668,9 +676,9 @@ export class HttpClient { } } } - + const additionalValue = additionalHeaders[Headers.ContentType] - + // Return the first non-undefined value, converting numbers or arrays to strings if necessary if (additionalValue !== undefined) { if (typeof additionalValue === 'number') { @@ -681,11 +689,11 @@ export class HttpClient { return additionalValue } } - + if (clientHeader !== undefined) { return clientHeader } - + return _default } From 07dd28b1562825da7dcebd6294479fe4c40b44ea Mon Sep 17 00:00:00 2001 From: Salman Muin Kayser Chishti Date: Thu, 4 Sep 2025 14:16:27 +0100 Subject: [PATCH 05/14] Bump package versions, and fix issues --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2bfd716..221934e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@actions/http-client", - "version": "2.2.3", + "version": "3.0.0", "description": "Actions Http Client", "engines": { "node": ">=24.0.0" From 39315f81cb81d705f003e36311631629e9fbbf14 Mon Sep 17 00:00:00 2001 From: Salman Muin Kayser Chishti Date: Thu, 4 Sep 2025 15:15:02 +0100 Subject: [PATCH 06/14] package updates --- package-lock.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index ac04c7e..912e743 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@actions/http-client", - "version": "2.2.3", + "version": "3.0.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@actions/http-client", - "version": "2.2.3", + "version": "3.0.0", "license": "MIT", "dependencies": { "tunnel": "^0.0.6", From b1b2b03b4ea951042d314e43e1229fd444680760 Mon Sep 17 00:00:00 2001 From: Salman Muin Kayser Chishti Date: Mon, 8 Sep 2025 15:36:39 +0100 Subject: [PATCH 07/14] http --- package-lock.json | 3 --- package.json | 3 --- 2 files changed, 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 912e743..d1b38ea 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,9 +17,6 @@ "@types/proxy": "^1.0.1", "@types/tunnel": "0.0.3", "proxy": "^2.1.1" - }, - "engines": { - "node": ">=24.0.0" } }, "node_modules/@fastify/busboy": { diff --git a/package.json b/package.json index 221934e..126731f 100644 --- a/package.json +++ b/package.json @@ -2,9 +2,6 @@ "name": "@actions/http-client", "version": "3.0.0", "description": "Actions Http Client", - "engines": { - "node": ">=24.0.0" - }, "keywords": [ "github", "actions", From 63b2a89b0d45e55c3e2eb359c1f565efe1c54b7a Mon Sep 17 00:00:00 2001 From: Salman Muin Kayser Chishti Date: Thu, 25 Sep 2025 13:03:33 +0100 Subject: [PATCH 08/14] update with dist updates --- package-lock.json | 236 +++++++++------------------------------------- package.json | 5 +- 2 files changed, 47 insertions(+), 194 deletions(-) diff --git a/package-lock.json b/package-lock.json index d1b38ea..4355a12 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,7 +1,7 @@ { "name": "@actions/http-client", "version": "3.0.0", - "lockfileVersion": 2, + "lockfileVersion": 3, "requires": true, "packages": { "": { @@ -20,9 +20,10 @@ } }, "node_modules/@fastify/busboy": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.0.0.tgz", - "integrity": "sha512-JUFJad5lv7jxj926GPgymrWQxxjPYuJNiNjNMzqT+HiuP6Vl3dk5xzG+8sTX96np0ZAluvaMzPsjhHZ5rNuNQQ==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz", + "integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==", + "license": "MIT", "engines": { "node": ">=14" } @@ -38,10 +39,11 @@ } }, "node_modules/@types/proxy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@types/proxy/-/proxy-1.0.2.tgz", - "integrity": "sha512-NDNsg7YuClVzEenn9SUButu43blypWvljGsIkDV7HI4N9apjrS0aeeMTUG0PYa71lD1AvIgvjkBagqHDiomDjA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@types/proxy/-/proxy-1.0.4.tgz", + "integrity": "sha512-KnYy7hpp3wXQ2U0ExvCMF9BvWZ6h2aI0XWb8g705mn26Zmn2HO/eLRi6UuhHELA6MNJtYtiZYWv38gobJN0xXQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*" } @@ -51,6 +53,7 @@ "resolved": "https://registry.npmjs.org/@types/tunnel/-/tunnel-0.0.3.tgz", "integrity": "sha512-sOUTGn6h1SfQ+gbgqC364jLFBw2lnFqkgF3q0WovEHRLMrVD1sd5aufqi/aJObLekJO+Aq5z646U4Oxy6shXMA==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*" } @@ -60,6 +63,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, + "license": "MIT", "dependencies": { "color-convert": "^1.9.0" }, @@ -72,6 +76,7 @@ "resolved": "https://registry.npmjs.org/args/-/args-5.0.3.tgz", "integrity": "sha512-h6k/zfFgusnv3i5TU08KQkVKuCPBtL/PWQbWkHUxvJrZ2nAyeaUupneemcrgn1xmqxPQsPIzwkUhOpoqPDRZuA==", "dev": true, + "license": "MIT", "dependencies": { "camelcase": "5.0.0", "chalk": "2.4.2", @@ -93,6 +98,7 @@ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.0.0.tgz", "integrity": "sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -102,6 +108,7 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -116,6 +123,7 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, + "license": "MIT", "dependencies": { "color-name": "1.1.3" } @@ -124,15 +132,17 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "dev": true, + "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -148,6 +158,7 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8.0" } @@ -157,6 +168,7 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -166,6 +178,7 @@ "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", "integrity": "sha512-nvVPLpIHUxCUoRLrFqTgSxXJ614d8AgQoWl7zPe/2VadE8+1dpU3LBhowRuBAcuwruWtOdD8oYC9jDNJjXDPyA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -175,26 +188,32 @@ "resolved": "https://registry.npmjs.org/mri/-/mri-1.1.4.tgz", "integrity": "sha512-6y7IjGPm8AzlvoUrwAaw1tLnUBudaS3752vcd8JtrpGGQn+rXIe63LFVHm/YMwtqAuh+LJPCFdlLYPWM1nYn6w==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" }, "node_modules/proxy": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/proxy/-/proxy-2.1.1.tgz", - "integrity": "sha512-nLgd7zdUAOpB3ZO/xCkU8gy74UER7P0aihU8DkUsDS5ZoFwVCX7u8dy+cv5tVK8UaB/yminU1GiLWE26TKPYpg==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/proxy/-/proxy-2.2.0.tgz", + "integrity": "sha512-nYclNIWj9UpXbVJ3W5EXIYiGR88AKZoGt90kyh3zoOBY5QW+7bbtPvMFgKGD4VJmpS3UXQXtlGXSg3lRNLOFLg==", "dev": true, + "license": "MIT", "dependencies": { "args": "^5.0.3", "basic-auth-parser": "0.0.2-1", "debug": "^4.3.4" }, + "bin": { + "proxy": "dist/bin/proxy.js" + }, "engines": { "node": ">= 14" } @@ -204,6 +223,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^3.0.0" }, @@ -215,14 +235,15 @@ "version": "0.0.6", "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", + "license": "MIT", "engines": { "node": ">=0.6.11 <=0.7.0 || >=0.7.3" } }, "node_modules/undici": { - "version": "5.28.5", - "resolved": "https://registry.npmjs.org/undici/-/undici-5.28.5.tgz", - "integrity": "sha512-zICwjrDrcrUE0pyyJc1I2QzBkLM8FINsgOrt6WjA+BgajVq9Nxu2PbFFXUrAggLfDXlZGZBVZYw7WNV5KiBiBA==", + "version": "5.29.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.29.0.tgz", + "integrity": "sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==", "license": "MIT", "dependencies": { "@fastify/busboy": "^2.0.0" @@ -238,176 +259,5 @@ "dev": true, "license": "MIT" } - }, - "dependencies": { - "@fastify/busboy": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.0.0.tgz", - "integrity": "sha512-JUFJad5lv7jxj926GPgymrWQxxjPYuJNiNjNMzqT+HiuP6Vl3dk5xzG+8sTX96np0ZAluvaMzPsjhHZ5rNuNQQ==" - }, - "@types/node": { - "version": "24.1.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.1.0.tgz", - "integrity": "sha512-ut5FthK5moxFKH2T1CUOC6ctR67rQRvvHdFLCD2Ql6KXmMuCrjsSsRI9UsLCm9M18BMwClv4pn327UvB7eeO1w==", - "dev": true, - "requires": { - "undici-types": "~7.8.0" - } - }, - "@types/proxy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@types/proxy/-/proxy-1.0.2.tgz", - "integrity": "sha512-NDNsg7YuClVzEenn9SUButu43blypWvljGsIkDV7HI4N9apjrS0aeeMTUG0PYa71lD1AvIgvjkBagqHDiomDjA==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/tunnel": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/@types/tunnel/-/tunnel-0.0.3.tgz", - "integrity": "sha512-sOUTGn6h1SfQ+gbgqC364jLFBw2lnFqkgF3q0WovEHRLMrVD1sd5aufqi/aJObLekJO+Aq5z646U4Oxy6shXMA==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "args": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/args/-/args-5.0.3.tgz", - "integrity": "sha512-h6k/zfFgusnv3i5TU08KQkVKuCPBtL/PWQbWkHUxvJrZ2nAyeaUupneemcrgn1xmqxPQsPIzwkUhOpoqPDRZuA==", - "dev": true, - "requires": { - "camelcase": "5.0.0", - "chalk": "2.4.2", - "leven": "2.1.0", - "mri": "1.1.4" - } - }, - "basic-auth-parser": { - "version": "0.0.2-1", - "resolved": "https://registry.npmjs.org/basic-auth-parser/-/basic-auth-parser-0.0.2-1.tgz", - "integrity": "sha512-GFj8iVxo9onSU6BnnQvVwqvxh60UcSHJEDnIk3z4B6iOjsKSmqe+ibW0Rsz7YO7IE1HG3D3tqCNIidP46SZVdQ==", - "dev": true - }, - "camelcase": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.0.0.tgz", - "integrity": "sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA==", - "dev": true - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "leven": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", - "integrity": "sha512-nvVPLpIHUxCUoRLrFqTgSxXJ614d8AgQoWl7zPe/2VadE8+1dpU3LBhowRuBAcuwruWtOdD8oYC9jDNJjXDPyA==", - "dev": true - }, - "mri": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/mri/-/mri-1.1.4.tgz", - "integrity": "sha512-6y7IjGPm8AzlvoUrwAaw1tLnUBudaS3752vcd8JtrpGGQn+rXIe63LFVHm/YMwtqAuh+LJPCFdlLYPWM1nYn6w==", - "dev": true - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "proxy": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/proxy/-/proxy-2.1.1.tgz", - "integrity": "sha512-nLgd7zdUAOpB3ZO/xCkU8gy74UER7P0aihU8DkUsDS5ZoFwVCX7u8dy+cv5tVK8UaB/yminU1GiLWE26TKPYpg==", - "dev": true, - "requires": { - "args": "^5.0.3", - "basic-auth-parser": "0.0.2-1", - "debug": "^4.3.4" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "tunnel": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", - "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==" - }, - "undici": { - "version": "5.28.5", - "resolved": "https://registry.npmjs.org/undici/-/undici-5.28.5.tgz", - "integrity": "sha512-zICwjrDrcrUE0pyyJc1I2QzBkLM8FINsgOrt6WjA+BgajVq9Nxu2PbFFXUrAggLfDXlZGZBVZYw7WNV5KiBiBA==", - "requires": { - "@fastify/busboy": "^2.0.0" - } - }, - "undici-types": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.8.0.tgz", - "integrity": "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==", - "dev": true - } } } diff --git a/package.json b/package.json index 126731f..a218fb8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@actions/http-client", - "version": "3.0.0", + "version": "3.0.1", "description": "Actions Http Client", "keywords": [ "github", @@ -47,5 +47,8 @@ "dependencies": { "tunnel": "^0.0.6", "undici": "^5.28.5" + }, + "overrides": { + "uri-js": "npm:uri-js-replace@^1.0.1" } } From abaad94e455beb7bf34478ac01f791a0cff00bee Mon Sep 17 00:00:00 2001 From: Salman Muin Kayser Chishti Date: Thu, 25 Sep 2025 18:06:28 +0100 Subject: [PATCH 09/14] update some version numbers, will revise in a bit --- package-lock.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4355a12..b3ee4a2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@actions/http-client", - "version": "3.0.0", + "version": "3.0.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@actions/http-client", - "version": "3.0.0", + "version": "3.0.1", "license": "MIT", "dependencies": { "tunnel": "^0.0.6", From 21b8fb9c624bbb592da8a9e94605f1ecafe03d90 Mon Sep 17 00:00:00 2001 From: Salman Muin Kayser Chishti Date: Mon, 13 Oct 2025 18:17:00 +0100 Subject: [PATCH 10/14] Update HTTP tests to use HTTPS for postman-echo.com --- __tests__/auth.test.ts | 12 +++--- __tests__/basics.test.ts | 84 ++++++++++++++++++------------------- __tests__/headers.test.ts | 16 +++---- __tests__/keepalive.test.ts | 20 ++++----- __tests__/proxy.test.ts | 18 ++++---- 5 files changed, 75 insertions(+), 75 deletions(-) diff --git a/__tests__/auth.test.ts b/__tests__/auth.test.ts index 50d0a6a..1b110df 100644 --- a/__tests__/auth.test.ts +++ b/__tests__/auth.test.ts @@ -15,7 +15,7 @@ describe('auth', () => { bh ]) const res: httpm.HttpClientResponse = await http.get( - 'http://postman-echo.com/get' + 'https://postman-echo.com/get' ) expect(res.message.statusCode).toBe(200) const body: string = await res.readBody() @@ -26,7 +26,7 @@ describe('auth', () => { 'base64' ).toString() expect(creds).toBe('johndoe:password') - expect(obj.url).toBe('http://postman-echo.com/get') + expect(obj.url).toBe('https://postman-echo.com/get') }) it('does basic http get request with pat token auth', async () => { @@ -38,7 +38,7 @@ describe('auth', () => { ph ]) const res: httpm.HttpClientResponse = await http.get( - 'http://postman-echo.com/get' + 'https://postman-echo.com/get' ) expect(res.message.statusCode).toBe(200) const body: string = await res.readBody() @@ -49,7 +49,7 @@ describe('auth', () => { 'base64' ).toString() expect(creds).toBe(`PAT:${token}`) - expect(obj.url).toBe('http://postman-echo.com/get') + expect(obj.url).toBe('https://postman-echo.com/get') }) it('does basic http get request with pat token auth', async () => { @@ -60,13 +60,13 @@ describe('auth', () => { ph ]) const res: httpm.HttpClientResponse = await http.get( - 'http://postman-echo.com/get' + 'https://postman-echo.com/get' ) expect(res.message.statusCode).toBe(200) const body: string = await res.readBody() const obj = JSON.parse(body) const auth: string = obj.headers.authorization expect(auth).toBe(`Bearer ${token}`) - expect(obj.url).toBe('http://postman-echo.com/get') + expect(obj.url).toBe('https://postman-echo.com/get') }) }) diff --git a/__tests__/basics.test.ts b/__tests__/basics.test.ts index 8d93abb..168cbc0 100644 --- a/__tests__/basics.test.ts +++ b/__tests__/basics.test.ts @@ -37,41 +37,41 @@ describe('basics', () => { // "user-agent": "typed-test-client-tests" // }, // "origin": "173.95.152.44", - // "url": "http://postman-echo.com/get" + // "url": "https://postman-echo.com/get" // } it('does basic http get request', async () => { const res: httpm.HttpClientResponse = await _http.get( - 'http://postman-echo.com/get' + 'https://postman-echo.com/get' ) expect(res.message.statusCode).toBe(200) const body: string = await res.readBody() const obj = JSON.parse(body) - expect(obj.url).toBe('http://postman-echo.com/get') + expect(obj.url).toBe('https://postman-echo.com/get') expect(obj.headers['user-agent']).toBeTruthy() }) it('does basic http get request with no user agent', async () => { const http: httpm.HttpClient = new httpm.HttpClient() const res: httpm.HttpClientResponse = await http.get( - 'http://postman-echo.com/get' + 'https://postman-echo.com/get' ) expect(res.message.statusCode).toBe(200) const body: string = await res.readBody() const obj = JSON.parse(body) - expect(obj.url).toBe('http://postman-echo.com/get') + expect(obj.url).toBe('https://postman-echo.com/get') expect(obj.headers['user-agent']).toBeFalsy() }) /* TODO write a mock rather then relying on a third party it('does basic https get request', async () => { const res: httpm.HttpClientResponse = await _http.get( - 'http://postman-echo.com/get' + 'https://postman-echo.com/get' ) expect(res.message.statusCode).toBe(200) const body: string = await res.readBody() const obj = JSON.parse(body) - expect(obj.url).toBe('http://postman-echo.com/get') + expect(obj.url).toBe('https://postman-echo.com/get') }) */ it('does basic http get request with default headers', async () => { @@ -86,14 +86,14 @@ describe('basics', () => { } ) const res: httpm.HttpClientResponse = await http.get( - 'http://postman-echo.com/get' + 'https://postman-echo.com/get' ) expect(res.message.statusCode).toBe(200) const body: string = await res.readBody() const obj = JSON.parse(body) expect(obj.headers.accept).toBe('application/json') expect(obj.headers['content-type']).toBe('application/json') - expect(obj.url).toBe('http://postman-echo.com/get') + expect(obj.url).toBe('https://postman-echo.com/get') }) it('does basic http get request with merged headers', async () => { @@ -108,7 +108,7 @@ describe('basics', () => { } ) const res: httpm.HttpClientResponse = await http.get( - 'http://postman-echo.com/get', + 'https://postman-echo.com/get', { 'content-type': 'application/x-www-form-urlencoded' } @@ -120,18 +120,18 @@ describe('basics', () => { expect(obj.headers['content-type']).toBe( 'application/x-www-form-urlencoded' ) - expect(obj.url).toBe('http://postman-echo.com/get') + expect(obj.url).toBe('https://postman-echo.com/get') }) it('pipes a get request', async () => { return new Promise(async resolve => { const file = fs.createWriteStream(sampleFilePath) - ;(await _http.get('http://postman-echo.com/get')).message + ;(await _http.get('https://postman-echo.com/get')).message .pipe(file) .on('close', () => { const body: string = fs.readFileSync(sampleFilePath).toString() const obj = JSON.parse(body) - expect(obj.url).toBe('http://postman-echo.com/get') + expect(obj.url).toBe('https://postman-echo.com/get') resolve() }) }) @@ -139,32 +139,32 @@ describe('basics', () => { it('does basic get request with redirects', async () => { const res: httpm.HttpClientResponse = await _http.get( - `http://postman-echo.com/redirect-to?url=${encodeURIComponent( - 'http://postman-echo.com/get' + `https://postman-echo.com/redirect-to?url=${encodeURIComponent( + 'https://postman-echo.com/get' )}` ) expect(res.message.statusCode).toBe(200) const body: string = await res.readBody() const obj = JSON.parse(body) - expect(obj.url).toBe('http://postman-echo.com/get') + expect(obj.url).toBe('https://postman-echo.com/get') }) it('does basic get request with redirects (303)', async () => { const res: httpm.HttpClientResponse = await _http.get( - `http://postman-echo.com/redirect-to?url=${encodeURIComponent( - 'http://postman-echo.com/get' + `https://postman-echo.com/redirect-to?url=${encodeURIComponent( + 'https://postman-echo.com/get' )}&status_code=303` ) expect(res.message.statusCode).toBe(200) const body: string = await res.readBody() const obj = JSON.parse(body) - expect(obj.url).toBe('http://postman-echo.com/get') + expect(obj.url).toBe('https://postman-echo.com/get') }) it('returns 404 for not found get request on redirect', async () => { const res: httpm.HttpClientResponse = await _http.get( - `http://postman-echo.com/redirect-to?url=${encodeURIComponent( - 'http://postman-echo.com/status/404' + `https://postman-echo.com/redirect-to?url=${encodeURIComponent( + 'https://postman-echo.com/status/404' )}&status_code=303` ) expect(res.message.statusCode).toBe(404) @@ -178,8 +178,8 @@ describe('basics', () => { {allowRedirects: false} ) const res: httpm.HttpClientResponse = await http.get( - `http://postman-echo.com/redirect-to?url=${encodeURIComponent( - 'http://postman-echo.com/get' + `https://postman-echo.com/redirect-to?url=${encodeURIComponent( + 'https://postman-echo.com/get' )}` ) expect(res.message.statusCode).toBe(302) @@ -192,7 +192,7 @@ describe('basics', () => { authorization: 'shhh' } const res: httpm.HttpClientResponse = await _http.get( - `http://postman-echo.com/redirect-to?url=${encodeURIComponent( + `https://postman-echo.com/redirect-to?url=${encodeURIComponent( 'http://www.postman-echo.com/get' )}`, headers @@ -214,7 +214,7 @@ describe('basics', () => { Authorization: 'shhh' } const res: httpm.HttpClientResponse = await _http.get( - `http://postman-echo.com/redirect-to?url=${encodeURIComponent( + `https://postman-echo.com/redirect-to?url=${encodeURIComponent( 'http://www.postman-echo.com/get' )}`, headers @@ -232,14 +232,14 @@ describe('basics', () => { it('does basic head request', async () => { const res: httpm.HttpClientResponse = await _http.head( - 'http://postman-echo.com/get' + 'https://postman-echo.com/get' ) expect(res.message.statusCode).toBe(200) }) it('does basic http delete request', async () => { const res: httpm.HttpClientResponse = await _http.del( - 'http://postman-echo.com/delete' + 'https://postman-echo.com/delete' ) expect(res.message.statusCode).toBe(200) const body: string = await res.readBody() @@ -249,32 +249,32 @@ describe('basics', () => { it('does basic http post request', async () => { const b = 'Hello World!' const res: httpm.HttpClientResponse = await _http.post( - 'http://postman-echo.com/post', + 'https://postman-echo.com/post', b ) expect(res.message.statusCode).toBe(200) const body: string = await res.readBody() const obj = JSON.parse(body) expect(obj.data).toBe(b) - expect(obj.url).toBe('http://postman-echo.com/post') + expect(obj.url).toBe('https://postman-echo.com/post') }) it('does basic http patch request', async () => { const b = 'Hello World!' const res: httpm.HttpClientResponse = await _http.patch( - 'http://postman-echo.com/patch', + 'https://postman-echo.com/patch', b ) expect(res.message.statusCode).toBe(200) const body: string = await res.readBody() const obj = JSON.parse(body) expect(obj.data).toBe(b) - expect(obj.url).toBe('http://postman-echo.com/patch') + expect(obj.url).toBe('https://postman-echo.com/patch') }) it('does basic http options request', async () => { const res: httpm.HttpClientResponse = await _http.options( - 'http://postman-echo.com' + 'https://postman-echo.com' ) expect(res.message.statusCode).toBe(200) await res.readBody() @@ -282,7 +282,7 @@ describe('basics', () => { it('returns 404 for not found get request', async () => { const res: httpm.HttpClientResponse = await _http.get( - 'http://postman-echo.com/status/404' + 'https://postman-echo.com/status/404' ) expect(res.message.statusCode).toBe(404) await res.readBody() @@ -290,11 +290,11 @@ describe('basics', () => { it('gets a json object', async () => { const jsonObj = await _http.getJson( - 'http://postman-echo.com/get' + 'https://postman-echo.com/get' ) expect(jsonObj.statusCode).toBe(200) expect(jsonObj.result).toBeDefined() - expect(jsonObj.result?.url).toBe('http://postman-echo.com/get') + expect(jsonObj.result?.url).toBe('https://postman-echo.com/get') expect(jsonObj.result?.headers[httpm.Headers.Accept]).toBe( httpm.MediaTypes.ApplicationJson ) @@ -305,7 +305,7 @@ describe('basics', () => { it('getting a non existent json object returns null', async () => { const jsonObj = await _http.getJson( - 'http://postman-echo.com/status/404' + 'https://postman-echo.com/status/404' ) expect(jsonObj.statusCode).toBe(404) expect(jsonObj.result).toBeNull() @@ -314,12 +314,12 @@ describe('basics', () => { it('posts a json object', async () => { const res = {name: 'foo'} const restRes = await _http.postJson( - 'http://postman-echo.com/post', + 'https://postman-echo.com/post', res ) expect(restRes.statusCode).toBe(200) expect(restRes.result).toBeDefined() - expect(restRes.result?.url).toBe('http://postman-echo.com/post') + expect(restRes.result?.url).toBe('https://postman-echo.com/post') expect(restRes.result?.json.name).toBe('foo') expect(restRes.result?.headers[httpm.Headers.Accept]).toBe( httpm.MediaTypes.ApplicationJson @@ -335,12 +335,12 @@ describe('basics', () => { it('puts a json object', async () => { const res = {name: 'foo'} const restRes = await _http.putJson( - 'http://postman-echo.com/put', + 'https://postman-echo.com/put', res ) expect(restRes.statusCode).toBe(200) expect(restRes.result).toBeDefined() - expect(restRes.result?.url).toBe('http://postman-echo.com/put') + expect(restRes.result?.url).toBe('https://postman-echo.com/put') expect(restRes.result?.json.name).toBe('foo') expect(restRes.result?.headers[httpm.Headers.Accept]).toBe( @@ -357,12 +357,12 @@ describe('basics', () => { it('patch a json object', async () => { const res = {name: 'foo'} const restRes = await _http.patchJson( - 'http://postman-echo.com/patch', + 'https://postman-echo.com/patch', res ) expect(restRes.statusCode).toBe(200) expect(restRes.result).toBeDefined() - expect(restRes.result?.url).toBe('http://postman-echo.com/patch') + expect(restRes.result?.url).toBe('https://postman-echo.com/patch') expect(restRes.result?.json.name).toBe('foo') expect(restRes.result?.headers[httpm.Headers.Accept]).toBe( httpm.MediaTypes.ApplicationJson diff --git a/__tests__/headers.test.ts b/__tests__/headers.test.ts index 887d933..c1ca0ec 100644 --- a/__tests__/headers.test.ts +++ b/__tests__/headers.test.ts @@ -12,7 +12,7 @@ describe('headers', () => { it('preserves existing headers on getJson', async () => { const additionalHeaders = {[httpm.Headers.Accept]: 'foo'} let jsonObj = await _http.getJson( - 'http://postman-echo.com/get', + 'https://postman-echo.com/get', additionalHeaders ) expect(jsonObj.result.headers[httpm.Headers.Accept]).toBe('foo') @@ -26,7 +26,7 @@ describe('headers', () => { [httpm.Headers.Accept]: 'baz' } } - jsonObj = await httpWithHeaders.getJson('http://postman-echo.com/get') + jsonObj = await httpWithHeaders.getJson('https://postman-echo.com/get') expect(jsonObj.result.headers[httpm.Headers.Accept]).toBe('baz') expect(jsonObj.headers[httpm.Headers.ContentType]).toContain( httpm.MediaTypes.ApplicationJson @@ -36,7 +36,7 @@ describe('headers', () => { it('preserves existing headers on postJson', async () => { const additionalHeaders = {[httpm.Headers.Accept]: 'foo'} let jsonObj = await _http.postJson( - 'http://postman-echo.com/post', + 'https://postman-echo.com/post', {}, additionalHeaders ) @@ -52,7 +52,7 @@ describe('headers', () => { } } jsonObj = await httpWithHeaders.postJson( - 'http://postman-echo.com/post', + 'https://postman-echo.com/post', {} ) expect(jsonObj.result.headers[httpm.Headers.Accept]).toBe('baz') @@ -64,7 +64,7 @@ describe('headers', () => { it('preserves existing headers on putJson', async () => { const additionalHeaders = {[httpm.Headers.Accept]: 'foo'} let jsonObj = await _http.putJson( - 'http://postman-echo.com/put', + 'https://postman-echo.com/put', {}, additionalHeaders ) @@ -80,7 +80,7 @@ describe('headers', () => { } } jsonObj = await httpWithHeaders.putJson( - 'http://postman-echo.com/put', + 'https://postman-echo.com/put', {} ) expect(jsonObj.result.headers[httpm.Headers.Accept]).toBe('baz') @@ -92,7 +92,7 @@ describe('headers', () => { it('preserves existing headers on patchJson', async () => { const additionalHeaders = {[httpm.Headers.Accept]: 'foo'} let jsonObj = await _http.patchJson( - 'http://postman-echo.com/patch', + 'https://postman-echo.com/patch', {}, additionalHeaders ) @@ -108,7 +108,7 @@ describe('headers', () => { } } jsonObj = await httpWithHeaders.patchJson( - 'http://postman-echo.com/patch', + 'https://postman-echo.com/patch', {} ) expect(jsonObj.result.headers[httpm.Headers.Accept]).toBe('baz') diff --git a/__tests__/keepalive.test.ts b/__tests__/keepalive.test.ts index 160069a..15f7761 100644 --- a/__tests__/keepalive.test.ts +++ b/__tests__/keepalive.test.ts @@ -13,30 +13,30 @@ describe('basics', () => { it.each([true, false])('creates Agent with keepAlive %s', keepAlive => { const http = new httpm.HttpClient('http-client-tests', [], {keepAlive}) - const agent = http.getAgent('http://postman-echo.com') + const agent = http.getAgent('https://postman-echo.com') expect(agent).toHaveProperty('keepAlive', keepAlive) }) it('does basic http get request with keepAlive true', async () => { const res: httpm.HttpClientResponse = await _http.get( - 'http://postman-echo.com/get' + 'https://postman-echo.com/get' ) expect(res.message.statusCode).toBe(200) const body: string = await res.readBody() const obj = JSON.parse(body) - expect(obj.url).toBe('http://postman-echo.com/get') + expect(obj.url).toBe('https://postman-echo.com/get') }) it('does basic head request with keepAlive true', async () => { const res: httpm.HttpClientResponse = await _http.head( - 'http://postman-echo.com/get' + 'https://postman-echo.com/get' ) expect(res.message.statusCode).toBe(200) }) it('does basic http delete request with keepAlive true', async () => { const res: httpm.HttpClientResponse = await _http.del( - 'http://postman-echo.com/delete' + 'https://postman-echo.com/delete' ) expect(res.message.statusCode).toBe(200) const body: string = await res.readBody() @@ -46,32 +46,32 @@ describe('basics', () => { it('does basic http post request with keepAlive true', async () => { const b = 'Hello World!' const res: httpm.HttpClientResponse = await _http.post( - 'http://postman-echo.com/post', + 'https://postman-echo.com/post', b ) expect(res.message.statusCode).toBe(200) const body: string = await res.readBody() const obj = JSON.parse(body) expect(obj.data).toBe(b) - expect(obj.url).toBe('http://postman-echo.com/post') + expect(obj.url).toBe('https://postman-echo.com/post') }) it('does basic http patch request with keepAlive true', async () => { const b = 'Hello World!' const res: httpm.HttpClientResponse = await _http.patch( - 'http://postman-echo.com/patch', + 'https://postman-echo.com/patch', b ) expect(res.message.statusCode).toBe(200) const body: string = await res.readBody() const obj = JSON.parse(body) expect(obj.data).toBe(b) - expect(obj.url).toBe('http://postman-echo.com/patch') + expect(obj.url).toBe('https://postman-echo.com/patch') }) it('does basic http options request with keepAlive true', async () => { const res: httpm.HttpClientResponse = await _http.options( - 'http://postman-echo.com' + 'https://postman-echo.com' ) expect(res.message.statusCode).toBe(200) await res.readBody() diff --git a/__tests__/proxy.test.ts b/__tests__/proxy.test.ts index fe29b6b..aff49c7 100644 --- a/__tests__/proxy.test.ts +++ b/__tests__/proxy.test.ts @@ -199,13 +199,13 @@ describe('proxy', () => { process.env['http_proxy'] = _proxyUrl const httpClient = new httpm.HttpClient() const res: httpm.HttpClientResponse = await httpClient.get( - 'http://postman-echo.com/get' + 'https://postman-echo.com/get' ) expect(res.message.statusCode).toBe(200) const body: string = await res.readBody() const obj = JSON.parse(body) - expect(obj.url).toBe('http://postman-echo.com/get') - expect(_proxyConnects).toEqual(['postman-echo.com:80']) + expect(obj.url).toBe('https://postman-echo.com/get') + expect(_proxyConnects).toEqual(['postman-echo.com:443']) }) it('HttpClient does basic http get request when bypass proxy', async () => { @@ -213,12 +213,12 @@ describe('proxy', () => { process.env['no_proxy'] = 'postman-echo.com' const httpClient = new httpm.HttpClient() const res: httpm.HttpClientResponse = await httpClient.get( - 'http://postman-echo.com/get' + 'https://postman-echo.com/get' ) expect(res.message.statusCode).toBe(200) const body: string = await res.readBody() const obj = JSON.parse(body) - expect(obj.url).toBe('http://postman-echo.com/get') + expect(obj.url).toBe('https://postman-echo.com/get') expect(_proxyConnects).toHaveLength(0) }) @@ -228,12 +228,12 @@ describe('proxy', () => { process.env['https_proxy'] = _proxyUrl const httpClient = new httpm.HttpClient() const res: httpm.HttpClientResponse = await httpClient.get( - 'http://postman-echo.com/get' + 'https://postman-echo.com/get' ) expect(res.message.statusCode).toBe(200) const body: string = await res.readBody() const obj = JSON.parse(body) - expect(obj.url).toBe('http://postman-echo.com/get') + expect(obj.url).toBe('https://postman-echo.com/get') expect(_proxyConnects).toEqual(['postman-echo.com:443']) }) */ @@ -243,12 +243,12 @@ describe('proxy', () => { process.env['no_proxy'] = 'postman-echo.com' const httpClient = new httpm.HttpClient() const res: httpm.HttpClientResponse = await httpClient.get( - 'http://postman-echo.com/get' + 'https://postman-echo.com/get' ) expect(res.message.statusCode).toBe(200) const body: string = await res.readBody() const obj = JSON.parse(body) - expect(obj.url).toBe('http://postman-echo.com/get') + expect(obj.url).toBe('https://postman-echo.com/get') expect(_proxyConnects).toHaveLength(0) }) From 082954e06b10a315ba310ff300a8742f37d209d5 Mon Sep 17 00:00:00 2001 From: Salman Muin Kayser Chishti Date: Mon, 13 Oct 2025 18:18:42 +0100 Subject: [PATCH 11/14] Update tests to use HTTPS for postman-echo.com and adjust proxy environment variable --- __tests__/basics.test.ts | 8 ++++---- __tests__/proxy.test.ts | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/__tests__/basics.test.ts b/__tests__/basics.test.ts index 168cbc0..254a8ec 100644 --- a/__tests__/basics.test.ts +++ b/__tests__/basics.test.ts @@ -193,7 +193,7 @@ describe('basics', () => { } const res: httpm.HttpClientResponse = await _http.get( `https://postman-echo.com/redirect-to?url=${encodeURIComponent( - 'http://www.postman-echo.com/get' + 'https://www.postman-echo.com/get' )}`, headers ) @@ -205,7 +205,7 @@ describe('basics', () => { expect(obj.headers[httpm.Headers.Accept]).toBe('application/json') expect(obj.headers['Authorization']).toBeUndefined() expect(obj.headers['authorization']).toBeUndefined() - expect(obj.url).toBe('http://www.postman-echo.com/get') + expect(obj.url).toBe('https://www.postman-echo.com/get') }) it('does not pass Auth with diff hostname redirects', async () => { @@ -215,7 +215,7 @@ describe('basics', () => { } const res: httpm.HttpClientResponse = await _http.get( `https://postman-echo.com/redirect-to?url=${encodeURIComponent( - 'http://www.postman-echo.com/get' + 'https://www.postman-echo.com/get' )}`, headers ) @@ -227,7 +227,7 @@ describe('basics', () => { expect(obj.headers[httpm.Headers.Accept]).toBe('application/json') expect(obj.headers['Authorization']).toBeUndefined() expect(obj.headers['authorization']).toBeUndefined() - expect(obj.url).toBe('http://www.postman-echo.com/get') + expect(obj.url).toBe('https://www.postman-echo.com/get') }) it('does basic head request', async () => { diff --git a/__tests__/proxy.test.ts b/__tests__/proxy.test.ts index aff49c7..ddad334 100644 --- a/__tests__/proxy.test.ts +++ b/__tests__/proxy.test.ts @@ -196,7 +196,7 @@ describe('proxy', () => { }) it('HttpClient does basic http get request through proxy', async () => { - process.env['http_proxy'] = _proxyUrl + process.env['https_proxy'] = _proxyUrl const httpClient = new httpm.HttpClient() const res: httpm.HttpClientResponse = await httpClient.get( 'https://postman-echo.com/get' From 0272d1a45ef30e1256906f3123733e04b3059b11 Mon Sep 17 00:00:00 2001 From: Salman Muin Kayser Chishti Date: Wed, 15 Oct 2025 14:33:34 +0100 Subject: [PATCH 12/14] Update documentation --- README.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 7e06ade..7d1750c 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ A lightweight HTTP client optimized for building actions. - HTTP client with TypeScript generics and async/await/Promises - Typings included! - [Proxy support](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/about-self-hosted-runners#using-a-proxy-server-with-self-hosted-runners) just works with actions and the runner - - Targets ES2019 (runner runs actions with node 12+). Only supported on node 12+. + - Targets ES2019 (runner runs actions with node 24+). Only supported on node 20+. - Basic, Bearer and PAT Support out of the box. Extensible handlers for others. - Redirects supported @@ -44,7 +44,7 @@ export NODE_DEBUG=http ## Node support -The http-client is built using the latest LTS version of Node 12. It may work on previous node LTS versions but it's tested and officially supported on Node12+. +The http-client is built using Node 24. It may work on previous node LTS versions but it's tested and officially supported on Node 20+. ## Support and Versioning diff --git a/package.json b/package.json index a218fb8..cb1c171 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@actions/http-client", - "version": "3.0.1", + "version": "3.0.0", "description": "Actions Http Client", "keywords": [ "github", From e8827bae9dfa1fed1afd5a5a9d93841855b0f1bd Mon Sep 17 00:00:00 2001 From: Salman Muin Kayser Chishti Date: Wed, 15 Oct 2025 14:34:59 +0100 Subject: [PATCH 13/14] change version for http-client --- package-lock.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index b3ee4a2..4355a12 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@actions/http-client", - "version": "3.0.1", + "version": "3.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@actions/http-client", - "version": "3.0.1", + "version": "3.0.0", "license": "MIT", "dependencies": { "tunnel": "^0.0.6", From 47dcc85a5b4d0c786020c2a96763c880fe73989f Mon Sep 17 00:00:00 2001 From: Salman Muin Kayser Chishti Date: Wed, 15 Oct 2025 17:14:54 +0100 Subject: [PATCH 14/14] Add comment to explain the method and return types --- src/index.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/index.ts b/src/index.ts index 553384c..5691e89 100644 --- a/src/index.ts +++ b/src/index.ts @@ -628,6 +628,13 @@ export class HttpClient { return lowercaseKeys(headers || {}) } + /** + * Gets an existing header value or returns a default. + * Handles converting number header values to strings since HTTP headers must be strings. + * Note: This returns string | string[] since some headers can have multiple values. + * For headers that must always be a single string (like Content-Type), use the + * specialized _getExistingOrDefaultContentTypeHeader method instead. + */ private _getExistingOrDefaultHeader( additionalHeaders: http.OutgoingHttpHeaders, header: string, @@ -657,6 +664,13 @@ export class HttpClient { return _default } + /** + * Specialized version of _getExistingOrDefaultHeader for Content-Type header. + * Always returns a single string (not an array) since Content-Type should be a single value. + * Converts arrays to comma-separated strings and numbers to strings to ensure type safety. + * This was split from _getExistingOrDefaultHeader to provide stricter typing for callers + * that assign the result to places expecting a string (e.g., additionalHeaders[Headers.ContentType]). + */ private _getExistingOrDefaultContentTypeHeader( additionalHeaders: http.OutgoingHttpHeaders, _default: string