feat(Chromium): roll Chromium to r579032 (#2989)

This patch rolls Chromium to r579032. The patch includes:
- https://crrev.com/577366 - DevTools: report redirect responses only if response interception is enabled
- https://crrev.com/577212 - DevTools: intercept requests resulting from redirects
- https://crrev.com/578934 - DevTools: Add a protocol method to insertText

Interception Logic in DevTools protocol has changed regarding redirects;
this patch migrates interceptions to dispatch "request" events based on
requestWillBeSent event.
This commit is contained in:
Andrey Lushnikov 2018-07-30 19:09:10 -07:00 committed by GitHub
parent 5bcb7cf512
commit 1931cb479e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 69 additions and 54 deletions

View File

@ -28,8 +28,8 @@ class NetworkManager extends EventEmitter {
this._frameManager = frameManager; this._frameManager = frameManager;
/** @type {!Map<string, !Request>} */ /** @type {!Map<string, !Request>} */
this._requestIdToRequest = new Map(); this._requestIdToRequest = new Map();
/** @type {!Map<string, !Request>} */ /** @type {!Map<string, !Protocol.Network.requestWillBeSentPayload>} */
this._interceptionIdToRequest = new Map(); this._requestIdToRequestWillBeSentEvent = new Map();
/** @type {!Object<string, string>} */ /** @type {!Object<string, string>} */
this._extraHTTPHeaders = {}; this._extraHTTPHeaders = {};
@ -125,6 +125,25 @@ class NetworkManager extends EventEmitter {
]); ]);
} }
/**
* @param {!Protocol.Network.requestWillBeSentPayload} event
*/
_onRequestWillBeSent(event) {
if (this._protocolRequestInterceptionEnabled) {
const requestHash = generateRequestHash(event.request);
const interceptionId = this._requestHashToInterceptionIds.firstValue(requestHash);
if (interceptionId) {
this._onRequest(event, interceptionId);
this._requestHashToInterceptionIds.delete(requestHash, interceptionId);
} else {
this._requestHashToRequestIds.set(requestHash, event.requestId);
this._requestIdToRequestWillBeSentEvent.set(event.requestId, event);
}
return;
}
this._onRequest(event, null);
}
/** /**
* @param {!Protocol.Network.requestInterceptedPayload} event * @param {!Protocol.Network.requestInterceptedPayload} event
*/ */
@ -151,25 +170,36 @@ class NetworkManager extends EventEmitter {
}).catch(debugError); }).catch(debugError);
} }
if (event.redirectUrl) {
const request = this._interceptionIdToRequest.get(event.interceptionId);
if (request) {
this._handleRequestRedirect(request, event.responseStatusCode, event.responseHeaders, false /* fromDiskCache */, false /* fromServiceWorker */, null /* securityDetails */);
this._handleRequestStart(request._requestId, event.interceptionId, event.redirectUrl, event.isNavigationRequest, event.resourceType, event.request, event.frameId, request._redirectChain);
}
return;
}
const requestHash = generateRequestHash(event.request); const requestHash = generateRequestHash(event.request);
const requestId = this._requestHashToRequestIds.firstValue(requestHash); const requestId = this._requestHashToRequestIds.firstValue(requestHash);
if (requestId) { if (requestId) {
const requestWillBeSentEvent = this._requestIdToRequestWillBeSentEvent.get(requestId);
this._onRequest(requestWillBeSentEvent, event.interceptionId);
this._requestHashToRequestIds.delete(requestHash, requestId); this._requestHashToRequestIds.delete(requestHash, requestId);
this._handleRequestStart(requestId, event.interceptionId, event.request.url, event.isNavigationRequest, event.resourceType, event.request, event.frameId, []); this._requestIdToRequestWillBeSentEvent.delete(requestId);
} else { } else {
this._requestHashToInterceptionIds.set(requestHash, event.interceptionId); this._requestHashToInterceptionIds.set(requestHash, event.interceptionId);
this._handleRequestStart(null, event.interceptionId, event.request.url, event.isNavigationRequest, event.resourceType, event.request, event.frameId, []);
} }
} }
/**
* @param {!Protocol.Network.requestWillBeSentPayload} event
* @param {?string} interceptionId
*/
_onRequest(event, interceptionId) {
let redirectChain = [];
if (event.redirectResponse) {
const request = this._requestIdToRequest.get(event.requestId);
// If we connect late to the target, we could have missed the requestWillBeSent event.
if (request) {
this._handleRequestRedirect(request, event.redirectResponse.status, event.redirectResponse.headers, event.redirectResponse.fromDiskCache, event.redirectResponse.fromServiceWorker, event.redirectResponse.securityDetails);
redirectChain = request._redirectChain;
}
}
const isNavigationRequest = event.requestId === event.loaderId && event.type === 'Document';
this._handleRequestStart(event.requestId, interceptionId, event.request.url, isNavigationRequest, event.type, event.request, event.frameId, redirectChain);
}
/** /**
* @param {!Protocol.Network.requestServedFromCachePayload} event * @param {!Protocol.Network.requestServedFromCachePayload} event
*/ */
@ -193,14 +223,13 @@ class NetworkManager extends EventEmitter {
request._redirectChain.push(request); request._redirectChain.push(request);
response._bodyLoadedPromiseFulfill.call(null, new Error('Response body is unavailable for redirect responses')); response._bodyLoadedPromiseFulfill.call(null, new Error('Response body is unavailable for redirect responses'));
this._requestIdToRequest.delete(request._requestId); this._requestIdToRequest.delete(request._requestId);
this._interceptionIdToRequest.delete(request._interceptionId);
this._attemptedAuthentications.delete(request._interceptionId); this._attemptedAuthentications.delete(request._interceptionId);
this.emit(NetworkManager.Events.Response, response); this.emit(NetworkManager.Events.Response, response);
this.emit(NetworkManager.Events.RequestFinished, request); this.emit(NetworkManager.Events.RequestFinished, request);
} }
/** /**
* @param {?string} requestId * @param {string} requestId
* @param {?string} interceptionId * @param {?string} interceptionId
* @param {string} url * @param {string} url
* @param {boolean} isNavigationRequest * @param {boolean} isNavigationRequest
@ -214,46 +243,10 @@ class NetworkManager extends EventEmitter {
if (frameId) if (frameId)
frame = this._frameManager.frame(frameId); frame = this._frameManager.frame(frameId);
const request = new Request(this._client, requestId, interceptionId, isNavigationRequest, this._userRequestInterceptionEnabled, url, resourceType, requestPayload, frame, redirectChain); const request = new Request(this._client, requestId, interceptionId, isNavigationRequest, this._userRequestInterceptionEnabled, url, resourceType, requestPayload, frame, redirectChain);
if (requestId)
this._requestIdToRequest.set(requestId, request); this._requestIdToRequest.set(requestId, request);
if (interceptionId)
this._interceptionIdToRequest.set(interceptionId, request);
this.emit(NetworkManager.Events.Request, request); this.emit(NetworkManager.Events.Request, request);
} }
/**
* @param {!Protocol.Network.requestWillBeSentPayload} event
*/
_onRequestWillBeSent(event) {
if (this._protocolRequestInterceptionEnabled) {
// All redirects are handled in requestIntercepted.
if (event.redirectResponse)
return;
const requestHash = generateRequestHash(event.request);
const interceptionId = this._requestHashToInterceptionIds.firstValue(requestHash);
const request = interceptionId ? this._interceptionIdToRequest.get(interceptionId) : null;
if (request) {
request._requestId = event.requestId;
this._requestIdToRequest.set(event.requestId, request);
this._requestHashToInterceptionIds.delete(requestHash, interceptionId);
} else {
this._requestHashToRequestIds.set(requestHash, event.requestId);
}
return;
}
let redirectChain = [];
if (event.redirectResponse) {
const request = this._requestIdToRequest.get(event.requestId);
// If we connect late to the target, we could have missed the requestWillBeSent event.
if (request) {
this._handleRequestRedirect(request, event.redirectResponse.status, event.redirectResponse.headers, event.redirectResponse.fromDiskCache, event.redirectResponse.fromServiceWorker, event.redirectResponse.securityDetails);
redirectChain = request._redirectChain;
}
}
const isNavigationRequest = event.requestId === event.loaderId && event.type === 'Document';
this._handleRequestStart(event.requestId, null, event.request.url, isNavigationRequest, event.type, event.request, event.frameId, redirectChain);
}
/** /**
* @param {!Protocol.Network.responseReceivedPayload} event * @param {!Protocol.Network.responseReceivedPayload} event
*/ */
@ -279,7 +272,6 @@ class NetworkManager extends EventEmitter {
return; return;
request.response()._bodyLoadedPromiseFulfill.call(null); request.response()._bodyLoadedPromiseFulfill.call(null);
this._requestIdToRequest.delete(request._requestId); this._requestIdToRequest.delete(request._requestId);
this._interceptionIdToRequest.delete(request._interceptionId);
this._attemptedAuthentications.delete(request._interceptionId); this._attemptedAuthentications.delete(request._interceptionId);
this.emit(NetworkManager.Events.RequestFinished, request); this.emit(NetworkManager.Events.RequestFinished, request);
} }
@ -298,7 +290,6 @@ class NetworkManager extends EventEmitter {
if (response) if (response)
response._bodyLoadedPromiseFulfill.call(null); response._bodyLoadedPromiseFulfill.call(null);
this._requestIdToRequest.delete(request._requestId); this._requestIdToRequest.delete(request._requestId);
this._interceptionIdToRequest.delete(request._interceptionId);
this._attemptedAuthentications.delete(request._interceptionId); this._attemptedAuthentications.delete(request._interceptionId);
this.emit(NetworkManager.Events.RequestFailed, request); this.emit(NetworkManager.Events.RequestFailed, request);
} }

