tracker/server/store/middleware/infohash/whitelist.go
2016-04-07 10:23:57 -04:00

99 lines
2.9 KiB
Go

// Copyright 2016 The Chihaya Authors. All rights reserved.
// Use of this source code is governed by the BSD 2-Clause license,
// which can be found in the LICENSE file.
package infohash
import (
"github.com/chihaya/chihaya"
"github.com/chihaya/chihaya/tracker"
)
func init() {
tracker.RegisterAnnounceMiddleware("infohash_whitelist", whitelistAnnounceInfohash)
tracker.RegisterScrapeMiddlewareConstructor("infohash_whitelist", whitelistScrapeInfohash)
}
// PrefixInfohash is the prefix to be used for infohashes.
const PrefixInfohash = "ih-"
// whitelistAnnounceInfohash provides a middleware that only allows announces
// for infohashes that are not stored in a StringStore
func whitelistAnnounceInfohash(next tracker.AnnounceHandler) tracker.AnnounceHandler {
return func(cfg *chihaya.TrackerConfig, req *chihaya.AnnounceRequest, resp *chihaya.AnnounceResponse) (err error) {
whitelisted, err := mustGetStore().HasString(PrefixInfohash + string(req.InfoHash))
if err != nil {
return err
} else if !whitelisted {
return ErrBlockedInfohash
}
return next(cfg, req, resp)
}
}
// whitelistScrapeInfohash provides a middleware constructor for a middleware
// that blocks or filters scrape requests based on the infohashes scraped.
//
// The middleware works in two modes: block and filter.
// The block mode blocks a scrape completely if any of the infohashes is
// disallowed.
// The filter mode filters any disallowed infohashes from the scrape,
// potentially leaving an empty scrape.
//
// ErrUnknownMode is returned if the Mode specified in the config is unknown.
func whitelistScrapeInfohash(c chihaya.MiddlewareConfig) (tracker.ScrapeMiddleware, error) {
cfg, err := newConfig(c)
if err != nil {
return nil, err
}
switch cfg.Mode {
case ModeFilter:
return whitelistFilterScrape, nil
case ModeBlock:
return whitelistBlockScrape, nil
default:
panic("unknown mode")
}
}
func whitelistFilterScrape(next tracker.ScrapeHandler) tracker.ScrapeHandler {
return func(cfg *chihaya.TrackerConfig, req *chihaya.ScrapeRequest, resp *chihaya.ScrapeResponse) (err error) {
whitelisted := false
storage := mustGetStore()
infohashes := req.InfoHashes
for i, ih := range infohashes {
whitelisted, err = storage.HasString(PrefixInfohash + string(ih))
if err != nil {
return err
} else if !whitelisted {
req.InfoHashes[i] = req.InfoHashes[len(req.InfoHashes)-1]
req.InfoHashes = req.InfoHashes[:len(req.InfoHashes)-1]
}
}
return next(cfg, req, resp)
}
}
func whitelistBlockScrape(next tracker.ScrapeHandler) tracker.ScrapeHandler {
return func(cfg *chihaya.TrackerConfig, req *chihaya.ScrapeRequest, resp *chihaya.ScrapeResponse) (err error) {
whitelisted := false
storage := mustGetStore()
for _, ih := range req.InfoHashes {
whitelisted, err = storage.HasString(PrefixInfohash + string(ih))
if err != nil {
return err
} else if !whitelisted {
return ErrBlockedInfohash
}
}
return next(cfg, req, resp)
}
}