blob: 4aac11828e0cfa43bcfd6f078e64b722c3572ecb [file] [log] [blame]
// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:io';
import 'package:collection/collection.dart';
import 'package:logging/logging.dart';
import 'package:path/path.dart' as p;
import 'package:test/test.dart';
import 'package:test_descriptor/test_descriptor.dart' as d;
import 'package:test_process/test_process.dart';
import 'package:webdev/src/logging.dart';
import 'package:webdev/src/serve/utils.dart';
import 'test_utils.dart';
void main() {
group('serve app with TLS options', () {
// Change to true for debugging.
final debug = false;
final testRunner = TestRunner();
late String exampleDirectory;
setUpAll(() async {
configureLogWriter(debug);
await testRunner.setUpAll();
exampleDirectory =
p.absolute(p.join(p.current, '..', 'fixtures', '_experimentSound'));
final process = await TestProcess.start(
'dart',
['pub', 'upgrade'],
workingDirectory: exampleDirectory,
environment: getPubEnvironment(),
);
await process.shouldExit(0);
await d
.file('.dart_tool/package_config.json', isNotEmpty)
.validate(exampleDirectory);
await d.file('pubspec.lock', isNotEmpty).validate(exampleDirectory);
});
test('listens on a loopback interface', () async {
final port = await findUnusedPort();
final args = [
'serve',
'web:$port',
'--hostname=0.0.0.0',
'--tls-cert-chain=localhost+2.pem',
'--tls-cert-key=localhost+2-key.pem',
];
final process =
await testRunner.runWebDev(args, workingDirectory: exampleDirectory);
await expectLater(
process.stdout, emitsThrough(contains('Built with build_runner')));
final client = HttpClient()
..badCertificateCallback = (_, __, ___) => true;
try {
final request =
await client.getUrl(Uri.parse('https://localhost:$port'));
final response = await request.close();
expect(response.statusCode, equals(200));
} finally {
client.close(force: true);
}
await process.kill();
await process.shouldExit();
});
test('listens on a non-loopback interface', () async {
final port = await findUnusedPort();
final args = [
'serve',
'web:$port',
'--hostname=0.0.0.0',
'--tls-cert-chain=localhost+2.pem',
'--tls-cert-key=localhost+2-key.pem',
];
final process =
await testRunner.runWebDev(args, workingDirectory: exampleDirectory);
await expectLater(
process.stdout, emitsThrough(contains('Built with build_runner')));
final interfaces = await NetworkInterface.list(
type: InternetAddressType.IPv4,
includeLoopback: false,
);
final nonLoopback = interfaces.expand((i) => i.addresses).firstOrNull;
if (nonLoopback == null) {
Logger.root.info(
'No non-loopback IPv4 address available, skipping hostname test.');
} else {
final client = HttpClient()
..badCertificateCallback = (_, __, ___) => true;
try {
final request = await client
.getUrl(Uri.parse('https://${nonLoopback.address}:$port'));
final response = await request.close();
expect(response.statusCode, equals(200));
} finally {
client.close(force: true);
}
}
await process.kill();
await process.shouldExit();
});
});
}