tracker: Shoehorn old client implementations into new tracker Announce interface
This commit is contained in:
parent
4587f61074
commit
f04af72757
@ -15,14 +15,16 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
RegisterClientScheme("http", NewClient)
|
registerClientScheme("http", newHTTPClient)
|
||||||
}
|
}
|
||||||
|
|
||||||
type httpClient struct {
|
type httpClient struct {
|
||||||
url url.URL
|
url url.URL
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewClient(url *url.URL) Client {
|
func (httpClient) Close() error { return nil }
|
||||||
|
|
||||||
|
func newHTTPClient(url *url.URL) client {
|
||||||
return &httpClient{
|
return &httpClient{
|
||||||
url: *url,
|
url: *url,
|
||||||
}
|
}
|
||||||
|
@ -46,27 +46,28 @@ const (
|
|||||||
Stopped // The local peer is leaving the swarm.
|
Stopped // The local peer is leaving the swarm.
|
||||||
)
|
)
|
||||||
|
|
||||||
type Client interface {
|
type client interface {
|
||||||
// Returns ErrNotConnected if Connect needs to be called.
|
// Returns ErrNotConnected if Connect needs to be called.
|
||||||
Announce(*AnnounceRequest) (AnnounceResponse, error)
|
Announce(*AnnounceRequest) (AnnounceResponse, error)
|
||||||
Connect() error
|
Connect() error
|
||||||
String() string
|
String() string
|
||||||
URL() string
|
URL() string
|
||||||
|
Close() error
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ErrNotConnected = errors.New("not connected")
|
ErrNotConnected = errors.New("not connected")
|
||||||
ErrBadScheme = errors.New("unknown scheme")
|
ErrBadScheme = errors.New("unknown scheme")
|
||||||
|
|
||||||
schemes = make(map[string]func(*url.URL) Client)
|
schemes = make(map[string]func(*url.URL) client)
|
||||||
)
|
)
|
||||||
|
|
||||||
func RegisterClientScheme(scheme string, newFunc func(*url.URL) Client) {
|
func registerClientScheme(scheme string, newFunc func(*url.URL) client) {
|
||||||
schemes[scheme] = newFunc
|
schemes[scheme] = newFunc
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns ErrBadScheme if the tracker scheme isn't recognised.
|
// Returns ErrBadScheme if the tracker scheme isn't recognised.
|
||||||
func New(rawurl string) (cl Client, err error) {
|
func new(rawurl string) (cl client, err error) {
|
||||||
url_s, err := url.Parse(rawurl)
|
url_s, err := url.Parse(rawurl)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
@ -79,3 +80,17 @@ func New(rawurl string) (cl Client, err error) {
|
|||||||
cl = newFunc(url_s)
|
cl = newFunc(url_s)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Announce(urlStr string, req *AnnounceRequest) (res AnnounceResponse, err error) {
|
||||||
|
cl, err := new(urlStr)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer cl.Close()
|
||||||
|
err = cl.Connect()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return cl.Announce(req)
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -6,7 +6,7 @@ import (
|
|||||||
|
|
||||||
func TestUnsupportedTrackerScheme(t *testing.T) {
|
func TestUnsupportedTrackerScheme(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
_, err := New("lol://tracker.openbittorrent.com:80/announce")
|
_, err := Announce("lol://tracker.openbittorrent.com:80/announce", nil)
|
||||||
if err != ErrBadScheme {
|
if err != ErrBadScheme {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -61,10 +61,10 @@ type AnnounceResponseHeader struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
RegisterClientScheme("udp", newClient)
|
registerClientScheme("udp", newUDPClient)
|
||||||
}
|
}
|
||||||
|
|
||||||
func newClient(url *url.URL) Client {
|
func newUDPClient(url *url.URL) client {
|
||||||
return &udpClient{
|
return &udpClient{
|
||||||
url: *url,
|
url: *url,
|
||||||
}
|
}
|
||||||
@ -93,6 +93,13 @@ type udpClient struct {
|
|||||||
url url.URL
|
url url.URL
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (me *udpClient) Close() error {
|
||||||
|
if me.socket != nil {
|
||||||
|
return me.socket.Close()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (c *udpClient) URL() string {
|
func (c *udpClient) URL() string {
|
||||||
return c.url.String()
|
return c.url.String()
|
||||||
}
|
}
|
||||||
|
@ -9,10 +9,10 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net"
|
"net"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
|
||||||
"sync"
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
_ "github.com/anacrolix/envpprof"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
@ -102,13 +102,9 @@ func TestAnnounceLocalhost(t *testing.T) {
|
|||||||
srv.pc, err = net.ListenPacket("udp", ":0")
|
srv.pc, err = net.ListenPacket("udp", ":0")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
defer srv.pc.Close()
|
defer srv.pc.Close()
|
||||||
tr, err := New(fmt.Sprintf("udp://%s/announce", srv.pc.LocalAddr().String()))
|
|
||||||
require.NoError(t, err)
|
|
||||||
go func() {
|
go func() {
|
||||||
require.NoError(t, srv.serveOne())
|
require.NoError(t, srv.serveOne())
|
||||||
}()
|
}()
|
||||||
err = tr.Connect()
|
|
||||||
require.NoError(t, err)
|
|
||||||
req := AnnounceRequest{
|
req := AnnounceRequest{
|
||||||
NumWant: -1,
|
NumWant: -1,
|
||||||
Event: Started,
|
Event: Started,
|
||||||
@ -118,7 +114,7 @@ func TestAnnounceLocalhost(t *testing.T) {
|
|||||||
go func() {
|
go func() {
|
||||||
require.NoError(t, srv.serveOne())
|
require.NoError(t, srv.serveOne())
|
||||||
}()
|
}()
|
||||||
ar, err := tr.Announce(&req)
|
ar, err := Announce(fmt.Sprintf("udp://%s/announce", srv.pc.LocalAddr().String()), &req)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.EqualValues(t, 1, ar.Seeders)
|
assert.EqualValues(t, 1, ar.Seeders)
|
||||||
assert.EqualValues(t, 2, len(ar.Peers))
|
assert.EqualValues(t, 2, len(ar.Peers))
|
||||||
@ -126,27 +122,25 @@ func TestAnnounceLocalhost(t *testing.T) {
|
|||||||
|
|
||||||
func TestUDPTracker(t *testing.T) {
|
func TestUDPTracker(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
tr, err := New("udp://tracker.openbittorrent.com:80/announce")
|
|
||||||
require.NoError(t, err)
|
|
||||||
if testing.Short() {
|
if testing.Short() {
|
||||||
t.SkipNow()
|
t.SkipNow()
|
||||||
}
|
}
|
||||||
if err := tr.Connect(); err != nil {
|
// if err := tr.Connect(); err != nil {
|
||||||
if strings.Contains(err.Error(), "no such host") {
|
// if strings.Contains(err.Error(), "no such host") {
|
||||||
t.Skip(err)
|
// t.Skip(err)
|
||||||
}
|
// }
|
||||||
if strings.Contains(err.Error(), "i/o timeout") {
|
// if strings.Contains(err.Error(), "i/o timeout") {
|
||||||
t.Skip(err)
|
// t.Skip(err)
|
||||||
}
|
// }
|
||||||
t.Fatal(err)
|
// t.Fatal(err)
|
||||||
}
|
// }
|
||||||
req := AnnounceRequest{
|
req := AnnounceRequest{
|
||||||
NumWant: -1,
|
NumWant: -1,
|
||||||
// Event: Started,
|
// Event: Started,
|
||||||
}
|
}
|
||||||
rand.Read(req.PeerId[:])
|
rand.Read(req.PeerId[:])
|
||||||
copy(req.InfoHash[:], []uint8{0xa3, 0x56, 0x41, 0x43, 0x74, 0x23, 0xe6, 0x26, 0xd9, 0x38, 0x25, 0x4a, 0x6b, 0x80, 0x49, 0x10, 0xa6, 0x67, 0xa, 0xc1})
|
copy(req.InfoHash[:], []uint8{0xa3, 0x56, 0x41, 0x43, 0x74, 0x23, 0xe6, 0x26, 0xd9, 0x38, 0x25, 0x4a, 0x6b, 0x80, 0x49, 0x10, 0xa6, 0x67, 0xa, 0xc1})
|
||||||
ar, err := tr.Announce(&req)
|
ar, err := Announce("udp://tracker.openbittorrent.com:80/announce", &req)
|
||||||
if ne, ok := err.(net.Error); ok {
|
if ne, ok := err.(net.Error); ok {
|
||||||
if ne.Timeout() {
|
if ne.Timeout() {
|
||||||
t.Skip(err)
|
t.Skip(err)
|
||||||
@ -183,15 +177,7 @@ func TestAnnounceRandomInfoHashThirdParty(t *testing.T) {
|
|||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func(url string) {
|
go func(url string) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
tr, err := New(url)
|
resp, err := Announce(url, &req)
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if err := tr.Connect(); err != nil {
|
|
||||||
t.Log(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
resp, err := tr.Announce(&req)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Logf("error announcing to %s: %s", url, err)
|
t.Logf("error announcing to %s: %s", url, err)
|
||||||
return
|
return
|
||||||
@ -226,19 +212,16 @@ func TestURLPathOption(t *testing.T) {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
cl := newClient(&url.URL{
|
go func() {
|
||||||
|
_, err := Announce((&url.URL{
|
||||||
|
Scheme: "udp",
|
||||||
Host: conn.LocalAddr().String(),
|
Host: conn.LocalAddr().String(),
|
||||||
Path: "/announce",
|
Path: "/announce",
|
||||||
})
|
}).String(), &AnnounceRequest{})
|
||||||
go func() {
|
|
||||||
err = cl.Connect()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
defer conn.Close()
|
||||||
}
|
|
||||||
_, err = cl.Announce(&AnnounceRequest{})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
}
|
||||||
|
require.NoError(t, err)
|
||||||
}()
|
}()
|
||||||
var b [512]byte
|
var b [512]byte
|
||||||
_, addr, _ := conn.ReadFrom(b[:])
|
_, addr, _ := conn.ReadFrom(b[:])
|
||||||
|
Loading…
x
Reference in New Issue
Block a user