defaultHandler function

Future<Handler> defaultHandler(
  1. ClientManager clients, {
  2. String? customDevToolsPath,
  3. bool debugMode = false,
})

Default shelf.Handler for serving DevTools files.

This serves files out from the build results of running a pub build of the DevTools project.

Implementation

Future<shelf.Handler> defaultHandler(
  ClientManager clients, {
  String? customDevToolsPath,
  bool debugMode = false,
}) async {
  final buildDir = customDevToolsPath ?? await _resolveBuildDir();

  // Default static handler for all non-package requests.
  Handler? buildDirHandler;
  if (!debugMode) {
    buildDirHandler = createStaticHandler(
      buildDir,
      defaultDocument: 'index.html',
    );
  }

  Handler? debugProxyHandler;
  if (debugMode) {
    // Start up a flutter run -d web-server instance.
    const webPort = 9101;

    // ignore: unawaited_futures
    Process.start(
      'flutter',
      [
        'run',
        '--dart-define=FLUTTER_WEB_USE_SKIA=true',
        '-d',
        'web-server',
        '--web-port=$webPort',
      ],
      workingDirectory: path.join('..', 'devtools_app'),
    ).then((Process process) {
      // Write all flutter run process output to the server's output.
      process
        ..stdout.transform(utf8.decoder).listen(stdout.write)
        ..stderr.transform(utf8.decoder).listen(stderr.write);

      // Proxy all stdin to the flutter run process's input.
      //stdin.pipe(process.stdin);
      stdin
        ..lineMode = false
        ..listen((event) => process.stdin.add(event));

      // Exit when the flutter run process exits.
      process.exitCode.then(exit);
    });

    debugProxyHandler = proxyHandler(Uri.parse('http://localhost:$webPort/'));
  }

  final sseHandler = SseHandler(Uri.parse('/api/sse'))
    ..connections.rest.listen(clients.acceptClient);

  // Make a handler that delegates based on path.
  final handler = (shelf.Request request) {
    if (request.url.path.startsWith('api/sse')) {
      return sseHandler.handler(request);
    }

    if (request.url.path == 'api/ping') {
      return shelf.Response(HttpStatus.ok, body: 'OK');
    }

    // The API handler takes all other calls to api/.
    if (ServerApi.canHandle(request)) {
      return ServerApi.handle(request);
    }

    if (debugMode) {
      return debugProxyHandler!(request);
    } else {
      return buildDirHandler!(request);
    }
  };

  return handler;
}