Sending Webmentions #10
|
@ -68,6 +68,9 @@ func readResponseBody(resp *http.Response) (string, error) {
|
||||||
|
|
||||||
func (OwlHtmlParser) ParseHEntry(resp *http.Response) (ParsedHEntry, error) {
|
func (OwlHtmlParser) ParseHEntry(resp *http.Response) (ParsedHEntry, error) {
|
||||||
htmlStr, err := readResponseBody(resp)
|
htmlStr, err := readResponseBody(resp)
|
||||||
|
if err != nil {
|
||||||
|
return ParsedHEntry{}, err
|
||||||
|
}
|
||||||
doc, err := html.Parse(strings.NewReader(htmlStr))
|
doc, err := html.Parse(strings.NewReader(htmlStr))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ParsedHEntry{}, err
|
return ParsedHEntry{}, err
|
||||||
|
@ -144,7 +147,27 @@ func (OwlHtmlParser) ParseLinksFromString(htmlStr string) ([]string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (OwlHtmlParser) GetWebmentionEndpoint(resp *http.Response) (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)
|
htmlStr, err := readResponseBody(resp)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
doc, err := html.Parse(strings.NewReader(htmlStr))
|
doc, err := html.Parse(strings.NewReader(htmlStr))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
|
@ -154,7 +177,7 @@ func (OwlHtmlParser) GetWebmentionEndpoint(resp *http.Response) (string, error)
|
||||||
findEndpoint = func(n *html.Node) (string, error) {
|
findEndpoint = func(n *html.Node) (string, error) {
|
||||||
if n.Type == html.ElementNode && (n.Data == "link" || n.Data == "a") {
|
if n.Type == html.ElementNode && (n.Data == "link" || n.Data == "a") {
|
||||||
for _, attr := range n.Attr {
|
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 {
|
for _, attr := range n.Attr {
|
||||||
if attr.Key == "href" {
|
if attr.Key == "href" {
|
||||||
return attr.Val, nil
|
return attr.Val, nil
|
||||||
|
@ -171,5 +194,13 @@ func (OwlHtmlParser) GetWebmentionEndpoint(resp *http.Response) (string, error)
|
||||||
}
|
}
|
||||||
return "", errors.New("no webmention endpoint found")
|
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
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,9 +5,20 @@ import (
|
||||||
"h4kor/owl-blogs"
|
"h4kor/owl-blogs"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/url"
|
||||||
"testing"
|
"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
|
// https://www.w3.org/TR/webmention/#h-webmention-verification
|
||||||
//
|
//
|
||||||
|
@ -41,7 +52,7 @@ func TestParseValidHEntryWithoutTitle(t *testing.T) {
|
||||||
func TestGetWebmentionEndpointLink(t *testing.T) {
|
func TestGetWebmentionEndpointLink(t *testing.T) {
|
||||||
html := []byte("<link rel=\"webmention\" href=\"http://example.com/webmention\" />")
|
html := []byte("<link rel=\"webmention\" href=\"http://example.com/webmention\" />")
|
||||||
parser := &owl.OwlHtmlParser{}
|
parser := &owl.OwlHtmlParser{}
|
||||||
endpoint, err := parser.GetWebmentionEndpoint(&http.Response{Body: io.NopCloser(bytes.NewReader(html))})
|
endpoint, err := parser.GetWebmentionEndpoint(constructResponse(html))
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Unable to parse feed: %v", err)
|
t.Errorf("Unable to parse feed: %v", err)
|
||||||
|
@ -54,7 +65,7 @@ func TestGetWebmentionEndpointLink(t *testing.T) {
|
||||||
func TestGetWebmentionEndpointLinkA(t *testing.T) {
|
func TestGetWebmentionEndpointLinkA(t *testing.T) {
|
||||||
html := []byte("<a rel=\"webmention\" href=\"http://example.com/webmention\" />")
|
html := []byte("<a rel=\"webmention\" href=\"http://example.com/webmention\" />")
|
||||||
parser := &owl.OwlHtmlParser{}
|
parser := &owl.OwlHtmlParser{}
|
||||||
endpoint, err := parser.GetWebmentionEndpoint(&http.Response{Body: io.NopCloser(bytes.NewReader(html))})
|
endpoint, err := parser.GetWebmentionEndpoint(constructResponse(html))
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Unable to parse feed: %v", err)
|
t.Errorf("Unable to parse feed: %v", err)
|
||||||
|
@ -64,42 +75,85 @@ func TestGetWebmentionEndpointLinkA(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// func TestRealWorldWebmention(t *testing.T) {
|
func TestGetWebmentionEndpointLinkHeader(t *testing.T) {
|
||||||
// links := []string{
|
html := []byte("")
|
||||||
// "https://webmention.rocks/test/1",
|
parser := &owl.OwlHtmlParser{}
|
||||||
// "https://webmention.rocks/test/2",
|
resp := constructResponse(html)
|
||||||
// "https://webmention.rocks/test/3",
|
resp.Header = http.Header{"Link": []string{"<http://example.com/webmention>; rel=\"webmention\""}}
|
||||||
// "https://webmention.rocks/test/4",
|
endpoint, err := parser.GetWebmentionEndpoint(resp)
|
||||||
// "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",
|
|
||||||
// }
|
|
||||||
|
|
||||||
// for _, link := range links {
|
if err != nil {
|
||||||
// parser := &owl.OwlHtmlParser{}
|
t.Errorf("Unable to parse feed: %v", err)
|
||||||
// client := &owl.OwlHttpClient{}
|
}
|
||||||
// html, _ := client.Get(link)
|
if endpoint != "http://example.com/webmention" {
|
||||||
// _, err := parser.GetWebmentionEndpoint(html)
|
t.Errorf("Wrong endpoint. Expected %v, got %v", "http://example.com/webmention", endpoint)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// if err != nil {
|
func TestGetWebmentionEndpointRelativeLink(t *testing.T) {
|
||||||
// t.Errorf("Unable to find webmention: %v for link %v", err, link)
|
html := []byte("<link rel=\"webmention\" href=\"/webmention\" />")
|
||||||
// }
|
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("<link rel=\"webmention\" href=\"/webmention\" />")
|
||||||
|
parser := &owl.OwlHtmlParser{}
|
||||||
|
resp := constructResponse(html)
|
||||||
|
resp.Header = http.Header{"Link": []string{"</webmention>; 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue