package handler import ( "bytes" "context" "encoding/json" "fmt" "io" "io/ioutil" "net/http" "time" ) func (h Handler) vpntor(ctx context.Context, r io.Reader) error { var form struct { Magnet string Dir string URL string } if err := json.NewDecoder(r).Decode(&form); err != nil { return err } if form.Magnet == "" || form.Dir == "" || form.URL == "" { return fmt.Errorf("did not specify all of .Magnet, .Dir, .URL") } c := http.Client{ Timeout: time.Minute, Transport: &http.Transport{DisableKeepAlives: true}, } sresp, err := c.Get(form.URL) if err != nil { return err } defer sresp.Body.Close() defer io.Copy(io.Discard, sresp.Body) b, _ := json.Marshal(map[string]any{ "method": "torrent-add", "arguments": map[string]string{ "filename": form.Magnet, "download-dir": form.Dir, }, }) req, err := http.NewRequest(http.MethodPost, form.URL, bytes.NewReader(b)) if err != nil { return err } req = req.WithContext(ctx) req.Header.Add("X-Transmission-Session-Id", sresp.Header.Get("X-Transmission-Session-Id")) resp, err := c.Do(req) if err != nil { return err } defer resp.Body.Close() defer io.Copy(io.Discard, resp.Body) if b, _ := ioutil.ReadAll(resp.Body); resp.StatusCode > 220 || !bytes.Contains(b, []byte(`success`)) { return fmt.Errorf("(%d) %s", resp.StatusCode, b) } return nil }