Skip to content

Commit

Permalink
Include the 'cookie' field in exported HAR data
Browse files Browse the repository at this point in the history
  • Loading branch information
pimterry committed Dec 5, 2024
1 parent e5b73eb commit 710d42e
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 8 deletions.
4 changes: 2 additions & 2 deletions src/components/view/http/set-cookie-header-description.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
distanceInWordsToNow
} from 'date-fns';

import { Cookie, parseSetCookieHeader } from '../../../model/http/cookies'
import { SetCookie, parseSetCookieHeader } from '../../../model/http/cookies'
import { Content } from '../../common/text-content';

function getExpiryExplanation(date: Date) {
Expand All @@ -33,7 +33,7 @@ export const CookieHeaderDescription = (p: { value: string, requestUrl: URL }) =

return <>{
// In 99% of cases there is only one cookie here, but we can play it safe.
cookies.map((cookie: Cookie) => {
cookies.map((cookie: SetCookie) => {
if (cookie.samesite?.toLowerCase() === 'none' && !cookie.secure) {
return <Content key={cookie.name}>
<p>
Expand Down
9 changes: 6 additions & 3 deletions src/model/http/cookies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
export interface Cookie {
name: string;
value: string;
}

export interface SetCookie extends Cookie {
path?: string;
httponly?: boolean;
secure?: boolean;
Expand All @@ -16,20 +19,20 @@ export interface Cookie {

export function parseSetCookieHeader(
headers: string | string[]
) {
): SetCookie[] {
if (!Array.isArray(headers)) {
headers = [headers];
}

const cookies: Array<Cookie> = [];
const cookies: Array<SetCookie> = [];

for (const header of headers) {
const [cookieKV, ...parts] = header.split(";");

const [name, value] = (cookieKV?.split("=") ?? []);
if (!name || value === undefined) continue;

const cookie: Cookie = {
const cookie: SetCookie = {
name,
value
};
Expand Down
37 changes: 34 additions & 3 deletions src/model/http/har.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,15 @@ import {
} from '../../types';

import { stringToBuffer } from '../../util/buffer';
import { lastHeader } from '../../util/headers';
import { getHeaderValues, lastHeader } from '../../util/headers';
import { ObservablePromise } from '../../util/observable';
import { unreachableCheck } from '../../util/error';

import { UI_VERSION } from '../../services/service-versions';
import { getStatusMessage } from './http-docs';
import { StreamMessage } from '../events/stream-message';
import { QueuedEvent } from '../events/events-store';
import { parseCookieHeader, parseSetCookieHeader } from './cookies';

// We only include request/response bodies that are under 500KB
const HAR_BODY_SIZE_LIMIT = 500000;
Expand Down Expand Up @@ -143,6 +144,36 @@ function asHtkHeaders(headers: HarFormat.Header[]) {
.value() as Headers;
}

function asHarRequestCookies(headers: Headers) {
const combinedHeader = getHeaderValues(headers, 'cookie').join('; ');
try {
return parseCookieHeader(combinedHeader);
} catch (e) {
console.warn('Could not parse request cookies for HAR', combinedHeader);
return [];
}
}

function asHarResponseCookies(headers: Headers) {
const setCookieHeaders = getHeaderValues(headers, 'set-cookie');
try {
// HAR has specific opinions about which fields to include and their casing
return parseSetCookieHeader(setCookieHeaders).map((cookie) => ({
name: cookie.name,
value: cookie.value,
path: cookie.path,
domain: cookie.domain,
expires: cookie.expires,
httpOnly: cookie.httponly,
secure: cookie.secure,
sameSite: cookie.samesite
}));
} catch (e) {
console.warn('Could not parse response cookies for HAR', setCookieHeaders);
return [];
}
}

export function generateHarRequest(
request: HtkRequest,
waitForDecoding: false,
Expand Down Expand Up @@ -171,7 +202,7 @@ export function generateHarRequest(
method: request.method,
url: request.parsedUrl.toString(),
httpVersion: `HTTP/${request.httpVersion || '1.1'}`,
cookies: [],
cookies: asHarRequestCookies(request.headers),
headers: asHarHeaders(request.headers),
...(request.trailers ? {
_trailers: asHarHeaders(request.trailers)
Expand Down Expand Up @@ -327,7 +358,7 @@ async function generateHarResponse(
status: response.statusCode,
statusText: response.statusMessage,
httpVersion: `HTTP/${request.httpVersion || '1.1'}`,
cookies: [],
cookies: asHarResponseCookies(response.headers),
headers: asHarHeaders(response.headers),
content: Object.assign(
{
Expand Down

0 comments on commit 710d42e

Please sign in to comment.