Remove the last of the "config dir" stuff
This just conflates the Client. It should be done orthogonally.
This commit is contained in:
parent
2d160b0419
commit
b5812bb0b7
89
client.go
89
client.go
|
@ -13,8 +13,6 @@ import (
|
||||||
mathRand "math/rand"
|
mathRand "math/rand"
|
||||||
"net"
|
"net"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -180,19 +178,6 @@ func (cl *Client) WriteStatus(_w io.Writer) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cl *Client) configDir() string {
|
|
||||||
if cl.config.ConfigDir == "" {
|
|
||||||
return filepath.Join(os.Getenv("HOME"), ".config/torrent")
|
|
||||||
}
|
|
||||||
return cl.config.ConfigDir
|
|
||||||
}
|
|
||||||
|
|
||||||
// The directory where the Client expects to find and store configuration
|
|
||||||
// data. Defaults to $HOME/.config/torrent.
|
|
||||||
func (cl *Client) ConfigDir() string {
|
|
||||||
return cl.configDir()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Creates a new client.
|
// Creates a new client.
|
||||||
func NewClient(cfg *Config) (cl *Client, err error) {
|
func NewClient(cfg *Config) (cl *Client, err error) {
|
||||||
if cfg == nil {
|
if cfg == nil {
|
||||||
|
@ -1442,45 +1427,11 @@ func (cl *Client) addPeers(t *Torrent, peers []Peer) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cl *Client) cachedMetaInfoFilename(ih metainfo.Hash) string {
|
|
||||||
return filepath.Join(cl.configDir(), "torrents", ih.HexString()+".torrent")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cl *Client) saveTorrentFile(t *Torrent) error {
|
|
||||||
path := cl.cachedMetaInfoFilename(t.infoHash)
|
|
||||||
os.MkdirAll(filepath.Dir(path), 0777)
|
|
||||||
f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("error opening file: %s", err)
|
|
||||||
}
|
|
||||||
defer f.Close()
|
|
||||||
e := bencode.NewEncoder(f)
|
|
||||||
err = e.Encode(t.metainfo())
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("error marshalling metainfo: %s", err)
|
|
||||||
}
|
|
||||||
mi, err := cl.torrentCacheMetaInfo(t.infoHash)
|
|
||||||
if err != nil {
|
|
||||||
// For example, a script kiddy makes us load too many files, and we're
|
|
||||||
// able to save the torrent, but not load it again to check it.
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if mi.Info.Hash() != t.infoHash {
|
|
||||||
log.Fatalf("%x != %x", mi.Info.Hash, t.infoHash[:])
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cl *Client) setMetaData(t *Torrent, md *metainfo.Info, bytes []byte) (err error) {
|
func (cl *Client) setMetaData(t *Torrent, md *metainfo.Info, bytes []byte) (err error) {
|
||||||
err = t.setMetadata(md, bytes)
|
err = t.setMetadata(md, bytes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !cl.config.DisableMetainfoCache {
|
|
||||||
if err := cl.saveTorrentFile(t); err != nil {
|
|
||||||
log.Printf("error saving torrent file for %s: %s", t, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cl.event.Broadcast()
|
cl.event.Broadcast()
|
||||||
close(t.gotMetainfo)
|
close(t.gotMetainfo)
|
||||||
return
|
return
|
||||||
|
@ -1551,32 +1502,6 @@ type Handle interface {
|
||||||
io.ReaderAt
|
io.ReaderAt
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns nil metainfo if it isn't in the cache. Checks that the retrieved
|
|
||||||
// metainfo has the correct infohash.
|
|
||||||
func (cl *Client) torrentCacheMetaInfo(ih metainfo.Hash) (mi *metainfo.MetaInfo, err error) {
|
|
||||||
if cl.config.DisableMetainfoCache {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
f, err := os.Open(cl.cachedMetaInfoFilename(ih))
|
|
||||||
if err != nil {
|
|
||||||
if os.IsNotExist(err) {
|
|
||||||
err = nil
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer f.Close()
|
|
||||||
dec := bencode.NewDecoder(f)
|
|
||||||
err = dec.Decode(&mi)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if mi.Info.Hash() != ih {
|
|
||||||
err = fmt.Errorf("cached torrent has wrong infohash: %x != %x", mi.Info.Hash, ih[:])
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Specifies a new torrent for adding to a client. There are helpers for
|
// Specifies a new torrent for adding to a client. There are helpers for
|
||||||
// magnet URIs and torrent metainfo files.
|
// magnet URIs and torrent metainfo files.
|
||||||
type TorrentSpec struct {
|
type TorrentSpec struct {
|
||||||
|
@ -1655,20 +1580,8 @@ func (cl *Client) AddTorrentSpec(spec *TorrentSpec) (t *Torrent, new bool, err e
|
||||||
}
|
}
|
||||||
// Try to merge in info we have on the torrent. Any err left will
|
// Try to merge in info we have on the torrent. Any err left will
|
||||||
// terminate the function.
|
// terminate the function.
|
||||||
if t.info == nil {
|
if t.info == nil && spec.Info != nil {
|
||||||
if spec.Info != nil {
|
|
||||||
err = cl.setMetaData(t, &spec.Info.Info, spec.Info.Bytes)
|
err = cl.setMetaData(t, &spec.Info.Info, spec.Info.Bytes)
|
||||||
} else {
|
|
||||||
var mi *metainfo.MetaInfo
|
|
||||||
mi, err = cl.torrentCacheMetaInfo(spec.InfoHash)
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("error getting cached metainfo: %s", err)
|
|
||||||
err = nil
|
|
||||||
} else if mi != nil {
|
|
||||||
t.addTrackers(mi.AnnounceList)
|
|
||||||
err = cl.setMetaData(t, &mi.Info.Info, mi.Info.Bytes)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
|
|
|
@ -10,7 +10,6 @@ import (
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
|
@ -40,7 +39,6 @@ var TestingConfig = Config{
|
||||||
ListenAddr: "localhost:0",
|
ListenAddr: "localhost:0",
|
||||||
NoDHT: true,
|
NoDHT: true,
|
||||||
DisableTrackers: true,
|
DisableTrackers: true,
|
||||||
DisableMetainfoCache: true,
|
|
||||||
DataDir: "/dev/null",
|
DataDir: "/dev/null",
|
||||||
DHTConfig: dht.ServerConfig{
|
DHTConfig: dht.ServerConfig{
|
||||||
NoDefaultBootstrap: true,
|
NoDefaultBootstrap: true,
|
||||||
|
@ -646,37 +644,6 @@ func TestAddTorrentSpecMerging(t *testing.T) {
|
||||||
require.NotNil(t, tt.Info())
|
require.NotNil(t, tt.Info())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that torrent Info is obtained from the metainfo file cache.
|
|
||||||
func TestAddTorrentMetainfoInCache(t *testing.T) {
|
|
||||||
cfg := TestingConfig
|
|
||||||
cfg.DisableMetainfoCache = false
|
|
||||||
cfg.ConfigDir, _ = ioutil.TempDir(os.TempDir(), "")
|
|
||||||
defer os.RemoveAll(cfg.ConfigDir)
|
|
||||||
cl, err := NewClient(&cfg)
|
|
||||||
require.NoError(t, err)
|
|
||||||
defer cl.Close()
|
|
||||||
dir, mi := testutil.GreetingTestTorrent()
|
|
||||||
defer os.RemoveAll(dir)
|
|
||||||
tt, new, err := cl.AddTorrentSpec(TorrentSpecFromMetaInfo(mi))
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.True(t, new)
|
|
||||||
require.NotNil(t, tt.Info())
|
|
||||||
_, err = os.Stat(filepath.Join(cfg.ConfigDir, "torrents", fmt.Sprintf("%x.torrent", mi.Info.Hash())))
|
|
||||||
require.NoError(t, err)
|
|
||||||
_, ok := cl.Torrent(mi.Info.Hash())
|
|
||||||
require.True(t, ok)
|
|
||||||
tt.Drop()
|
|
||||||
_, ok = cl.Torrent(mi.Info.Hash())
|
|
||||||
require.False(t, ok)
|
|
||||||
tt, new, err = cl.AddTorrentSpec(&TorrentSpec{
|
|
||||||
InfoHash: mi.Info.Hash(),
|
|
||||||
})
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.True(t, new)
|
|
||||||
// Obtained from the metainfo cache.
|
|
||||||
require.NotNil(t, tt.Info())
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestTorrentDroppedBeforeGotInfo(t *testing.T) {
|
func TestTorrentDroppedBeforeGotInfo(t *testing.T) {
|
||||||
dir, mi := testutil.GreetingTestTorrent()
|
dir, mi := testutil.GreetingTestTorrent()
|
||||||
os.RemoveAll(dir)
|
os.RemoveAll(dir)
|
||||||
|
|
|
@ -33,13 +33,6 @@ type Config struct {
|
||||||
DisableUTP bool
|
DisableUTP bool
|
||||||
// For the bittorrent protocol.
|
// For the bittorrent protocol.
|
||||||
DisableTCP bool `long:"disable-tcp"`
|
DisableTCP bool `long:"disable-tcp"`
|
||||||
// Defaults to "$HOME/.config/torrent". This is where "blocklist",
|
|
||||||
// "torrents" and other operational files are stored. TODO: Dump this
|
|
||||||
// stuff, this is specific to the default cmd/torrent client only.
|
|
||||||
ConfigDir string
|
|
||||||
// Don't save or load to a cache of torrent files stored in
|
|
||||||
// "$ConfigDir/torrents".
|
|
||||||
DisableMetainfoCache bool
|
|
||||||
// Called to instantiate storage for each added torrent. Provided backends
|
// Called to instantiate storage for each added torrent. Provided backends
|
||||||
// are in $REPO/data. If not set, the "file" implementation is used.
|
// are in $REPO/data. If not set, the "file" implementation is used.
|
||||||
DefaultStorage storage.I
|
DefaultStorage storage.I
|
||||||
|
|
|
@ -166,9 +166,6 @@ func TestDownloadOnDemand(t *testing.T) {
|
||||||
NoDHT: true,
|
NoDHT: true,
|
||||||
ListenAddr: "localhost:0",
|
ListenAddr: "localhost:0",
|
||||||
Seed: true,
|
Seed: true,
|
||||||
// Ensure that the metainfo is obtained over the wire, since we added
|
|
||||||
// the torrent to the seeder by magnet.
|
|
||||||
DisableMetainfoCache: true,
|
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
defer seeder.Close()
|
defer seeder.Close()
|
||||||
|
|
Loading…
Reference in New Issue