diff --git a/app/browser/webtorrent.js b/app/browser/webtorrent.js index 30025973d93..d7e976ce61c 100644 --- a/app/browser/webtorrent.js +++ b/app/browser/webtorrent.js @@ -1,9 +1,10 @@ const electron = require('electron') const ipc = electron.ipcMain const appUrlUtil = require('../../js/lib/appUrlUtil') +const appActions = require('../../js/actions/appActions') const messages = require('../../js/constants/messages') const Filtering = require('../filtering') -const url = require('url') +const urlParse = require('url').parse // Set to see communication between WebTorrent and torrent viewer tabs const DEBUG_IPC = false @@ -52,7 +53,27 @@ function send (msg) { channel.send(messages.TORRENT_MESSAGE, msg) } +/** + * Intercepts a request that should be redirected to the webtorrent viewer + * @param {Object} details - Details returned by the filtering callback + * @return {Object} + */ +function getInterceptedRequest (details) { + const viewerUrl = getViewerURL(details.url) + appActions.loadURLRequested(details.tabId, viewerUrl) + return { + resourceName: 'webtorrent', + cancel: true + } +} + function setupFiltering () { + Filtering.registerBeforeRequestFilteringCB(function (details) { + if (isMagnetURL(details)) { + return getInterceptedRequest(details) + } + return {} + }) Filtering.registerHeadersReceivedFilteringCB(function (details, isPrivate) { if (details.method !== 'GET') { return {} @@ -61,21 +82,13 @@ function setupFiltering () { return {} } - const parsedUrl = url.parse(details.url) + const parsedUrl = urlParse(details.url) const directDownload = parsedUrl && parsedUrl.query && parsedUrl.query.includes('download=true') if (directDownload) { return {} } - const viewerUrl = getViewerURL(details.url) - - return { - responseHeaders: { - 'Location': [ viewerUrl ] - }, - statusLine: 'HTTP/1.1 301 Moved Permanently', - resourceName: 'webtorrent' - } + return getInterceptedRequest(details) }) } @@ -107,6 +120,19 @@ function isTorrentFile (details) { return false } +/** + * Checks if request is a magnet URL + * @param {Object} details + * @return {boolean} + */ +function isMagnetURL (details) { + try { + return urlParse(details.url).protocol === 'magnet:' + } catch (e) { + return false + } +} + function getHeader (headers, headerName) { var headerNames = Object.keys(headers) for (var i = 0; i < headerNames.length; ++i) { diff --git a/app/extensions.js b/app/extensions.js index 0bc9a19473e..a1b3fafd049 100644 --- a/app/extensions.js +++ b/app/extensions.js @@ -136,9 +136,6 @@ let generateBraveManifest = () => { '' ] }, - web_accessible_resources: [ - 'img/favicon.ico' - ], incognito: 'split', key: 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAupOLMy5Fd4dCSOtjcApsAQOnuBdTs+OvBVt/3P93noIrf068x0xXkvxbn+fpigcqfNamiJ5CjGyfx9zAIs7zcHwbxjOw0Uih4SllfgtK+svNTeE0r5atMWE0xR489BvsqNuPSxYJUmW28JqhaSZ4SabYrRx114KcU6ko7hkjyPkjQa3P+chStJjIKYgu5tWBiMJp5QVLelKoM+xkY6S7efvJ8AfajxCViLGyDQPDviGr2D0VvIBob0D1ZmAoTvYOWafcNCaqaejPDybFtuLFX3pZBqfyOCyyzGhucyCmfBXJALKbhjRAqN5glNsUmGhhPK87TuGATQfVuZtenMvXMQIDAQAB' } @@ -213,11 +210,6 @@ let generateTorrentManifest = () => { 48: 'img/webtorrent-48.png', 16: 'img/webtorrent-16.png' }, - web_accessible_resources: [ - 'img/favicon.ico', - 'img/webtorrent-128.png', - 'webtorrent.html' - ], incognito: 'split', key: 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyWl+wMvL0wZX3JUs7GeZAvxMP+LWEh2bwMV1HyuBra/lGZIq3Fmh0+AFnvFPXz1NpQkbLS3QWyqhdIn/lepGwuc2ma0glPzzmieqwctUurMGSGManApGO1MkcbSPhb+R1mx8tMam5+wbme4WoW37PI3oATgOs2NvHYuP60qol3U7b/zB3IWuqtwtqKe2Q1xY17btvPuz148ygWWIHneedt0jwfr6Zp+CSLARB9Heq/jqGXV4dPSVZ5ebBHLQ452iZkHxS6fm4Z+IxjKdYs3HNj/s8xbfEZ2ydnArGdJ0lpSK9jkDGYyUBugq5Qp3FH6zV89WqBvoV1dqUmL9gxbHsQIDAQAB' } diff --git a/app/filtering.js b/app/filtering.js index 7cd1d542586..f6ec68258e5 100644 --- a/app/filtering.js +++ b/app/filtering.js @@ -306,6 +306,10 @@ function registerForHeadersReceived (session, partition) { if (!module.exports.isResourceEnabled(results.resourceName, firstPartyUrl, isPrivate)) { continue } + if (results.cancel) { + cb({ cancel: true }) + return + } if (results.responseHeaders) { cb({ responseHeaders: results.responseHeaders, @@ -527,6 +531,10 @@ function registerForMagnetHandler (session) { const webtorrentUrl = appUrlUtil.getTorrentExtUrl('webtorrent.html') try { if (getSetting(settings.TORRENT_VIEWER_ENABLED)) { + // Loading webtorrentUrl from external sources will fail since it is + // not whitelisted in web_accessible_resources. However the protocol + // registration is needed so that onBeforeRequest can handle magnet: + // requests. session.protocol.registerNavigatorHandler('magnet', `${webtorrentUrl}#%s`) } else { session.protocol.unregisterNavigatorHandler('magnet', `${webtorrentUrl}#%s`) @@ -584,7 +592,7 @@ const initPartition = (partition) => { } module.exports.initPartition = initPartition -const filterableProtocols = ['http:', 'https:', 'ws:', 'wss:'] +const filterableProtocols = ['http:', 'https:', 'ws:', 'wss:', 'magnet:'] function shouldIgnoreUrl (details) { // internal requests @@ -664,15 +672,19 @@ module.exports.isResourceEnabled = (resourceName, url, isPrivate) => { // TODO(bridiver) - need to clean up the rest of this so web can // remove this because it duplicates checks made in siteSettings // and not all resources are controlled by shields up/down - if (resourceName === 'flash' || resourceName === 'webtorrent') { + if (resourceName === 'flash') { return true } + if (resourceName === 'webtorrent') { + return getSetting(settings.TORRENT_VIEWER_ENABLED) + } + const appState = appStore.getState() - const settings = siteSettings.getSiteSettingsForURL(appState.get('siteSettings'), url) + const savedSettings = siteSettings.getSiteSettingsForURL(appState.get('siteSettings'), url) const tempSettings = siteSettings.getSiteSettingsForURL(appState.get('temporarySiteSettings'), url) - let braverySettings = siteSettings.activeSettings(settings, appState, appConfig) + let braverySettings = siteSettings.activeSettings(savedSettings, appState, appConfig) if (isPrivate && tempSettings) { braverySettings = siteSettings.activeSettings(tempSettings, appState, appConfig) }