-
Notifications
You must be signed in to change notification settings - Fork 26
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
Add WebRequest API #7
Merged
Merged
Changes from all commits
Commits
Show all changes
29 commits
Select commit
Hold shift + click to select a range
a15d459
Start implementing webRequest
d016ab6
Pass urls only
617dceb
Dummy webRequest
49b707d
Right headers format
a44802f
Clean up
0cd332f
Add handlerBehaviorChanged
72464cd
Implement calls in dummy extension
6ff8393
Implement missing methods on Event
9e4bce4
Refacto
01a503f
Better wording
569452e
Bump version
5ddf5ab
Remove unnecessary code
1dcd9e1
Remove useless code
cbc95cc
add missing file and remove useless import
f4202af
Remove useless line
bcc9ba7
Pseudo-code for RCEvent+RCEventControler
alexstrat 6f535a6
oops
alexstrat 62b47f4
From Alex’s review
ca809df
Oops
alexstrat 093cd9c
Require event-emeiter
alexstrat 88f0831
Lint
alexstrat 395db78
Add uuid
alexstrat 130da8f
Handle case where no listener
alexstrat adf9472
Real working implementation
alexstrat 24d22e5
Merge remote-tracking branch 'origin/fi/mixmax/abstract-rc-event' int…
332d1f2
Remove useless code
c90bc7e
Handle timeout
d8a63d5
Small fixes
7680b32
typo
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
// Try it with motherfuckingwebsite.com | ||
|
||
chrome.webRequest.onBeforeRequest.addListener(function(details) { | ||
// Fires when a request is about to occur. | ||
// This event is sent before any TCP connection is made and can be used to cancel or redirect requests. | ||
console.log('--- onBeforeRequest details') | ||
console.log(details) | ||
return { | ||
cancel: details.url.indexOf("://evil.com/") !== -1 | ||
}; | ||
}, { | ||
urls: ['<all_urls>'], | ||
types: ['main_frame'] | ||
}); | ||
|
||
|
||
chrome.webRequest.onBeforeSendHeaders.addListener(function(details) { | ||
// Fires when a request is about to occur and the initial headers have been prepared. | ||
// The event is intended to allow extensions to add, modify, and delete request headers (*). | ||
// The onBeforeSendHeaders event is passed to all subscribers, so different subscribers may attempt to modify the request; | ||
// see the Implementation details section for how this is handled. This event can be used to cancel the request. | ||
details.requestHeaders['User-Agent'] = 'My Awesome Agent added onBeforeSendHeaders' | ||
console.log('--- onBeforeSendHeaders details') | ||
console.log(details) | ||
return { | ||
cancel: false, | ||
requestHeaders: details.requestHeaders, | ||
}; | ||
}, { | ||
urls: ['<all_urls>'], | ||
types: ['main_frame'] | ||
}); | ||
|
||
chrome.webRequest.onSendHeaders.addListener(function(details) { | ||
// Fires after all extensions have had a chance to modify the request headers, and presents the final (*) version. | ||
// The event is triggered before the headers are sent to the network. This event is informational and handled asynchronously. | ||
// It does not allow modifying or cancelling the request. | ||
console.log('--- onSendHeaders details') | ||
console.log(details) | ||
}, { | ||
urls: ['<all_urls>'], | ||
types: ['main_frame'] | ||
}); | ||
|
||
chrome.webRequest.onHeadersReceived.addListener(function(details) { | ||
// Fired when HTTP response headers of a request have been received. | ||
details.responseHeaders.push({ | ||
name: 'X-onHeadersReceived', | ||
value: 'ok' | ||
}); | ||
|
||
return { | ||
cancel: false, | ||
responseHeaders: details.responseHeaders, | ||
}; | ||
}, { | ||
urls: ['<all_urls>'], | ||
types: ['main_frame'] | ||
}); | ||
// | ||
// chrome.webRequest.onAuthRequired.addListener(function(details) { | ||
// // not available in electron. We have to implement it. | ||
// }, { | ||
// urls: ['<all_urls>'], | ||
// types: ['main_frame'] | ||
// }); | ||
|
||
chrome.webRequest.onBeforeRedirect.addListener(function(details) { | ||
// Fires when a redirect is about to be executed. A redirection can be triggered by an HTTP response code or by an extension. | ||
// This event is informational and handled asynchronously. | ||
// It does not allow you to modify or cancel the request. | ||
console.log('--- onBeforeRedirect details') | ||
console.log(details) | ||
}, { | ||
urls: ['<all_urls>'], | ||
types: ['main_frame'] | ||
}); | ||
|
||
|
||
chrome.webRequest.onResponseStarted.addListener(function(details) { | ||
// Fires when the first byte of the response body is received. | ||
// For HTTP requests, this means that the status line and response headers are available. | ||
// This event is informational and handled asynchronously. | ||
// It does not allow modifying or cancelling the request. | ||
console.log('--- onResponseStarted details') | ||
console.log(details) | ||
}, { | ||
urls: ['<all_urls>'], | ||
types: ['main_frame'] | ||
}); | ||
|
||
chrome.webRequest.onCompleted.addListener(function(details) { | ||
// Fires when a request has been processed successfully. | ||
console.log('--- onCompleted details') | ||
console.log(details) | ||
}, { | ||
urls: ['<all_urls>'], | ||
types: ['main_frame'] | ||
}); | ||
|
||
chrome.webRequest.onErrorOccurred.addListener(function(details) { | ||
// Fires when a request could not be processed successfully. | ||
console.log('--- onErrorOccurred details') | ||
console.log(details) | ||
}, { | ||
urls: ['<all_urls>'], | ||
types: ['main_frame'] | ||
}); | ||
|
||
const sampleRequest = new XMLHttpRequest(); | ||
sampleRequest.addEventListener('load', function () { | ||
console.log('--- sampleRequest AllResponseHeaders'); | ||
console.log(this.getAllResponseHeaders()); | ||
}); | ||
sampleRequest.open('GET', `http://motherfuckingwebsite.com/?foo=${Date.now()}`); | ||
sampleRequest.send(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
const { session } = require('electron'); | ||
const RCEventController = require('../rc-event-controller'); | ||
|
||
const WEBREQUEST_EVENTS = ['onBeforeRequest', 'onBeforeSendHeaders', 'onSendHeaders', | ||
'onHeadersReceived', 'onAuthRequired', 'onResponseStarted', 'onBeforeRedirect', 'onCompleted', | ||
'onErrorOccurred']; | ||
|
||
const fromElectronHeadersToChromeHeaders = (cbReturn) => { | ||
if (cbReturn && cbReturn.responseHeaders) { | ||
const responseHeaders = {}; | ||
cbReturn.responseHeaders.forEach((header) => responseHeaders[header.name] = [header.value]); | ||
cbReturn.responseHeaders = responseHeaders; | ||
} | ||
|
||
return cbReturn | ||
}; | ||
|
||
const fromChromeHeadersToElectronHeaders = (details) => { | ||
if (details.responseHeaders) | ||
details.responseHeaders = Object.keys(details.responseHeaders).map((k) => | ||
({ name: k, value: details.responseHeaders[k][0]})); | ||
|
||
return details; | ||
}; | ||
|
||
class ChromeWebRequestAPIHandler { | ||
constructor(extensionId) { | ||
this.electronWebRequestApi = session.defaultSession.webRequest; | ||
this.rcEventControllers = []; | ||
|
||
WEBREQUEST_EVENTS.forEach(methodName => { | ||
const controller = new RCEventController(`${extensionId}-webRequest-${methodName}`); | ||
this.rcEventControllers.push(controller); | ||
controller.on('add-listener', (listenerArgs, remoteCallListener) => { | ||
const [filter, extraInfos] = listenerArgs; | ||
this.electronWebRequestApi[methodName](filter, (details, callback) => { | ||
if (callback) | ||
remoteCallListener(fromChromeHeadersToElectronHeaders(details)) | ||
.then(returnedDetails => { | ||
if (!returnedDetails) return callback(details); | ||
return callback(fromElectronHeadersToChromeHeaders(returnedDetails)) | ||
}) | ||
.catch(e => {}) | ||
}) | ||
}) | ||
}); | ||
}; | ||
|
||
release () { | ||
this.rcEventControllers.forEach(c => c.release()) | ||
} | ||
} | ||
|
||
module.exports = ChromeWebRequestAPIHandler; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
const { rpc, RpcIpcManager } = require('electron-simple-rpc'); | ||
const { ipcMain } = require('electron'); | ||
const EventEmitter = require('events'); | ||
|
||
ipcMain.setMaxListeners(100); | ||
|
||
class RCEventController extends EventEmitter { | ||
constructor(eventId) { | ||
super(); | ||
|
||
this.controlerRPCScope = `${eventId}-controller`; | ||
this.eventRPCScope = `${eventId}-event`; | ||
|
||
this.rpcManager = new RpcIpcManager({ | ||
addListener: this._addListener.bind(this) | ||
}, this.controlerRPCScope); | ||
|
||
} | ||
|
||
_addListener(listenerId, listenerArgs) { | ||
const remoteCallListener = (args) => | ||
rpc(this.eventRPCScope, 'triggerListener')(listenerId, args).timeout(2500); | ||
this.emit('add-listener', listenerArgs, remoteCallListener); | ||
} | ||
|
||
release() { | ||
this.rpcManager.release(); | ||
} | ||
} | ||
|
||
module.exports = RCEventController; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,24 +1,28 @@ | ||
class Event { | ||
constructor () { | ||
this.listeners = [] | ||
this.listeners = []; | ||
} | ||
|
||
addListener (callback) { | ||
this.listeners.push(callback) | ||
this.listeners.push(callback); | ||
} | ||
|
||
hasListener (callback) { | ||
return this.listeners.indexOf(callback) !== -1; | ||
} | ||
|
||
removeListener (callback) { | ||
const index = this.listeners.indexOf(callback) | ||
const index = this.listeners.indexOf(callback); | ||
if (index !== -1) { | ||
this.listeners.splice(index, 1) | ||
} | ||
} | ||
|
||
emit (...args) { | ||
for (const listener of this.listeners) { | ||
listener(...args) | ||
listener(...args); | ||
} | ||
} | ||
} | ||
|
||
module.exports = Event | ||
module.exports = Event; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
const { rpc, RpcIpcManager } = require('electron-simple-rpc'); | ||
const uuid = require('uuid/v1'); | ||
|
||
class RCEvent { | ||
constructor(eventId) { | ||
this.listeners = new Map(); | ||
|
||
this.controllerRPCScope = `${eventId}-controller`; | ||
this.eventRPCScope = `${eventId}-event`; | ||
|
||
this.rpcManager = new RpcIpcManager({ | ||
triggerListener: this._triggerListener.bind(this) | ||
}, this.eventRPCScope) | ||
} | ||
|
||
addListener(callback, ...args) { | ||
const listenerId = uuid(); | ||
this.listeners.set(listenerId, callback); | ||
rpc(this.controllerRPCScope, 'addListener')(listenerId, args); | ||
} | ||
|
||
hasListener(callback) { | ||
return !!this._listenerIdFromCallback(callback) | ||
} | ||
|
||
removeListener(callback) { | ||
const [listenerId, cb] = this._listenerIdFromCallback(callback); | ||
this.listeners.delete(listenerId) | ||
} | ||
|
||
_triggerListener(listenerId, args) { | ||
const listener = this.listeners.get(listenerId); | ||
if (!listener) return; | ||
|
||
try { | ||
return listener.call(this, args); | ||
} catch (e) { | ||
console.error(e); | ||
} | ||
} | ||
|
||
_listenerIdFromCallback(callback) { | ||
return this.listeners.entries() | ||
.find(e => e[1] === callback) | ||
} | ||
} | ||
|
||
module.exports = RCEvent; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,22 @@ | ||
const Event = require('./event'); | ||
const { rpc, RpcIpcManager } = require('electron-simple-rpc'); | ||
const capitalize = require('capitalize'); | ||
const Event = require('../../renderer/extensions/event'); | ||
const RCEvent = require('./rc-event'); | ||
|
||
exports.setup = extensionId => { | ||
return { | ||
onBeforeRequest: new Event(), | ||
onBeforeSendHeaders: new Event(), | ||
onSendHeaders: new Event(), | ||
onHeadersReceived: new Event(), | ||
onAuthRequired: new Event(), | ||
onResponseStarted: new Event(), | ||
onBeforeRedirect: new Event(), | ||
onCompleted: new Event(), | ||
onErrorOccurred: new Event(), | ||
handlerBehaviorChanged () {}, | ||
MAX_HANDLER_BEHAVIOR_CHANGED_CALLS_PER_10_MINUTES: 10 | ||
const WEBREQUEST_EVENTS = ['onBeforeRequest', 'onBeforeSendHeaders', 'onSendHeaders', | ||
'onHeadersReceived', 'onAuthRequired', 'onResponseStarted', 'onBeforeRedirect', 'onCompleted', | ||
'onErrorOccurred']; | ||
|
||
class ChromeWebRequestAPIClient { | ||
constructor(extensionId) { | ||
this.MAX_HANDLER_BEHAVIOR_CHANGED_CALLS_PER_10_MINUTES = 10; | ||
WEBREQUEST_EVENTS.forEach(event => this[event] = new RCEvent(`${extensionId}-webRequest-${event}`)); | ||
} | ||
|
||
handlerBehaviorChanged () { | ||
console.warn('Call not implemented method **handlerBehaviorChanged**'); | ||
return Promise.resolve() | ||
} | ||
} | ||
|
||
exports.setup = extensionId => new ChromeWebRequestAPIClient(extensionId); |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
One day we'll need to handle this correctly :) one day