View File

@ -8,7 +8,7 @@
"node": ">=6.4.0" "node": ">=6.4.0"
}, },
"puppeteer": { "puppeteer": {
"chromium_revision": "574897" "chromium_revision": "579032"
}, },
"scripts": { "scripts": {
"unit": "node test/test.js", "unit": "node test/test.js",

View File

@ -389,6 +389,30 @@ module.exports.addTests = function({testRunner, expect}) {
expect(request.redirectChain().indexOf(request)).toBe(i); expect(request.redirectChain().indexOf(request)).toBe(i);
} }
}); });
it('should work with redirects for subresources', async({page, server}) => {
await page.setRequestInterception(true);
const requests = [];
page.on('request', request => {
request.continue();
requests.push(request);
});
server.setRedirect('/one-style.css', '/two-style.css');
server.setRedirect('/two-style.css', '/three-style.css');
server.setRedirect('/three-style.css', '/four-style.css');
server.setRoute('/four-style.css', (req, res) => res.end('body {box-sizing: border-box; }'));
const response = await page.goto(server.PREFIX + '/one-style.html');
expect(response.status()).toBe(200);
expect(response.url()).toContain('one-style.html');
expect(requests.length).toBe(5);
expect(requests[0].resourceType()).toBe('document');
expect(requests[1].resourceType()).toBe('stylesheet');
// Check redirect chain
const redirectChain = requests[1].redirectChain();
expect(redirectChain.length).toBe(3);
expect(redirectChain[0].url()).toContain('/one-style.css');
expect(redirectChain[2].url()).toContain('/three-style.css');
});
it('should be able to abort redirects', async({page, server}) => { it('should be able to abort redirects', async({page, server}) => {
await page.setRequestInterception(true); await page.setRequestInterception(true);
server.setRedirect('/non-existing.json', '/non-existing-2.json'); server.setRedirect('/non-existing.json', '/non-existing-2.json');