122 lines
2.9 KiB
Go
122 lines
2.9 KiB
Go
package main
|
||
|
||
import (
|
||
"log"
|
||
"net/http"
|
||
"net/http/httputil"
|
||
"net/url"
|
||
|
||
"github.com/darkit/goproxy/pkg/rewriter"
|
||
)
|
||
|
||
// RewriteReverseProxy 重写反向代理
|
||
// 在请求发送到后端服务器前重写URL
|
||
type RewriteReverseProxy struct {
|
||
// 后端服务器地址
|
||
Target *url.URL
|
||
// URL重写器
|
||
Rewriter *rewriter.Rewriter
|
||
// 反向代理
|
||
Proxy *httputil.ReverseProxy
|
||
}
|
||
|
||
// NewRewriteReverseProxy 创建重写反向代理
|
||
func NewRewriteReverseProxy(target string, rewriteRulesFile string) (*RewriteReverseProxy, error) {
|
||
// 解析目标URL
|
||
targetURL, err := url.Parse(target)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
// 创建重写器
|
||
rw := rewriter.NewRewriter()
|
||
|
||
// 加载重写规则
|
||
if rewriteRulesFile != "" {
|
||
if err := rw.LoadRulesFromFile(rewriteRulesFile); err != nil {
|
||
return nil, err
|
||
}
|
||
}
|
||
|
||
// 创建反向代理
|
||
proxy := httputil.NewSingleHostReverseProxy(targetURL)
|
||
|
||
// 修改默认的Director函数,添加URL重写逻辑
|
||
defaultDirector := proxy.Director
|
||
proxy.Director = func(req *http.Request) {
|
||
// 先执行默认的Director函数
|
||
defaultDirector(req)
|
||
|
||
// 然后执行URL重写
|
||
rw.Rewrite(req)
|
||
|
||
// 记录重写后的URL
|
||
log.Printf("请求重写: %s -> %s", req.URL.Path, req.URL.String())
|
||
}
|
||
|
||
// 修改响应处理器,重写响应头
|
||
proxy.ModifyResponse = func(resp *http.Response) error {
|
||
// 重写响应
|
||
rw.RewriteResponse(resp, targetURL.Host)
|
||
return nil
|
||
}
|
||
|
||
return &RewriteReverseProxy{
|
||
Target: targetURL,
|
||
Rewriter: rw,
|
||
Proxy: proxy,
|
||
}, nil
|
||
}
|
||
|
||
// ServeHTTP 实现http.Handler接口
|
||
func (rrp *RewriteReverseProxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||
log.Printf("收到请求: %s %s", r.Method, r.URL.Path)
|
||
rrp.Proxy.ServeHTTP(w, r)
|
||
}
|
||
|
||
// RewriteMiddleware 中间件:将重写器应用到处理链中
|
||
func RewriteMiddleware(rw *rewriter.Rewriter, next http.Handler) http.Handler {
|
||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||
// 重写URL
|
||
originalPath := r.URL.Path
|
||
rw.Rewrite(r)
|
||
|
||
if originalPath != r.URL.Path {
|
||
log.Printf("URL重写: %s -> %s", originalPath, r.URL.Path)
|
||
}
|
||
|
||
// 继续处理链
|
||
next.ServeHTTP(w, r)
|
||
})
|
||
}
|
||
|
||
func main() {
|
||
// 创建重写器
|
||
rw := rewriter.NewRewriter()
|
||
|
||
// 加载重写规则
|
||
if err := rw.LoadRulesFromFile("rules.json"); err != nil {
|
||
log.Fatalf("加载重写规则失败: %v", err)
|
||
}
|
||
|
||
// 创建反向代理
|
||
proxy, err := NewRewriteReverseProxy("http://192.168.1.212:80", "rules.json")
|
||
if err != nil {
|
||
log.Fatalf("创建反向代理失败: %v", err)
|
||
}
|
||
|
||
// 创建静态文件服务器(模拟普通Web服务器)
|
||
fileServer := http.FileServer(http.Dir("./static"))
|
||
|
||
// 使用中间件包装文件服务器
|
||
rewrittenFileServer := RewriteMiddleware(rw, fileServer)
|
||
|
||
// 设置处理函数
|
||
http.Handle("/api/", rewrittenFileServer)
|
||
http.Handle("/", proxy)
|
||
|
||
// 启动服务器
|
||
log.Println("服务器启动在 :8080...")
|
||
log.Fatal(http.ListenAndServe(":8080", nil))
|
||
}
|