]> Sergey Matveev's repositories - btrtrc.git/commitdiff
Added support for trackerless metainfo files
authorMilos Gajdos <milosgajdos83@gmail.com>
Sun, 3 May 2015 10:30:27 +0000 (11:30 +0100)
committerMilos Gajdos <milosgajdos83@gmail.com>
Sun, 3 May 2015 10:30:27 +0000 (11:30 +0100)
Based on the official spec
(http://www.bittorrent.org/beps/bep_0005.html) trackerless metainfo
files do not contain announce key. Instead nodes key has to be
specified. This PR adds support for nodes key into metainfo package. It
also contains a test metainfo file.

metainfo/_testdata/trackerless.torrent [new file with mode: 0644]
metainfo/builder.go
metainfo/metainfo.go

diff --git a/metainfo/_testdata/trackerless.torrent b/metainfo/_testdata/trackerless.torrent
new file mode 100644 (file)
index 0000000..b90f253
--- /dev/null
@@ -0,0 +1 @@
+d7:comment19:This is just a test10:created by12:Johnny Bravo13:creation datei1430648794e8:encoding5:UTF-84:infod6:lengthi1128e4:name12:testfile.bin12:piece lengthi32768e6:pieces20:Õ\88ë        =\91U\8cäiÎ^æ °Eâ?ÇÒe5:nodesll35:udp://tracker.openbittorrent.com:8035:udp://tracker.openbittorrent.com:80eee
\ No newline at end of file
index b697f88fdc4e65e9cbeefc6146413a7c9de65090..96df1939732165c3d13e9dbcc93ebbbd0aa11bcd 100644 (file)
@@ -67,6 +67,11 @@ func (b *Builder) AddAnnounceGroup(group []string) {
        b.announce_list = append(b.announce_list, group)
 }
 
+// Add DHT nodes URLs for trackerless mode
+func (b *Builder) AddDhtNodes(group []string) {
+       b.node_list = append(b.node_list, group)
+}
+
 // Sets creation date. The default is time.Now() when the .Build method was
 // called.
 func (b *Builder) SetCreationDate(date time.Time) {
@@ -203,20 +208,18 @@ func (b *Builder) check_parameters() error {
                return errors.New("no files were queued")
        }
 
-       // let's clean up the announce_list
-       newal := make([][]string, 0, len(b.announce_list))
-       for _, ag := range b.announce_list {
-               ag = remove_empty_strings(ag)
+       // let's clean up the announce_list and node_list
+       b.announce_list = cleanUpLists(b.announce_list)
+       b.node_list = cleanUpLists(b.node_list)
 
-               // discard empty announce groups
-               if len(ag) == 0 {
-                       continue
-               }
-               newal = append(newal, ag)
+       if len(b.announce_list) == 0 && len(b.node_list) == 0 {
+               return errors.New("no announce group or DHT nodes specified")
        }
-       b.announce_list = newal
-       if len(b.announce_list) == 0 {
-               return errors.New("no announce groups were specified")
+
+       // Either the node_list or announce_list can be present
+       // Never the both!
+       if len(b.announce_list) > 0 && len(b.node_list) > 0 {
+               return errors.New("announce group and nodes are mutually exclusive")
        }
 
        // and clean up the urls
@@ -225,6 +228,20 @@ func (b *Builder) check_parameters() error {
        return nil
 }
 
+func cleanUpLists(list [][]string) [][]string {
+       newList := make([][]string, 0, len(list))
+       for _, l := range list {
+               l = remove_empty_strings(l)
+
+               // discard empty announce groups
+               if len(l) == 0 {
+                       continue
+               }
+               newList = append(newList, l)
+       }
+       return newList
+}
+
 //----------------------------------------------------------------------------
 // Batch
 //----------------------------------------------------------------------------
@@ -346,10 +363,19 @@ func (b *Batch) Start(w io.Writer, nworkers int) (<-chan error, <-chan int64) {
 
 func (b *Batch) write_torrent(w io.Writer) error {
        var td MetaInfo
-       td.Announce = b.announce_list[0][0]
-       if len(b.announce_list) != 1 || len(b.announce_list[0]) != 1 {
-               td.AnnounceList = b.announce_list
+
+       // Either announce or node lists are allowed - not both
+       if len(b.announce_list) != 0 {
+               td.Announce = b.announce_list[0][0]
+               if len(b.announce_list) != 1 || len(b.announce_list[0]) != 1 {
+                       td.AnnounceList = b.announce_list
+               }
+       }
+
+       if len(b.node_list) != 0 {
+               td.Nodes = b.node_list
        }
+
        td.CreationDate = b.creation_date.Unix()
        td.Comment = b.comment
        td.CreatedBy = b.created_by
@@ -420,6 +446,7 @@ type batch_state struct {
        pieces        []byte
        private       bool
        announce_list [][]string
+       node_list     [][]string
        creation_date time.Time
        comment       string
        created_by    string
index 2f15cacce7978689f09893f9595b656d32669ae8..ce3246a5bf092fc727b41183137971aa4f75d6e0 100644 (file)
@@ -144,8 +144,9 @@ func (this InfoEx) MarshalBencode() ([]byte, error) {
 
 type MetaInfo struct {
        Info         InfoEx      `bencode:"info"`
-       Announce     string      `bencode:"announce"`
+       Announce     string      `bencode:"announce,omitempty"`
        AnnounceList [][]string  `bencode:"announce-list,omitempty"`
+       Nodes        [][]string  `bencode:"nodes,omitempty"`
        CreationDate int64       `bencode:"creation date,omitempty"`
        Comment      string      `bencode:"comment,omitempty"`
        CreatedBy    string      `bencode:"created by,omitempty"`