]> Sergey Matveev's repositories - btrtrc.git/commitdiff
tracker: Support the original http response peers format
authorMatt Joiner <anacrolix@gmail.com>
Tue, 22 Nov 2016 04:40:46 +0000 (15:40 +1100)
committerMatt Joiner <anacrolix@gmail.com>
Tue, 22 Nov 2016 04:40:46 +0000 (15:40 +1100)
Fixes #130

tracker/http.go
tracker/http_test.go [new file with mode: 0644]
tracker/peer.go [new file with mode: 0644]
tracker/tracker.go

index 20678b8c1d90ac0f734b27c4dbe454ee13422a24..d295fc55d9faebdfc37839cc32c18ddc19e55eae 100644 (file)
@@ -5,7 +5,6 @@ import (
        "errors"
        "fmt"
        "io"
-       "net"
        "net/http"
        "net/url"
        "strconv"
@@ -26,20 +25,32 @@ type httpResponse struct {
 }
 
 func (r *httpResponse) UnmarshalPeers() (ret []Peer, err error) {
-       s, ok := r.Peers.(string)
-       if !ok {
-               err = fmt.Errorf("unsupported peers value type: %T", r.Peers)
+       switch v := r.Peers.(type) {
+       case string:
+               var cps []util.CompactPeer
+               cps, err = util.UnmarshalIPv4CompactPeers([]byte(v))
+               if err != nil {
+                       return
+               }
+               ret = make([]Peer, 0, len(cps))
+               for _, cp := range cps {
+                       ret = append(ret, Peer{
+                               IP:   cp.IP[:],
+                               Port: int(cp.Port),
+                       })
+               }
                return
-       }
-       cp, err := util.UnmarshalIPv4CompactPeers([]byte(s))
-       if err != nil {
+       case []interface{}:
+               for _, i := range v {
+                       var p Peer
+                       p.fromDictInterface(i.(map[string]interface{}))
+                       ret = append(ret, p)
+               }
+               return
+       default:
+               err = fmt.Errorf("unsupported peers value type: %T", r.Peers)
                return
        }
-       ret = make([]Peer, 0, len(cp))
-       for _, p := range cp {
-               ret = append(ret, Peer{net.IP(p.IP[:]), int(p.Port)})
-       }
-       return
 }
 
 func setAnnounceParams(_url *url.URL, ar *AnnounceRequest) {
diff --git a/tracker/http_test.go b/tracker/http_test.go
new file mode 100644 (file)
index 0000000..e081f63
--- /dev/null
@@ -0,0 +1,26 @@
+package tracker
+
+import (
+       "testing"
+
+       "github.com/stretchr/testify/assert"
+       "github.com/stretchr/testify/require"
+
+       "github.com/anacrolix/torrent/bencode"
+)
+
+func TestUnmarshalHTTPResponsePeerDicts(t *testing.T) {
+       var hr httpResponse
+       require.NoError(t, bencode.Unmarshal([]byte("d5:peersl"+
+               "d2:ip7:1.2.3.47:peer id20:thisisthe20bytepeeri4:porti9999ee"+
+               "d7:peer id20:thisisthe20bytepeeri2:ip39:2001:0db8:85a3:0000:0000:8a2e:0370:73344:porti9998ee"+
+               "ee"), &hr))
+       ps, err := hr.UnmarshalPeers()
+       require.NoError(t, err)
+       require.Len(t, ps, 2)
+       assert.Equal(t, []byte("thisisthe20bytepeeri"), ps[0].ID)
+       assert.EqualValues(t, 9999, ps[0].Port)
+       assert.EqualValues(t, 9998, ps[1].Port)
+       assert.NotNil(t, ps[0].IP)
+       assert.NotNil(t, ps[1].IP)
+}
diff --git a/tracker/peer.go b/tracker/peer.go
new file mode 100644 (file)
index 0000000..e7718ef
--- /dev/null
@@ -0,0 +1,11 @@
+package tracker
+
+import (
+       "net"
+)
+
+func (p *Peer) fromDictInterface(d map[string]interface{}) {
+       p.IP = net.ParseIP(d["ip"].(string))
+       p.ID = []byte(d["peer id"].(string))
+       p.Port = int(d["port"].(int64))
+}
index ed8c42d80009426658d1f2dcfcdde8cc53240fc7..9f14041e72e236c5eb8af1cfbd2c2992f65d7f05 100644 (file)
@@ -39,6 +39,7 @@ func (e AnnounceEvent) String() string {
 type Peer struct {
        IP   net.IP
        Port int
+       ID   []byte
 }
 
 const (