-
Notifications
You must be signed in to change notification settings - Fork 9.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
core: INSECURE_DOCUMENT_REQUEST errors still return lhr #6608
Changes from 3 commits
4c658fb
eb7f5a3
62787ee
3577e0c
2c0b251
e22d9ca
9e54f1b
059d95e
51e4f05
1ce9144
4bd59e4
53e00a7
1b6e678
dde5b95
4807cf0
2d505e8
1e1fc8a
0a0e8e0
b863fbd
da6fd9c
3c54326
ab0582b
f272978
e6a659a
271a80a
8bbcbc4
04b1f64
1da3b01
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -81,13 +81,6 @@ class Driver { | |
this._eventEmitter.emit(event.method, event.params); | ||
}); | ||
|
||
/** | ||
* Used for monitoring network status events during gotoURL. | ||
* @type {?LH.Crdp.Security.SecurityStateChangedEvent} | ||
* @private | ||
*/ | ||
this._lastSecurityState = null; | ||
|
||
/** | ||
* @type {number} | ||
* @private | ||
|
@@ -512,6 +505,35 @@ class Driver { | |
}); | ||
} | ||
|
||
/** | ||
* Returns LHError if the security state is insecure. | ||
* @param {LH.Crdp.Security.SecurityStateChangedEvent} securityState | ||
* @returns {LHError|undefined} | ||
*/ | ||
checkForSecurityIssues({securityState, explanations}) { | ||
if (securityState === 'insecure') { | ||
const insecureDescriptions = explanations | ||
.filter(exp => exp.securityState === 'insecure') | ||
.map(exp => exp.description); | ||
return new LHError(LHError.errors.INSECURE_DOCUMENT_REQUEST, { | ||
securityMessages: insecureDescriptions.join(' '), | ||
}); | ||
} | ||
} | ||
|
||
waitForSecurityIssuesCheck() { | ||
return new Promise((resolve, reject) => { | ||
this.once('Security.securityStateChanged', state => { | ||
const err = this.checkForSecurityIssues(state); | ||
if (err) { | ||
reject(err); | ||
} else { | ||
resolve(); | ||
} | ||
}); | ||
}); | ||
} | ||
|
||
/** | ||
* Returns a promise that resolve when a frame has been navigated. | ||
* Used for detecting that our about:blank reset has been completed. | ||
|
@@ -895,6 +917,13 @@ class Driver { | |
// No timeout needed for Page.navigate. See #6413. | ||
const waitforPageNavigateCmd = this._innerSendCommand('Page.navigate', {url}); | ||
|
||
try { | ||
await this.sendCommand('Security.enable'); | ||
await this.waitForSecurityIssuesCheck(); | ||
} finally { | ||
this.sendCommand('Security.disable'); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To do this right, I think @paulirish is right and this should move into Take a look at (and forgive the state of the code in those methods...they're super old and have pretty much only grown through accretion, not really refactored, so they're a bit creaky and brittle :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what about the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
that's only used for loading |
||
|
||
if (waitForNavigated) { | ||
await this._waitForFrameNavigated(); | ||
} else if (waitForLoad) { | ||
|
@@ -959,26 +988,6 @@ class Driver { | |
return result.body; | ||
} | ||
|
||
async listenForSecurityStateChanges() { | ||
this.on('Security.securityStateChanged', state => { | ||
this._lastSecurityState = state; | ||
}); | ||
await this.sendCommand('Security.enable'); | ||
} | ||
|
||
/** | ||
* @return {LH.Crdp.Security.SecurityStateChangedEvent} | ||
*/ | ||
getSecurityState() { | ||
if (!this._lastSecurityState) { | ||
// happens if 'listenForSecurityStateChanges' is not called, | ||
// or if some assumptions about the Security domain are wrong | ||
throw new Error('Expected a security state.'); | ||
} | ||
|
||
return this._lastSecurityState; | ||
} | ||
|
||
/** | ||
* @param {string} name The name of API whose permission you wish to query | ||
* @return {Promise<string>} The state of permissions, resolved in a promise. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -109,7 +109,6 @@ class GatherRunner { | |
await driver.cacheNatives(); | ||
await driver.registerPerformanceObserver(); | ||
await driver.dismissJavaScriptDialogs(); | ||
await driver.listenForSecurityStateChanges(); | ||
if (resetStorage) await driver.clearDataForOrigin(options.requestedUrl); | ||
log.timeEnd(status); | ||
} | ||
|
@@ -172,23 +171,6 @@ class GatherRunner { | |
} | ||
} | ||
|
||
/** | ||
* Throws an error if the security state is insecure. | ||
* @param {LH.Crdp.Security.SecurityStateChangedEvent} securityState | ||
* @throws {LHError} | ||
*/ | ||
static assertNoSecurityIssues({securityState, explanations}) { | ||
if (securityState === 'insecure') { | ||
const insecureDescriptions = explanations | ||
.filter(exp => exp.securityState === 'insecure') | ||
.map(exp => exp.description); | ||
throw new LHError( | ||
LHError.errors.INSECURE_DOCUMENT_REQUEST, | ||
{securityMessages: insecureDescriptions.join(' ')} | ||
); | ||
} | ||
} | ||
|
||
/** | ||
* Calls beforePass() on gatherers before tracing | ||
* has started and before navigation to the target page. | ||
|
@@ -256,8 +238,11 @@ class GatherRunner { | |
if (recordTrace) await driver.beginTrace(settings); | ||
|
||
// Navigate. | ||
await GatherRunner.loadPage(driver, passContext); | ||
log.timeEnd(status); | ||
try { | ||
await GatherRunner.loadPage(driver, passContext); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we're injecting a lot of new if/try/catch blocks into some already beefy methods, do you think there's a way we might be able to push some of these complications down a level so the busier method is still easy to parse? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes, if we can refactor Runner.run to easily return a (errored) LHR in its catch. Then changes to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We're dropping the LHR requirement for now, so we can also drop these changes (there won't be a timing object to add this to if an error was thrown) |
||
} finally { | ||
log.timeEnd(status); | ||
} | ||
|
||
const pStatus = {msg: `Running pass methods`, id: `lh:gather:pass`}; | ||
log.time(pStatus, 'verbose'); | ||
|
@@ -311,8 +296,6 @@ class GatherRunner { | |
const networkRecords = NetworkRecorder.recordsFromLogs(devtoolsLog); | ||
log.timeEnd(status); | ||
|
||
this.assertNoSecurityIssues(driver.getSecurityState()); | ||
|
||
let pageLoadError = GatherRunner.getPageLoadError(passContext.url, networkRecords); | ||
// If the driver was offline, a page load error is expected, so do not save it. | ||
if (!driver.online) pageLoadError = undefined; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,11 +16,11 @@ | |
* Generate a filenamePrefix of hostname_YYYY-MM-DD_HH-MM-SS | ||
* Date/time uses the local timezone, however Node has unreliable ICU | ||
* support, so we must construct a YYYY-MM-DD date format manually. :/ | ||
* @param {{finalUrl: string, fetchTime: string}} lhr | ||
* @param {{requestedUrl: string, finalUrl: string, fetchTime: string}} lhr | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is this requestedUrl business about? Does it relate to INSECURE DOC requests? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if the doc fails to load, the "finalUrl" is never set. so fall back to requestUrl There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I believe left over from the old version of the PR, should be able to remove from here now (and from There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oof you're right, forgot to check if that was still necessary. |
||
* @return {string} | ||
*/ | ||
function getFilenamePrefix(lhr) { | ||
const hostname = new (getUrlConstructor())(lhr.finalUrl).hostname; | ||
const hostname = new (getUrlConstructor())(lhr.finalUrl || lhr.requestedUrl).hostname; | ||
const date = (lhr.fetchTime && new Date(lhr.fetchTime)) || new Date(); | ||
|
||
const timeStr = date.toLocaleTimeString('en-US', {hour12: false}); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,7 +22,7 @@ const UIStrings = { | |
/** Error message explaining that Lighthouse could not load the requested URL and the steps that might be taken to fix the unreliability. */ | ||
pageLoadFailedWithDetails: 'Lighthouse was unable to reliably load the page you requested. Make sure you are testing the correct URL and that the server is properly responding to all requests. (Details: {errorDetails})', | ||
/** Error message explaining that the credentials included in the Lighthouse run were invalid, so the URL cannot be accessed. */ | ||
pageLoadFailedInsecure: 'The URL you have provided does not have valid security credentials. ({securityMessages})', | ||
pageLoadFailedInsecure: 'The URL you have provided does not have valid security credentials. {securityMessages}', | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Any reason for removing these? I feel like a list that might make no sense as a sentence like this belongs in parens. e.g. The URL...credentials. (Reason 1 Reason 2) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A realistic error message reads like this:
Which is a valid sentence. So...ignore this maybe. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. correct-o, the sentences should make sense as - is. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. at least, in english .. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we need to add something about |
||
/** Error message explaining that Chrome has encountered an error during the Lighthouse run, and that Chrome should be restarted. */ | ||
internalChromeError: 'An internal Chrome error occurred. Please restart Chrome and try re-running Lighthouse.', | ||
/** Error message explaining that fetching the resources of the webpage has taken longer than the maximum time. */ | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we just combine the two of these? Seems unnecessary to split (
waitForSecurityIssuesCheck
doesn't really do anything in isolation and they aren't called separately)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we talked earlier about the order of the listener vs calling enable().
......maybe the order right now is OK. if you listened before calling security.enable then perhaps you would get a statechanged event for the about:blank state.
I'm not totally sure about this.
but typically we do like setting up the event listener before enable is called, because enable usually flushes all events before it results.