startHTTPServer starts the embedded HTTP server on an available port.
()
| 145 | |
| 146 | // startHTTPServer starts the embedded HTTP server on an available port. |
| 147 | func (s *Server) startHTTPServer() error { |
| 148 | s.mu.Lock() |
| 149 | defer s.mu.Unlock() |
| 150 | |
| 151 | if s.running { |
| 152 | s.logger.Debug("HTTP server already running on port %d", s.port) |
| 153 | |
| 154 | return nil // Already running |
| 155 | } |
| 156 | |
| 157 | s.logger.Debug("Finding available port for HTTP server") |
| 158 | |
| 159 | // Find an available port on all interfaces |
| 160 | listener, err := net.Listen("tcp", ":0") |
| 161 | if err != nil { |
| 162 | s.logger.Error("Failed to find available port: %v", err) |
| 163 | |
| 164 | return fmt.Errorf("failed to find available port: %w", err) |
| 165 | } |
| 166 | |
| 167 | tcpAddr, ok := listener.Addr().(*net.TCPAddr) |
| 168 | if !ok { |
| 169 | return fmt.Errorf("failed to get TCP address from listener") |
| 170 | } |
| 171 | |
| 172 | s.port = tcpAddr.Port |
| 173 | if err := listener.Close(); err != nil { |
| 174 | s.logger.Error("Failed to close listener: %v", err) |
| 175 | } |
| 176 | |
| 177 | s.logger.Info("Allocated port %d for HTTP server", s.port) |
| 178 | |
| 179 | // Create HTTP server |
| 180 | mux := http.NewServeMux() |
| 181 | |
| 182 | // Serve all noVNC client files from embedded filesystem |
| 183 | s.logger.Debug("Setting up embedded noVNC file server") |
| 184 | |
| 185 | novncFS, err := fs.Sub(novncFiles, "novnc") |
| 186 | if err != nil { |
| 187 | s.logger.Error("Failed to create noVNC filesystem: %v", err) |
| 188 | |
| 189 | return fmt.Errorf("failed to create noVNC filesystem: %w", err) |
| 190 | } |
| 191 | |
| 192 | mux.Handle("/", http.FileServer(http.FS(novncFS))) |
| 193 | |
| 194 | // WebSocket proxy endpoint |
| 195 | s.logger.Debug("Setting up WebSocket proxy endpoint") |
| 196 | mux.HandleFunc("/vnc-proxy", s.proxy.HandleWebSocketProxy) |
| 197 | |
| 198 | // VNC forward endpoint for shortened URLs |
| 199 | s.logger.Debug("Setting up VNC forward endpoint") |
| 200 | mux.HandleFunc("/vnc-forward", s.handleVNCForward) |
| 201 | |
| 202 | s.httpServer = &http.Server{ |
| 203 | Addr: fmt.Sprintf(":%d", s.port), |
| 204 | Handler: mux, |
no test coverage detected