package main import ( "encoding/json" "fmt" "net/http" "net/http/cookiejar" "net/url" "os" ) type HTTPClient struct { client *http.Client basePath string jar *cookiejar.Jar } func NewHTTPClient(basePath string) *HTTPClient { jar, err := cookiejar.New(nil) if err != nil { panic(err) } return &HTTPClient{ client: &http.Client{Jar: jar}, basePath: basePath, jar: jar, } } func (c *HTTPClient) Get(subPath string, query map[string]string) (*http.Response, error) { combined, err := url.JoinPath(c.basePath, subPath) if err != nil { return nil, err } parsed, err := url.Parse(combined) if err != nil { return nil, err } if query != nil { q := parsed.Query() for k, v := range query { q.Set(k, v) } parsed.RawQuery = q.Encode() } return c.client.Get(parsed.String()) } func (c *HTTPClient) PostForm(subPath string, data map[string][]string) (*http.Response, error) { url, err := url.JoinPath(c.basePath, subPath) if err != nil { return nil, err } return c.client.PostForm(url, data) } func (c *HTTPClient) Login(username string, password string) error { resp, err := c.PostForm("/api/v2/auth/login", map[string][]string{"username": {username}, "password": {password}}) if err != nil { return err } if resp.StatusCode != 200 { return fmt.Errorf("unexpected status code: %d", resp.StatusCode) } setCookie := resp.Header.Get("Set-Cookie") if setCookie == "" { return fmt.Errorf("no Set-Cookie in response header") } jarCookie := c.jar.Cookies(resp.Request.URL) if len(jarCookie) == 0 { return fmt.Errorf("no cookie saved to cookiejar") } return nil } func main() { basePath := os.Getenv("TORRENT_BASEPATH") username := os.Getenv("TORRENT_USERNAME") password := os.Getenv("TORRENT_PASSWORD") client := NewHTTPClient(basePath) err := client.Login(username, password) if err != nil { panic(err) } resp, err := client.Get("/api/v2/torrents/info", map[string]string{"filter": "seeding"}) if err != nil { panic(err) } if resp.StatusCode != 200 { panic(fmt.Errorf("unexpected status code: %d", resp.StatusCode)) } decoder := json.NewDecoder(resp.Body) var torrents []map[string]interface{} err = decoder.Decode(&torrents) if err != nil { panic(err) } for _, torrent := range torrents { resp, err := client.PostForm("/api/v2/torrents/stop", map[string][]string{"hashes": {torrent["hash"].(string)}}) if err != nil { panic(err) } if resp.StatusCode != 200 { panic(fmt.Errorf("unexpected status code: %d", resp.StatusCode)) } } fmt.Println("done") }