diff --git a/docs/configuration.md b/docs/configuration.md index 06e8731..c35df8c 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -527,10 +527,22 @@ An array of RSS/atom feeds. The title can optionally be changed. | hide-categories | boolean | no | false | Only applicable for `detailed-list` style | | hide-description | boolean | no | false | Only applicable for `detailed-list` style | | item-link-prefix | string | no | | | +| headers | key (string) & value (string) | no | | | ###### `item-link-prefix` If an RSS feed isn't returning item links with a base domain and Glance has failed to automatically detect the correct domain you can manually add a prefix to each link with this property. +###### `headers` +Optionally specify the headers that will be sent with the request. Example: + +```yaml +- type: rss + feeds: + - url: https://domain.com/rss + headers: + User-Agent: Custom User Agent +``` + ##### `limit` The maximum number of articles to show. diff --git a/internal/feed/rss.go b/internal/feed/rss.go index ec6ab2e..45cbb14 100644 --- a/internal/feed/rss.go +++ b/internal/feed/rss.go @@ -1,10 +1,11 @@ package feed import ( - "context" "fmt" "html" + "io" "log/slog" + "net/http" "net/url" "regexp" "sort" @@ -57,12 +58,13 @@ func shortenFeedDescriptionLen(description string, maxLen int) string { } type RSSFeedRequest struct { - Url string `yaml:"url"` - Title string `yaml:"title"` - HideCategories bool `yaml:"hide-categories"` - HideDescription bool `yaml:"hide-description"` - ItemLinkPrefix string `yaml:"item-link-prefix"` - IsDetailed bool `yaml:"-"` + Url string `yaml:"url"` + Title string `yaml:"title"` + HideCategories bool `yaml:"hide-categories"` + HideDescription bool `yaml:"hide-description"` + ItemLinkPrefix string `yaml:"item-link-prefix"` + Headers map[string]string `yaml:"headers"` + IsDetailed bool `yaml:"-"` } type RSSFeedItems []RSSFeedItem @@ -78,10 +80,31 @@ func (f RSSFeedItems) SortByNewest() RSSFeedItems { var feedParser = gofeed.NewParser() func getItemsFromRSSFeedTask(request RSSFeedRequest) ([]RSSFeedItem, error) { - ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) - defer cancel() + req, err := http.NewRequest("GET", request.Url, nil) + if err != nil { + return nil, err + } - feed, err := feedParser.ParseURLWithContext(request.Url, ctx) + for key, value := range request.Headers { + req.Header.Add(key, value) + } + + resp, err := defaultClient.Do(req) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + return nil, fmt.Errorf("unexpected status code %d from %s", resp.StatusCode, request.Url) + } + + body, err := io.ReadAll(resp.Body) + if err != nil { + return nil, err + } + + feed, err := feedParser.ParseString(string(body)) if err != nil { return nil, err