                   HTTP-BASED SEEDING SPECIFICATION
                   ================================

This specification is for John Hoffman's and DeHackEd's proposed
extension to the BitTorrent metadata format, and for an alternate
protocol for retrieving torrent data from a web server.  This
extension is not official as of this writing.


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.