package proxy
import (
"bytes"
"strings"
"golang.org/x/net/html"
)
// rewriteHTMLBody parses HTML and rewrites absolute URLs in known attributes
// so they include the token prefix. This is needed because many sites (e.g.
// GitHub) use Content-Security-Policy that blocks inline scripts, making the
// JS-injection approach unreliable.
func rewriteHTMLBody(body []byte, prefix string) []byte {
if prefix == "" {
return body
}
doc, err := html.Parse(bytes.NewReader(body))
if err != nil {
return body
}
rewriteNode(doc, prefix)
var buf bytes.Buffer
if err := html.Render(&buf, doc); err != nil {
return body
}
return buf.Bytes()
}
// urlAttrs lists element attributes that contain URLs which should be rewritten.
var urlAttrs = []string{
"href",
"src",
"action",
"poster",
"formaction",
"cite",
"longdesc",
"profile",
"background",
"data-url",
"data-href",
}
func rewriteNode(n *html.Node, prefix string) {
if n.Type == html.ElementNode {
for i := range n.Attr {
attr := &n.Attr[i]
if isURLAttr(attr.Key) {
attr.Val = rewriteURL(attr.Val, prefix)
continue
}
//
if strings.EqualFold(n.Data, "meta") &&
strings.EqualFold(attr.Key, "content") &&
isRefreshMeta(n) {
attr.Val = rewriteRefreshContent(attr.Val, prefix)
}
}
// Rewrite url(...) inside