diff --git a/webmention.go b/webmention.go
index 0e47c43..4a82994 100644
--- a/webmention.go
+++ b/webmention.go
@@ -68,6 +68,9 @@ func readResponseBody(resp *http.Response) (string, error) {
func (OwlHtmlParser) ParseHEntry(resp *http.Response) (ParsedHEntry, error) {
htmlStr, err := readResponseBody(resp)
+ if err != nil {
+ return ParsedHEntry{}, err
+ }
doc, err := html.Parse(strings.NewReader(htmlStr))
if err != nil {
return ParsedHEntry{}, err
@@ -144,7 +147,27 @@ func (OwlHtmlParser) ParseLinksFromString(htmlStr string) ([]string, error) {
}
func (OwlHtmlParser) GetWebmentionEndpoint(resp *http.Response) (string, error) {
+ //request url
+ requestUrl := resp.Request.URL
+
+ // Check link headers
+ for _, link := range resp.Header["Link"] {
+ if strings.Contains(link, "rel=\"webmention\"") || strings.Contains(link, "rel=webmention") {
+ link := strings.Split(link, ";")[0]
+ link = strings.Trim(link, "<>")
+ linkUrl, err := url.Parse(link)
+ if err != nil {
+ return "", err
+ }
+ return requestUrl.ResolveReference(linkUrl).String(), nil
+
+ }
+ }
+
htmlStr, err := readResponseBody(resp)
+ if err != nil {
+ return "", err
+ }
doc, err := html.Parse(strings.NewReader(htmlStr))
if err != nil {
return "", err
@@ -154,7 +177,7 @@ func (OwlHtmlParser) GetWebmentionEndpoint(resp *http.Response) (string, error)
findEndpoint = func(n *html.Node) (string, error) {
if n.Type == html.ElementNode && (n.Data == "link" || n.Data == "a") {
for _, attr := range n.Attr {
- if attr.Key == "rel" && attr.Val == "webmention" {
+ if attr.Key == "rel" && strings.Contains(attr.Val, "webmention") {
for _, attr := range n.Attr {
if attr.Key == "href" {
return attr.Val, nil
@@ -171,5 +194,13 @@ func (OwlHtmlParser) GetWebmentionEndpoint(resp *http.Response) (string, error)
}
return "", errors.New("no webmention endpoint found")
}
- return findEndpoint(doc)
+ linkUrlStr, err := findEndpoint(doc)
+ if err != nil {
+ return "", err
+ }
+ linkUrl, err := url.Parse(linkUrlStr)
+ if err != nil {
+ return "", err
+ }
+ return requestUrl.ResolveReference(linkUrl).String(), nil
}
diff --git a/webmention_test.go b/webmention_test.go
index abb7bea..682587d 100644
--- a/webmention_test.go
+++ b/webmention_test.go
@@ -5,9 +5,20 @@ import (
"h4kor/owl-blogs"
"io"
"net/http"
+ "net/url"
"testing"
)
+func constructResponse(html []byte) *http.Response {
+ url, _ := url.Parse("http://example.com/foo/bar")
+ return &http.Response{
+ Request: &http.Request{
+ URL: url,
+ },
+ Body: io.NopCloser(bytes.NewReader([]byte(html))),
+ }
+}
+
//
// https://www.w3.org/TR/webmention/#h-webmention-verification
//
@@ -41,7 +52,7 @@ func TestParseValidHEntryWithoutTitle(t *testing.T) {
func TestGetWebmentionEndpointLink(t *testing.T) {
html := []byte("")
parser := &owl.OwlHtmlParser{}
- endpoint, err := parser.GetWebmentionEndpoint(&http.Response{Body: io.NopCloser(bytes.NewReader(html))})
+ endpoint, err := parser.GetWebmentionEndpoint(constructResponse(html))
if err != nil {
t.Errorf("Unable to parse feed: %v", err)
@@ -54,7 +65,7 @@ func TestGetWebmentionEndpointLink(t *testing.T) {
func TestGetWebmentionEndpointLinkA(t *testing.T) {
html := []byte("")
parser := &owl.OwlHtmlParser{}
- endpoint, err := parser.GetWebmentionEndpoint(&http.Response{Body: io.NopCloser(bytes.NewReader(html))})
+ endpoint, err := parser.GetWebmentionEndpoint(constructResponse(html))
if err != nil {
t.Errorf("Unable to parse feed: %v", err)
@@ -64,42 +75,85 @@ func TestGetWebmentionEndpointLinkA(t *testing.T) {
}
}
-// func TestRealWorldWebmention(t *testing.T) {
-// links := []string{
-// "https://webmention.rocks/test/1",
-// "https://webmention.rocks/test/2",
-// "https://webmention.rocks/test/3",
-// "https://webmention.rocks/test/4",
-// "https://webmention.rocks/test/5",
-// "https://webmention.rocks/test/6",
-// "https://webmention.rocks/test/7",
-// "https://webmention.rocks/test/8",
-// "https://webmention.rocks/test/9",
-// "https://webmention.rocks/test/10",
-// "https://webmention.rocks/test/11",
-// "https://webmention.rocks/test/12",
-// "https://webmention.rocks/test/13",
-// "https://webmention.rocks/test/14",
-// "https://webmention.rocks/test/15",
-// "https://webmention.rocks/test/16",
-// "https://webmention.rocks/test/17",
-// "https://webmention.rocks/test/18",
-// "https://webmention.rocks/test/19",
-// "https://webmention.rocks/test/20",
-// "https://webmention.rocks/test/21",
-// "https://webmention.rocks/test/22",
-// "https://webmention.rocks/test/23/page",
-// }
+func TestGetWebmentionEndpointLinkHeader(t *testing.T) {
+ html := []byte("")
+ parser := &owl.OwlHtmlParser{}
+ resp := constructResponse(html)
+ resp.Header = http.Header{"Link": []string{"; rel=\"webmention\""}}
+ endpoint, err := parser.GetWebmentionEndpoint(resp)
-// for _, link := range links {
-// parser := &owl.OwlHtmlParser{}
-// client := &owl.OwlHttpClient{}
-// html, _ := client.Get(link)
-// _, err := parser.GetWebmentionEndpoint(html)
+ if err != nil {
+ t.Errorf("Unable to parse feed: %v", err)
+ }
+ if endpoint != "http://example.com/webmention" {
+ t.Errorf("Wrong endpoint. Expected %v, got %v", "http://example.com/webmention", endpoint)
+ }
+}
-// if err != nil {
-// t.Errorf("Unable to find webmention: %v for link %v", err, link)
-// }
-// }
+func TestGetWebmentionEndpointRelativeLink(t *testing.T) {
+ html := []byte("")
+ parser := &owl.OwlHtmlParser{}
+ endpoint, err := parser.GetWebmentionEndpoint(constructResponse(html))
-// }
+ if err != nil {
+ t.Errorf("Unable to parse feed: %v", err)
+ }
+ if endpoint != "http://example.com/webmention" {
+ t.Errorf("Wrong endpoint. Expected %v, got %v", "http://example.com/webmention", endpoint)
+ }
+}
+
+func TestGetWebmentionEndpointRelativeLinkInHeader(t *testing.T) {
+ html := []byte("")
+ parser := &owl.OwlHtmlParser{}
+ resp := constructResponse(html)
+ resp.Header = http.Header{"Link": []string{"; rel=\"webmention\""}}
+ endpoint, err := parser.GetWebmentionEndpoint(resp)
+
+ if err != nil {
+ t.Errorf("Unable to parse feed: %v", err)
+ }
+ if endpoint != "http://example.com/webmention" {
+ t.Errorf("Wrong endpoint. Expected %v, got %v", "http://example.com/webmention", endpoint)
+ }
+}
+
+func TestRealWorldWebmention(t *testing.T) {
+ links := []string{
+ "https://webmention.rocks/test/1",
+ "https://webmention.rocks/test/2",
+ "https://webmention.rocks/test/3",
+ "https://webmention.rocks/test/4",
+ "https://webmention.rocks/test/5",
+ "https://webmention.rocks/test/6",
+ "https://webmention.rocks/test/7",
+ "https://webmention.rocks/test/8",
+ "https://webmention.rocks/test/9",
+ // "https://webmention.rocks/test/10", // not supported
+ "https://webmention.rocks/test/11",
+ "https://webmention.rocks/test/12",
+ "https://webmention.rocks/test/13",
+ "https://webmention.rocks/test/14",
+ "https://webmention.rocks/test/15",
+ "https://webmention.rocks/test/16",
+ "https://webmention.rocks/test/17",
+ "https://webmention.rocks/test/18",
+ "https://webmention.rocks/test/19",
+ "https://webmention.rocks/test/20",
+ "https://webmention.rocks/test/21",
+ "https://webmention.rocks/test/22",
+ "https://webmention.rocks/test/23/page",
+ }
+
+ for _, link := range links {
+ parser := &owl.OwlHtmlParser{}
+ client := &owl.OwlHttpClient{}
+ html, _ := client.Get(link)
+ _, err := parser.GetWebmentionEndpoint(html)
+
+ if err != nil {
+ t.Errorf("Unable to find webmention: %v for link %v", err, link)
+ }
+ }
+
+}