1 package httpTrackerServer
10 "github.com/anacrolix/dht/v2/krpc"
11 "github.com/anacrolix/log"
13 "github.com/anacrolix/torrent/bencode"
14 "github.com/anacrolix/torrent/tracker"
15 httpTracker "github.com/anacrolix/torrent/tracker/http"
16 udpTrackerServer "github.com/anacrolix/torrent/tracker/udp/server"
20 AnnounceTracker udpTrackerServer.AnnounceTracker
23 func unmarshalQueryKeyToArray(w http.ResponseWriter, key string, query url.Values) (ret [20]byte, ok bool) {
25 if len(str) != len(ret) {
26 http.Error(w, fmt.Sprintf("%v has wrong length", key), http.StatusBadRequest)
34 func (me Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
36 var event tracker.AnnounceEvent
37 err := event.UnmarshalText([]byte(vs.Get("event")))
39 http.Error(w, err.Error(), http.StatusBadRequest)
42 infoHash, ok := unmarshalQueryKeyToArray(w, "info_hash", vs)
46 peerId, ok := unmarshalQueryKeyToArray(w, "peer_id", vs)
50 host, _, err := net.SplitHostPort(r.RemoteAddr)
52 log.Printf("error splitting remote port: %v", err)
53 http.Error(w, "error determining your IP", http.StatusInternalServerError)
56 addrPort, err := netip.ParseAddrPort(net.JoinHostPort(host, vs.Get("port")))
57 err = me.AnnounceTracker.TrackAnnounce(r.Context(), tracker.AnnounceRequest{
61 Port: addrPort.Port(),
64 log.Printf("error tracking announce: %v", err)
65 http.Error(w, "error tracking announce", http.StatusInternalServerError)
68 peers, err := me.AnnounceTracker.GetPeers(r.Context(), infoHash, tracker.GetPeersOpts{})
70 log.Printf("error getting peers: %v", err)
71 http.Error(w, "error getting peers", http.StatusInternalServerError)
74 var resp httpTracker.HttpResponse
75 resp.Interval = 5 * 60
76 resp.Peers.Compact = true
77 for _, peer := range peers {
78 if peer.Addr().Is4() {
79 resp.Peers.List = append(resp.Peers.List, tracker.Peer{
80 IP: peer.Addr().AsSlice(),
81 Port: int(peer.Port()),
83 } else if peer.Addr().Is6() {
84 resp.Peers6 = append(resp.Peers6, krpc.NodeAddr{
85 IP: peer.Addr().AsSlice(),
86 Port: int(peer.Port()),
90 err = bencode.NewEncoder(w).Encode(resp)
92 log.Printf("error encoding and writing response body: %v", err)