Files
demo/examples/rewriter/web_admin.go
2025-03-14 18:50:49 +00:00

260 lines
7.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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))
}