Skip to content
This repository has been archived by the owner on Dec 11, 2019. It is now read-only.

Support .torrent files in Torrent Viewer #7351

Merged
merged 13 commits into from
Apr 3, 2017
Merged

Conversation

feross
Copy link
Contributor

@feross feross commented Feb 22, 2017

Test Plan

  • Visit https://codepen.io/ferossity/full/qaezaB/
  • Click the "torrent" link for any of the given files.
  • Verify the following:
    1. The URL bar shows an http link that ends in ".torrent"
    2. The torrent viewer loads
    3. Clicking "Save Torrent File" causes a .torrent file to download.
    4. Clicking "Start Download" causes the download to start.
    5. Clicking "Save Torrent File" still causes a .torrent file to download.
    6. Clicking on a video/audio file inside the torrent causes streaming to immediately start.

Also, confirm that magnet links continue to work:

  • Visit https://codepen.io/ferossity/full/qaezaB/
  • Click the "magnet" link for any of the given files.
  • Verify the following:
    1. The URL bar shows a magnet link
    2. The torrent viewer loads
    3. Clicking "Copy Magnet Link" causes the magnet link to be copied to the clipboard.
    4. Clicking "Start Download" causes the download to start.
    5. Clicking "Copy Magnet Link" still causes the magnet link to be copied to the clipboard.
    6. Clicking on a video/audio file inside the torrent causes streaming to immediately start.

Description

Behold, .torrent file support!

screen shot 2017-03-17 at 5 08 08 pm

Fixes: #6671
Fixes: #7772


  • Submitted a ticket for my issue if one did not already exist.
  • Used Github auto-closing keywords in the commit message.
  • Added/updated tests for this change (for new code or code which already has tests).
  • Ran git rebase -i to squash commits (if needed).

