]> Sergey Matveev's repositories - btrtrc.git/blob - sources.go
Separate torrent sources source file
[btrtrc.git] / sources.go
1 package torrent
2
3 import (
4         "context"
5         "net/http"
6
7         "github.com/anacrolix/log"
8         "github.com/anacrolix/torrent/bencode"
9         "github.com/anacrolix/torrent/metainfo"
10 )
11
12 func (t *Torrent) useSources(sources []string) {
13         select {
14         case <-t.Closed():
15                 return
16         case <-t.GotInfo():
17                 return
18         default:
19         }
20         for _, s := range sources {
21                 _, loaded := t.activeSources.LoadOrStore(s, struct{}{})
22                 if loaded {
23                         continue
24                 }
25                 s := s
26                 go func() {
27                         err := t.useActiveTorrentSource(s)
28                         _, loaded := t.activeSources.LoadAndDelete(s)
29                         if !loaded {
30                                 panic(s)
31                         }
32                         level := log.Debug
33                         if err != nil {
34                                 level = log.Warning
35                         }
36                         t.logger.Levelf(level, "used torrent source %q [err=%q]", s, err)
37                 }()
38         }
39 }
40
41 func (t *Torrent) useActiveTorrentSource(source string) error {
42         ctx, cancel := context.WithCancel(context.Background())
43         defer cancel()
44         go func() {
45                 select {
46                 case <-t.GotInfo():
47                 case <-t.Closed():
48                 case <-ctx.Done():
49                 }
50                 cancel()
51         }()
52         mi, err := getTorrentSource(ctx, source, t.cl.httpClient)
53         if err != nil {
54                 return err
55         }
56         return t.MergeSpec(TorrentSpecFromMetaInfo(&mi))
57 }
58
59 func getTorrentSource(ctx context.Context, source string, hc *http.Client) (mi metainfo.MetaInfo, err error) {
60         var req *http.Request
61         if req, err = http.NewRequestWithContext(ctx, http.MethodGet, source, nil); err != nil {
62                 return
63         }
64         var resp *http.Response
65         if resp, err = hc.Do(req); err != nil {
66                 return
67         }
68         defer resp.Body.Close()
69         err = bencode.NewDecoder(resp.Body).Decode(&mi)
70         return
71 }