serveHTTP method

Future serveHTTP()

Implementation

Future serveHTTP() async {
  var port = container.make('@config.app.port') ?? 4040;
  server = await HttpServer.bind(
    InternetAddress.anyIPv6,
    port,
  );

  print('Bound server to port $port');

  await for (HttpRequest request in server!) {
    var hasMatch = false;
    for (var i = 0; i < bindings.length; i++) {
      var params = <String>[];

// Get the root pattern from the pathToRegex call
      var rootPattern = pathToRegExp(bindings[i].path,
              parameters: params, prefix: bindings[i].isPrefixBinding)
          .pattern;

      // TODO: Circumvent this for prefix bindings I guess?

      // Build a new regex by removing the $, adding in the optional trailing slash
      // and then adding the end terminator back on ($).
      var cleanedPattern = rootPattern.substring(0, rootPattern.lastIndexOf('\$'));
      // account for the path already ending in slash
      if (cleanedPattern.endsWith('/')) {
        cleanedPattern =
            cleanedPattern.substring(0, cleanedPattern.length - 1);
      }
      var regex = RegExp('$cleanedPattern\\/?${bindings[i].isPrefixBinding ? '\$)' :'\$'}', caseSensitive: false);
      hasMatch = regex.hasMatch(request.uri.path);

      if (hasMatch) {
        // TODO: We can clean up the unmatched path a bit too
        var match = regex.matchAsPrefix(request.uri.path);
        if (match != null) {
          var pathParams = extract(params, match);
          var req = Request(request: request, pathParams: pathParams)
            ..setContainer(container.clone());

          var allMiddlewares = [
            ...bindings[i].middleware.reversed,
            ...middleware.reversed,
          ];

          try {
            var handler = bindings[i].process;
            allMiddlewares.forEach((element) async {
              handler = element(handler);
            });

            var response = handler(req);
            await writeResponse(request, response);
          } catch (err, stacktrace) {
            await writeErrorResponse(request, err, stacktrace);
          }
          break;
        }
      }
    }

    if (!hasMatch) {
      // TODO: We can clean this up a bit
      var allMiddlewares = [...middleware.reversed];
      var handler = (Request req) => Future.value(Response.NotFound());
      allMiddlewares.forEach((element) {
        handler = element(handler);
      });

      var response = handler(Request(request: request));
      await writeResponse(request, response);
    }

    await request.response.close();
  }
}