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