// Remove torrent from download list func del(w http.ResponseWriter, r *http.Request) { user := r.URL.Query().Get("user") if user == "" { httpd.Error(w, nil, "Missing user arg.") return } hash := r.URL.Query().Get("hash") if hash == "" { httpd.Error(w, nil, "Missing hash arg.") return } q, ok := clients[user] if !ok { httpd.Error(w, nil, "No such user.") return } ok = false for _, t := range q.Torrents() { if t.InfoHash().HexString() == hash { t.Drop() ok = true break } } if ok { w.WriteHeader(200) } else { w.WriteHeader(404) } }
// List downloads func list(w http.ResponseWriter, r *http.Request) { c := List{} c.User = r.URL.Query().Get("user") if c.User == "" { httpd.Error(w, nil, "Invalid input.") return } q, ok := clients[c.User] if !ok { httpd.Error(w, nil, "No such user.") return } res := ListRet{User: c.User} for _, t := range q.Torrents() { res.Torrents = append(res.Torrents, ListTorrentRet{ InfoHash: t.InfoHash().HexString(), BytesCompleted: t.BytesCompleted(), PieceState: t.PieceStateRuns(), }) } j, e := json.Marshal(res) if e != nil { httpd.Error(w, nil, "Failed json encoding.") return } w.Header().Set("Content-Type", "application/json") if _, e := w.Write(j); e != nil { httpd.Error(w, e, "Flush failed") return } }
// Finish pending jobs and close application func shutdown(w http.ResponseWriter, r *http.Request) { if config.Stopping { pending := 0 if _, e := w.Write([]byte(fmt.Sprintf(`{success: true, msg: "Already stopping.", pending: %d}`, pending))); e != nil { httpd.Error(w, e, "Flush failed") return } } config.L.Printf("Disconnecting") config.Stopping = true if e := ln.Close(); e != nil { httpd.Error(w, e, `{success: false, msg: "Error stopping HTTP-listener"}`) } if e := torrent.Close(); e != nil { httpd.Error(w, e, `{success: false, msg: "Error stopping Torrent-IO"}`) } if _, e := w.Write([]byte(`{success: true, msg: "Stopped listening, waiting for empty queue."}`)); e != nil { httpd.Error(w, e, "Flush failed") return } }
func verbose(w http.ResponseWriter, r *http.Request) { msg := `{success: true, msg: "Set verbosity to ` if config.Verbose { config.Verbose = false msg += "OFF" } else { config.Verbose = true msg += "ON" } msg += `"}` if _, e := w.Write([]byte(msg)); e != nil { httpd.Error(w, e, "Flush failed") return } }
// Add Torrent/Magnet func add(w http.ResponseWriter, r *http.Request) { c := Add{} if e := json.NewDecoder(r.Body).Decode(&c); e != nil { httpd.Error(w, e, "Invalid input.") return } if c.User == "" { httpd.Error(w, nil, "No user.") return } if c.Dir == "" { httpd.Error(w, nil, "No dir.") return } if strings.Contains(c.Dir, "..") { httpd.Error(w, nil, "Dir hack.") return } if _, ok := clients[c.User]; !ok { dlDir := fmt.Sprintf(config.C.Basedir + c.Dir) if _, e := os.Stat(config.C.Basedir); os.IsNotExist(e) { if e := os.Mkdir(dlDir, os.ModeDir); e != nil { config.L.Printf("CRIT: %s", e.Error()) httpd.Error(w, e, "Permission error.") return } } // https://github.com/anacrolix/torrent/blob/master/config.go#L9 cl, e := torrent.NewClient(&torrent.Config{ DataDir: config.C.Basedir + c.Dir, // IPBlocklist => http://john.bitsurge.net/public/biglist.p2p.gz }) if e != nil { httpd.Error(w, e, "Client init failed") return } clients[c.User] = cl } client := clients[c.User] var ( t torrent.Torrent e error ) if len(c.Magnet) > 0 { t, e = client.AddMagnet(c.Magnet) if e != nil { httpd.Error(w, e, "Magnet add failed") return } } else if len(c.Torrent) > 0 { // strip base64 b, e := base64.StdEncoding.DecodeString(c.Torrent) if e != nil { httpd.Error(w, e, "Failed base64 decode torrent input") return } m, e := metainfo.Load(bytes.NewReader(b)) if e != nil { httpd.Error(w, e, "Failed base64 decode torrent input") return } t, e = client.AddTorrent(m) if e != nil { httpd.Error(w, e, "Failed adding torrent") return } } else { httpd.Error(w, nil, "No magnet nor torrent.") return } // queue go func() { <-t.GotInfo() t.DownloadAll() }() // (cl *Client) AddTorrentSpec(spec *TorrentSpec) (T Torrent, new bool, err error) { // TorrentSpecFromMagnetURI(uri string) (spec *TorrentSpec, err error) { // TorrentSpecFromMetaInfo(mi *metainfo.MetaInfo) (spec *TorrentSpec) { // (me *Client) AddMagnet(uri string) (T Torrent, err error) { // (me *Client) AddTorrent(mi *metainfo.MetaInfo) (T Torrent, err error) { msg := fmt.Sprintf(`{"status": true, "hash": "%s", "text": "Queued."}`, t.InfoHash().HexString()) w.Header().Set("Content-Type", "application/json") if _, e := w.Write([]byte(msg)); e != nil { httpd.Error(w, e, "Flush failed") return } }