mirror of
https://github.com/sot-tech/mochi.git
synced 2026-07-29 02:28:10 -07:00
Implement simple PGDC methods for storage
* sanitize code a little * move e2e build to 'e2e' tag
This commit is contained in:
committed by
Lawrence, Rendall
parent
566d99fcd7
commit
beb4736b86
@@ -47,7 +47,11 @@ func TestClientID(t *testing.T) {
|
||||
t.Run(tt.peerID, func(t *testing.T) {
|
||||
var clientID ClientID
|
||||
copy(clientID[:], tt.clientID)
|
||||
parsedID := NewClientID(bittorrent.NewPeerID([]byte(tt.peerID)))
|
||||
peerId, err := bittorrent.NewPeerID([]byte(tt.peerID))
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
parsedID := NewClientID(peerId)
|
||||
if parsedID != clientID {
|
||||
t.Error("Incorrectly parsed peer ID", tt.peerID, "as", parsedID)
|
||||
}
|
||||
|
||||
@@ -59,8 +59,8 @@ func TestHandleAnnounce(t *testing.T) {
|
||||
req := &bittorrent.AnnounceRequest{}
|
||||
resp := &bittorrent.AnnounceResponse{}
|
||||
|
||||
peerid := bittorrent.NewPeerID([]byte(tt.peerID))
|
||||
|
||||
peerid, err := bittorrent.NewPeerID([]byte(tt.peerID))
|
||||
require.Nil(t, err)
|
||||
req.Peer.ID = peerid
|
||||
|
||||
nctx, err := h.HandleAnnounce(ctx, req, resp)
|
||||
|
||||
+3
-3
@@ -28,7 +28,7 @@ type swarmInteractionHook struct {
|
||||
store storage.Storage
|
||||
}
|
||||
|
||||
func (h *swarmInteractionHook) HandleAnnounce(ctx context.Context, req *bittorrent.AnnounceRequest, resp *bittorrent.AnnounceResponse) (_ context.Context, err error) {
|
||||
func (h *swarmInteractionHook) HandleAnnounce(ctx context.Context, req *bittorrent.AnnounceRequest, _ *bittorrent.AnnounceResponse) (_ context.Context, err error) {
|
||||
if ctx.Value(SkipSwarmInteractionKey) != nil {
|
||||
return ctx, nil
|
||||
}
|
||||
@@ -75,14 +75,14 @@ type skipResponseHook struct{}
|
||||
// skip.
|
||||
var SkipResponseHookKey = skipResponseHook{}
|
||||
|
||||
type scrapeAddressType struct{}
|
||||
//type scrapeAddressType struct{}
|
||||
|
||||
// ScrapeIsIPv6Key is the key under which to store whether or not the
|
||||
// address used to request a scrape was an IPv6 address.
|
||||
// The value is expected to be of type bool.
|
||||
// A missing value or a value that is not a bool for this key is equivalent to
|
||||
// it being set to false.
|
||||
var ScrapeIsIPv6Key = scrapeAddressType{}
|
||||
//var ScrapeIsIPv6Key = scrapeAddressType{}
|
||||
|
||||
type responseHook struct {
|
||||
store storage.Storage
|
||||
|
||||
@@ -22,7 +22,7 @@ import (
|
||||
"github.com/SermoDigital/jose/jws"
|
||||
"github.com/SermoDigital/jose/jwt"
|
||||
"github.com/mendsley/gojwk"
|
||||
yaml "gopkg.in/yaml.v2"
|
||||
"gopkg.in/yaml.v2"
|
||||
|
||||
"github.com/chihaya/chihaya/bittorrent"
|
||||
"github.com/chihaya/chihaya/middleware"
|
||||
|
||||
@@ -15,11 +15,11 @@ import (
|
||||
// benchmarks.
|
||||
type nopHook struct{}
|
||||
|
||||
func (h *nopHook) HandleAnnounce(ctx context.Context, req *bittorrent.AnnounceRequest, resp *bittorrent.AnnounceResponse) (context.Context, error) {
|
||||
func (h *nopHook) HandleAnnounce(ctx context.Context, _ *bittorrent.AnnounceRequest, _ *bittorrent.AnnounceResponse) (context.Context, error) {
|
||||
return ctx, nil
|
||||
}
|
||||
|
||||
func (h *nopHook) HandleScrape(ctx context.Context, req *bittorrent.ScrapeRequest, resp *bittorrent.ScrapeResponse) (context.Context, error) {
|
||||
func (h *nopHook) HandleScrape(ctx context.Context, _ *bittorrent.ScrapeRequest, _ *bittorrent.ScrapeResponse) (context.Context, error) {
|
||||
return ctx, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
"github.com/chihaya/chihaya/storage"
|
||||
"sync"
|
||||
|
||||
yaml "gopkg.in/yaml.v2"
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
var (
|
||||
|
||||
@@ -7,7 +7,9 @@ import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
type Builder func ([]byte, storage.Storage) (Container, error)
|
||||
const DefaultStorageCtxName = "MW_APPROVAL"
|
||||
|
||||
type Builder func([]byte, storage.Storage) (Container, error)
|
||||
|
||||
var (
|
||||
buildersMU sync.Mutex
|
||||
@@ -30,7 +32,7 @@ func Register(n string, c Builder) {
|
||||
}
|
||||
|
||||
type Container interface {
|
||||
Contains(bittorrent.InfoHash) bool
|
||||
Approved(bittorrent.InfoHash) bool
|
||||
}
|
||||
|
||||
func GetContainer(name string, confBytes []byte, storage storage.Storage) (Container, error) {
|
||||
|
||||
@@ -4,63 +4,88 @@
|
||||
package directory
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"fmt"
|
||||
"github.com/anacrolix/torrent/metainfo"
|
||||
"github.com/anacrolix/torrent/util/dirwatch"
|
||||
"github.com/chihaya/chihaya/bittorrent"
|
||||
"github.com/chihaya/chihaya/middleware/torrentapproval/container"
|
||||
"github.com/chihaya/chihaya/middleware/torrentapproval/container/list"
|
||||
"github.com/chihaya/chihaya/pkg/log"
|
||||
"github.com/chihaya/chihaya/pkg/stop"
|
||||
"github.com/chihaya/chihaya/storage"
|
||||
"gopkg.in/yaml.v2"
|
||||
"sync"
|
||||
)
|
||||
|
||||
const Name = "directory"
|
||||
|
||||
func init() {
|
||||
container.Register("directory", build)
|
||||
container.Register(Name, build)
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
WhitelistPath string `yaml:"whitelist_path"`
|
||||
BlacklistPath string `yaml:"blacklist_path"`
|
||||
list.Config
|
||||
Path string `yaml:"path"`
|
||||
}
|
||||
|
||||
// TODO: change sync map to provided storage
|
||||
func build(confBytes []byte, storage storage.Storage) (container.Container, error) {
|
||||
func build(confBytes []byte, st storage.Storage) (container.Container, error) {
|
||||
c := new(Config)
|
||||
if err := yaml.Unmarshal(confBytes, c); err != nil {
|
||||
return nil, fmt.Errorf("unable to deserialise configuration: %v", err)
|
||||
}
|
||||
if len(c.WhitelistPath) > 0 && len(c.BlacklistPath) > 0 {
|
||||
return nil, fmt.Errorf("using both whitelist and blacklist is invalid")
|
||||
}
|
||||
var err error
|
||||
lst := &directory{
|
||||
d := &directory{
|
||||
List: list.List{
|
||||
Hashes: sync.Map{},
|
||||
Invert: len(c.WhitelistPath) == 0,
|
||||
Invert: c.Invert,
|
||||
Storage: st,
|
||||
StorageCtx: c.StorageCtx,
|
||||
},
|
||||
watcher: nil,
|
||||
}
|
||||
dir := c.WhitelistPath
|
||||
if lst.Invert {
|
||||
dir = c.BlacklistPath
|
||||
}
|
||||
//FIXME: implement V2 torrent add/delete
|
||||
var w *dirwatch.Instance
|
||||
if w, err = dirwatch.New(dir); err != nil {
|
||||
if w, err = dirwatch.New(c.Path); err != nil {
|
||||
return nil, fmt.Errorf("unable to initialize directory watch: %v", err)
|
||||
}
|
||||
lst.watcher = w
|
||||
d.watcher = w
|
||||
if len(d.StorageCtx) == 0 {
|
||||
log.Info("Storage context not set, using default value: " + container.DefaultStorageCtxName)
|
||||
d.StorageCtx = container.DefaultStorageCtxName
|
||||
}
|
||||
go func() {
|
||||
for event := range lst.watcher.Events {
|
||||
for event := range d.watcher.Events {
|
||||
switch event.Change {
|
||||
case dirwatch.Added:
|
||||
lst.Hashes.Store(event.InfoHash, list.DUMMY)
|
||||
data := make([]storage.Pair, 1, 2)
|
||||
data[0] = storage.Pair{Left: event.InfoHash[:], Right: list.DUMMY}
|
||||
if v2ih, err := v2InfoHash(event.TorrentFilePath); err == nil {
|
||||
data = append(data, storage.Pair{Left: v2ih, Right: list.DUMMY})
|
||||
} else {
|
||||
log.Err(err)
|
||||
}
|
||||
d.Storage.BulkPut(c.StorageCtx, data...)
|
||||
case dirwatch.Removed:
|
||||
lst.Hashes.Delete(event.InfoHash)
|
||||
data := make([]interface{}, 1, 2)
|
||||
data[0] = event.InfoHash[:]
|
||||
if v2ih, err := v2InfoHash(event.TorrentFilePath); err == nil {
|
||||
data = append(data, v2ih)
|
||||
} else {
|
||||
log.Err(err)
|
||||
}
|
||||
d.Storage.Delete(c.StorageCtx, data...)
|
||||
}
|
||||
}
|
||||
}()
|
||||
return lst, err
|
||||
return d, err
|
||||
}
|
||||
|
||||
func v2InfoHash(path string) (ih bittorrent.InfoHash, err error) {
|
||||
var mi *metainfo.MetaInfo
|
||||
if mi, err = metainfo.LoadFromFile(path); err == nil {
|
||||
hash := sha256.New()
|
||||
hash.Write(mi.InfoBytes)
|
||||
ih, err = bittorrent.NewInfoHash(hash.Sum(nil))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
type directory struct {
|
||||
|
||||
@@ -5,63 +5,68 @@ package list
|
||||
import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
bittorrent "github.com/chihaya/chihaya/bittorrent"
|
||||
"github.com/chihaya/chihaya/bittorrent"
|
||||
"github.com/chihaya/chihaya/middleware/torrentapproval/container"
|
||||
"github.com/chihaya/chihaya/pkg/log"
|
||||
"github.com/chihaya/chihaya/storage"
|
||||
"gopkg.in/yaml.v2"
|
||||
"sync"
|
||||
)
|
||||
|
||||
const Name = "list"
|
||||
|
||||
func init() {
|
||||
container.Register("list", build)
|
||||
container.Register(Name, build)
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
Whitelist []string `yaml:"whitelist"`
|
||||
Blacklist []string `yaml:"blacklist"`
|
||||
HashList []string `yaml:"hash_list"`
|
||||
Invert bool `yaml:"invert"`
|
||||
StorageCtx string `yaml:"storage_ctx"`
|
||||
}
|
||||
|
||||
var DUMMY struct{}
|
||||
const DUMMY = true
|
||||
|
||||
// TODO: change sync map to provided storage
|
||||
func build(confBytes []byte, storage storage.Storage) (container.Container, error) {
|
||||
func build(confBytes []byte, st storage.Storage) (container.Container, error) {
|
||||
c := new(Config)
|
||||
if err := yaml.Unmarshal(confBytes, c); err != nil {
|
||||
return nil, fmt.Errorf("unable to deserialise configuration: %v", err)
|
||||
}
|
||||
if len(c.Whitelist) > 0 && len(c.Blacklist) > 0 {
|
||||
return nil, fmt.Errorf("using both whitelist and blacklist is invalid")
|
||||
}
|
||||
l := &List{
|
||||
Hashes: sync.Map{},
|
||||
Invert: len(c.Whitelist) == 0,
|
||||
Invert: c.Invert,
|
||||
Storage: st,
|
||||
StorageCtx: c.StorageCtx,
|
||||
}
|
||||
|
||||
hashList := c.Whitelist
|
||||
if l.Invert {
|
||||
hashList = c.Blacklist
|
||||
if len(l.StorageCtx) == 0 {
|
||||
log.Info("Storage context not set, using default value: " + container.DefaultStorageCtxName)
|
||||
l.StorageCtx = container.DefaultStorageCtxName
|
||||
}
|
||||
|
||||
for _, hashString := range hashList {
|
||||
hashBytes, err := hex.DecodeString(hashString)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("whitelist : invalid hash %s, %v", hashString, err)
|
||||
if len(c.HashList) > 0 {
|
||||
init := make([]storage.Pair, 0, len(c.HashList))
|
||||
for _, hashString := range c.HashList {
|
||||
hashBytes, err := hex.DecodeString(hashString)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("whitelist : invalid hash %s, %v", hashString, err)
|
||||
}
|
||||
ih, err := bittorrent.NewInfoHash(hashBytes)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("whitelist : %s : %v", hashString, err)
|
||||
}
|
||||
init = append(init, storage.Pair{Left: ih, Right: DUMMY})
|
||||
}
|
||||
ih, err := bittorrent.NewInfoHash(hashBytes)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("whitelist : %s : %v", hashString, err)
|
||||
}
|
||||
l.Hashes.Store(ih, DUMMY)
|
||||
l.Storage.BulkPut(l.StorageCtx, init...)
|
||||
}
|
||||
return l, nil
|
||||
}
|
||||
|
||||
type List struct {
|
||||
Invert bool
|
||||
Hashes sync.Map
|
||||
Invert bool
|
||||
Storage storage.Storage
|
||||
StorageCtx string
|
||||
}
|
||||
|
||||
func (l *List) Contains(hash bittorrent.InfoHash) bool {
|
||||
_, result := l.Hashes.Load(hash)
|
||||
return result != l.Invert
|
||||
func (l *List) Approved(hash bittorrent.InfoHash) bool {
|
||||
b := l.Storage.Contains(l.StorageCtx, hash)
|
||||
return b != l.Invert
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ type hook struct {
|
||||
func (h *hook) HandleAnnounce(ctx context.Context, req *bittorrent.AnnounceRequest, _ *bittorrent.AnnounceResponse) (context.Context, error) {
|
||||
var err error
|
||||
|
||||
if !h.hashContainer.Contains(req.InfoHash) {
|
||||
if !h.hashContainer.Approved(req.InfoHash) {
|
||||
err = ErrTorrentUnapproved
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"github.com/chihaya/chihaya/middleware"
|
||||
"github.com/chihaya/chihaya/storage/memory"
|
||||
"gopkg.in/yaml.v2"
|
||||
"testing"
|
||||
|
||||
@@ -23,7 +24,7 @@ var cases = []struct {
|
||||
middleware.Config{
|
||||
Name: "list",
|
||||
Options: map[string]interface{}{
|
||||
"whitelist": []string{"3532cf2d327fad8448c075b4cb42c8136964a435"},
|
||||
"hash_list": []string{"3532cf2d327fad8448c075b4cb42c8136964a435"},
|
||||
},
|
||||
},
|
||||
"3532cf2d327fad8448c075b4cb42c8136964a435",
|
||||
@@ -34,7 +35,7 @@ var cases = []struct {
|
||||
middleware.Config{
|
||||
Name: "list",
|
||||
Options: map[string]interface{}{
|
||||
"whitelist": []string{"3532cf2d327fad8448c075b4cb42c8136964a435"},
|
||||
"hash_list": []string{"3532cf2d327fad8448c075b4cb42c8136964a435"},
|
||||
},
|
||||
},
|
||||
"4532cf2d327fad8448c075b4cb42c8136964a435",
|
||||
@@ -45,7 +46,8 @@ var cases = []struct {
|
||||
middleware.Config{
|
||||
Name: "list",
|
||||
Options: map[string]interface{}{
|
||||
"blacklist": []string{"3532cf2d327fad8448c075b4cb42c8136964a435"},
|
||||
"hash_list": []string{"3532cf2d327fad8448c075b4cb42c8136964a435"},
|
||||
"invert": true,
|
||||
},
|
||||
},
|
||||
"4532cf2d327fad8448c075b4cb42c8136964a435",
|
||||
@@ -56,7 +58,8 @@ var cases = []struct {
|
||||
middleware.Config{
|
||||
Name: "list",
|
||||
Options: map[string]interface{}{
|
||||
"blacklist": []string{"3532cf2d327fad8448c075b4cb42c8136964a435"},
|
||||
"hash_list": []string{"3532cf2d327fad8448c075b4cb42c8136964a435"},
|
||||
"invert": true,
|
||||
},
|
||||
},
|
||||
"3532cf2d327fad8448c075b4cb42c8136964a435",
|
||||
@@ -65,12 +68,15 @@ var cases = []struct {
|
||||
}
|
||||
|
||||
func TestHandleAnnounce(t *testing.T) {
|
||||
config := memory.Config{}.Validate()
|
||||
storage, err := memory.New(config)
|
||||
require.Nil(t, err)
|
||||
for _, tt := range cases {
|
||||
t.Run(fmt.Sprintf("testing hash %s", tt.ih), func(t *testing.T) {
|
||||
d := driver{}
|
||||
cfg, err := yaml.Marshal(tt.cfg)
|
||||
require.Nil(t, err)
|
||||
h, err := d.NewHook(cfg)
|
||||
h, err := d.NewHook(cfg, storage)
|
||||
require.Nil(t, err)
|
||||
|
||||
ctx := context.Background()
|
||||
@@ -80,7 +86,8 @@ func TestHandleAnnounce(t *testing.T) {
|
||||
hashbytes, err := hex.DecodeString(tt.ih)
|
||||
require.Nil(t, err)
|
||||
|
||||
hashinfo := bittorrent.NewInfoHash(hashbytes)
|
||||
hashinfo, err := bittorrent.NewInfoHash(hashbytes)
|
||||
require.Nil(t, err)
|
||||
|
||||
req.InfoHash = hashinfo
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
yaml "gopkg.in/yaml.v2"
|
||||
"gopkg.in/yaml.v2"
|
||||
|
||||
"github.com/chihaya/chihaya/bittorrent"
|
||||
"github.com/chihaya/chihaya/middleware"
|
||||
|
||||
Reference in New Issue
Block a user