tracker

package module
v0.0.0-...-5f5d79f Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 20, 2024 License: MIT Imports: 28 Imported by: 0

README

tracker

This is a BitTorrent tracker that relies on PostgreSQL for persistence. All announced torrents will be tracked automatically. The HTTP server provides a torrent index list with magnet metadata support on the / route by default.

Features

  • HTTP Tracker: Allows tracking of torrents over HTTP.
  • Compact Peer Format: Utilizes a compact format for representing peers in the tracker.
  • Scrape: Supports scraping information from the tracker.
  • UDP Tracker
  • IPv6

Environment Variables

  • ADDRESS (default: 0.0.0.0:9999): Specifies the address and port for the tracker.
  • ANNOUNCE_URL (default: http://localhost:9999/announce): Used for magnet links in the index view.
  • DSN (default: postgres://tracker:tracker@localhost:5432/tracker): PostgreSQL connection string.
  • TEMPLATE_PATH (default: ../templates/): Path to the template files.
  • STATIC_PATH (default: ../static/): Path to static files.

Installation

Local
  1. Run go mod download && go build -v -o ./dist/tracker ./cmd.
  2. The application can be found under the dist directory.
Docker
  1. Configure the environment variables under the backend block in docker-compose.yml.
  2. Run docker compose up.

Documentation

Index

Constants

View Source
const (
	TemplateIndex = iota
	TemplateTorrent
)

Variables

This section is empty.

Functions

func AnnounceHandler

func AnnounceHandler(server *Server) http.HandlerFunc

func HealthHandler

func HealthHandler() http.HandlerFunc

func IndexHandler

func IndexHandler(server *Server) http.HandlerFunc

func NewTemplateStore

func NewTemplateStore() *templateStore

Create new template store.

func NewTorrentStore

func NewTorrentStore(pool *pgxpool.Pool) *torrentStore

func PlaintextMiddleware

func PlaintextMiddleware(next http.Handler) http.Handler

Middleware for setting Content-Type to charset=ISO-8859-1.

func ScrapeHandler

func ScrapeHandler(server *Server) http.HandlerFunc

func TorrentHandler

func TorrentHandler(server *Server) http.HandlerFunc

Types

type AnnounceRequest

type AnnounceRequest struct {
	InfoHash []byte `db:"info_hash" validate:"required,ascii"`
	PeerID   []byte `db:"peer_id" validate:"required,ascii,len=20"`
	Event    string `db:"event" validate:"ascii"`
	IP       string `db:"ip" validate:"required,ip"`
	Port     int    `db:"port" validate:"required,number"`
	Key      string `db:"key" validate:"ascii"`

	Uploaded   int `db:"uploaded" validate:"number"`
	Downloaded int `db:"downloaded" validate:"number"`
	Left       int `db:"left" validate:"number"`
}

type AnnounceResponse

type AnnounceResponse struct {
	Interval    int    `bencode:"interval"`
	MinInterval int    `bencode:"min interval"`
	Complete    int    `bencode:"complete"`
	Incomplete  int    `bencode:"incomplete"`
	Peers       string `bencode:"peers"`
}

type ErrorResponse

type ErrorResponse struct {
	FailureReason string `bencode:"failure reason"`
}

type Peer

type Peer struct {
	ID         uuid.UUID `db:"id"`
	TorrentID  uuid.UUID `db:"torrent_id"`
	PeerID     []byte    `db:"peer_id"`
	Port       int       `db:"port"`
	Uploaded   int       `db:"uploaded"`
	Downloaded int       `db:"downloaded"`
	Left       int       `db:"left"`
	Key        string    `db:"key"`
	IP         net.IP    `db:"ip"`
	UpdatedAt  time.Time `db:"updated_at"`
	Event      string    `db:"event"`
}

func (*Peer) Client

func (peer *Peer) Client() string

Tries to return client type based on peer_id

func (*Peer) Marshal

func (peer *Peer) Marshal() ([]byte, error)

type ScrapeResponse

type ScrapeResponse struct {
	Files map[string]ScrapeTorrent `bencode:"files"`
}

type ScrapeTorrent

type ScrapeTorrent struct {
	Complete   int `bencode:"complete"`
	Incomplete int `bencode:"incomplete"`
	Downloaded int `bencode:"downloaded"`
}

type Server

type Server struct {
	// contains filtered or unexported fields
}

func NewServer

func NewServer(config *ServerConfig) *Server

func (*Server) CacheTemplates

func (sv *Server) CacheTemplates()

func (*Server) RunTask

func (sv *Server) RunTask(d time.Duration, f func(ts TorrentStorable))

Creates a goroutine that runs function f every duration d. ts gives access to the store.

type ServerConfig

type ServerConfig struct {
	Address      string
	AnnounceURL  string
	DSN          string
	TemplatePath string
}

func NewServerConfig

func NewServerConfig(address string, announceURL string, dsn string, templatePath string) *ServerConfig

type TemplateID

type TemplateID int

type Templater

type Templater interface {
	// Add template to cache.
	Add(ID TemplateID, template *template.Template)
	// Execute template from cache using data.
	Execute(ID TemplateID, wr io.Writer, data any) error
}

type Torrent

type Torrent struct {
	ID        uuid.UUID `db:"id" json:"id"`
	InfoHash  []byte    `db:"info_hash" json:"info_hash"`
	Completed int       `db:"completed" json:"completed"`
	CreatedAt time.Time `db:"created_at" json:"created_at"`

	Seeders  int `db:"seeders" json:"seeders"`
	Leechers int `db:"leechers" json:"leechers"`
}

func (*Torrent) MarshalJSON

func (t *Torrent) MarshalJSON() ([]byte, error)

type TorrentStorable

type TorrentStorable interface {
	// Add torrent to store.
	AddTorrent(ctx context.Context, infoHash []byte) (Torrent, error)
	// Get torrent from store.
	Torrent(ctx context.Context, infoHash []byte) (Torrent, error)
	// Increments torrentID completed property by one.
	IncrementTorrent(ctx context.Context, torrentID uuid.UUID) error
	// Get all torrents in store.
	Torrents(ctx context.Context) ([]Torrent, error)
	Scrape(ctx context.Context, hashes [][]byte) ([]Torrent, error)
	// Get all peers for torrentID.
	Peers(ctx context.Context, torrentID uuid.UUID) ([]Peer, error)
	// Try to update peer which already exist in the store.
	// Operation success is denoted by bool.
	UpdatePeerWithKey(ctx context.Context, torrentID uuid.UUID, req AnnounceRequest) (bool, error)
	// Update or insert peer to store.
	UpsertPeer(ctx context.Context, torrentID uuid.UUID, req AnnounceRequest) error
	// Remove stale peers that have not announced in interval.
	CleanPeers(ctx context.Context, interval time.Duration) (int, error)
	// Log announce request.
	Log(ctx context.Context, req AnnounceRequest) error
	// Test store connection.
	Ping(ctx context.Context) (bool, error)
}

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL