diff --git a/src/feeds/http.go b/src/feeds/http.go index 738f1ca..31f7cdd 100644 --- a/src/feeds/http.go +++ b/src/feeds/http.go @@ -3,6 +3,9 @@ package feeds import ( "context" "fmt" + "io" + "net/http" + "net/url" "regexp" "slices" "sort" @@ -14,6 +17,16 @@ import ( "github.com/robfig/cron/v3" ) +var ( + ProxyU = func() *url.URL { + u, err := url.Parse("socks5://wghttp.inhome.blapointe.com:63114") + if err != nil { + panic(err) + } + return u + }() +) + func (feed Feed) ShouldExecute() (bool, error) { if feed.Entry.Deleted.IsZero() { return false, nil @@ -36,7 +49,12 @@ func (feed Feed) ShouldExecute() (bool, error) { } func (feed Feed) Fetch(ctx context.Context) (Items, error) { - gfeed, err := gofeed.NewParser().ParseURLWithContext(feed.Version.URL, ctx) + resp, err := proxyFetch(ctx, feed.Version.URL) + if err != nil { + return nil, err + } + + gfeed, err := gofeed.NewParser().ParseString(resp) if err != nil { return nil, err } @@ -84,3 +102,30 @@ func (feed Feed) Fetch(ctx context.Context) (Items, error) { return result, nil } + +func proxyFetch(ctx context.Context, u string) (string, error) { + req, err := http.NewRequest(http.MethodGet, u, nil) + if err != nil { + return "", err + } + + c := http.Client{Timeout: time.Minute} + if ProxyU != nil { + c.Transport = &http.Transport{Proxy: http.ProxyURL(ProxyU)} + } + + resp, err := c.Do(req) + if err != nil { + return "", err + } + defer resp.Body.Close() + defer io.Copy(io.Discard, resp.Body) + + b, _ := io.ReadAll(resp.Body) + + if resp.StatusCode != http.StatusOK { + return "", fmt.Errorf("failed fetch: (%d) %s", resp.StatusCode, b) + } + + return string(b), nil +} diff --git a/src/feeds/http_integration_test.go b/src/feeds/http_integration_test.go new file mode 100644 index 0000000..0923aec --- /dev/null +++ b/src/feeds/http_integration_test.go @@ -0,0 +1,48 @@ +//go:build integration + +package feeds_test + +import ( + "context" + "os" + "show-rss/src/feeds" + "testing" + "time" +) + +func TestIntegrationFeedFetchProxy(t *testing.T) { + os.Setenv("PROXY", "socks5://wghttp.inhome.blapointe.com:63114") + t.Cleanup(func() { + os.Unsetenv("PROXY") + }) + + ctx := context.Background() + + created := time.Now().Add(-4 * time.Second) + feed := feeds.Feed{ + Entry: feeds.Entry{ + ID: "id", + Created: created, + Updated: created, + Deleted: time.Time{}, + }, + Version: feeds.Version{ + Created: created, + URL: "http://rss.slashdot.org/Slashdot/slashdotMain?format=usm", + Cron: "* * * * *", + Pattern: ".*", + }, + Execution: feeds.Execution{ + Executed: created.Add(-2 * time.Second), + Version: created, + }, + } + + items, err := feed.Fetch(ctx) + if err != nil { + t.Fatalf("failed fetch: %v", err) + } + for i, item := range items { + t.Logf("[%d] %+v", i, item) + } +} diff --git a/src/feeds/http_test.go b/src/feeds/http_test.go index 83aa3c5..47e3288 100644 --- a/src/feeds/http_test.go +++ b/src/feeds/http_test.go @@ -14,6 +14,12 @@ import ( func TestFeedFetch(t *testing.T) { ctx := context.Background() + proxyU := feeds.ProxyU + feeds.ProxyU = nil + t.Cleanup(func() { + feeds.ProxyU = proxyU + }) + s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { t.Logf("%s", r.URL.String())