Skip to content

Commit 710d42e

Browse files
committed
Include the 'cookie' field in exported HAR data
1 parent e5b73eb commit 710d42e

File tree

3 files changed

+42
-8
lines changed

3 files changed

+42
-8
lines changed

src/components/view/http/set-cookie-header-description.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
distanceInWordsToNow
88
} from 'date-fns';
99

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

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

3434
return <>{
3535
// In 99% of cases there is only one cookie here, but we can play it safe.
36-
cookies.map((cookie: Cookie) => {
36+
cookies.map((cookie: SetCookie) => {
3737
if (cookie.samesite?.toLowerCase() === 'none' && !cookie.secure) {
3838
return <Content key={cookie.name}>
3939
<p>

src/model/http/cookies.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
export interface Cookie {
55
name: string;
66
value: string;
7+
}
8+
9+
export interface SetCookie extends Cookie {
710
path?: string;
811
httponly?: boolean;
912
secure?: boolean;
@@ -16,20 +19,20 @@ export interface Cookie {
1619

1720
export function parseSetCookieHeader(
1821
headers: string | string[]
19-
) {
22+
): SetCookie[] {
2023
if (!Array.isArray(headers)) {
2124
headers = [headers];
2225
}
2326

24-
const cookies: Array<Cookie> = [];
27+
const cookies: Array<SetCookie> = [];
2528

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

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

32-
const cookie: Cookie = {
35+
const cookie: SetCookie = {
3336
name,
3437
value
3538
};

src/model/http/har.ts

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,15 @@ import {
1919
} from '../../types';
2020

2121
import { stringToBuffer } from '../../util/buffer';
22-
import { lastHeader } from '../../util/headers';
22+
import { getHeaderValues, lastHeader } from '../../util/headers';
2323
import { ObservablePromise } from '../../util/observable';
2424
import { unreachableCheck } from '../../util/error';
2525

2626
import { UI_VERSION } from '../../services/service-versions';
2727
import { getStatusMessage } from './http-docs';
2828
import { StreamMessage } from '../events/stream-message';
2929
import { QueuedEvent } from '../events/events-store';
30+
import { parseCookieHeader, parseSetCookieHeader } from './cookies';
3031

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

147+
function asHarRequestCookies(headers: Headers) {
148+
const combinedHeader = getHeaderValues(headers, 'cookie').join('; ');
149+
try {
150+
return parseCookieHeader(combinedHeader);
151+
} catch (e) {
152+
console.warn('Could not parse request cookies for HAR', combinedHeader);
153+
return [];
154+
}
155+
}
156+
157+
function asHarResponseCookies(headers: Headers) {
158+
const setCookieHeaders = getHeaderValues(headers, 'set-cookie');
159+
try {
160+
// HAR has specific opinions about which fields to include and their casing
161+
return parseSetCookieHeader(setCookieHeaders).map((cookie) => ({
162+
name: cookie.name,
163+
value: cookie.value,
164+
path: cookie.path,
165+
domain: cookie.domain,
166+
expires: cookie.expires,
167+
httpOnly: cookie.httponly,
168+
secure: cookie.secure,
169+
sameSite: cookie.samesite
170+
}));
171+
} catch (e) {
172+
console.warn('Could not parse response cookies for HAR', setCookieHeaders);
173+
return [];
174+
}
175+
}
176+
146177
export function generateHarRequest(
147178
request: HtkRequest,
148179
waitForDecoding: false,
@@ -171,7 +202,7 @@ export function generateHarRequest(
171202
method: request.method,
172203
url: request.parsedUrl.toString(),
173204
httpVersion: `HTTP/${request.httpVersion || '1.1'}`,
174-
cookies: [],
205+
cookies: asHarRequestCookies(request.headers),
175206
headers: asHarHeaders(request.headers),
176207
...(request.trailers ? {
177208
_trailers: asHarHeaders(request.trailers)
@@ -327,7 +358,7 @@ async function generateHarResponse(
327358
status: response.statusCode,
328359
statusText: response.statusMessage,
329360
httpVersion: `HTTP/${request.httpVersion || '1.1'}`,
330-
cookies: [],
361+
cookies: asHarResponseCookies(response.headers),
331362
headers: asHarHeaders(response.headers),
332363
content: Object.assign(
333364
{

0 commit comments

Comments
 (0)