From fffd444cba38784d45a612512252f3f370c4fe27 Mon Sep 17 00:00:00 2001 From: XOF Date: Mon, 15 Dec 2025 01:47:36 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20proxy/rewriter.go?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- proxy/rewriter.go | 306 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 306 insertions(+) create mode 100644 proxy/rewriter.go diff --git a/proxy/rewriter.go b/proxy/rewriter.go new file mode 100644 index 0000000..fd93cdc --- /dev/null +++ b/proxy/rewriter.go @@ -0,0 +1,306 @@ +//proxy/rewriter.go +package proxy + +import ( + "bytes" + "golang.org/x/net/html" + "net/url" + "strings" +) + +type ContentRewriter struct { + baseURL *url.URL +} + +func NewContentRewriter(baseURL string) (*ContentRewriter, error) { + u, err := url.Parse(baseURL) + if err != nil { + return nil, err + } + + return &ContentRewriter{ + baseURL: u, + }, nil +} + +// RewriteHTML 重写 HTML 内容中的所有 URL +func (r *ContentRewriter) RewriteHTML(body []byte) ([]byte, error) { + doc, err := html.Parse(bytes.NewReader(body)) + if err != nil { + // 如果解析失败,使用简单的字符串替换 + return r.simpleRewriteHTML(body), nil + } + + r.rewriteNode(doc) + + var buf bytes.Buffer + if err := html.Render(&buf, doc); err != nil { + return r.simpleRewriteHTML(body), nil + } + + return buf.Bytes(), nil +} + +// rewriteNode 递归重写 HTML 节点 +func (r *ContentRewriter) rewriteNode(n *html.Node) { + if n.Type == html.ElementNode { + // 重写需要处理的属性 + attrs := map[string]bool{ + "href": true, + "src": true, + "action": true, + "data": true, + } + + for i, attr := range n.Attr { + if attrs[attr.Key] { + if rewritten := r.rewriteURL(attr.Val); rewritten != attr.Val { + n.Attr[i].Val = rewritten + } + } + + // 处理 srcset 属性 + if attr.Key == "srcset" { + n.Attr[i].Val = r.rewriteSrcset(attr.Val) + } + + // 处理 style 属性中的 URL + if attr.Key == "style" { + n.Attr[i].Val = r.rewriteInlineCSS(attr.Val) + } + } + + // 处理 标签 + if n.Data == "base" { + for i, attr := range n.Attr { + if attr.Key == "href" { + n.Attr[i].Val = r.baseURL.String() + } + } + } + + // 处理