Files
sync_replay_project/packages/server/bin/server.dart
T
foxyzandClaude Opus 5.5 e2301aa4ec Server hardening: finite numbers, open servers, unkickable host, no URL leaks
- Reject non-finite numerics at protocol parse and in the engine
  (a 1e400 seek became Infinity and broke every broadcast).
- Reject empty swaps; sanitize URL-looking media names.
- Blank password = open server; defaults no longer 'change-me'.
- Loopback peers (the in-process host) can't be kicked.
- /health no longer exposes media/transport; file URLs use the
  host the client dialled instead of 127.0.0.1.
- Count served bytes as streamed, not as requested.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 00:30:12 +03:00

48 lines
1.4 KiB
Dart

import 'dart:io';
import 'package:args/args.dart';
import 'package:logging/logging.dart' as pkg_logging;
import 'package:sync_relay_core/core.dart';
import 'package:sync_relay_server/server.dart';
Future<void> main(List<String> args) async {
final parser = ArgParser()
..addOption('port', abbr: 'p', defaultsTo: '8080')
..addOption('secret', defaultsTo: '')
..addOption('name', defaultsTo: 'room')
..addOption('media', defaultsTo: '')
..addOption('advertise-host', defaultsTo: '')
..addOption('config')
..addFlag('help', abbr: 'h', negatable: false);
final parsed = parser.parse(args);
if (parsed['help'] as bool) {
// ignore: avoid_print
print(parser.usage);
return;
}
initLogging(level: pkg_logging.Level.INFO);
AppConfig config;
final configPath = parsed['config'] as String?;
if (configPath != null) {
config = await AppConfig.loadFile(configPath);
} else {
config = AppConfig(
port: int.tryParse('${parsed['port']}') ?? 8080,
secret: '${parsed['secret']}',
name: '${parsed['name']}',
mediaPath: '${parsed['media']}',
advertiseHost: '${parsed['advertise-host']}',
);
}
final server = RoomServer(config);
await server.start();
// ignore: avoid_print
print('READY port=${server.boundPort} room=${config.name}');
await ProcessSignal.sigint.watch().first;
await server.stop();
}