Line data Source code
1 : import 'dart:io';
2 : import 'package:at_client/at_client.dart';
3 : import 'package:at_client/src/service/encryption_service.dart';
4 : import 'package:at_client/src/stream/at_stream_notification.dart';
5 : import 'package:at_lookup/at_lookup.dart';
6 : import 'package:at_utils/at_logger.dart';
7 :
8 : class StreamNotificationHandler {
9 : RemoteSecondary? remoteSecondary;
10 :
11 : LocalSecondary? localSecondary;
12 :
13 : AtClientPreference? preference;
14 :
15 : EncryptionService? encryptionService;
16 :
17 : var logger = AtSignLogger('StreamNotificationHandler');
18 :
19 0 : Future<void> streamAck(AtStreamNotification streamNotification,
20 : Function streamCompletionCallBack, streamReceiveCallBack) async {
21 0 : var streamId = streamNotification.streamId;
22 0 : var secondaryUrl = await AtLookupImpl.findSecondary(
23 0 : streamNotification.senderAtSign,
24 0 : preference!.rootDomain,
25 0 : preference!.rootPort);
26 0 : var secondaryInfo = AtClientUtil.getSecondaryInfo(secondaryUrl);
27 0 : var host = secondaryInfo[0];
28 0 : var port = secondaryInfo[1];
29 0 : var socket = await SecureSocket.connect(host, int.parse(port));
30 0 : var f = File(
31 0 : '${preference!.downloadPath}/encrypted_${streamNotification.fileName}');
32 0 : logger.info('sending stream receive for : $streamId');
33 0 : var command = 'stream:receive $streamId\n';
34 0 : socket.write(command);
35 : var bytesReceived = 0;
36 : var firstByteSkipped = false;
37 : var sharedKey =
38 0 : await encryptionService!.getSharedKey(streamNotification.senderAtSign);
39 0 : socket.listen((onData) async {
40 0 : if (onData.length == 1 && onData.first == 64) {
41 : //skip @ prompt
42 0 : logger.finer('skipping prompt');
43 : return;
44 : }
45 0 : if (onData.first == 64 && firstByteSkipped == false) {
46 0 : onData = onData.sublist(1);
47 : firstByteSkipped = true;
48 0 : logger.finer('skipping @');
49 : }
50 0 : bytesReceived += onData.length;
51 0 : f.writeAsBytesSync(onData, mode: FileMode.append);
52 0 : streamReceiveCallBack(bytesReceived);
53 0 : if (bytesReceived == streamNotification.fileLength) {
54 0 : var startTime = DateTime.now();
55 : var decryptedBytes =
56 0 : encryptionService!.decryptStream(f.readAsBytesSync(), sharedKey);
57 : var decryptedFile =
58 0 : File('${preference!.downloadPath}/${streamNotification.fileName}');
59 0 : decryptedFile.writeAsBytesSync(decryptedBytes);
60 0 : f.deleteSync(); // delete encrypted file
61 0 : var endTime = DateTime.now();
62 0 : logger.info(
63 0 : 'Decrypting stream data completed in ${endTime.difference(startTime).inMilliseconds} milliseconds');
64 0 : logger.info('Stream transfer complete:$streamId');
65 0 : socket.write('stream:done $streamId\n');
66 0 : streamCompletionCallBack(streamId);
67 : return;
68 : }
69 0 : }, onDone: () {
70 0 : socket.destroy();
71 : });
72 : }
73 : }
|