]> Sergey Matveev's repositories - btrtrc.git/commitdiff
tracker: Support peers6 key in http responses
authorMatt Joiner <anacrolix@gmail.com>
Mon, 12 Feb 2018 13:23:07 +0000 (00:23 +1100)
committerMatt Joiner <anacrolix@gmail.com>
Mon, 12 Feb 2018 13:23:07 +0000 (00:23 +1100)
tracker/http.go
tracker/http_test.go

index d207f85268435ef30db2d370d688d61daa510f06..6c9dcafc96157beaf586fbbff9fe98d609983425 100644 (file)
@@ -16,39 +16,50 @@ import (
 )
 
 type httpResponse struct {
-       FailureReason string      `bencode:"failure reason"`
-       Interval      int32       `bencode:"interval"`
-       TrackerId     string      `bencode:"tracker id"`
-       Complete      int32       `bencode:"complete"`
-       Incomplete    int32       `bencode:"incomplete"`
-       Peers         interface{} `bencode:"peers"`
+       FailureReason string `bencode:"failure reason"`
+       Interval      int32  `bencode:"interval"`
+       TrackerId     string `bencode:"tracker id"`
+       Complete      int32  `bencode:"complete"`
+       Incomplete    int32  `bencode:"incomplete"`
+       Peers         Peers  `bencode:"peers"`
+       // BEP 7
+       Peers6 krpc.CompactIPv6NodeAddrs `bencode:"peers6"`
 }
 
-func (r *httpResponse) UnmarshalPeers() (ret []Peer, err error) {
-       switch v := r.Peers.(type) {
+type Peers []Peer
+
+func (me *Peers) UnmarshalBencode(b []byte) (err error) {
+       var _v interface{}
+       err = bencode.Unmarshal(b, &_v)
+       if err != nil {
+               return
+       }
+       switch v := _v.(type) {
        case string:
-               var cps krpc.CompactIPv4NodeAddrs
-               err = cps.UnmarshalBinary([]byte(v))
+               vars.Add("http responses with string peers", 1)
+               var cnas krpc.CompactIPv4NodeAddrs
+               err = cnas.UnmarshalBinary([]byte(v))
                if err != nil {
                        return
                }
-               ret = make([]Peer, 0, len(cps))
-               for _, cp := range cps {
-                       ret = append(ret, Peer{
+               for _, cp := range cnas {
+                       *me = append(*me, Peer{
                                IP:   cp.IP[:],
                                Port: int(cp.Port),
                        })
                }
                return
        case []interface{}:
+               vars.Add("http responses with list peers", 1)
                for _, i := range v {
                        var p Peer
                        p.fromDictInterface(i.(map[string]interface{}))
-                       ret = append(ret, p)
+                       *me = append(*me, p)
                }
                return
        default:
-               err = fmt.Errorf("unsupported peers value type: %T", r.Peers)
+               vars.Add("http responses with unhandled peers type", 1)
+               err = fmt.Errorf("unsupported type: %T", _v)
                return
        }
 }
@@ -100,9 +111,22 @@ func announceHTTP(cl *http.Client, userAgent string, ar *AnnounceRequest, _url *
                err = errors.New(trackerResponse.FailureReason)
                return
        }
+       vars.Add("successful http announces", 1)
        ret.Interval = trackerResponse.Interval
        ret.Leechers = trackerResponse.Incomplete
        ret.Seeders = trackerResponse.Complete
-       ret.Peers, err = trackerResponse.UnmarshalPeers()
+       if len(trackerResponse.Peers) != 0 {
+               vars.Add("http responses with nonempty peers key", 1)
+       }
+       ret.Peers = trackerResponse.Peers
+       if len(trackerResponse.Peers6) != 0 {
+               vars.Add("http responses with nonempty peers6 key", 1)
+       }
+       for _, na := range trackerResponse.Peers6 {
+               ret.Peers = append(ret.Peers, Peer{
+                       IP:   na.IP,
+                       Port: na.Port,
+               })
+       }
        return
 }
index d658d62c218990fbff12dfa9942a63ebf3a411f6..c90a35ef5e11b362dab3afad799f994472e95cb2 100644 (file)
@@ -13,16 +13,41 @@ var defaultHTTPUserAgent = "Go-Torrent"
 
 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)
+       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"+
+                       "e"+
+                       "6:peers618:123412341234123456"+
+                       "e"),
+               &hr))
+
+       require.Len(t, hr.Peers, 2)
+       assert.Equal(t, []byte("thisisthe20bytepeeri"), hr.Peers[0].ID)
+       assert.EqualValues(t, 9999, hr.Peers[0].Port)
+       assert.EqualValues(t, 9998, hr.Peers[1].Port)
+       assert.NotNil(t, hr.Peers[0].IP)
+       assert.NotNil(t, hr.Peers[1].IP)
+
+       assert.Len(t, hr.Peers6, 1)
+       assert.EqualValues(t, "1234123412341234", hr.Peers6[0].IP)
+       assert.EqualValues(t, 0x3536, hr.Peers6[0].Port)
+}
+
+func TestUnmarshalHttpResponseNoPeers(t *testing.T) {
+       var hr httpResponse
+       require.NoError(t, bencode.Unmarshal(
+               []byte("d6:peers618:123412341234123456e"),
+               &hr,
+       ))
+       require.Len(t, hr.Peers, 0)
+       assert.Len(t, hr.Peers6, 1)
+}
+
+func TestUnmarshalHttpResponsePeers6NotCompact(t *testing.T) {
+       var hr httpResponse
+       require.Error(t, bencode.Unmarshal(
+               []byte("d6:peers6lee"),
+               &hr,
+       ))
 }