From dae31bb0192e6b519111d3cb80ddd4312cda306c Mon Sep 17 00:00:00 2001 From: René 'Necoro' Neumann Date: Mon, 25 May 2020 20:33:06 +0200 Subject: 'Exec' as an alternative to 'Url' --- internal/feed/parse.go | 47 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 39 insertions(+), 8 deletions(-) (limited to 'internal/feed/parse.go') diff --git a/internal/feed/parse.go b/internal/feed/parse.go index a8f705a..77dfe69 100644 --- a/internal/feed/parse.go +++ b/internal/feed/parse.go @@ -2,6 +2,8 @@ package feed import ( "fmt" + "io" + "os/exec" "github.com/google/uuid" "github.com/mmcdole/gofeed" @@ -13,15 +15,44 @@ import ( func (feed *Feed) parse() error { fp := gofeed.NewParser() - // we do not use the http support in gofeed, so that we can control the behavior of http requests - // and ensure it to be the same in all places - resp, cancel, err := http.Get(feed.Url, feed.Global.Timeout, feed.NoTLS) - if err != nil { - return fmt.Errorf("while fetching %s from %s: %w", feed.Name, feed.Url, err) + var reader io.Reader + var cleanup func() error + + if feed.Url != "" { + // we do not use the http support in gofeed, so that we can control the behavior of http requests + // and ensure it to be the same in all places + resp, cancel, err := http.Get(feed.Url, feed.Global.Timeout, feed.NoTLS) + if err != nil { + return fmt.Errorf("while fetching %s from %s: %w", feed.Name, feed.Url, err) + } + defer cancel() // includes resp.Body.Close + + reader = resp.Body + cleanup = func() error { return nil } + } else { // exec + // we use the same context as for HTTP + ctx, cancel := http.Context(feed.Global.Timeout) + cmd := exec.CommandContext(ctx, feed.Exec[0], feed.Exec[1:]...) + defer func() { + cancel() + // cmd.Wait might have already been called -- but call it again to be sure + _ = cmd.Wait() + }() + + stdout, err := cmd.StdoutPipe() + if err != nil { + return fmt.Errorf("preparing exec for feed '%s': %w", feed.Name, err) + } + + if err = cmd.Start(); err != nil { + return fmt.Errorf("starting exec for feed '%s: %w", feed.Name, err) + } + + reader = stdout + cleanup = cmd.Wait } - defer cancel() // includes resp.Body.Close - parsedFeed, err := fp.Parse(resp.Body) + parsedFeed, err := fp.Parse(reader) if err != nil { return fmt.Errorf("parsing feed '%s': %w", feed.Name, err) } @@ -31,7 +62,7 @@ func (feed *Feed) parse() error { for idx, feedItem := range parsedFeed.Items { feed.items[idx] = item{Feed: parsedFeed, Item: feedItem, itemId: uuid.New(), feed: feed} } - return nil + return cleanup() } func handleFeed(feed *Feed) { -- cgit v1.2.3-54-g00ecf