start method

Future<void> start({
  1. int port = 8080,
  2. String? host,
})

Implementation

Future<void> start({int port = 8080, String? host}) async {
  final handler = HttpRequestProcessor(
    router: _router,
    globalMiddleware: _middleware.pipeline,
    staticHandler: _static.staticHandler,
  );

  _server = await HttpServer.bind(
    host != null ? InternetAddress(host) : InternetAddress.anyIPv4,
    port,
    shared: true,
  );

  final server = _server!;

  // Enable compression and set idle timeout
  server.autoCompress = autoCompress;
  server.idleTimeout = idleTimeout;

  Log.info('🟢 HTTP Server started on http://${host ?? 'localhost'}:$port');

  // Handle graceful shutdown
  _signalSubscription = ProcessSignal.sigint.watch().listen((signal) {
    Log.info('🛑 Received signal $signal. Shutting down...');
    stop().then((_) {
      Log.info('👋 Server closed.');
      exit(0);
    });
  });

  try {
    await for (final raw in server) {
      final req = Request(raw);
      final res = Response(raw);

      Zone.current.fork(
        zoneValues: {
          ServerContext.zoneKey: ServerContext(
            request: req,
            response: res,
          ),
        },
      ).run(() async {
        try {
          // Execute global middleware pipeline with the request processor as the final handler
          // This uses the optimized static execute method to avoid allocations
          await MiddlewarePipeline.execute(
            _middleware.pipeline.middleware,
            req,
            res,
            (request, response) {
              if (response is! Response) {
                throw StateError(
                  'HTTP server lifecycle requires a concrete Response instance.',
                );
              }
              return handler.handle(request, response);
            },
          );
        } catch (e, stackTrace) {
          final exceptionHandler = resolve<ExceptionHandlerContract>();
          final result = await exceptionHandler.handle(e, stackTrace);

          if (!res.sent) {
            res.status(result.statusCode).problem(
              title: result.title,
              status: result.statusCode,
              detail: result.message,
              type: result.type,
              instance: result.instance,
              extensions: {
                if (result.details != null) 'details': result.details,
                if (result.stackTrace != null)
                  'stack_trace': result.stackTrace.toString(),
                ...result.extensions,
              },
            );
          }
        } finally {
          // Clean up request resources (e.g. temporary files)
          await req.cleanup();
        }
      });
    }
  } finally {
    await _signalSubscription?.cancel();
  }
}