122 lines
2.9 KiB
Go
122 lines
2.9 KiB
Go
package main
|
||
|
||
import (
|
||
"flag"
|
||
"fmt"
|
||
"log"
|
||
"net/http"
|
||
"os"
|
||
"os/signal"
|
||
"syscall"
|
||
|
||
"github.com/darkit/goproxy"
|
||
"github.com/darkit/goproxy/config"
|
||
)
|
||
|
||
func main() {
|
||
// 解析命令行参数
|
||
var (
|
||
listenAddr = flag.String("listen", ":8080", "监听地址")
|
||
rulesFile = flag.String("rules", "proxy_rules.json", "代理规则文件")
|
||
enableCache = flag.Bool("cache", false, "启用缓存")
|
||
enableCORS = flag.Bool("cors", true, "启用CORS")
|
||
)
|
||
flag.Parse()
|
||
|
||
// 检查规则文件是否存在
|
||
if _, err := os.Stat(*rulesFile); os.IsNotExist(err) {
|
||
// 创建示例规则文件
|
||
createExampleRulesFile(*rulesFile)
|
||
fmt.Printf("已创建示例规则文件: %s\n", *rulesFile)
|
||
}
|
||
|
||
// 创建配置
|
||
cfg := config.DefaultConfig()
|
||
|
||
// 配置反向代理
|
||
cfg.ReverseProxy = true // 启用反向代理模式
|
||
cfg.ListenAddr = *listenAddr // 监听地址
|
||
cfg.ReverseProxyRulesFile = *rulesFile // 规则文件
|
||
cfg.EnableCache = *enableCache // 是否启用缓存
|
||
cfg.EnableCORS = *enableCORS // 是否启用CORS
|
||
cfg.PreserveClientIP = true // 保留客户端IP
|
||
cfg.AddXForwardedFor = true // 添加X-Forwarded-For头
|
||
cfg.AddXRealIP = true // 添加X-Real-IP头
|
||
cfg.TargetAddr = "https://git.zishuo.net"
|
||
|
||
// 创建代理实例
|
||
proxy := goproxy.New(&goproxy.Options{
|
||
Config: cfg,
|
||
})
|
||
|
||
// 创建HTTP服务器
|
||
server := &http.Server{
|
||
Addr: *listenAddr,
|
||
Handler: proxy,
|
||
}
|
||
|
||
// 优雅退出
|
||
quit := make(chan os.Signal, 1)
|
||
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
|
||
|
||
// 启动服务
|
||
go func() {
|
||
fmt.Printf("反向代理启动在 %s,使用规则文件 %s\n", *listenAddr, *rulesFile)
|
||
if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
||
log.Fatalf("服务器启动失败: %v\n", err)
|
||
}
|
||
}()
|
||
|
||
// 等待退出信号
|
||
<-quit
|
||
fmt.Println("服务器正在关闭...")
|
||
|
||
// 关闭服务器
|
||
if err := server.Close(); err != nil {
|
||
log.Fatalf("服务器关闭失败: %v\n", err)
|
||
}
|
||
fmt.Println("服务器已关闭")
|
||
}
|
||
|
||
// 创建示例规则文件
|
||
func createExampleRulesFile(filename string) {
|
||
content := `{
|
||
"rules": [
|
||
{
|
||
"path": "/api/",
|
||
"target": "http://api-server:8000",
|
||
"strip_prefix": true
|
||
},
|
||
{
|
||
"path": "/admin/",
|
||
"target": "http://admin-server:9000",
|
||
"strip_prefix": false
|
||
},
|
||
{
|
||
"path": "/static/",
|
||
"target": "http://static-server:8080",
|
||
"strip_prefix": true,
|
||
"cache": true,
|
||
"cache_ttl": 3600
|
||
},
|
||
{
|
||
"host": "api.example.com",
|
||
"target": "http://api-server:8000"
|
||
},
|
||
{
|
||
"host": "admin.example.com",
|
||
"target": "http://admin-server:9000"
|
||
},
|
||
{
|
||
"default": true,
|
||
"target": "http://default-server:8080"
|
||
}
|
||
]
|
||
}`
|
||
|
||
err := os.WriteFile(filename, []byte(content), 0o644)
|
||
if err != nil {
|
||
log.Fatalf("创建规则文件失败: %v", err)
|
||
}
|
||
}
|