BEP:17
Title:HTTP Seeding
Version:11020
Last-Modified:2008-02-25 22:14:29 -0800 (Mon, 25 Feb 2008)
Author:John Hoffman <theshadow at degreez.net>, DeHackEd
Status:Draft
Type:Standards Track
Created:07-Feb-2008
Post-History:

Metadata Extension

  • "httpseeds"

In the main area of the metadata file and not part of the "info" section, will be a new key, "httpseeds". This key will refer to a list of URLs, and will contain a list of web addresses where torrent data can be retrieved. This key may be safely ignored if the client is not capable of using it.

Examples:

d['httpseeds'] = [ 'http://www.whatever.com/seed.php' ]

This specifies the client can retrieve data by accessing the given URL with the parameters supplied in the protocol specification below:

d['httpseeds'] = [ 'http://www.site1.com/source1.php',
                   'http://www.site2.com/source2.php'  ]

More than one URL may be specified; if so, the client will attempt to access both URLs to download seed data.

Protocol

The client calls the URL given, in the following format:

<url>?info_hash=[hash]&piece=[piece]{&ranges=[start]-[end]{,[start]-[end]}...}

Examples:

http://www.whatever.com/seed.php?info_hash=%9C%D9i%8A%F5Uu%1A%91%86%AE%06lW%EA%21W%235%E0&piece=3
http://www.whatever.com/seed.php?info_hash=%9C%D9i%8A%F5Uu%1A%91%86%AE%06lW%EA%21W%235%E0&piece=8&ranges=49152-131071,180224-262143

The URL would be for a script which has access to the files contained in the torrent, and to the metadata (.torrent) file itself, so that it may calculate what byte ranges to pull from what files. One such script has been written by DeHackEd, and is available at http://bt.degreez.net .

The script should return, if everything is okay, either a status of 200 (OK) and a block of data (either the entire piece if no ranges were given, or the ranges of data requested for that piece appended together), in binary format, or 503 (Service Temporarily Unavailable), with the body of the return being an ASCII integer value specifying how long the client should wait before retrying. The client should consider any other return code as an error. In the case of an error, the client should retry, but should retry less often if the failure to contact the seed continues.

Server-side Implementation Notes

The purpose of the http seed script is to limit access to the data being downloaded so that the web server isn't overwhelmed by clients asking for the data. If it weren't for this limiting, there would be no way to prevent someone from coding a client to try to download continuously or multiply, resulting in a heavy load on the server. Limiting the download rate also allows an http seed script to be run on a web account where the total amount of data downloaded is restricted or may result in extra service charges.

The script must provide three major functions:

  1. Limit its average upload to a reasonable level.
  2. Intelligently tell peers how long they should wait before retrying.
  3. translate from an info-hash and piece number to a byte range within a file or set of files, and return those bytes.

Another highly desirable function is to check whether peers are retrying too often, and to automatically ban those peers.

Other desirable features include a way of monitoring the tracker the torrent is using and to stop uploading data if sufficient P2P seeds exist, and a way to feed back to the tracker to show a seed is present.

Client-side Implementation Notes

The prototype code base has a default retry time of 30 seconds; after 3 retries with errors, the time is lengthened with each cycle.

The prototype code will not display any errors with contacting http seeds (unless the URL given in the .torrent is incorrect) until it has received data from that seed. (The prototype code also won't display any errors for any http reply that was actually received.)

Current behavior is: Request the rarest piece you're missing in entirety that you can locate. If you have no pieces that aren't partially downloaded, skip one retry cycle, then start requesting partials. If you receive a 503 response, set the retry time equal to the integer value received in the response.