github.com/anacrolix/torrent@v1.61.0/tracker/http/protocol.go (about) 1 package httpTracker 2 3 import ( 4 "fmt" 5 6 "github.com/anacrolix/dht/v2/krpc" 7 8 "github.com/anacrolix/torrent/bencode" 9 ) 10 11 type HttpResponse struct { 12 FailureReason string `bencode:"failure reason"` 13 Interval int32 `bencode:"interval"` 14 TrackerId string `bencode:"tracker id"` 15 Complete int32 `bencode:"complete"` 16 Incomplete int32 `bencode:"incomplete"` 17 Peers Peers `bencode:"peers"` 18 // BEP 7 19 Peers6 krpc.CompactIPv6NodeAddrs `bencode:"peers6"` 20 } 21 22 type Peers struct { 23 List []Peer 24 Compact bool 25 } 26 27 func (me Peers) MarshalBencode() ([]byte, error) { 28 if me.Compact { 29 cnas := make([]krpc.NodeAddr, 0, len(me.List)) 30 for _, peer := range me.List { 31 cnas = append(cnas, krpc.NodeAddr{ 32 IP: peer.IP, 33 Port: peer.Port, 34 }) 35 } 36 return krpc.CompactIPv4NodeAddrs(cnas).MarshalBencode() 37 } else { 38 return bencode.Marshal(me.List) 39 } 40 } 41 42 var ( 43 _ bencode.Unmarshaler = (*Peers)(nil) 44 _ bencode.Marshaler = Peers{} 45 ) 46 47 func (me *Peers) UnmarshalBencode(b []byte) (err error) { 48 var _v interface{} 49 err = bencode.Unmarshal(b, &_v) 50 if err != nil { 51 return 52 } 53 switch v := _v.(type) { 54 case string: 55 vars.Add("http responses with string peers", 1) 56 var cnas krpc.CompactIPv4NodeAddrs 57 err = cnas.UnmarshalBinary([]byte(v)) 58 if err != nil { 59 return 60 } 61 me.Compact = true 62 for _, cp := range cnas { 63 me.List = append(me.List, Peer{ 64 IP: cp.IP[:], 65 Port: cp.Port, 66 }) 67 } 68 return 69 case []interface{}: 70 vars.Add("http responses with list peers", 1) 71 me.Compact = false 72 for _, i := range v { 73 var p Peer 74 p.FromDictInterface(i.(map[string]interface{})) 75 me.List = append(me.List, p) 76 } 77 return 78 default: 79 vars.Add("http responses with unhandled peers type", 1) 80 err = fmt.Errorf("unsupported type: %T", _v) 81 return 82 } 83 }