createBindServerMethod function

Method createBindServerMethod()

Emits _bindServer, which binds the HTTP listener for the generated server.

When app.host is localhost, binds dual-stack on InternetAddress.anyIPv6 with v6Only: false so IPv4 clients can connect on platforms where HttpServer.bind('localhost', …) would land on IPv6 loopback only.

Implementation

Method createBindServerMethod() {
  return Method(
    (b) => b
      ..name = '_bindServer'
      ..returns = TypeReference(
        (p) => p
          ..symbol = (Future).name
          ..types.add(refer((HttpServer).name)),
      )
      ..modifier = MethodModifier.async
      ..requiredParameters.add(
        Parameter(
          (p) => p
            ..name = 'app'
            ..type = refer((AppConfig).name),
        ),
      )
      ..optionalParameters.addAll([
        Parameter(
          (p) => p
            ..name = 'providedServer'
            ..named = true
            ..type = refer('${(HttpServer).name}?'),
        ),
        Parameter(
          (p) => p
            ..name = 'shared'
            ..named = true
            ..defaultTo = const Code('false')
            ..type = refer('bool'),
        ),
      ])
      ..body = Block.of([
        const Code('''
if (providedServer != null) {
  return providedServer;
}

final host = switch (app.host) {
  'localhost' => InternetAddress.anyIPv6,
  final String h => h,
};

final v6Only = app.host != 'localhost';

// --cert/--key (revali dev) take precedence over AppConfig.secure's own
// securityContext, since they're an explicit run-time request for TLS.
const certPath = String.fromEnvironment('REVALI_CERT');
const keyPath = String.fromEnvironment('REVALI_KEY');
final usingCliTls = certPath.isNotEmpty && keyPath.isNotEmpty;
final securityContext = usingCliTls
    ? (SecurityContext()
        ..useCertificateChain(certPath)
        ..usePrivateKey(keyPath))
    : app.securityContext;

// AppConfig.onServerStarted only knows about app.securityContext, so it
// can't tell this override happened -- print it here instead.
if (usingCliTls) {
  print('TLS enabled via --cert/--key');
}

if (securityContext != null) {
  return await HttpServer.bindSecure(
    host,
    app.port,
    securityContext,
    requestClientCertificate: app.requestClientCertificate,
    v6Only: v6Only,
    shared: shared,
    backlog: app.backlog,
  );
}

return await HttpServer.bind(
  host,
  app.port,
  shared: shared,
  v6Only: v6Only,
  backlog: app.backlog,
);
'''),
      ]),
  );
}