Repository: GoogleChrome/lighthouse
Pull request #6157 (2018-10-02 19:06:08)

core(network): handle invalid NetworkRequests
**Summary**
Adds `isValid` property to a NetworkRequest and ignores invalid requests when making the list of records to surface to rest of application.

**Related Issues/PRs**
fixes: #6145 


Patch:
diff --git a/lighthouse-core/lib/network-recorder.js b/lighthouse-core/lib/network-recorder.js
index d7511d833..25df2d4d0 100644
--- a/lighthouse-core/lib/network-recorder.js
+++ b/lighthouse-core/lib/network-recorder.js
@@ -320,7 +320,7 @@ class NetworkRecorder extends EventEmitter {
    */
   _findRealRequest(requestId) {
     let request = this._recordsById.get(requestId);
-    if (!request) return undefined;
+    if (!request || !request.isValid) return undefined;
 
     while (request.redirectDestination) {
       request = request.redirectDestination;
@@ -339,8 +339,8 @@ class NetworkRecorder extends EventEmitter {
     // playback all the devtools messages to recreate network records
     devtoolsLog.forEach(message => networkRecorder.dispatch(message));
 
-    // get out the list of records
-    const records = networkRecorder.getRecords();
+    // get out the list of records & filter out invalid records
+    const records = networkRecorder.getRecords().filter(record => record.isValid);
 
     // create a map of all the records by URL to link up initiator
     const recordsByURL = new Map();
diff --git a/lighthouse-core/lib/network-request.js b/lighthouse-core/lib/network-request.js
index 0581655a1..dd157c868 100644
--- a/lighthouse-core/lib/network-request.js
+++ b/lighthouse-core/lib/network-request.js
@@ -58,6 +58,7 @@ module.exports = class NetworkRequest {
     this.url = '';
     this.protocol = '';
     this.isSecure = false;
+    this.isValid = false;
     this.parsedURL = /** @type {ParsedURL} */ ({scheme: ''});
     this.documentURL = '';
 
@@ -124,8 +125,14 @@ module.exports = class NetworkRequest {
    */
   onRequestWillBeSent(data) {
     this.requestId = data.requestId;
-
-    const url = new URL(data.request.url);
+    let url;
+    try {
+      // try to construct the url and fill in request
+      url = new URL(data.request.url);
+    } catch (e) {
+      // isValid left false, all other data is blank
+      return;
+    }
     this.url = data.request.url;
     this.documentURL = data.documentURL;
     this.parsedURL = {
@@ -146,6 +153,7 @@ module.exports = class NetworkRequest {
 
     this.frameId = data.frameId;
     this.isLinkPreload = data.initiator.type === 'preload' || !!data.request.isLinkPreload;
+    this.isValid = true;
   }
 
   onRequestServedFromCache() {
diff --git a/lighthouse-extension/app/src/lighthouse-ext-background.js b/lighthouse-extension/app/src/lighthouse-ext-background.js
index 9041b9ae1..8556f3be2 100644
--- a/lighthouse-extension/app/src/lighthouse-ext-background.js
+++ b/lighthouse-extension/app/src/lighthouse-ext-background.js
@@ -99,10 +99,6 @@ async function runLighthouseInLR(connection, url, flags, {lrDevice, categoryIDs,
   // Certain fixes need to kick-in under LR, see https://github.com/GoogleChrome/lighthouse/issues/5839
   global.isLightRider = true;
 
-  // Override default device to be desktop, since LR default device has viewport 1x1.
-  connection.sendCommand('Emulation.setDeviceMetricsOverride',
-    {width: 800, height: 600, deviceScaleFactor: 0, mobile: false});
-
   // disableStorageReset because it causes render server hang
   flags.disableStorageReset = true;
   flags.logLevel = flags.logLevel || 'info';


Test patch:
diff --git a/lighthouse-core/test/lib/network-recorder-test.js b/lighthouse-core/test/lib/network-recorder-test.js
index ac73e5fc6..0a409ef3d 100644
--- a/lighthouse-core/test/lib/network-recorder-test.js
+++ b/lighthouse-core/test/lib/network-recorder-test.js
@@ -45,6 +45,66 @@ describe('network recorder', function() {
     assert.equal(mainDocument.resourceType, 'Document');
   });
 
+  it('recordsFromLogs ignores invalid records', function() {
+    const logs = [
+      { // valid request
+        'method': 'Network.requestWillBeSent',
+        'params': {
+          'requestId': '1',
+          'frameId': '1',
+          'loaderId': '1',
+          'documentURL': 'https://www.example.com',
+          'request': {
+            'url': 'https://www.example.com',
+            'method': 'GET',
+            'headers': {
+              'Upgrade-Insecure-Requests': '1',
+              'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_5) ' +
+                ' AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2774.2 Safari/537.36',
+            },
+            'mixedContentType': 'none',
+            'initialPriority': 'VeryHigh',
+          },
+          'timestamp': 107988.912007,
+          'wallTime': 1466620735.21187,
+          'initiator': {
+            'type': 'other',
+          },
+          'type': 'Document',
+        },
+      },
+      { // invalid request
+        'method': 'Network.requestWillBeSent',
+        'params': {
+          'requestId': '2',
+          'loaderId': '2',
+          'documentURL': 'https://www.example.com',
+          'request': {
+            'url': 'https:',
+            'method': 'GET',
+            'headers': {
+              'Origin': 'https://www.example.com',
+            },
+            'mixedContentType': 'blockable',
+            'initialPriority': 'VeryLow',
+            'referrerPolicy': 'no-referrer-when-downgrade',
+          },
+          'timestamp': 831346.969485,
+          'wallTime': 1538411434.25547,
+          'initiator': {
+            'type': 'other',
+          },
+          'type': 'Font',
+          'frameId': '1',
+          'hasUserGesture': false,
+        },
+      },
+    ];
+    assert.equal(logs.length, 2);
+    const records = NetworkRecorder.recordsFromLogs(logs);
+    assert.equal(records.length, 1);
+  });
+
   describe('#findNetworkQuietPeriods', () => {
     function record(data) {
       const url = data.url || 'https://example.com';