]> Sergey Matveev's repositories - btrtrc.git/blob - tracker/tracker.go
gofumpt
[btrtrc.git] / tracker / tracker.go
1 package tracker
2
3 import (
4         "context"
5         "errors"
6         "net/http"
7         "net/url"
8         "time"
9
10         "github.com/anacrolix/dht/v2/krpc"
11         trHttp "github.com/anacrolix/torrent/tracker/http"
12         "github.com/anacrolix/torrent/tracker/shared"
13         "github.com/anacrolix/torrent/tracker/udp"
14 )
15
16 const (
17         None      = shared.None
18         Started   = shared.Started
19         Stopped   = shared.Stopped
20         Completed = shared.Completed
21 )
22
23 type AnnounceRequest = udp.AnnounceRequest
24
25 type AnnounceResponse = trHttp.AnnounceResponse
26
27 type Peer = trHttp.Peer
28
29 type AnnounceEvent = udp.AnnounceEvent
30
31 var ErrBadScheme = errors.New("unknown scheme")
32
33 type Announce struct {
34         TrackerUrl string
35         Request    AnnounceRequest
36         HostHeader string
37         HTTPProxy  func(*http.Request) (*url.URL, error)
38         ServerName string
39         UserAgent  string
40         UdpNetwork string
41         // If the port is zero, it's assumed to be the same as the Request.Port.
42         ClientIp4 krpc.NodeAddr
43         // If the port is zero, it's assumed to be the same as the Request.Port.
44         ClientIp6 krpc.NodeAddr
45         Context   context.Context
46 }
47
48 // The code *is* the documentation.
49 const DefaultTrackerAnnounceTimeout = 15 * time.Second
50
51 func (me Announce) Do() (res AnnounceResponse, err error) {
52         cl, err := NewClient(me.TrackerUrl, NewClientOpts{
53                 Http: trHttp.NewClientOpts{
54                         Proxy:      me.HTTPProxy,
55                         ServerName: me.ServerName,
56                 },
57                 UdpNetwork: me.UdpNetwork,
58         })
59         if err != nil {
60                 return
61         }
62         defer cl.Close()
63         if me.Context == nil {
64                 // This is just to maintain the old behaviour that should be a timeout of 15s. Users can
65                 // override it by providing their own Context. See comments elsewhere about longer timeouts
66                 // acting as rate limiting overloaded trackers.
67                 ctx, cancel := context.WithTimeout(context.Background(), DefaultTrackerAnnounceTimeout)
68                 defer cancel()
69                 me.Context = ctx
70         }
71         return cl.Announce(me.Context, me.Request, trHttp.AnnounceOpt{
72                 UserAgent:  me.UserAgent,
73                 HostHeader: me.HostHeader,
74                 ClientIp4:  me.ClientIp4.IP,
75                 ClientIp6:  me.ClientIp6.IP,
76         })
77 }