求可直接使用的带REST HTTP API的Golang HTTP端口转发代理服务程序
基于Golang的HTTP端口转发代理服务器(带REST API)
功能特性
- 动态端口转发:通过REST API添加/删除TCP流量转发规则
- 并发安全:使用互斥锁管理转发规则,支持多API请求并发操作
- 轻量高效:基于Golang原生net包实现,性能优异
完整可运行代码
package main import ( "encoding/json" "io" "log" "net" "net/http" "sync" ) // ForwardRule 存储端口转发规则 type ForwardRule struct { LocalPort int `json:"local_port"` TargetAddr string `json:"target_addr"` listener net.Listener } var ( forwardRules = make(map[int]*ForwardRule) rulesMutex sync.Mutex apiPort = 8080 // REST API监听端口 ) func main() { // 注册API路由 http.HandleFunc("/add", handleAddRule) http.HandleFunc("/remove", handleRemoveRule) http.HandleFunc("/list", handleListRules) log.Printf("REST API server starting on :%d", apiPort) log.Fatal(http.ListenAndServe(":"+string(rune(apiPort+'0')), nil)) } // handleAddRule 添加新的转发规则 func handleAddRule(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { http.Error(w, "only POST method allowed", http.StatusMethodNotAllowed) return } var rule ForwardRule if err := json.NewDecoder(r.Body).Decode(&rule); err != nil { http.Error(w, "invalid request body: "+err.Error(), http.StatusBadRequest) return } rulesMutex.Lock() defer rulesMutex.Unlock() if _, exists := forwardRules[rule.LocalPort]; exists { http.Error(w, "local port already in use", http.StatusConflict) return } // 启动本地端口监听 listener, err := net.Listen("tcp", ":"+string(rune(rule.LocalPort+'0'))) if err != nil { http.Error(w, "failed to listen on local port: "+err.Error(), http.StatusInternalServerError) return } rule.listener = listener forwardRules[rule.LocalPort] = &rule // 启动转发协程 go startForwarding(&rule) w.WriteHeader(http.StatusCreated) json.NewEncoder(w).Encode(map[string]string{"status": "success", "message": "forward rule added"}) } // handleRemoveRule 删除指定转发规则 func handleRemoveRule(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodDelete { http.Error(w, "only DELETE method allowed", http.StatusMethodNotAllowed) return } var req struct { LocalPort int `json:"local_port"` } if err := json.NewDecoder(r.Body).Decode(&req); err != nil { http.Error(w, "invalid request body: "+err.Error(), http.StatusBadRequest) return } rulesMutex.Lock() defer rulesMutex.Unlock() rule, exists := forwardRules[req.LocalPort] if !exists { http.Error(w, "forward rule not found", http.StatusNotFound) return } // 关闭监听 if err := rule.listener.Close(); err != nil { log.Printf("warning: failed to close listener on port %d: %v", req.LocalPort, err) } delete(forwardRules, req.LocalPort) w.WriteHeader(http.StatusOK) json.NewEncoder(w).Encode(map[string]string{"status": "success", "message": "forward rule removed"}) } // handleListRules 返回所有当前转发规则 func handleListRules(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodGet { http.Error(w, "only GET method allowed", http.StatusMethodNotAllowed) return } rulesMutex.Lock() defer rulesMutex.Unlock() // 构造返回的规则列表(不含listener) var rules []ForwardRule for _, rule := range forwardRules { rules = append(rules, ForwardRule{ LocalPort: rule.LocalPort, TargetAddr: rule.TargetAddr, }) } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(rules) } // startForwarding 处理端口转发逻辑 func startForwarding(rule *ForwardRule) { log.Printf("starting forward from :%d to %s", rule.LocalPort, rule.TargetAddr) defer log.Printf("stopped forward from :%d", rule.LocalPort) for { conn, err := rule.listener.Accept() if err != nil { // 监听关闭时退出 return } go handleConnection(conn, rule.TargetAddr) } } // handleConnection 处理单个连接的流量转发 func handleConnection(localConn net.Conn, targetAddr string) { defer localConn.Close() targetConn, err := net.Dial("tcp", targetAddr) if err != nil { log.Printf("failed to connect to target %s: %v", targetAddr, err) return } defer targetConn.Close() // 双向转发流量 var wg sync.WaitGroup wg.Add(2) go func() { defer wg.Done() io.Copy(targetConn, localConn) }() go func() { defer wg.Done() io.Copy(localConn, targetConn) }() wg.Wait() }
使用说明
编译程序:
将上述代码保存为main.go,执行编译命令:go build -o proxy-server main.go启动服务器:
./proxy-server默认REST API监听8080端口,可修改代码中
apiPort变量调整。API调用示例:
- 添加转发规则:
curl -X POST -H "Content-Type: application/json" -d '{"local_port": 8081, "target_addr": "example.com:80"}' http://localhost:8080/add - 删除转发规则:
curl -X DELETE -H "Content-Type: application/json" -d '{"local_port": 8081}' http://localhost:8080/remove - 查看所有规则:
curl http://localhost:8080/list
- 添加转发规则:
内容的提问来源于stack exchange,提问作者zerohh
相关产品推荐
相关产品推荐

