fix(chromium): use blockedReason as failure reason when available (#29849)

This covers blocked requests, e.g. mixed-content, that receive
`loadingFailed` with empty `errorText`.

Also, forcefully resolve `allHeaders()` in this case, since we know
there will be no actual network headers.

Fixes #29833.
This commit is contained in:
Dmitry Gozman 2024-03-07 14:07:04 -08:00 коммит произвёл GitHub
Родитель 84d3308969
Коммит 875ce1cf09
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
2 изменённых файлов: 43 добавлений и 1 удалений

Просмотреть файл

@ -523,9 +523,12 @@ export class CRNetworkManager {
response.setTransferSize(null);
response.setEncodedBodySize(null);
response._requestFinished(helper.secondsToRoundishMillis(event.timestamp - request._timestamp));
} else {
// Loading failed before response has arrived - there will be no extra info events.
request.request.setRawRequestHeaders(null);
}
this._deleteRequest(request);
request.request._setFailureText(event.errorText);
request.request._setFailureText(event.errorText || event.blockedReason || '');
(this._page?._frameManager || this._serviceWorker)!.requestFailed(request.request, !!event.canceled);
}

Просмотреть файл

@ -17,6 +17,7 @@
import { test as it, expect } from './pageTest';
import { attachFrame } from '../config/utils';
import fs from 'fs';
it('should work for main frame navigation request', async ({ page, server }) => {
const requests = [];
@ -482,3 +483,41 @@ it('page.reload return 304 status code', async ({ page, server, browserName }) =
expect(response2.statusText()).toBe('Not Modified');
}
});
it('should handle mixed-content blocked requests', async ({ page, asset, browserName }) => {
it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/29833' });
it.skip(browserName !== 'chromium', 'FF and WK actually succeed with the request, and block afterwards');
await page.route('**/mixedcontent.html', route => {
void route.fulfill({
status: 200,
contentType: 'text/html',
body: `
<!doctype html>
<meta charset="utf-8">
<style>
@font-face {
font-family: 'pwtest-iconfont';
src: url('http://another.com/iconfont.woff2') format('woff2');
}
body {
font-family: 'pwtest-iconfont';
}
</style>
<span>+-</span>
`,
});
});
await page.route('**/iconfont.woff2', async route => {
const body = await fs.promises.readFile(asset('webfont/iconfont2.woff'));
await route.fulfill({ body });
});
const [request] = await Promise.all([
page.waitForEvent('requestfailed', r => r.url().includes('iconfont.woff2')),
page.goto('https://example.com/mixedcontent.html'),
]);
const headers = await request.allHeaders();
expect(headers['origin']).toBeTruthy();
expect(request.failure().errorText).toBe('mixed-content');
});