diff --git a/packages/utils/network.ts b/packages/utils/network.ts index de32b45d7f840..5f721242eb277 100644 --- a/packages/utils/network.ts +++ b/packages/utils/network.ts @@ -59,6 +59,10 @@ export function httpRequest(params: HTTPRequestParams, onResponse: (r: http.Inco const parsedProxyURL = normalizeProxyURL(proxyURL); if (params.url.startsWith('http:')) { options.path = url.toString(); + const headers = options.headers || {}; + if (!Object.keys(headers).some(header => header.toLowerCase() === 'host')) + headers.host = url.host; + options.headers = headers; url = parsedProxyURL; } else { options.agent = new HttpsProxyAgent(parsedProxyURL); diff --git a/tests/config/proxy.ts b/tests/config/proxy.ts index 697f39f956dff..1e534268dfc04 100644 --- a/tests/config/proxy.ts +++ b/tests/config/proxy.ts @@ -38,6 +38,7 @@ export class TestProxy { connectHosts: string[] = []; requestUrls: string[] = []; + requestHosts: string[] = []; wsUrls: string[] = []; private readonly _server: ProxyServer; @@ -69,6 +70,7 @@ export class TestProxy { forwardTo(port: number, options?: { allowConnectRequests?: boolean, removePrefix?: string, preserveHostname?: boolean }) { this._prependHandler('request', (req: IncomingMessage) => { this.requestUrls.push(req.url); + this.requestHosts.push(req.headers.host); const url = new URL(req.url, `http://${req.headers.host}`); if (options?.preserveHostname) url.port = '' + port; @@ -116,6 +118,7 @@ export class TestProxy { reset() { this.connectHosts = []; this.requestUrls = []; + this.requestHosts = []; for (const { event, handler } of this._handlers) this._server.removeListener(event, handler); this._handlers = []; diff --git a/tests/library/chromium/connect-over-cdp.spec.ts b/tests/library/chromium/connect-over-cdp.spec.ts index f68634fa55e0c..889f0b35f88a4 100644 --- a/tests/library/chromium/connect-over-cdp.spec.ts +++ b/tests/library/chromium/connect-over-cdp.spec.ts @@ -448,6 +448,25 @@ test('should use env proxy with connectOverCDP discovery request', async ({ brow } }); +test('should send target Host header when using env HTTP proxy with connectOverCDP', async ({ browserType, server, proxyServer, mode }) => { + test.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/40811' }); + test.skip(mode !== 'default'); // Out of process transport does not allow us to set env vars dynamically. + proxyServer.forwardTo(server.PORT); + + const oldValue = process.env.HTTP_PROXY; + try { + process.env.HTTP_PROXY = proxyServer.URL; + const error = await browserType.connectOverCDP(server.PREFIX).catch(e => e); + expect(error.message).toContain(`Unexpected status 404 when connecting to ${server.PREFIX}/json/version/`); + expect(proxyServer.requestHosts).toEqual([new URL(server.PREFIX).host]); + } finally { + if (oldValue === undefined) + delete process.env.HTTP_PROXY; + else + process.env.HTTP_PROXY = oldValue; + } +}); + test('should be able to connect via localhost', async ({ browserType }, testInfo) => { const port = 9339 + testInfo.workerIndex; const browserServer = await browserType.launch({