chore: rewrite non-web protocol for Electron tracing (#13305)

This commit is contained in:
Pavel Feldman 2022-04-04 19:56:04 -08:00 committed by GitHub
parent 5c282e50a9
commit 23d9dbc011
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 38 additions and 10 deletions

View File

@ -44,7 +44,6 @@ export function frameSnapshotStreamer(snapshotStreamer: string) {
const kScrollTopAttribute = '__playwright_scroll_top_';
const kScrollLeftAttribute = '__playwright_scroll_left_';
const kStyleSheetAttribute = '__playwright_style_sheet_';
const kBlobUrlPrefix = 'http://playwright.bloburl/#';
// Symbols for our own info on Nodes/StyleSheets.
const kSnapshotFrameId = Symbol('__playwright_snapshot_frameid_');
@ -220,9 +219,6 @@ export function frameSnapshotStreamer(snapshotStreamer: string) {
private _sanitizeUrl(url: string): string {
if (url.startsWith('javascript:'))
return '';
// Rewrite blob urls so that Service Worker can intercept them.
if (url.startsWith('blob:'))
return kBlobUrlPrefix + url;
return url;
}

View File

@ -62,8 +62,9 @@ export class SnapshotRenderer {
// Never set relative URLs as <iframe src> - they start fetching frames immediately.
const isFrame = n[0] === 'IFRAME' || n[0] === 'FRAME';
for (const [attr, value] of Object.entries(n[1] || {})) {
const attrToSet = isFrame && attr.toLowerCase() === 'src' ? '__playwright_src__' : attr;
builder.push(' ', attrToSet, '="', escapeAttribute(value as string), '"');
const attrName = isFrame && attr.toLowerCase() === 'src' ? '__playwright_src__' : attr;
const attrValue = attr.toLowerCase() === 'href' || attr.toLowerCase() === 'src' ? rewriteURLForCustomProtocol(value) : value;
builder.push(' ', attrName, '="', escapeAttribute(attrValue as string), '"');
}
builder.push('>');
for (let i = 2; i < n.length; i++)
@ -273,3 +274,33 @@ function snapshotScript() {
return `\n(${applyPlaywrightAttributes.toString()})()`;
}
const schemas = ['about:', 'blob:', 'data:', 'file:', 'ftp:', 'http:', 'https:', 'mailto:', 'sftp:', 'ws:', 'wss:' ];
const kLegacyBlobPrefix = 'http://playwright.bloburl/#';
export function rewriteURLForCustomProtocol(href: string): string {
// Legacy support, we used to prepend this to blobs, strip it away.
if (href.startsWith(kLegacyBlobPrefix))
href = href.substring(kLegacyBlobPrefix.length);
try {
const url = new URL(href);
// Sanitize URL.
if (url.protocol === 'javascript:')
return 'javascript:void(0)';
// Pass through if possible.
const isBlob = url.protocol === 'blob:';
if (!isBlob && schemas.includes(url.protocol))
return href;
// Rewrite blob and custom schemas.
const prefix = 'pw-' + url.protocol.slice(0, url.protocol.length - 1);
url.protocol = 'https:';
url.hostname = url.hostname ? `${prefix}.${url.hostname}` : prefix;
return url.toString();
} catch {
return href;
}
}

View File

@ -19,8 +19,6 @@ import type { Point } from '@playwright-core/common/types';
import { URLSearchParams } from 'url';
import { SnapshotRenderer } from './snapshotRenderer';
const kBlobUrlPrefix = 'http://playwright.bloburl/#';
export class SnapshotServer {
private _snapshotStorage: SnapshotStorage;
private _snapshotIds = new Map<string, SnapshotRenderer>();
@ -65,7 +63,7 @@ export class SnapshotServer {
async serveResource(requestUrl: string, snapshotUrl: string): Promise<Response> {
const snapshot = this._snapshotIds.get(snapshotUrl)!;
const url = requestUrl.startsWith(kBlobUrlPrefix) ? requestUrl.substring(kBlobUrlPrefix.length) : removeHash(requestUrl);
const url = removeHash(requestUrl);
const resource = snapshot?.resourceByUrl(url);
if (!resource)
return new Response(null, { status: 404 });

View File

@ -16,7 +16,7 @@
import type { FrameSnapshot, ResourceSnapshot } from '@playwright-core/server/trace/common/snapshotTypes';
import { EventEmitter } from './events';
import { SnapshotRenderer } from './snapshotRenderer';
import { rewriteURLForCustomProtocol, SnapshotRenderer } from './snapshotRenderer';
export interface SnapshotStorage {
resources(): ResourceSnapshot[];
@ -40,10 +40,13 @@ export abstract class BaseSnapshotStorage implements SnapshotStorage {
}
addResource(resource: ResourceSnapshot): void {
resource.request.url = rewriteURLForCustomProtocol(resource.request.url);
this._resources.push(resource);
}
addFrameSnapshot(snapshot: FrameSnapshot): void {
for (const override of snapshot.resourceOverrides)
override.url = rewriteURLForCustomProtocol(override.url);
let frameSnapshots = this._frameSnapshots.get(snapshot.frameId);
if (!frameSnapshots) {
frameSnapshots = {