diff --git a/app/browser/webtorrent.js b/app/browser/webtorrent.js index f5a44945c9d..7f08ba2e2be 100644 --- a/app/browser/webtorrent.js +++ b/app/browser/webtorrent.js @@ -1,11 +1,19 @@ const electron = require('electron') const ipc = electron.ipcMain +const appUrlUtil = require('../../js/lib/appUrlUtil') const messages = require('../../js/constants/messages') +const Filtering = require('../filtering') // Set to see communication between WebTorrent and torrent viewer tabs const DEBUG_IPC = false if (DEBUG_IPC) console.log('WebTorrent IPC debugging enabled') +var VIEWER_URL = appUrlUtil.getTorrentExtUrl('webtorrent.html') + +function getViewerURL (torrentUrl) { + return VIEWER_URL + '#' + encodeURIComponent(torrentUrl) +} + // Connects to the BitTorrent network // Communicates with the WebTorrentRemoteClients via message passing let server = null @@ -23,7 +31,7 @@ function init (state, action) { channels[msg.clientKey] = e.sender server.receive(msg) }) - + setupFiltering() return state } @@ -43,6 +51,64 @@ function send (msg) { channel.send(messages.TORRENT_MESSAGE, msg) } +function setupFiltering () { + Filtering.registerHeadersReceivedFilteringCB(function (details, isPrivate) { + if (details.method !== 'GET') { + return {} + } + if (!isTorrentFile(details)) { + return {} + } + + var viewerUrl = getViewerURL(details.url) + + return { + responseHeaders: { + 'Location': [ viewerUrl ] + }, + statusLine: 'HTTP/1.1 301 Moved Permanently', + resourceName: 'webtorrent' + } + }) +} + +/** + * Check if the request is a torrent file. + * @param {Object} details First argument of the webRequest.onHeadersReceived + * event. The properties "responseHeaders" and "url" + * are read. + * @return {boolean} True if the resource is a torrent file. + */ +function isTorrentFile (details) { + var header = getHeader(details.responseHeaders, 'content-type') + if (header) { + var headerValue = header.toLowerCase().split(';', 1)[0].trim() + if (headerValue === 'application/x-bittorrent') { + return true + } + if (headerValue === 'application/octet-stream') { + if (details.url.toLowerCase().indexOf('.torrent') > 0) { + return true + } + var cdHeader = + getHeader(details.responseHeaders, 'content-disposition') + if (cdHeader && /\.torrent(["']|$)/i.test(cdHeader)) { + return true + } + } + } + return false +} + +function getHeader (headers, headerName) { + var headerNames = Object.keys(headers) + for (var i = 0; i < headerNames.length; ++i) { + if (headerNames[i].toLowerCase() === headerName) { + return headers[headerNames[i]][0] + } + } +} + module.exports = { init, resourceName: 'webtorrent' diff --git a/app/extensions/torrent/locales/en-US/app.properties b/app/extensions/torrent/locales/en-US/app.properties index 1cfc2137536..c714874277a 100644 --- a/app/extensions/torrent/locales/en-US/app.properties +++ b/app/extensions/torrent/locales/en-US/app.properties @@ -1,7 +1,7 @@ startPrompt=Start Downloading "{{name}}"? startPromptUntitled=Start Downloading? startDownload=Start Download -saveTorrentFile=Save Torrent File +saveTorrentFile=Save Torrent File... legalNotice=When you start a torrent, its data will be made available to others by means of upload. You are responsible for abiding by your local laws. missingFilesList=Click "Start Download" to load the torrent file list. loadingFilesList=Loading the torrent file list... @@ -18,3 +18,5 @@ downloadFile=Save File torrentStatus=Torrent Status torrentLoadingInfo=Loading torrent info... torrentLoadingMedia=Loading... +copyMagnetLink=Copy Magnet Link +webtorrentPage=WebTorrent diff --git a/app/extensions/torrent/webtorrent.html b/app/extensions/torrent/webtorrent.html index b22cfbe6a17..6826dd3825a 100644 --- a/app/extensions/torrent/webtorrent.html +++ b/app/extensions/torrent/webtorrent.html @@ -10,10 +10,10 @@