package web import ( "encoding/json" "fmt" "net/http" "strconv" "github.com/miaomint/port-manager/internal/scanner" "github.com/miaomint/port-manager/internal/service" ) // Server Web服务器 type Server struct { scanner *scanner.PortScanner identifier *service.ServiceIdentifier } // NewServer 创建新的Web服务器 func NewServer() *Server { return &Server{ scanner: scanner.NewPortScanner(true, false), // 只显示监听端口 identifier: service.NewServiceIdentifier(), } } // Start 启动Web服务器 func (s *Server) Start(port int) error { mux := http.NewServeMux() // 静态文件路由 mux.HandleFunc("/", s.indexHandler) mux.HandleFunc("/api/ports", s.portsAPIHandler) mux.HandleFunc("/api/random-port", s.randomPortHandler) mux.HandleFunc("/api/scan-range", s.scanRangeHandler) fmt.Printf("端口管理器启动在: http://localhost:%d\n", port) return http.ListenAndServe(fmt.Sprintf(":%d", port), mux) } // indexHandler 主页处理器 func (s *Server) indexHandler(w http.ResponseWriter, r *http.Request) { tmpl := ` 端口管理器

🔌 NAS 端口管理器

` w.Header().Set("Content-Type", "text/html; charset=utf-8") fmt.Fprint(w, tmpl) } // portsAPIHandler 端口API处理器 func (s *Server) portsAPIHandler(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") result, err := s.scanner.ScanPorts() if err != nil { http.Error(w, fmt.Sprintf(`{"error": "%s"}`, err.Error()), http.StatusInternalServerError) return } // 识别服务 for i := range result.Ports { identified := s.identifier.IdentifyService(&result.Ports[i]) result.Ports[i] = *identified } json.NewEncoder(w).Encode(result) } // randomPortHandler 随机端口处理器 func (s *Server) randomPortHandler(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") minPort := 8000 maxPort := 9999 if min := r.URL.Query().Get("min"); min != "" { if p, err := strconv.Atoi(min); err == nil { minPort = p } } if max := r.URL.Query().Get("max"); max != "" { if p, err := strconv.Atoi(max); err == nil { maxPort = p } } port, err := s.scanner.GenerateRandomPort(minPort, maxPort) if err != nil { http.Error(w, fmt.Sprintf(`{"error": "%s"}`, err.Error()), http.StatusInternalServerError) return } response := map[string]int{"port": port} json.NewEncoder(w).Encode(response) } // scanRangeHandler 扫描端口范围处理器 func (s *Server) scanRangeHandler(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") startStr := r.URL.Query().Get("start") endStr := r.URL.Query().Get("end") if startStr == "" || endStr == "" { http.Error(w, `{"error": "需要提供start和end参数"}`, http.StatusBadRequest) return } start, err := strconv.Atoi(startStr) if err != nil { http.Error(w, `{"error": "无效的start参数"}`, http.StatusBadRequest) return } end, err := strconv.Atoi(endStr) if err != nil { http.Error(w, `{"error": "无效的end参数"}`, http.StatusBadRequest) return } openPorts, err := s.scanner.ScanPortRange(start, end) if err != nil { http.Error(w, fmt.Sprintf(`{"error": "%s"}`, err.Error()), http.StatusInternalServerError) return } response := map[string][]int{"openPorts": openPorts} json.NewEncoder(w).Encode(response) }