Пример #1
0
func main() {
	log.SetFlags(log.LstdFlags | log.Lshortfile)
	tagflag.Parse(&opts, tagflag.SkipBadTypes())
	clientConfig := opts.Config
	if opts.Mmap {
		clientConfig.TorrentDataOpener = func(info *metainfo.Info) torrent.Data {
			ret, err := mmap.TorrentData(info, "")
			if err != nil {
				log.Fatalf("error opening torrent data for %q: %s", info.Name, err)
			}
			return ret
		}
	}

	client, err := torrent.NewClient(&clientConfig)
	if err != nil {
		log.Fatalf("error creating client: %s", err)
	}
	defer client.Close()
	http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
		client.WriteStatus(w)
	})
	uiprogress.Start()
	addTorrents(client)
	if client.WaitAll() {
		log.Print("downloaded ALL the torrents")
	} else {
		log.Fatal("y u no complete torrents?!")
	}
	if opts.Seed {
		select {}
	}
}
Пример #2
0
func main() {
	log.SetFlags(log.LstdFlags | log.Lshortfile)
	var rootGroup struct {
		Client    torrent.Config `group:"Client Options"`
		TestPeers []string       `long:"test-peer" description:"address of peer to inject to every torrent"`
		MMap      bool           `long:"mmap" description:"memory-map the torrent files"`
	}
	// Don't pass flags.PrintError because it's inconsistent with printing.
	// https://github.com/jessevdk/go-flags/issues/132
	parser := flags.NewParser(&rootGroup, flags.HelpFlag|flags.PassDoubleDash)
	parser.Usage = "[OPTIONS] (magnet URI or .torrent file path)..."
	posArgs, err := parser.Parse()
	if err != nil {
		fmt.Fprintln(os.Stderr, "Download from the BitTorrent network.")
		fmt.Println(err)
		os.Exit(2)
	}
	testPeers, err := resolvedPeerAddrs(rootGroup.TestPeers)
	if err != nil {
		log.Fatal(err)
	}
	if rootGroup.MMap {
		rootGroup.Client.TorrentDataOpener = func(info *metainfo.Info) torrent.Data {
			ret, err := mmap.TorrentData(info, "")
			if err != nil {
				log.Fatalf("error opening torrent data for %q: %s", info.Name, err)
			}
			return ret
		}
	}

	if len(posArgs) == 0 {
		fmt.Fprintln(os.Stderr, "no torrents specified")
		return
	}
	client, err := torrent.NewClient(&rootGroup.Client)
	if err != nil {
		log.Fatalf("error creating client: %s", err)
	}
	http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
		client.WriteStatus(w)
	})
	defer client.Close()
	for _, arg := range posArgs {
		t := func() torrent.Torrent {
			if strings.HasPrefix(arg, "magnet:") {
				t, err := client.AddMagnet(arg)
				if err != nil {
					log.Fatalf("error adding magnet: %s", err)
				}
				return t
			} else {
				metaInfo, err := metainfo.LoadFromFile(arg)
				if err != nil {
					log.Fatal(err)
				}
				t, err := client.AddTorrent(metaInfo)
				if err != nil {
					log.Fatal(err)
				}
				return t
			}
		}()
		err := t.AddPeers(testPeers)
		if err != nil {
			log.Fatal(err)
		}
		go func() {
			<-t.GotInfo()
			t.DownloadAll()
		}()
	}
	done := make(chan struct{})
	go func() {
		defer close(done)
		if client.WaitAll() {
			log.Print("downloaded ALL the torrents")
		} else {
			log.Fatal("y u no complete torrents?!")
		}
	}()
	ticker := time.NewTicker(time.Second)
