github.com/anacrolix/torrent@v1.61.0/tracker/tracker.go (about)

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