From 1b9927d1c7656c286c15ba85bc3e8cd77ebe93e2 Mon Sep 17 00:00:00 2001 From: Yu <73045972+yangy-23@users.noreply.github.com> Date: Sat, 17 Aug 2024 02:43:10 +1000 Subject: [PATCH] Handle Encoded URL for Proxy Username and Password in HTTP Client (#1782) * uri-decode-fix Signed-off-by: Yu * http-client URLdecode fix Signed-off-by: Yu * http-client URLdecode test typo fix Signed-off-by: Yu --------- Signed-off-by: Yu --- packages/http-client/__tests__/proxy.test.ts | 12 ++++++++++ packages/http-client/src/proxy.ts | 23 ++++++++++++++++++-- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/packages/http-client/__tests__/proxy.test.ts b/packages/http-client/__tests__/proxy.test.ts index 01888412..fe29b6b1 100644 --- a/packages/http-client/__tests__/proxy.test.ts +++ b/packages/http-client/__tests__/proxy.test.ts @@ -307,6 +307,18 @@ describe('proxy', () => { console.log(agent) expect(agent instanceof ProxyAgent).toBe(true) }) + + it('proxyAuth is set in tunnel agent when authentication is provided with URIencoding', async () => { + process.env['https_proxy'] = + 'http://user%40github.com:p%40ssword@127.0.0.1:8080' + const httpClient = new httpm.HttpClient() + const agent: any = httpClient.getAgent('https://some-url') + // eslint-disable-next-line no-console + console.log(agent) + expect(agent.proxyOptions.host).toBe('127.0.0.1') + expect(agent.proxyOptions.port).toBe('8080') + expect(agent.proxyOptions.proxyAuth).toBe('user@github.com:p@ssword') + }) }) function _clearVars(): void { diff --git a/packages/http-client/src/proxy.ts b/packages/http-client/src/proxy.ts index 32afce6a..3a9c6834 100644 --- a/packages/http-client/src/proxy.ts +++ b/packages/http-client/src/proxy.ts @@ -15,10 +15,10 @@ export function getProxyUrl(reqUrl: URL): URL | undefined { if (proxyVar) { try { - return new URL(proxyVar) + return new DecodedURL(proxyVar) } catch { if (!proxyVar.startsWith('http://') && !proxyVar.startsWith('https://')) - return new URL(`http://${proxyVar}`) + return new DecodedURL(`http://${proxyVar}`) } } else { return undefined @@ -87,3 +87,22 @@ function isLoopbackAddress(host: string): boolean { hostLower.startsWith('[0:0:0:0:0:0:0:1]') ) } + +class DecodedURL extends URL { + private _decodedUsername: string + private _decodedPassword: string + + constructor(url: string | URL, base?: string | URL) { + super(url, base) + this._decodedUsername = decodeURIComponent(super.username) + this._decodedPassword = decodeURIComponent(super.password) + } + + get username(): string { + return this._decodedUsername + } + + get password(): string { + return this._decodedPassword + } +}