Start begins listening for and serving HTTP or HTTPS requests. It's a blocking call and will only return on an unrecoverable error. Returns: - error: An error if the server fails to start
()
| 1431 | // Returns: |
| 1432 | // - error: An error if the server fails to start |
| 1433 | func (s *Server) Start() error { |
| 1434 | if s == nil || s.server == nil { |
| 1435 | return fmt.Errorf("failed to start HTTP server: server not initialized") |
| 1436 | } |
| 1437 | |
| 1438 | addr := s.server.Addr |
| 1439 | listener, errListen := net.Listen("tcp", addr) |
| 1440 | if errListen != nil { |
| 1441 | return fmt.Errorf("failed to start HTTP server: %v", errListen) |
| 1442 | } |
| 1443 | |
| 1444 | useTLS := s.cfg != nil && s.cfg.TLS.Enable |
| 1445 | if useTLS { |
| 1446 | certPath := strings.TrimSpace(s.cfg.TLS.Cert) |
| 1447 | keyPath := strings.TrimSpace(s.cfg.TLS.Key) |
| 1448 | if certPath == "" || keyPath == "" { |
| 1449 | if errClose := listener.Close(); errClose != nil { |
| 1450 | log.Errorf("failed to close listener after TLS validation failure: %v", errClose) |
| 1451 | } |
| 1452 | return fmt.Errorf("failed to start HTTPS server: tls.cert or tls.key is empty") |
| 1453 | } |
| 1454 | certPair, errLoad := tls.LoadX509KeyPair(certPath, keyPath) |
| 1455 | if errLoad != nil { |
| 1456 | if errClose := listener.Close(); errClose != nil { |
| 1457 | log.Errorf("failed to close listener after TLS key pair load failure: %v", errClose) |
| 1458 | } |
| 1459 | return fmt.Errorf("failed to start HTTPS server: %v", errLoad) |
| 1460 | } |
| 1461 | |
| 1462 | tlsConfig := &tls.Config{ |
| 1463 | Certificates: []tls.Certificate{certPair}, |
| 1464 | NextProtos: []string{"h2", "http/1.1"}, |
| 1465 | } |
| 1466 | s.server.TLSConfig = tlsConfig |
| 1467 | if errHTTP2 := http2.ConfigureServer(s.server, &http2.Server{}); errHTTP2 != nil { |
| 1468 | log.Warnf("failed to configure HTTP/2: %v", errHTTP2) |
| 1469 | } |
| 1470 | listener = tls.NewListener(listener, tlsConfig) |
| 1471 | log.Debugf("Starting API server on %s with TLS", addr) |
| 1472 | } else { |
| 1473 | log.Debugf("Starting API server on %s", addr) |
| 1474 | } |
| 1475 | |
| 1476 | httpListener := newMuxListener(listener.Addr(), 1024) |
| 1477 | s.muxBaseListener = listener |
| 1478 | s.muxHTTPListener = httpListener |
| 1479 | |
| 1480 | httpErrCh := make(chan error, 1) |
| 1481 | acceptErrCh := make(chan error, 1) |
| 1482 | |
| 1483 | go func() { |
| 1484 | httpErrCh <- s.server.Serve(httpListener) |
| 1485 | }() |
| 1486 | go func() { |
| 1487 | acceptErrCh <- s.acceptMuxConnections(listener, httpListener) |
| 1488 | }() |
| 1489 | |
| 1490 | select { |