9 "github.com/anacrolix/log"
11 "github.com/anacrolix/torrent/bencode"
12 "github.com/anacrolix/torrent/metainfo"
15 // Add HTTP endpoints that serve the metainfo. They will be used if the torrent info isn't obtained
16 // yet. The Client HTTP client is used.
17 func (t *Torrent) UseSources(sources []string) {
25 for _, s := range sources {
26 _, loaded := t.activeSources.LoadOrStore(s, struct{}{})
32 err := t.useActiveTorrentSource(s)
33 _, loaded := t.activeSources.LoadAndDelete(s)
38 if err != nil && !errors.Is(err, context.Canceled) {
41 t.logger.Levelf(level, "used torrent source %q [err=%v]", s, err)
46 func (t *Torrent) useActiveTorrentSource(source string) error {
47 ctx, cancel := context.WithCancel(context.Background())
57 mi, err := getTorrentSource(ctx, source, t.cl.httpClient)
61 return t.MergeSpec(TorrentSpecFromMetaInfo(&mi))
64 func getTorrentSource(ctx context.Context, source string, hc *http.Client) (mi metainfo.MetaInfo, err error) {
66 if req, err = http.NewRequestWithContext(ctx, http.MethodGet, source, nil); err != nil {
69 var resp *http.Response
70 if resp, err = hc.Do(req); err != nil {
73 defer resp.Body.Close()
74 if resp.StatusCode != http.StatusOK {
75 err = fmt.Errorf("unexpected response status code: %v", resp.StatusCode)
78 err = bencode.NewDecoder(resp.Body).Decode(&mi)