diff --git a/cmd/chihaya/config.go b/cmd/chihaya/config.go index 26b11e3..04921e3 100644 --- a/cmd/chihaya/config.go +++ b/cmd/chihaya/config.go @@ -10,9 +10,15 @@ import ( httpfrontend "github.com/chihaya/chihaya/frontend/http" udpfrontend "github.com/chihaya/chihaya/frontend/udp" "github.com/chihaya/chihaya/middleware" + "github.com/chihaya/chihaya/middleware/jwt" "github.com/chihaya/chihaya/storage/memory" ) +type hookConfig struct { + Name string `yaml:"name"` + Config interface{} `yaml:"config"` +} + // ConfigFile represents a namespaced YAML configation file. type ConfigFile struct { MainConfigBlock struct { @@ -21,6 +27,8 @@ type ConfigFile struct { HTTPConfig httpfrontend.Config `yaml:"http"` UDPConfig udpfrontend.Config `yaml:"udp"` Storage memory.Config `yaml:"storage"` + PreHooks []hookConfig `yaml:"prehooks"` + PostHooks []hookConfig `yaml:"posthooks"` } `yaml:"chihaya"` } @@ -52,3 +60,31 @@ func ParseConfigFile(path string) (*ConfigFile, error) { return &cfgFile, nil } + +// CreateHooks creates instances of Hooks for all of the PreHooks and PostHooks +// configured in a ConfigFile. +func (cfg ConfigFile) CreateHooks() (preHooks, postHooks []middleware.Hook, err error) { + for _, hookCfg := range cfg.MainConfigBlock.PreHooks { + cfgBytes, err := yaml.Marshal(hookCfg.Config) + if err != nil { + panic("failed to remarshal valid YAML") + } + + switch hookCfg.Name { + case "jwt": + var jwtCfg jwt.Config + err := yaml.Unmarshal(cfgBytes, &jwtCfg) + if err != nil { + return nil, nil, errors.New("invalid JWT middleware config" + err.Error()) + } + preHooks = append(preHooks, jwt.NewHook(jwtCfg)) + } + } + + for _, hookCfg := range cfg.MainConfigBlock.PostHooks { + switch hookCfg.Name { + } + } + + return +} diff --git a/cmd/chihaya/main.go b/cmd/chihaya/main.go index 7faf9b4..3473717 100644 --- a/cmd/chihaya/main.go +++ b/cmd/chihaya/main.go @@ -54,8 +54,12 @@ func rootCmdRun(cmd *cobra.Command, args []string) error { return err } - // TODO create Hooks - logic := middleware.NewLogic(cfg.Config, peerStore, nil, nil, nil, nil) + preHooks, postHooks, err := configFile.CreateHooks() + if err != nil { + return err + } + + logic := middleware.NewLogic(cfg.Config, peerStore, preHooks, postHooks) if err != nil { return err } diff --git a/middleware/middleware.go b/middleware/middleware.go index 18cb64b..0778ce0 100644 --- a/middleware/middleware.go +++ b/middleware/middleware.go @@ -18,30 +18,20 @@ type Config struct { var _ frontend.TrackerLogic = &Logic{} -func NewLogic(config Config, peerStore storage.PeerStore, announcePreHooks, announcePostHooks, scrapePreHooks, scrapePostHooks []Hook) *Logic { +func NewLogic(cfg Config, peerStore storage.PeerStore, preHooks, postHooks []Hook) *Logic { l := &Logic{ - announceInterval: config.AnnounceInterval, - peerStore: peerStore, - announcePreHooks: announcePreHooks, - announcePostHooks: announcePostHooks, - scrapePreHooks: scrapePreHooks, - scrapePostHooks: scrapePostHooks, + announceInterval: cfg.AnnounceInterval, + peerStore: peerStore, + preHooks: preHooks, + postHooks: postHooks, } - if len(l.announcePreHooks) == 0 { - l.announcePreHooks = []Hook{nopHook{}} + if len(l.preHooks) == 0 { + l.preHooks = []Hook{nopHook{}} } - if len(l.announcePostHooks) == 0 { - l.announcePostHooks = []Hook{nopHook{}} - } - - if len(l.scrapePreHooks) == 0 { - l.scrapePreHooks = []Hook{nopHook{}} - } - - if len(l.scrapePostHooks) == 0 { - l.scrapePostHooks = []Hook{nopHook{}} + if len(l.postHooks) == 0 { + l.postHooks = []Hook{nopHook{}} } return l @@ -50,12 +40,10 @@ func NewLogic(config Config, peerStore storage.PeerStore, announcePreHooks, anno // Logic is an implementation of the TrackerLogic that functions by // executing a series of middleware hooks. type Logic struct { - announceInterval time.Duration - peerStore storage.PeerStore - announcePreHooks []Hook - announcePostHooks []Hook - scrapePreHooks []Hook - scrapePostHooks []Hook + announceInterval time.Duration + peerStore storage.PeerStore + preHooks []Hook + postHooks []Hook } // HandleAnnounce generates a response for an Announce. @@ -63,7 +51,7 @@ func (l *Logic) HandleAnnounce(ctx context.Context, req *bittorrent.AnnounceRequ resp := &bittorrent.AnnounceResponse{ Interval: l.announceInterval, } - for _, h := range l.announcePreHooks { + for _, h := range l.preHooks { if err := h.HandleAnnounce(ctx, req, resp); err != nil { return nil, err } @@ -75,7 +63,7 @@ func (l *Logic) HandleAnnounce(ctx context.Context, req *bittorrent.AnnounceRequ // AfterAnnounce does something with the results of an Announce after it has // been completed. func (l *Logic) AfterAnnounce(ctx context.Context, req *bittorrent.AnnounceRequest, resp *bittorrent.AnnounceResponse) { - for _, h := range l.announcePostHooks { + for _, h := range l.postHooks { if err := h.HandleAnnounce(ctx, req, resp); err != nil { log.Println("chihaya: post-announce hooks failed:", err.Error()) return @@ -88,7 +76,7 @@ func (l *Logic) HandleScrape(ctx context.Context, req *bittorrent.ScrapeRequest) resp := &bittorrent.ScrapeResponse{ Files: make(map[bittorrent.InfoHash]bittorrent.Scrape), } - for _, h := range l.scrapePreHooks { + for _, h := range l.preHooks { if err := h.HandleScrape(ctx, req, resp); err != nil { return nil, err } @@ -100,7 +88,7 @@ func (l *Logic) HandleScrape(ctx context.Context, req *bittorrent.ScrapeRequest) // AfterScrape does something with the results of a Scrape after it has been // completed. func (l *Logic) AfterScrape(ctx context.Context, req *bittorrent.ScrapeRequest, resp *bittorrent.ScrapeResponse) { - for _, h := range l.scrapePostHooks { + for _, h := range l.postHooks { if err := h.HandleScrape(ctx, req, resp); err != nil { log.Println("chihaya: post-scrape hooks failed:", err.Error()) return