This commit is contained in:
2025-03-14 18:50:49 +00:00
commit 1a53a9a8f3
90 changed files with 13116 additions and 0 deletions

View File

@@ -0,0 +1,259 @@
package main
import (
"encoding/json"
"fmt"
"html/template"
"log"
"net/http"
"strconv"
"github.com/darkit/goproxy/pkg/rewriter"
)
// 全局重写器实例
var rw *rewriter.Rewriter
// 规则配置文件路径
var rulesFile = "rules.json"
// AdminHandler Web管理页面处理器
func AdminHandler(w http.ResponseWriter, r *http.Request) {
// 定义模板
tmpl := `
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>URL重写规则管理</title>
<style>
body { font-family: Arial, sans-serif; margin: 20px; }
h1 { color: #333; }
table { width: 100%; border-collapse: collapse; margin-top: 20px; }
th, td { padding: 10px; text-align: left; border-bottom: 1px solid #ddd; }
th { background-color: #f2f2f2; }
.enabled { color: green; }
.disabled { color: red; }
.form-group { margin-bottom: 15px; }
label { display: block; margin-bottom: 5px; }
input[type="text"], textarea { width: 100%; padding: 8px; box-sizing: border-box; }
input[type="checkbox"] { margin-right: 5px; }
button { padding: 10px 15px; background-color: #4CAF50; color: white; border: none; cursor: pointer; }
button:hover { background-color: #45a049; }
.action-btn { padding: 5px 10px; margin-right: 5px; }
.delete-btn { background-color: #f44336; }
.edit-btn { background-color: #2196F3; }
</style>
</head>
<body>
<h1>URL重写规则管理</h1>
<h2>当前规则</h2>
<table>
<tr>
<th>索引</th>
<th>匹配模式</th>
<th>替换模式</th>
<th>类型</th>
<th>描述</th>
<th>状态</th>
<th>操作</th>
</tr>
{{range $i, $rule := .Rules}}
<tr>
<td>{{$i}}</td>
<td>{{$rule.Pattern}}</td>
<td>{{$rule.Replacement}}</td>
<td>{{if $rule.UseRegex}}正则表达式{{else}}前缀匹配{{end}}</td>
<td>{{$rule.Description}}</td>
<td class="{{if $rule.Enabled}}enabled{{else}}disabled{{end}}">
{{if $rule.Enabled}}启用{{else}}禁用{{end}}
</td>
<td>
{{if $rule.Enabled}}
<a href="/disable/{{$i}}"><button class="action-btn">禁用</button></a>
{{else}}
<a href="/enable/{{$i}}"><button class="action-btn">启用</button></a>
{{end}}
<a href="/remove/{{$i}}"><button class="action-btn delete-btn">删除</button></a>
</td>
</tr>
{{end}}
</table>
<h2>添加新规则</h2>
<form action="/add" method="post">
<div class="form-group">
<label for="pattern">匹配模式:</label>
<input type="text" id="pattern" name="pattern" required>
</div>
<div class="form-group">
<label for="replacement">替换模式:</label>
<input type="text" id="replacement" name="replacement" required>
</div>
<div class="form-group">
<label for="regex">
<input type="checkbox" id="regex" name="regex">
使用正则表达式
</label>
</div>
<div class="form-group">
<label for="description">描述:</label>
<textarea id="description" name="description" rows="3"></textarea>
</div>
<button type="submit">添加规则</button>
</form>
<h2>保存配置</h2>
<form action="/save" method="post">
<button type="submit">保存规则配置</button>
</form>
</body>
</html>
`
// 解析模板
t, err := template.New("admin").Parse(tmpl)
if err != nil {
http.Error(w, fmt.Sprintf("模板解析错误: %v", err), http.StatusInternalServerError)
return
}
// 渲染模板
data := struct {
Rules []*rewriter.RewriteRule
}{
Rules: rw.GetRules(),
}
if err := t.Execute(w, data); err != nil {
http.Error(w, fmt.Sprintf("模板渲染错误: %v", err), http.StatusInternalServerError)
}
}
// AddRuleHandler 添加规则处理器
func AddRuleHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Redirect(w, r, "/", http.StatusSeeOther)
return
}
r.ParseForm()
pattern := r.Form.Get("pattern")
replacement := r.Form.Get("replacement")
useRegex := r.Form.Get("regex") == "on"
description := r.Form.Get("description")
if pattern == "" || replacement == "" {
http.Error(w, "匹配模式和替换模式不能为空", http.StatusBadRequest)
return
}
if err := rw.AddRuleWithDescription(pattern, replacement, useRegex, description); err != nil {
http.Error(w, fmt.Sprintf("添加规则失败: %v", err), http.StatusInternalServerError)
return
}
http.Redirect(w, r, "/", http.StatusSeeOther)
}
// EnableRuleHandler 启用规则处理器
func EnableRuleHandler(w http.ResponseWriter, r *http.Request) {
// 解析URL中的规则索引
indexStr := r.URL.Path[len("/enable/"):]
index, err := strconv.Atoi(indexStr)
if err != nil {
http.Error(w, "无效的规则索引", http.StatusBadRequest)
return
}
if err := rw.EnableRule(index); err != nil {
http.Error(w, fmt.Sprintf("启用规则失败: %v", err), http.StatusInternalServerError)
return
}
http.Redirect(w, r, "/", http.StatusSeeOther)
}
// DisableRuleHandler 禁用规则处理器
func DisableRuleHandler(w http.ResponseWriter, r *http.Request) {
// 解析URL中的规则索引
indexStr := r.URL.Path[len("/disable/"):]
index, err := strconv.Atoi(indexStr)
if err != nil {
http.Error(w, "无效的规则索引", http.StatusBadRequest)
return
}
if err := rw.DisableRule(index); err != nil {
http.Error(w, fmt.Sprintf("禁用规则失败: %v", err), http.StatusInternalServerError)
return
}
http.Redirect(w, r, "/", http.StatusSeeOther)
}
// RemoveRuleHandler 删除规则处理器
func RemoveRuleHandler(w http.ResponseWriter, r *http.Request) {
// 解析URL中的规则索引
indexStr := r.URL.Path[len("/remove/"):]
index, err := strconv.Atoi(indexStr)
if err != nil {
http.Error(w, "无效的规则索引", http.StatusBadRequest)
return
}
if err := rw.RemoveRule(index); err != nil {
http.Error(w, fmt.Sprintf("删除规则失败: %v", err), http.StatusInternalServerError)
return
}
http.Redirect(w, r, "/", http.StatusSeeOther)
}
// SaveRulesHandler 保存规则处理器
func SaveRulesHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Redirect(w, r, "/", http.StatusSeeOther)
return
}
if err := rw.SaveRulesToFile(rulesFile); err != nil {
http.Error(w, fmt.Sprintf("保存规则失败: %v", err), http.StatusInternalServerError)
return
}
http.Redirect(w, r, "/", http.StatusSeeOther)
}
// APIHandler API处理器返回JSON格式的规则列表
func APIHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
rules := rw.GetRules()
json.NewEncoder(w).Encode(rules)
}
func main() {
// 创建重写器
rw = rewriter.NewRewriter()
// 尝试从文件加载规则
if err := rw.LoadRulesFromFile(rulesFile); err != nil {
log.Printf("加载规则失败: %v, 将使用空规则集", err)
}
// 注册处理器
http.HandleFunc("/", AdminHandler)
http.HandleFunc("/add", AddRuleHandler)
http.HandleFunc("/enable/", EnableRuleHandler)
http.HandleFunc("/disable/", DisableRuleHandler)
http.HandleFunc("/remove/", RemoveRuleHandler)
http.HandleFunc("/save", SaveRulesHandler)
http.HandleFunc("/api/rules", APIHandler)
// 启动服务器
log.Println("管理界面启动在 :8080...")
log.Fatal(http.ListenAndServe(":8080", nil))
}