Repository: raviqqe/muffet (go)

Issue:
Wrong handling of multi-url srcset
Muffet finds 1 link instead of 3 in the following HTML:

```html
<picture>
  <source type="image/webp" srcset="images/1-300w.webp 300w, images/1-600w.webp 600w, images/1-1200w.webp 1200w">
</picture
```

For example, for `http://localhost` would be `http://localhost/images/1-300w.webp 300w, images/1-600w.webp 600w, images/1-1200w.webp 1200w` URL that always fails with 404 error

Pull request description:
Fix srcset parsing
Close #196.


Patch:
diff --git a/link_finder.go b/link_finder.go
index 74d9acc..6688704 100644
--- a/link_finder.go
+++ b/link_finder.go
@@ -27,6 +27,8 @@ var atomToAttributes = map[atom.Atom][]string{
 	atom.Track:  {"src"},
 }
 
+var imageDescriptorPattern = regexp.MustCompile(" [^ ]*$")
+
 type linkFinder struct {
 	excludedPatterns []*regexp.Regexp
 }
@@ -43,18 +45,31 @@ func (f linkFinder) Find(n *html.Node, base *url.URL) map[string]error {
 		return ok
 	}) {
 		for _, a := range atomToAttributes[n.DataAtom] {
-			s := strings.TrimSpace(scrape.Attr(n, a))
+			s := scrape.Attr(n, a)
+			ss := []string{}
 
-			if s == "" || f.isLinkExcluded(s) {
-				continue
+			if a == "srcset" {
+				for _, s := range strings.Split(s, ",") {
+					ss = append(ss, imageDescriptorPattern.ReplaceAllString(strings.TrimSpace(s), ""))
+				}
+			} else {
+				ss = append(ss, s)
 			}
 
-			u, err := url.Parse(s)
-			if err != nil {
-				ls[s] = err
-				continue
-			} else if _, ok := validSchemes[u.Scheme]; ok {
-				ls[base.ResolveReference(u).String()] = nil
+			for _, s := range ss {
+				s := strings.TrimSpace(s)
+
+				if s == "" || f.isLinkExcluded(s) {
+					continue
+				}
+
+				u, err := url.Parse(s)
+				if err != nil {
+					ls[s] = err
+					continue
+				} else if _, ok := validSchemes[u.Scheme]; ok {
+					ls[base.ResolveReference(u).String()] = nil
+				}
 			}
 		}
 	}


Test patch:
diff --git a/link_finder_test.go b/link_finder_test.go
index 2a6ec5a..66159c8 100644
--- a/link_finder_test.go
+++ b/link_finder_test.go
@@ -141,6 +141,62 @@ func TestLinkFinderIsLinkExcluded(t *testing.T) {
 	}
 }
 
+func TestLinkFinderFindLinkInSrcSet(t *testing.T) {
+	b, err := url.Parse("http://foo.com")
+	assert.Nil(t, err)
+
+	n, err := html.Parse(strings.NewReader(
+		htmlWithBody(`<source srcset="foo.png" />`)),
+	)
+	assert.Nil(t, err)
+
+	ls := newLinkFinder(nil).Find(n, b)
+
+	err, ok := ls["http://foo.com/foo.png"]
+	assert.True(t, ok)
+	assert.Nil(t, err)
+}
+
+func TestLinkFinderFindMultipleLinksInSrcSet(t *testing.T) {
+	b, err := url.Parse("http://foo.com")
+	assert.Nil(t, err)
+
+	n, err := html.Parse(strings.NewReader(
+		htmlWithBody(`<source srcset="foo.png, bar.png" />`)),
+	)
+	assert.Nil(t, err)
+
+	ls := newLinkFinder(nil).Find(n, b)
+
+	err, ok := ls["http://foo.com/foo.png"]
+	assert.True(t, ok)
+	assert.Nil(t, err)
+
+	err, ok = ls["http://foo.com/bar.png"]
+	assert.True(t, ok)
+	assert.Nil(t, err)
+}
+
+func TestLinkFinderFindMultipleLinksInSrcSetWithDescriptors(t *testing.T) {
+	b, err := url.Parse("http://foo.com")
+	assert.Nil(t, err)
+
+	n, err := html.Parse(strings.NewReader(
+		htmlWithBody(`<source srcset="foo.png 100w, bar.png 200w" />`)),
+	)
+	assert.Nil(t, err)
+
+	ls := newLinkFinder(nil).Find(n, b)
+
+	err, ok := ls["http://foo.com/foo.png"]
+	assert.True(t, ok)
+	assert.Nil(t, err)
+
+	err, ok = ls["http://foo.com/bar.png"]
+	assert.True(t, ok)
+	assert.Nil(t, err)
+}
+
 func htmlWithBody(b string) string {
 	return fmt.Sprintf(`<html><body>%v</body></html>`, b)
 }