package rel2abs import ( "bytes" "fmt" "net/url" "golang.org/x/net/html" ) func rel2abs(n *html.Node, nurl *url.URL) error { if n.Type == html.ElementNode && n.Data == "a" { for _, a := range n.Attr { if a.Key == "href" { rel, err := url.Parse(a.Val) if err != nil { return fmt.Errorf("relative url: %w\n", err) } a.Val = nurl.ResolveReference(rel).String() } } for c := n.FirstChild; c != nil; c = c.NextSibling { rel2abs(c, nurl) } } return nil } // Converts all relative URLs in htmlContent to absolute URLs, // resolved against a base URL. // Example, with base as http://example.com/foo: // // becomes // func Rel2Abs(htmlContent []byte, base string) ([]byte, error) { doc, err := html.Parse(bytes.NewReader(htmlContent)) if err != nil { return nil, fmt.Errorf("html parse: %w\n", err) } nurl, err := url.Parse(base) if err != nil { return nil, fmt.Errorf("url parse: %w\n", err) } rel2abs(doc, nurl) buf := bytes.Buffer{} html.Render(&buf, doc) return buf.Bytes(), nil }