Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -286,9 +286,15 @@ module.exports = {
continue;
}

const entry = entries.find(
let entry = entries.find(
entry => entry._requestId === params.requestId
);

if (!entry) {
entry = entriesWithoutPage.find(
entry => entry._requestId === params.requestId
);
}
if (!entry) {
debug(
`Extra info sent for requestId ${
Expand Down Expand Up @@ -316,11 +322,6 @@ module.exports = {

case 'Network.responseReceivedExtraInfo':
{
if (pages.length < 1) {
//we haven't loaded any pages yet.
continue;
}

if (ignoredRequests.has(params.requestId)) {
continue;
}
Expand Down
7 changes: 7 additions & 0 deletions lib/entryFromResponse.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,13 @@ module.exports = function(entry, response, page, options) {
})
);
}
// Merging and de-duplicating because extraResponse headers contain the original response headers as well
if (entry.extraResponseInfo.headers) {
const mergedHeaders = new Set(
[...headers, ...entry.extraResponseInfo.headers].map(JSON.stringify)
);
headers = Array.from(mergedHeaders, JSON.parse);
}
Comment on lines +54 to +64
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the only section that really jumped out to me (not a maintainer).

Is it possible that extraResponseInfo.headers always includes all of headers? if so, we can avoid all of this computation and just use that, yes?

I don't think we can rely on unique header names, so this solution certainly works.
Per RFC7230 3.2.2:

A sender MUST NOT generate multiple header fields with the same field
name in a message unless either the entire field value for that
header field is defined as a comma-separated list [i.e., #(values)]
or the header field is a well-known exception (as noted below).

A recipient MAY combine multiple header fields with the same field
name into one "field-name: field-value" pair, without changing the
semantics of the message, by appending each subsequent field value to
the combined field value in order, separated by a comma. The order
in which header fields with the same field name are received is
therefore significant to the interpretation of the combined field
value; a proxy MUST NOT change the order of these field values when
forwarding a message.

The only thing I could think of that might work better (and here we'd need some performance tests) is to use a Map instead.:

const list = [
  {name: 'a', value: 1},
  {name: 'a', value: 2},
  {name: 'b', value: 1},
  {name: 'b', value: 1},
]

function makeUniqueSet(list) {
  const map = new Map()
  list.forEach(l => map.set(`${l.name}-${l.value}`, l))
  const uniqueSet = [...map.values()]
  return uniqueSet;
}

Example Repl.it

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks Stephen! Made use of your suggestion and updated the PR. Will leave this comment open though to see if @soulgalore thinks this step is even necessary.


// Remove extra info once it has been added to the response
delete entry.extraResponseInfo;
Expand Down
219 changes: 219 additions & 0 deletions test/perflogs/parse-cookies-set-cookies.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
[
{
"method": "Network.requestWillBeSent",
"params": {
"requestId": "1803F03934F9C36D47C5B58E49C99BC7",
"loaderId": "1803F03934F9C36D47C5B58E49C99BC7",
"documentURL": "https://sfbay.craigslist.org/",
"request": {
"url": "https://sfbay.craigslist.org/",
"method": "GET",
"headers": {
"Upgrade-Insecure-Requests": "1",
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/116.0.5845.96 Safari/537.36",
"sec-ch-ua": "\"Chromium\";v=\"116\", \"Not)A;Brand\";v=\"24\", \"HeadlessChrome\";v=\"116\"",
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": "\"macOS\""
},
"mixedContentType": "none",
"initialPriority": "VeryHigh",
"referrerPolicy": "strict-origin-when-cross-origin",
"isSameSite": true
},
"timestamp": 582126.799807,
"wallTime": 1692941334.595684,
"initiator": {
"type": "other"
},
"redirectHasExtraInfo": false,
"type": "Document",
"frameId": "16E942851554F8949EFBCE17D1B8FE9E",
"hasUserGesture": false
}
},
{
"method": "Network.requestWillBeSentExtraInfo",
"params": {
"requestId": "1803F03934F9C36D47C5B58E49C99BC7",
"associatedCookies": [
{
"blockedReasons": [],
"cookie": {
"name": "cl_def_hp",
"value": "sfbay",
"domain": ".craigslist.org",
"path": "/",
"expires": 1724477335.007591,
"size": 14,
"httpOnly": false,
"secure": true,
"session": false,
"priority": "Medium",
"sameParty": false,
"sourceScheme": "Secure",
"sourcePort": 443
}
},
{
"blockedReasons": [],
"cookie": {
"name": "cl_b",
"value": "XXXXXXXX",
"domain": ".craigslist.org",
"path": "/",
"expires": 1727501335.008006,
"size": 62,
"httpOnly": false,
"secure": true,
"session": false,
"priority": "Medium",
"sameParty": false,
"sourceScheme": "Secure",
"sourcePort": 443
}
}
],
"headers": {
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
"Accept-Encoding": "gzip, deflate, br",
"Connection": "keep-alive",
"Host": "sfbay.craigslist.org",
"Sec-Fetch-Dest": "document",
"Sec-Fetch-Mode": "navigate",
"Sec-Fetch-Site": "none",
"Sec-Fetch-User": "?1",
"Upgrade-Insecure-Requests": "1",
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/116.0.5845.96 Safari/537.36",
"sec-ch-ua": "\"Chromium\";v=\"116\", \"Not)A;Brand\";v=\"24\", \"HeadlessChrome\";v=\"116\"",
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": "\"macOS\""
},
"connectTiming": {
"requestTime": 582126.801796
},
"siteHasCookieInOtherPartition": false
}
},
{
"method": "Network.responseReceivedExtraInfo",
"params": {
"requestId": "1803F03934F9C36D47C5B58E49C99BC7",
"blockedCookies": [],
"headers": {
"Cache-Control": "max-age=3600, public",
"Content-Encoding": "gzip",
"Content-Length": "11396",
"Content-Security-Policy": "base-uri 'self' https://hcaptcha.com https://*.hcaptcha.com; child-src https://*.craigslist.org; connect-src https://*.craigslist.org https://hcaptcha.com https://*.hcaptcha.com; font-src data:; form-action https://*.craigslist.org; frame-ancestors 'self'; frame-src https://*.craigslist.org https://hcaptcha.com https://*.hcaptcha.com; media-src data:; object-src 'none'; script-src 'unsafe-inline' 'unsafe-eval' https://*.craigslist.org https://hcaptcha.com https://*.hcaptcha.com; style-src 'unsafe-inline' https://*.craigslist.org https://hcaptcha.com https://*.hcaptcha.com",
"Content-Type": "text/html; charset=UTF-8",
"Date": "Fri, 25 Aug 2023 05:16:04 GMT",
"Expires": "Fri, 25 Aug 2023 06:16:04 GMT",
"Last-Modified": "Fri, 25 Aug 2023 05:16:04 GMT",
"Set-Cookie": "XXXXXX",
"Strict-Transport-Security": "max-age=63072000",
"Vary": "Accept-Encoding",
"X-Frame-Options": "SAMEORIGIN"
},
"resourceIPAddressSpace": "Public",
"statusCode": 200,
"headersText": "XXXXX",
"cookiePartitionKey": "https://craigslist.org",
"cookiePartitionKeyOpaque": false
}
},
{
"method": "Network.responseReceived",
"params": {
"requestId": "1803F03934F9C36D47C5B58E49C99BC7",
"loaderId": "1803F03934F9C36D47C5B58E49C99BC7",
"timestamp": 582127.216792,
"type": "Document",
"response": {
"url": "https://sfbay.craigslist.org/",
"status": 200,
"statusText": "OK",
"headers": {
"Cache-Control": "max-age=3600, public",
"Content-Encoding": "gzip",
"Content-Length": "11396",
"Content-Security-Policy": "base-uri 'self' https://hcaptcha.com https://*.hcaptcha.com; child-src https://*.craigslist.org; connect-src https://*.craigslist.org https://hcaptcha.com https://*.hcaptcha.com; font-src data:; form-action https://*.craigslist.org; frame-ancestors 'self'; frame-src https://*.craigslist.org https://hcaptcha.com https://*.hcaptcha.com; media-src data:; object-src 'none'; script-src 'unsafe-inline' 'unsafe-eval' https://*.craigslist.org https://hcaptcha.com https://*.hcaptcha.com; style-src 'unsafe-inline' https://*.craigslist.org https://hcaptcha.com https://*.hcaptcha.com",
"Content-Type": "text/html; charset=UTF-8",
"Date": "Fri, 25 Aug 2023 05:16:04 GMT",
"Expires": "Fri, 25 Aug 2023 06:16:04 GMT",
"Last-Modified": "Fri, 25 Aug 2023 05:16:04 GMT",
"Strict-Transport-Security": "max-age=63072000",
"Vary": "Accept-Encoding",
"X-Frame-Options": "SAMEORIGIN"
},
"mimeType": "text/html",
"connectionReused": false,
"connectionId": 13,
"remoteIPAddress": "208.82.238.130",
"remotePort": 443,
"fromDiskCache": false,
"fromServiceWorker": false,
"fromPrefetchCache": false,
"encodedDataLength": 1228,
"timing": {
"requestTime": 582126.801796,
"proxyStart": -1,
"proxyEnd": -1,
"dnsStart": 11.062,
"dnsEnd": 40.836,
"connectStart": 40.836,
"connectEnd": 380.711,
"sslStart": 55.638,
"sslEnd": 380.695,
"workerStart": -1,
"workerReady": -1,
"workerFetchStart": -1,
"workerRespondWithSettled": -1,
"sendStart": 381.25,
"sendEnd": 381.804,
"pushStart": 0,
"pushEnd": 0,
"receiveHeadersStart": 399.327,
"receiveHeadersEnd": 410.652
},
"responseTime": 1692941334996.253,
"protocol": "http/1.1",
"alternateProtocolUsage": "unspecifiedReason",
"securityState": "secure",
"securityDetails": {
"protocol": "TLS 1.2",
"keyExchange": "ECDHE_ECDSA",
"keyExchangeGroup": "P-256",
"cipher": "AES_128_GCM",
"certificateId": 0,
"subjectName": "craigslist.org",
"sanList": [
"craigslist.org",
"cl.com",
"craigslist.ca",
"craigslist.com",
"craigslist.net",
"*.cl.com",
"*.craigslist.ca",
"*.craigslist.com",
"*.craigslist.net",
"*.craigslist.org"
],
"issuer": "DigiCert TLS Hybrid ECC SHA384 2020 CA1",
"validFrom": 1675728000,
"validTo": 1709078399,
"signedCertificateTimestampList": [],
"certificateTransparencyCompliance": "unknown",
"serverSignatureAlgorithm": 1027,
"encryptedClientHello": false
}
},
"hasExtraInfo": true,
"frameId": "16E942851554F8949EFBCE17D1B8FE9E"
}
},
{
"method": "Page.frameStartedLoading",
"params": {
"frameId": "16E942851554F8949EFBCE17D1B8FE9E"
}
}
]
14 changes: 14 additions & 0 deletions test/tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -261,3 +261,17 @@ test('Includes initial redirect', t => {
.tap(log => t.is(log.entries.length, 99))
.tap(log => t.is(log.entries[0].response.status, 308));
});

test('parses cookies and set-cookies', t => {
const perflogPath = perflog('parse-cookies-set-cookies.json');
return parsePerflog(perflogPath)
.then(har => har.log)
.tap(log => {
const request = log.entries.find(
e => e.request.url === 'https://sfbay.craigslist.org/'
);
t.is(request.request.cookies.length, 2);
t.is(request.response.headers.length, 12);
t.is(request.response.headers.some(h => h.name === 'Set-Cookie'), true);
});
});