fix: Use new requestId for interception request matching (#4248)

Fix #3471
This commit is contained in:
Joseph Arhar 2019-04-08 14:17:57 -07:00 committed by Andrey Lushnikov
parent 9d31068225
commit fd0f58e9c2
2 changed files with 9 additions and 51 deletions

View File

@ -16,7 +16,6 @@
const EventEmitter = require('events');
const {helper, assert, debugError} = require('./helper');
const {Events} = require('./Events');
const Multimap = require('./Multimap');
class NetworkManager extends EventEmitter {
/**
@ -41,10 +40,8 @@ class NetworkManager extends EventEmitter {
this._attemptedAuthentications = new Set();
this._userRequestInterceptionEnabled = false;
this._protocolRequestInterceptionEnabled = false;
/** @type {!Multimap<string, string>} */
this._requestHashToRequestIds = new Multimap();
/** @type {!Multimap<string, string>} */
this._requestHashToInterceptionIds = new Multimap();
/** @type {!Map<string, string>} */
this._requestIdToInterceptionId = new Map();
this._client.on('Network.requestWillBeSent', this._onRequestWillBeSent.bind(this));
this._client.on('Network.requestIntercepted', this._onRequestIntercepted.bind(this));
@ -138,13 +135,12 @@ class NetworkManager extends EventEmitter {
_onRequestWillBeSent(event) {
// Request interception doesn't happen for data URLs with Network Service.
if (this._protocolRequestInterceptionEnabled && !event.request.url.startsWith('data:')) {
const requestHash = generateRequestHash(event.request);
const interceptionId = this._requestHashToInterceptionIds.firstValue(requestHash);
const requestId = event.requestId;
const interceptionId = this._requestIdToInterceptionId.get(requestId);
if (interceptionId) {
this._onRequest(event, interceptionId);
this._requestHashToInterceptionIds.delete(requestHash, interceptionId);
this._requestIdToInterceptionId.delete(requestId);
} else {
this._requestHashToRequestIds.set(requestHash, event.requestId);
this._requestIdToRequestWillBeSentEvent.set(event.requestId, event);
}
return;
@ -178,15 +174,13 @@ class NetworkManager extends EventEmitter {
}).catch(debugError);
}
const requestHash = generateRequestHash(event.request);
const requestId = this._requestHashToRequestIds.firstValue(requestHash);
if (requestId) {
const requestId = event.requestId;
if (requestId && this._requestIdToRequestWillBeSentEvent.has(requestId)) {
const requestWillBeSentEvent = this._requestIdToRequestWillBeSentEvent.get(requestId);
this._onRequest(requestWillBeSentEvent, event.interceptionId);
this._requestHashToRequestIds.delete(requestHash, requestId);
this._requestIdToRequestWillBeSentEvent.delete(requestId);
} else {
this._requestHashToInterceptionIds.set(requestHash, event.interceptionId);
this._requestIdToInterceptionId.set(requestId, event.interceptionId);
}
}
@ -648,42 +642,6 @@ class Response {
}
}
const IGNORED_HEADERS = new Set(['accept', 'referer', 'x-devtools-emulate-network-conditions-client-id', 'cookie', 'origin', 'content-type', 'intervention']);
/**
* @param {!Protocol.Network.Request} request
* @return {string}
*/
function generateRequestHash(request) {
let normalizedURL = request.url;
try {
// Decoding is necessary to normalize URLs. @see crbug.com/759388
// The method will throw if the URL is malformed. In this case,
// consider URL to be normalized as-is.
normalizedURL = decodeURI(request.url);
} catch (e) {
}
const hash = {
url: normalizedURL,
method: request.method,
postData: request.postData,
headers: {},
};
if (!normalizedURL.startsWith('data:')) {
const headers = Object.keys(request.headers);
headers.sort();
for (let header of headers) {
const headerValue = request.headers[header];
header = header.toLowerCase();
if (IGNORED_HEADERS.has(header))
continue;
hash.headers[header] = headerValue;
}
}
return JSON.stringify(hash);
}
class SecurityDetails {
/**
* @param {!Protocol.Network.SecurityDetails} securityPayload

View File

@ -412,7 +412,7 @@ module.exports.addTests = function({testRunner, expect, CHROME}) {
]);
});
// @see https://github.com/GoogleChrome/puppeteer/issues/3973
xit('should work when header manipulation headers with redirect', async({page, server}) => {
it('should work when header manipulation headers with redirect', async({page, server}) => {
server.setRedirect('/rrredirect', '/empty.html');
await page.setRequestInterception(true);
page.on('request', request => {