diff --git a/packages/http-client/__tests__/basics.test.ts b/packages/http-client/__tests__/basics.test.ts index 2bb57ed3bf..e0fa1cfba6 100644 --- a/packages/http-client/__tests__/basics.test.ts +++ b/packages/http-client/__tests__/basics.test.ts @@ -66,6 +66,31 @@ describe('basics', () => { expect(obj.headers['user-agent']).toBe('actions/http-client') }) + it('can make a request to an IPv6 literal host', async () => { + const res: httpm.HttpClientResponse = await _http.get( + // This is Cloudflare's DNS, the IPv6 equivalent of 1.1.1.1 + 'https://[2606:4700:4700::1111]' + ) + + expect(res.message.statusCode).toBeDefined() + }) + + it('can make a request to an IPv6 literal host with an explicit port', async () => { + const res: httpm.HttpClientResponse = await _http.get( + 'https://[2606:4700:4700::1111]:443' + ) + + expect(res.message.statusCode).toBeDefined() + }) + + it('can make a request to an IPv6 literal host with a path', async () => { + const res: httpm.HttpClientResponse = await _http.get( + 'https://[2606:4700:4700::1111]/hello' + ) + + expect(res.message.statusCode).toBeDefined() + }) + /* 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( diff --git a/packages/http-client/src/index.ts b/packages/http-client/src/index.ts index 2f940949fa..6fbef646bd 100644 --- a/packages/http-client/src/index.ts +++ b/packages/http-client/src/index.ts @@ -588,9 +588,13 @@ export class HttpClient { const usingSsl: boolean = info.parsedUrl.protocol === 'https:' info.httpModule = usingSsl ? https : http const defaultPort: number = usingSsl ? 443 : 80 + const normalizedHostname = this._normalizeHostname(info.parsedUrl.hostname) info.options = {} - info.options.host = info.parsedUrl.hostname + // URL.hostname returns bracketed IPv6 literals (e.g. "[2001:db8::1]"). + // Node request options expect an unbracketed address for DNS/socket connect. + info.options.hostname = normalizedHostname + info.options.host = normalizedHostname info.options.port = info.parsedUrl.port ? parseInt(info.parsedUrl.port) : defaultPort @@ -614,6 +618,14 @@ export class HttpClient { return info } + private _normalizeHostname(hostname: string): string { + if (hostname.startsWith('[') && hostname.endsWith(']')) { + return hostname.slice(1, -1) + } + + return hostname + } + private _mergeHeaders( headers?: http.OutgoingHttpHeaders ): http.OutgoingHttpHeaders {