/** * Copyright (c) Microsoft Corporation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import './networkResourceDetails.css'; import * as React from 'react'; import { Expandable } from './helpers'; import { NetworkResourceTraceEvent } from '../../../server/trace/traceTypes'; const utf8Encoder = new TextDecoder('utf-8'); export const NetworkResourceDetails: React.FunctionComponent<{ resource: NetworkResourceTraceEvent, index: number, selected: boolean, setSelected: React.Dispatch>, }> = ({ resource, index, selected, setSelected }) => { const [expanded, setExpanded] = React.useState(false); const [requestBody, setRequestBody] = React.useState(null); const [responseBody, setResponseBody] = React.useState(null); React.useEffect(() => { setExpanded(false); setSelected(-1); }, [resource, setSelected]); React.useEffect(() => { const readResources = async () => { if (resource.requestSha1 !== 'none') { const response = await fetch(`/sha1/${resource.requestSha1}`); const requestResource = await response.text(); setRequestBody(requestResource); } if (resource.responseSha1 !== 'none') { const response = await fetch(`/sha1/${resource.responseSha1}`); const responseResource = await response.arrayBuffer(); setResponseBody(responseResource); } }; readResources(); }, [expanded, resource.responseSha1, resource.requestSha1]); function formatBody(body: string | null, contentType: string): string { if (body === null) return 'Loading...'; const bodyStr = body; if (bodyStr === '') return ''; if (contentType.includes('application/json')) { try { return JSON.stringify(JSON.parse(bodyStr), null, 2); } catch (err) { return bodyStr; } } if (contentType.includes('application/x-www-form-urlencoded')) return decodeURIComponent(bodyStr); return bodyStr; } function formatStatus(status: number): string { if (status >= 200 && status < 400) return 'status-success'; if (status >= 400) return 'status-failure'; return 'status-neutral'; } const requestContentTypeHeader = resource.requestHeaders.find(q => q.name === 'Content-Type'); const requestContentType = requestContentTypeHeader ? requestContentTypeHeader.value : ''; return
setSelected(index)}>
{resource.status}
{resource.method}:  
{resource.url}
{resource.contentType}
} body={

URL

{resource.url}

Request Headers

{resource.requestHeaders.map(pair => `${pair.name}: ${pair.value}`).join('\n')}

Response Headers

{resource.responseHeaders.map(pair => `${pair.name}: ${pair.value}`).join('\n')}
{resource.requestSha1 !== 'none' ?

Request Body

: ''} {resource.requestSha1 !== 'none' ?
{formatBody(requestBody, requestContentType)}
: ''}

Response Body

{resource.responseSha1 === 'none' ?
Response body is not available for this request.
: ''} {responseBody !== null && resource.contentType.includes('image') ? : ''} {responseBody !== null && !resource.contentType.includes('image') ?
{formatBody(utf8Encoder.decode(responseBody), resource.contentType)}
: ''}
}/> ; };