app/filtering.js Outdated
@@ -303,7 +303,7 @@ function registerForHeadersReceived (session, partition) {
continue
}
if (results.responseHeaders) {
cb({responseHeaders: results.responseHeaders})
cb({ responseHeaders: results.responseHeaders, statusLine: results.statusLine })
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't seem to actually redirect the browser to the given Location header. Instead, it loads about-error.html page. Any ideas?

screen shot 2017-02-21 at 6 19 07 pm

@luixxiul
Copy link
Contributor

@feross
Copy link
Contributor Author

feross commented Feb 28, 2017

@luixxiul I've never seen a .magnet file before. That's a first for me. They're non-standard and it looks like they're only used by the Vuze torrent client. We could support them, but I think that the libreoffice team was probably expecting users to open the .magnet file and paste the link into a torrent app.

@feross feross changed the title WIP: Show .torrent files in Torrent Viewer Show .torrent files in Torrent Viewer Mar 17, 2017
@feross feross changed the title Show .torrent files in Torrent Viewer Support .torrent files in Torrent Viewer Mar 18, 2017
@feross
Copy link
Contributor Author

feross commented Mar 18, 2017

This PR is ready for review! I have no idea who should review it, so I added a bunch of potential reviewers. Looking forward to finally landing this!

<link rel="localization" href="locales/{locale}/app.properties">
</head>
<body>
<div id="appContainer" />
<script src='gen/webtorrentPage.entry.js'></script>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This let's us use the DOM node #appContainer right away, without waiting for DOM ready.

* are read.
* @return {boolean} True if the resource is a torrent file.
*/
function isTorrentFile (details) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This .torrent file detection is pretty conservative. It looks for a torrent mimetype, and only uses the ".torrent" extension to indicate a torrent if the server sets the 'content-type' to 'application/octet-stream'.

@@ -0,0 +1,35 @@
const React = require('react')
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pulled this into its own component


let content
if (torrent.serverURL == null) {
if (!file || !serverUrl) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix race condition where media is briefly added to <iframe>. If there is no file object yet, but there is a serverUrl, then an iframe is added to the page, instead of a "Loading..." message.

return <a href={magnetURL}>{file.name}</a>
const suffix = /^https?:/.test(torrentId)
? '#ix=' + ix
: '&ix=' + ix
Copy link
Contributor Author

@feross feross Mar 18, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For http torrent links, we use a hash symbol instead of a query param to indicate the file that is selected, since we don't want to add random query params to the URL, which could cause the server to 404 if it doesn't like it.

For magnet links, adding a query param is acceptable since unknown keys are ignored by all torrent clients.

l10nId='copyMagnetLink'
className='whiteButton copyMagnetLink'
onClick={() => dispatch('copyMagnetLink')}
/>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Magnet links get a "Copy Magnet Link" button, instead of "Save Torrent File" which made no sense.

store.torrentIdProtocol = parsedUrl.protocol

// `ix` param can be set by query param or hash, e.g. ?ix=1 or #ix=1
if (parsedUrl.protocol === 'http:' || parsedUrl.protocol === 'https:') {
Copy link
Contributor Author

@feross feross Mar 18, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is where you can see how torrent links and magnet links are handled differently.

// Clean up the client. Note: Since this does IPC, it's not guaranteed to send
// before the page is closed. But that's okay; webtorrent-remote expects regular
// heartbeats and assumes clients are dead after 30s without one. So basically,
// this is an optimization to destroy the client sooner.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a much more descriptive comment here. We're not relying on this IPC succeeding before the page is unloaded. (It only succeeds like 50% of the time.)

// update() call that happens on a 1 second interval.
torrent.on('infohash', update)
torrent.on('metadata', update)
torrent.on('done', update)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These handlers make the UI snappier

@@ -123,7 +124,7 @@
"tracking-protection": "1.1.x",
"underscore": "1.8.3",
"url-loader": "^0.5.7",
"webtorrent-remote": "^1.0.0"
"webtorrent-remote": "^2.0.0"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lots of fixes went into the next version of webtorrent-remote to support this PR

@@ -87,6 +87,7 @@
"ad-block": "^2.0.0",
"aphrodite": "^1.0.0",
"async": "^2.0.1",
"clipboard-copy": "^1.0.0",
Copy link
Contributor Author

@feross feross Mar 18, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Published this to npm since it's reuseable and useful in other contexts. It's simpler than the other copy-to-clipboard solutions out there. Unfortunately, this is not just a simple one-liner.

@feross
Copy link
Contributor Author

feross commented Mar 21, 2017

@bsclifton Rebased, and ready for review!

@alexwykoff
Copy link
Contributor

This is beautiful beyond words.
screen shot 2017-03-23 at 9 16 43 pm

Why does the save down-arrow icon link to localhost? What is the expected behavior? (currently does nothing)
screen shot 2017-03-23 at 9 21 14 pm
Also, could we perhaps show per-file info and have controls to stop/start on contents?
(Likely out of scope, better for another issue&PR)

What do I do if I want to start a new torrent?

Other than these questions ^ it looks great. Well done @feross!

@feross
Copy link
Contributor Author

feross commented Mar 30, 2017

This is beautiful beyond words.

Thanks :)

Why does the save down-arrow icon link to localhost? What is the expected behavior? (currently does nothing)

We serve the files in the torrent from a local HTTP server. That way when the browser makes a request for a specific file (or a part of a file, in the case of streaming) the torrent engine knows to prioritize downloading that part of the torrent first. It's unfortunate that we're exposing localhost in the link, but I think it's acceptable.

The expected behavior is that clicking it will trigger a file download for just that one file. In some cases, I notice a long delay before that dialog shows up. It's unclear why that's happening. I can look into it for a future PR.

Also, could we perhaps show per-file info and have controls to stop/start on contents?

Per-file info is doable. What do you mean by controls to stop/start on contents?

What do I do if I want to start a new torrent?

The torrent viewer works just like the PDF viewer that's also built into Brave. You start a new torrent by navigating to a magnet link or torrent file URL.

@srirambv
Copy link
Collaborator

Also, could we perhaps show per-file info and have controls to stop/start on contents?

What do you mean by controls to stop/start on contents?

I think its start/stop/exclude buttons for individual downloads. As there is no option to exclude specific files form the list. This is (not sure if it still there) a feature in utorrent where you can pause/cancel/exclude specific files even after torrent download is started. That would be a nice addition to the existing feature

@alexwykoff
Copy link
Contributor

@feross I think there are a few things which probably should be managed before we push this out the door.

  1. Support local .torrent files (pdf.js has the same problem)
  2. Allow users to stop a torrent (or seeding)

For future consideration:

  1. For compilations, the ability to selectively download
  2. Seed ratios
  3. Bandwidth rate capping
  4. Creating and hosting new torrents based on local files
  5. Tracking multiple torrents on the same page

I'm sure I'm missing some obvious things here, but as a first push, this is great. If we get the first two issues resolved, this is good to go.
Network recovery tests totally worked, resume after quit Brave worked.

Tested on OS X and Windows. Linux test underway.

@luixxiul luixxiul removed their request for review April 1, 2017 17:44
Copy link
Member

@bsclifton bsclifton left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alexwykoff has done a comprehensive review; I reviewed the code and also tried the PR- works great 😄 Will go ahead and merge and we can address any opens items with a follow up issue

@feross
Copy link
Contributor Author

feross commented Apr 13, 2017

@alexwykoff I opened an issue for your request:

Your other suggestions are interesting. My thoughts are inline.

  • For compilations, the ability to selectively download

Useful, but definitely a power user feature. We already support this feature in WebTorrent Desktop, though I believe that are some bugs in the implementation right now and extra files end up getting downloaded.

FWIW, files are already prioritized based on need. So, media that is being consumed via the built-in video player, or that is being downloaded via the 'save file' button will be prioritized before the rest of the files in the torrent.

So the primary benefit of this feature would be saving bandwidth/disk space by not downloading files you know you don't need.

  • Seed ratios

Does an average user know what a seed ratio is? WebTorrent Desktop doesn't even include a seed ratio and it hasn't generated too many complaints.

  • Bandwidth rate capping

Definitely useful in some situations, but would this be a client-wide cap? Does that mean we need a page for configuring the torrent viewer extension?

  • Creating and hosting new torrents based on local files

Does the PDF viewer support creating PDF files? I think this is out of scope.

  • Tracking multiple torrents on the same page

I know that most existing torrent apps show all the torrents in one big table. But I like the current model where torrents are treated just like any other webpage. One torrent per tab.

Thanks for the review and for landing this, @alexwykoff @bsclifton!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants