diff --git a/reader/atom/atom.go b/reader/atom/atom.go index f72a150c..315961ed 100644 --- a/reader/atom/atom.go +++ b/reader/atom/atom.go @@ -14,6 +14,7 @@ import ( "github.com/miniflux/miniflux/helper" "github.com/miniflux/miniflux/model" "github.com/miniflux/miniflux/reader/date" + "github.com/miniflux/miniflux/url" ) type atomFeed struct { @@ -70,10 +71,19 @@ func (a *atomFeed) Transform() *model.Feed { for _, entry := range a.Entries { item := entry.Transform() + entryURL, err := url.AbsoluteURL(feed.SiteURL, item.URL) + if err == nil { + item.URL = entryURL + } + if item.Author == "" { item.Author = getAuthor(a.Author) } + if item.Title == "" { + item.Title = item.URL + } + feed.Entries = append(feed.Entries, item) } @@ -89,11 +99,6 @@ func (a *atomEntry) Transform() *model.Entry { entry.Content = getContent(a) entry.Title = strings.TrimSpace(a.Title) entry.Enclosures = getEnclosures(a) - - if entry.Title == "" { - entry.Title = entry.URL - } - return entry } diff --git a/reader/atom/parser_test.go b/reader/atom/parser_test.go index 66ca0f05..be07383c 100644 --- a/reader/atom/parser_test.go +++ b/reader/atom/parser_test.go @@ -152,6 +152,32 @@ func TestParseFeedURL(t *testing.T) { } } +func TestParseEntryWithRelativeURL(t *testing.T) { + data := ` + + Example Feed + + + + Test + + urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a + 2003-12-13T18:30:02Z + Some text. + + + ` + + feed, err := Parse(bytes.NewBufferString(data)) + if err != nil { + t.Error(err) + } + + if feed.Entries[0].URL != "http://example.org/something.html" { + t.Errorf("Incorrect entry URL, got: %s", feed.Entries[0].URL) + } +} + func TestParseEntryTitleWithWhitespaces(t *testing.T) { data := ` diff --git a/reader/json/json.go b/reader/json/json.go index 59249163..ad920686 100644 --- a/reader/json/json.go +++ b/reader/json/json.go @@ -13,6 +13,7 @@ import ( "github.com/miniflux/miniflux/model" "github.com/miniflux/miniflux/reader/date" "github.com/miniflux/miniflux/reader/sanitizer" + "github.com/miniflux/miniflux/url" ) type jsonFeed struct { @@ -66,6 +67,11 @@ func (j *jsonFeed) Transform() *model.Feed { for _, item := range j.Items { entry := item.Transform() + entryURL, err := url.AbsoluteURL(feed.SiteURL, entry.URL) + if err == nil { + entry.URL = entryURL + } + if entry.Author == "" { entry.Author = j.GetAuthor() } diff --git a/reader/json/parser_test.go b/reader/json/parser_test.go index e6fa9ed5..a3d5b5be 100644 --- a/reader/json/parser_test.go +++ b/reader/json/parser_test.go @@ -174,6 +174,31 @@ func TestParsePodcast(t *testing.T) { } } +func TestParseFeedWithRelativeURL(t *testing.T) { + data := `{ + "version": "https://jsonfeed.org/version/1", + "title": "Example", + "home_page_url": "https://example.org/", + "feed_url": "https://example.org/feed.json", + "items": [ + { + "id": "2347259", + "url": "something.html", + "date_published": "2016-02-09T14:22:00-07:00" + } + ] + }` + + feed, err := Parse(bytes.NewBufferString(data)) + if err != nil { + t.Error(err) + } + + if feed.Entries[0].URL != "https://example.org/something.html" { + t.Errorf("Incorrect entry URL, got: %s", feed.Entries[0].URL) + } +} + func TestParseAuthor(t *testing.T) { data := `{ "version": "https://jsonfeed.org/version/1", diff --git a/reader/rdf/parser_test.go b/reader/rdf/parser_test.go index 6447bf2e..e025e537 100644 --- a/reader/rdf/parser_test.go +++ b/reader/rdf/parser_test.go @@ -266,6 +266,31 @@ func TestParseItemWithOnlyFeedAuthor(t *testing.T) { } } +func TestParseItemRelativeURL(t *testing.T) { + data := ` + + + Example + http://example.org + + + + Title + Test + something.html + + ` + + feed, err := Parse(bytes.NewBufferString(data)) + if err != nil { + t.Error(err) + } + + if feed.Entries[0].URL != "http://example.org/something.html" { + t.Errorf("Incorrect entry url, got: %s", feed.Entries[0].URL) + } +} + func TestParseItemWithoutLink(t *testing.T) { data := ` diff --git a/reader/rdf/rdf.go b/reader/rdf/rdf.go index ad4d53a0..3586f6e9 100644 --- a/reader/rdf/rdf.go +++ b/reader/rdf/rdf.go @@ -12,6 +12,7 @@ import ( "github.com/miniflux/miniflux/helper" "github.com/miniflux/miniflux/model" "github.com/miniflux/miniflux/reader/sanitizer" + "github.com/miniflux/miniflux/url" ) type rdfFeed struct { @@ -29,13 +30,17 @@ func (r *rdfFeed) Transform() *model.Feed { for _, item := range r.Items { entry := item.Transform() - if entry.Author == "" && r.Creator != "" { entry.Author = sanitizer.StripTags(r.Creator) } if entry.URL == "" { entry.URL = feed.SiteURL + } else { + entryURL, err := url.AbsoluteURL(feed.SiteURL, entry.URL) + if err == nil { + entry.URL = entryURL + } } feed.Entries = append(feed.Entries, entry) diff --git a/reader/rss/parser_test.go b/reader/rss/parser_test.go index 982d4f0b..7d724177 100644 --- a/reader/rss/parser_test.go +++ b/reader/rss/parser_test.go @@ -537,6 +537,27 @@ func TestParseEntryWithFeedBurnerEnclosures(t *testing.T) { } } +func TestParseEntryWithRelativeURL(t *testing.T) { + data := ` + + + https://example.org/ + + item.html + + + ` + + feed, err := Parse(bytes.NewBufferString(data)) + if err != nil { + t.Error(err) + } + + if feed.Entries[0].Title != "https://example.org/item.html" { + t.Errorf("Incorrect entry title, got: %s", feed.Entries[0].Title) + } +} + func TestParseInvalidXml(t *testing.T) { data := `garbage` _, err := Parse(bytes.NewBufferString(data)) diff --git a/reader/rss/rss.go b/reader/rss/rss.go index b80692c0..fcfccbd1 100644 --- a/reader/rss/rss.go +++ b/reader/rss/rss.go @@ -15,6 +15,7 @@ import ( "github.com/miniflux/miniflux/helper" "github.com/miniflux/miniflux/model" "github.com/miniflux/miniflux/reader/date" + "github.com/miniflux/miniflux/url" ) type rssFeed struct { @@ -103,6 +104,15 @@ func (r *rssFeed) Transform() *model.Feed { if entry.URL == "" { entry.URL = feed.SiteURL + } else { + entryURL, err := url.AbsoluteURL(feed.SiteURL, entry.URL) + if err == nil { + entry.URL = entryURL + } + } + + if entry.Title == "" { + entry.Title = entry.URL } feed.Entries = append(feed.Entries, entry) @@ -213,11 +223,6 @@ func (r *rssItem) Transform() *model.Entry { entry.Content = r.GetContent() entry.Title = strings.TrimSpace(r.Title) entry.Enclosures = r.GetEnclosures() - - if entry.Title == "" { - entry.Title = entry.URL - } - return entry }