Implement Page.setRequestInterceptor
This patch: - introduces Request class. - implements Page.setRequestInterceptor method. The method allows to install a callback which will be called for every request with a |Request| object as a single parameter. The callback is free to override certain request's properties and then either continue or abort it. - implements request interception api for phantom-shim and unskips the module/webpage/abort-network-request.js phantomjs test References #1
This commit is contained in:
parent
9bdf9ed5de
commit
e274c26e8b
20
lib/Page.js
20
lib/Page.js
@ -18,6 +18,7 @@ var fs = require('fs');
|
||||
var EventEmitter = require('events');
|
||||
var helpers = require('./helpers');
|
||||
var mime = require('mime');
|
||||
var Request = require('./Request');
|
||||
|
||||
class Page extends EventEmitter {
|
||||
/**
|
||||
@ -56,16 +57,35 @@ class Page extends EventEmitter {
|
||||
this._scriptIdToPageCallback = new Map();
|
||||
/** @type {!Array<string>} */
|
||||
this._blockedURLs = [];
|
||||
/** @type {?function(!Request)} */
|
||||
this._requestInterceptor = null;
|
||||
|
||||
client.on('Debugger.paused', event => this._onDebuggerPaused(event));
|
||||
client.on('Debugger.scriptParsed', event => this._onScriptParsed(event));
|
||||
client.on('Network.responseReceived', event => this.emit(Page.Events.ResponseReceived, event.response));
|
||||
client.on('Network.loadingFailed', event => this.emit(Page.Events.ResourceLoadingFailed, event));
|
||||
client.on('Network.requestIntercepted', event => this._onRequestIntercepted(event));
|
||||
client.on('Runtime.consoleAPICalled', event => this._onConsoleAPI(event));
|
||||
client.on('Page.javascriptDialogOpening', event => this._onDialog(event));
|
||||
client.on('Runtime.exceptionThrown', exception => this._handleException(exception.exceptionDetails));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {?function(!Request)} interceptor
|
||||
*/
|
||||
async setRequestInterceptor(interceptor) {
|
||||
this._requestInterceptor = interceptor;
|
||||
await this._client.send('Network.enableRequestInterception', {enabled: !!interceptor});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {!Object} event
|
||||
*/
|
||||
_onRequestIntercepted(event) {
|
||||
var request = new Request(this._client, event.InterceptionId, event.request);
|
||||
this._requestInterceptor(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {!Array<string>} patterns
|
||||
* @return {!Promise}
|
||||
|
123
lib/Request.js
Normal file
123
lib/Request.js
Normal file
@ -0,0 +1,123 @@
|
||||
/**
|
||||
* Copyright 2017 Google Inc. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
class Request {
|
||||
/**
|
||||
* @param {!Connection} client
|
||||
* @param {string} interceptionId
|
||||
* @param {!Object} payload
|
||||
*/
|
||||
constructor(client, interceptionId, payload) {
|
||||
this._client = client;
|
||||
this._interceptionId = interceptionId;
|
||||
this._url = payload.url;
|
||||
this._method = payload.method;
|
||||
this._headers = payload.headers;
|
||||
this._postData = payload.postData;
|
||||
|
||||
this._urlOverride = undefined;
|
||||
this._methodOverride = undefined;
|
||||
this._postDataOverride = undefined;
|
||||
|
||||
this._handled = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {string}
|
||||
*/
|
||||
url() {
|
||||
return this._urlOverride || this._url;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} url
|
||||
*/
|
||||
setUrl(url) {
|
||||
this._urlOverride = url;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {string}
|
||||
*/
|
||||
method() {
|
||||
return this._methodOverride || this._method;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} method
|
||||
*/
|
||||
setMethod(method) {
|
||||
this._methodOverride = method;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {!Object}
|
||||
*/
|
||||
headers() {
|
||||
return Object.assign({}, this._headersOverride || this._headers);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {!Object} headers
|
||||
*/
|
||||
setHeaders(headers) {
|
||||
this._headersOverride = headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {(string|undefined)}
|
||||
*/
|
||||
postData() {
|
||||
return this._postDataOverride || this._postData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {(string|undefined)}
|
||||
*/
|
||||
setPostData(data) {
|
||||
this._postDataOverride = data;
|
||||
}
|
||||
|
||||
abort() {
|
||||
console.assert(!this._handled, 'This request is already handled!');
|
||||
this._handled = true;
|
||||
this._client.send('Network.continueInterceptedRequest', {
|
||||
interceptionId: this._interceptionId,
|
||||
errorReason: 'Aborted'
|
||||
});
|
||||
}
|
||||
|
||||
continue() {
|
||||
console.assert(!this._handled, 'This request is already handled!');
|
||||
this._handled = true;
|
||||
this._client.send('Network.continueInterceptedRequest', {
|
||||
interceptionId: this._interceptionId,
|
||||
url: this._urlOverride,
|
||||
method: this._methodOverride,
|
||||
postData: this._postDataOverride,
|
||||
headers: this._headersOverride
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {boolean}
|
||||
*/
|
||||
handled() {
|
||||
return this._handled;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Request;
|
@ -52,6 +52,7 @@ class WebPage {
|
||||
|
||||
this.libraryPath = path.dirname(scriptPath);
|
||||
|
||||
this._onResourceRequestedCallback = undefined;
|
||||
this._onConfirmCallback = undefined;
|
||||
this._onAlertCallback = undefined;
|
||||
this._onError = noop;
|
||||
@ -65,6 +66,34 @@ class WebPage {
|
||||
this._pageEvents.on(PageEvents.Exception, (exception, stack) => (this._onError || noop).call(null, exception, stack));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {?function(!Object, !Request)}
|
||||
*/
|
||||
get onResourceRequested() {
|
||||
return this._onResourceRequestedCallback;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {?function(!Object, !Request)} callback
|
||||
*/
|
||||
set onResourceRequested(callback) {
|
||||
this._onResourceRequestedCallback = callback;
|
||||
this._page.setRequestInterceptor(callback ? resourceInterceptor : null);
|
||||
|
||||
/**
|
||||
* @param {!Request} request
|
||||
*/
|
||||
function resourceInterceptor(request) {
|
||||
var requestData = {
|
||||
url: request.url(),
|
||||
headers: request.headers()
|
||||
};
|
||||
callback(requestData, request);
|
||||
if (!request.handled())
|
||||
request.continue();
|
||||
}
|
||||
}
|
||||
|
||||
_onResponseReceived(response) {
|
||||
if (!this.onResourceReceived)
|
||||
return;
|
||||
|
23
test/test.js
23
test/test.js
@ -84,6 +84,29 @@ describe('Puppeteer', function() {
|
||||
expect(result).toBe(15);
|
||||
}));
|
||||
});
|
||||
|
||||
describe('Page.setRequestInterceptor', function() {
|
||||
it('should work', SX(async function() {
|
||||
page.setRequestInterceptor(request => {
|
||||
expect(request.url()).toContain('empty.html');
|
||||
expect(request.headers()['User-Agent']).toBeTruthy();
|
||||
expect(request.method()).toBe('GET');
|
||||
expect(request.postData()).toBe(undefined);
|
||||
request.continue();
|
||||
});
|
||||
var success = await page.navigate(EMPTY_PAGE);
|
||||
}));
|
||||
it('should show extraHTTPHeaders', SX(async function() {
|
||||
await page.setExtraHTTPHeaders({
|
||||
foo: 'bar'
|
||||
});
|
||||
page.setRequestInterceptor(request => {
|
||||
expect(request.headers()['foo']).toBe('bar');
|
||||
request.continue();
|
||||
});
|
||||
var success = await page.navigate(EMPTY_PAGE);
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
||||
// Since Jasmine doesn't like async functions, they should be wrapped
|
||||
|
@ -23,4 +23,4 @@ page.open(address, function(status) {
|
||||
console.log('Unable to load the address!');
|
||||
phantom.exit();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -1,4 +1,3 @@
|
||||
//! unsupported
|
||||
var webpage = require('webpage');
|
||||
|
||||
async_test(function () {
|
||||
|
Loading…
Reference in New Issue
Block a user