waitDone:
	for {
		select {
		case <-done:
			break waitDone
		case <-ticker.C:
			os.Stdout.WriteString(progressLine(client))
		}
	}
	if rootGroup.Client.Seed {
		select {}
	}
}
Пример #3
0
func TestDownloadOnDemand(t *testing.T) {
	layout, err := newGreetingLayout()
	if err != nil {
		t.Fatal(err)
	}
	defer layout.Destroy()
	seeder, err := torrent.NewClient(&torrent.Config{
		DataDir:         layout.Completed,
		DisableTrackers: true,
		NoDHT:           true,
		ListenAddr:      ":0",
		Seed:            true,

		NoDefaultBlocklist: true,
		// Ensure that the metainfo is obtained over the wire, since we added
		// the torrent to the seeder by magnet.
		DisableMetainfoCache: true,
	})
	if err != nil {
		t.Fatalf("error creating seeder client: %s", err)
	}
	seeder.SetIPBlockList(nil)
	defer seeder.Close()
	http.HandleFunc("/seeder", func(w http.ResponseWriter, req *http.Request) {
		seeder.WriteStatus(w)
	})
	_, err = seeder.AddMagnet(fmt.Sprintf("magnet:?xt=urn:btih:%x", layout.Metainfo.Info.Hash))
	if err != nil {
		t.Fatal(err)
	}
	leecher, err := torrent.NewClient(&torrent.Config{
		DisableTrackers: true,
		NoDHT:           true,
		ListenAddr:      ":0",
		DisableTCP:      true,

		NoDefaultBlocklist: true,

		TorrentDataOpener: func(info *metainfo.Info) data.Data {
			ret, _ := mmap.TorrentData(info, filepath.Join(layout.BaseDir, "download"))
			return ret
		},

		// This can be used to check if clients can connect to other clients
		// with the same ID.

		// PeerID: seeder.PeerID(),
	})
	leecher.SetIPBlockList(nil)
	http.HandleFunc("/leecher", func(w http.ResponseWriter, req *http.Request) {
		leecher.WriteStatus(w)
	})
	defer leecher.Close()
	leecherTorrent, _ := leecher.AddTorrent(layout.Metainfo)
	leecherTorrent.AddPeers([]torrent.Peer{func() torrent.Peer {
		_, port, err := net.SplitHostPort(seeder.ListenAddr().String())
		if err != nil {
			panic(err)
		}
		portInt64, err := strconv.ParseInt(port, 0, 0)
		if err != nil {
			panic(err)
		}
		return torrent.Peer{
			IP: func() net.IP {
				ret, _ := net.ResolveIPAddr("ip", "localhost")
				return ret.IP
			}(),
			Port: int(portInt64),
		}
	}()})
	fs := New(leecher)
	defer fs.Destroy()
	root, _ := fs.Root()
	node, _ := root.(fusefs.NodeStringLookuper).Lookup(netContext.Background(), "greeting")
	var attr fuse.Attr
	node.Attr(netContext.Background(), &attr)
	size := attr.Size
	resp := &fuse.ReadResponse{
		Data: make([]byte, size),
	}
	node.(fusefs.HandleReader).Read(netContext.Background(), &fuse.ReadRequest{
		Size: int(size),
	}, resp)
	content := resp.Data
	if string(content) != testutil.GreetingFileContents {
		t.Fatalf("%q != %q", string(content), testutil.GreetingFileContents)
	}
}
Пример #4
0
func main() {
	log.SetFlags(log.LstdFlags | log.Lshortfile)
	var opts struct {
		torrent.Config `name:"Client"`
		Mmap           bool           `help:"memory-map torrent data"`
		TestPeer       []*net.TCPAddr `short:"p" help:"addresses of some starting peers"`
		Torrent        []string       `type:"pos" arity:"+" help:"torrent file path or magnet uri"`
	}
	tagflag.Parse(&opts, tagflag.SkipBadTypes())
	clientConfig := opts.Config
	if opts.Mmap {
		clientConfig.TorrentDataOpener = func(info *metainfo.Info) torrent.Data {
			ret, err := mmap.TorrentData(info, "")
			if err != nil {
				log.Fatalf("error opening torrent data for %q: %s", info.Name, err)
			}
			return ret
		}
	}

	torrents := opts.Torrent
	if len(torrents) == 0 {
		fmt.Fprintf(os.Stderr, "no torrents specified\n")
		return
	}
	client, err := torrent.NewClient(&clientConfig)
	if err != nil {
		log.Fatalf("error creating client: %s", err)
	}
	http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
		client.WriteStatus(w)
	})
	defer client.Close()
	for _, arg := range torrents {
		t := func() torrent.Torrent {
			if strings.HasPrefix(arg, "magnet:") {
				t, err := client.AddMagnet(arg)
				if err != nil {
					log.Fatalf("error adding magnet: %s", err)
				}
				return t
			} else {
				metaInfo, err := metainfo.LoadFromFile(arg)
				if err != nil {
					fmt.Fprintf(os.Stderr, "error loading torrent file %q: %s\n", arg, err)
					os.Exit(1)
				}
				t, err := client.AddTorrent(metaInfo)
				if err != nil {
					log.Fatal(err)
				}
				return t
			}
		}()
		err := t.AddPeers(func() (ret []torrent.Peer) {
			for _, ta := range opts.TestPeer {
				ret = append(ret, torrent.Peer{
					IP:   ta.IP,
					Port: ta.Port,
				})
			}
			return
		}())
		if err != nil {
			log.Fatal(err)
		}
		go func() {
			<-t.GotInfo()
			t.DownloadAll()
		}()
	}
	done := make(chan struct{})
	go func() {
		defer close(done)
		if client.WaitAll() {
			log.Print("downloaded ALL the torrents")
		} else {
			log.Fatal("y u no complete torrents?!")
		}
	}()
	ticker := time.NewTicker(time.Second)
waitDone:
	for {
		select {
		case <-done:
			break waitDone
		case <-ticker.C:
			os.Stdout.WriteString(progressLine(client))
		}
	}
	if opts.Seed {
		select {}
	}
}