| // Copyright 2022 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| import * as Platform from '../../core/platform/platform.js'; |
| import * as SDK from '../../core/sdk/sdk.js'; |
| import type * as Protocol from '../../generated/protocol.js'; |
| import * as TextUtils from '../../models/text_utils/text_utils.js'; |
| import {renderElementIntoDOM} from '../../testing/DOMHelpers.js'; |
| import {describeWithLocale} from '../../testing/EnvironmentHelpers.js'; |
| |
| import * as Network from './network.js'; |
| |
| const {urlString} = Platform.DevToolsPath; |
| |
| async function contentData(): Promise<TextUtils.ContentData.ContentData> { |
| const content = '<style> p { color: red; }</style><link rel="stylesheet" ref="http://devtools-frontend.test/style">'; |
| return new TextUtils.ContentData.ContentData(content, false, 'text/css'); |
| } |
| |
| function renderPreviewView(request: SDK.NetworkRequest.NetworkRequest): Network.RequestPreviewView.RequestPreviewView { |
| const component = new Network.RequestPreviewView.RequestPreviewView(request); |
| const div = document.createElement('div'); |
| renderElementIntoDOM(div); |
| component.markAsRoot(); |
| component.show(div); |
| return component; |
| } |
| |
| describeWithLocale('RequestPreviewView', () => { |
| it('prevents previewed html from making same-site requests', async () => { |
| const request = SDK.NetworkRequest.NetworkRequest.create( |
| 'requestId' as Protocol.Network.RequestId, urlString`http://devtools-frontend.test/content`, urlString``, null, |
| null, null); |
| request.setContentDataProvider(contentData); |
| request.mimeType = Platform.MimeType.MimeType.HTML; |
| const component = renderPreviewView(request); |
| const widget = await component.showPreview(); |
| const frame = widget.contentElement.querySelector('iframe'); |
| expect(frame).to.be.not.null; |
| expect(frame?.getAttribute('csp')).to.eql('default-src \'none\';img-src data:;style-src \'unsafe-inline\''); |
| component.detach(); |
| }); |
| |
| it('does add utf-8 charset to the data URL for the HTML preview for already decoded content', async () => { |
| const request = SDK.NetworkRequest.NetworkRequest.create( |
| 'requestId' as Protocol.Network.RequestId, urlString`http://devtools-frontend.test/index.html`, urlString``, |
| null, null, null); |
| request.setContentDataProvider( |
| () => Promise.resolve(new TextUtils.ContentData.ContentData( |
| '<!DOCTYPE html>\n<p>Iñtërnâtiônàlizætiøn☃𝌆</p>', false, 'text/html', 'utf-16'))); |
| request.mimeType = Platform.MimeType.MimeType.HTML; |
| request.setCharset('utf-16'); |
| |
| assert.strictEqual(request.charset(), 'utf-16'); |
| |
| const component = renderPreviewView(request); |
| const widget = await component.showPreview(); |
| const frame = widget.contentElement.querySelector('iframe'); |
| assert.exists(frame); |
| |
| assert.include(frame.src, 'charset=utf-8'); |
| assert.notInclude(frame.src, ' base64'); |
| }); |
| |
| it('does add the correct charset to the data URL for the HTML preview for base64 content', async () => { |
| const request = SDK.NetworkRequest.NetworkRequest.create( |
| 'requestId' as Protocol.Network.RequestId, urlString`http://devtools-frontend.test/index.html`, urlString``, |
| null, null, null); |
| // UTF-16 + base64 encoded "<!DOCTYPE html>\n<p>Iñtërnâtiônàlizætiøn☃𝌆</p>". |
| request.setContentDataProvider( |
| () => Promise.resolve(new TextUtils.ContentData.ContentData( |
| '//48ACEARABPAEMAVABZAFAARQAgAGgAdABtAGwAPgAKADwAcAA+AEkA8QB0AOsAcgBuAOIAdABpAPQAbgDgAGwAaQB6AOYAdABpAPgAbgADJjTYBt88AC8AcAA+AAoA', |
| true, 'text/html', 'utf-16'))); |
| request.mimeType = Platform.MimeType.MimeType.HTML; |
| request.setCharset('utf-16'); |
| |
| assert.strictEqual(request.charset(), 'utf-16'); |
| |
| const component = renderPreviewView(request); |
| const widget = await component.showPreview(); |
| const frame = widget.contentElement.querySelector('iframe'); |
| assert.exists(frame); |
| |
| assert.include(frame.src, 'charset=utf-16'); |
| assert.include(frame.src, 'base64'); |
| }); |
| }); |