"errors"
"fmt"
"io"
- "net"
"net/http"
"net/url"
"strconv"
}
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) {
--- /dev/null
+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)
+}
--- /dev/null
+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))
+}
type Peer struct {
IP net.IP
Port int
+ ID []byte
}
const (