612d68f56f
Go + Vue 管理台,SQLite 持久化;支持隧道/域名穿透、域名转发插件链、访客认证、 IP 规则、API Key、Docker 单镜像部署;配置通过 Web 系统设置管理,无需 YAML 文件。 Co-authored-by: Cursor <cursoragent@cursor.com>
65 lines
1.4 KiB
Go
65 lines
1.4 KiB
Go
package forwardplugin
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/http"
|
|
"strings"
|
|
)
|
|
|
|
func init() {
|
|
Register("inject_js", newInjectJSPlugin)
|
|
}
|
|
|
|
type injectJSConfig struct {
|
|
Script string `json:"script"`
|
|
}
|
|
|
|
type injectJSPlugin struct {
|
|
script string
|
|
}
|
|
|
|
func newInjectJSPlugin(raw json.RawMessage) (Plugin, error) {
|
|
var cfg injectJSConfig
|
|
if err := json.Unmarshal(raw, &cfg); err != nil {
|
|
return nil, fmt.Errorf("inject_js 配置无效")
|
|
}
|
|
return &injectJSPlugin{script: cfg.Script}, nil
|
|
}
|
|
|
|
func (p *injectJSPlugin) Type() string { return "inject_js" }
|
|
|
|
func (p *injectJSPlugin) ValidateConfig(raw json.RawMessage) error {
|
|
var cfg injectJSConfig
|
|
if err := json.Unmarshal(raw, &cfg); err != nil {
|
|
return fmt.Errorf("inject_js 配置无效")
|
|
}
|
|
if strings.TrimSpace(cfg.Script) == "" {
|
|
return fmt.Errorf("inject_js.script 不能为空")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (p *injectJSPlugin) NeedsBody() bool { return true }
|
|
|
|
func (p *injectJSPlugin) HandleRequest(_ *Context, _ *http.Request) (bool, error) {
|
|
return false, nil
|
|
}
|
|
|
|
func (p *injectJSPlugin) HandleResponse(_ *Context, resp *BufferedResponse) error {
|
|
ct := strings.ToLower(resp.Header.Get("Content-Type"))
|
|
if !strings.Contains(ct, "text/html") {
|
|
return nil
|
|
}
|
|
body := string(resp.Body)
|
|
lower := strings.ToLower(body)
|
|
idx := strings.LastIndex(lower, "</body>")
|
|
if idx >= 0 {
|
|
body = body[:idx] + p.script + body[idx:]
|
|
} else {
|
|
body += p.script
|
|
}
|
|
resp.Body = []byte(body)
|
|
return nil
|
|
}
|