2020-04-06 13:38:01 +08:00
|
|
|
package torrent
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
2021-12-14 23:57:19 +08:00
|
|
|
"github.com/anacrolix/log"
|
|
|
|
"github.com/anacrolix/torrent/tracker/http"
|
|
|
|
"github.com/gorilla/websocket"
|
2020-04-06 13:38:01 +08:00
|
|
|
"net/url"
|
2020-04-21 16:08:43 +08:00
|
|
|
"sync"
|
2020-04-06 14:45:47 +08:00
|
|
|
|
2020-04-21 16:08:43 +08:00
|
|
|
"github.com/anacrolix/torrent/tracker"
|
2020-04-06 14:45:47 +08:00
|
|
|
"github.com/anacrolix/torrent/webtorrent"
|
2020-04-21 16:08:43 +08:00
|
|
|
"github.com/pion/datachannel"
|
2020-04-06 13:38:01 +08:00
|
|
|
)
|
|
|
|
|
2020-04-22 09:42:31 +08:00
|
|
|
type websocketTrackerStatus struct {
|
2020-04-06 13:38:01 +08:00
|
|
|
url url.URL
|
2020-04-22 09:42:31 +08:00
|
|
|
tc *webtorrent.TrackerClient
|
2020-04-06 13:38:01 +08:00
|
|
|
}
|
|
|
|
|
2020-04-22 09:42:31 +08:00
|
|
|
func (me websocketTrackerStatus) statusLine() string {
|
2020-04-28 07:13:44 +08:00
|
|
|
return fmt.Sprintf("%+v", me.tc.Stats())
|
2020-04-06 13:38:01 +08:00
|
|
|
}
|
|
|
|
|
2020-04-28 07:13:44 +08:00
|
|
|
func (me websocketTrackerStatus) URL() *url.URL {
|
|
|
|
return &me.url
|
2020-04-06 13:38:01 +08:00
|
|
|
}
|
2020-04-21 16:08:43 +08:00
|
|
|
|
|
|
|
type refCountedWebtorrentTrackerClient struct {
|
|
|
|
webtorrent.TrackerClient
|
|
|
|
refCount int
|
|
|
|
}
|
|
|
|
|
|
|
|
type websocketTrackers struct {
|
|
|
|
PeerId [20]byte
|
|
|
|
Logger log.Logger
|
2020-05-02 16:36:32 +08:00
|
|
|
GetAnnounceRequest func(event tracker.AnnounceEvent, infoHash [20]byte) (tracker.AnnounceRequest, error)
|
2020-04-21 16:08:43 +08:00
|
|
|
OnConn func(datachannel.ReadWriteCloser, webtorrent.DataChannelContext)
|
|
|
|
mu sync.Mutex
|
|
|
|
clients map[string]*refCountedWebtorrentTrackerClient
|
2021-12-14 23:57:19 +08:00
|
|
|
Proxy http.ProxyFunc
|
2020-04-21 16:08:43 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
func (me *websocketTrackers) Get(url string) (*webtorrent.TrackerClient, func()) {
|
|
|
|
me.mu.Lock()
|
|
|
|
defer me.mu.Unlock()
|
|
|
|
value, ok := me.clients[url]
|
|
|
|
if !ok {
|
2021-12-14 23:57:19 +08:00
|
|
|
dialer := &websocket.Dialer{Proxy: me.Proxy, HandshakeTimeout: websocket.DefaultDialer.HandshakeTimeout}
|
2020-04-21 16:08:43 +08:00
|
|
|
value = &refCountedWebtorrentTrackerClient{
|
|
|
|
TrackerClient: webtorrent.TrackerClient{
|
2021-12-14 23:57:19 +08:00
|
|
|
Dialer: dialer,
|
2020-04-21 16:08:43 +08:00
|
|
|
Url: url,
|
|
|
|
GetAnnounceRequest: me.GetAnnounceRequest,
|
|
|
|
PeerId: me.PeerId,
|
|
|
|
OnConn: me.OnConn,
|
|
|
|
Logger: me.Logger.WithText(func(m log.Msg) string {
|
|
|
|
return fmt.Sprintf("tracker client for %q: %v", url, m)
|
|
|
|
}),
|
|
|
|
},
|
|
|
|
}
|
2021-10-25 13:15:42 +08:00
|
|
|
value.TrackerClient.Start(func(err error) {
|
2020-04-21 16:08:43 +08:00
|
|
|
if err != nil {
|
|
|
|
me.Logger.Printf("error running tracker client for %q: %v", url, err)
|
|
|
|
}
|
2021-10-25 13:15:42 +08:00
|
|
|
})
|
2020-04-21 16:08:43 +08:00
|
|
|
if me.clients == nil {
|
|
|
|
me.clients = make(map[string]*refCountedWebtorrentTrackerClient)
|
|
|
|
}
|
|
|
|
me.clients[url] = value
|
|
|
|
}
|
|
|
|
value.refCount++
|
|
|
|
return &value.TrackerClient, func() {
|
|
|
|
me.mu.Lock()
|
|
|
|
defer me.mu.Unlock()
|
|
|
|
value.refCount--
|
|
|
|
if value.refCount == 0 {
|
|
|
|
value.TrackerClient.Close()
|
|
|
|
delete(me.clients, url)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|