From: Matt Joiner Date: Tue, 22 Nov 2016 04:40:46 +0000 (+1100) Subject: tracker: Support the original http response peers format X-Git-Tag: v1.0.0~532 X-Git-Url: http://www.git.stargrave.org/?a=commitdiff_plain;h=389898bb84b81c4e16d4dd1a7da3447246fe9788;p=btrtrc.git tracker: Support the original http response peers format Fixes #130 --- diff --git a/tracker/http.go b/tracker/http.go index 20678b8c..d295fc55 100644 --- a/tracker/http.go +++ b/tracker/http.go @@ -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 index 00000000..e081f639 --- /dev/null +++ b/tracker/http_test.go @@ -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 index 00000000..e7718ef6 --- /dev/null +++ b/tracker/peer.go @@ -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)) +} diff --git a/tracker/tracker.go b/tracker/tracker.go index ed8c42d8..9f14041e 100644 --- a/tracker/tracker.go +++ b/tracker/tracker.go @@ -39,6 +39,7 @@ func (e AnnounceEvent) String() string { type Peer struct { IP net.IP Port int + ID []byte } const (