Example #1
0
// 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)
	}
}
Example #2
0
// 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
	}
}
Example #3
0
// 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
	}
}
Example #4
0
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
	}
}
Example #5
0
// 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
	}
}