1
1
use core:: fmt;
2
2
use std:: convert:: TryInto ;
3
- use std:: path:: Path ;
4
3
use std:: path:: PathBuf ;
5
4
use std:: time:: Duration ;
6
5
use std:: time:: UNIX_EPOCH ;
7
6
8
7
use anyhow:: { anyhow, bail, Context as _} ;
8
+ use axum:: extract:: Path ;
9
+ use axum:: routing:: post;
10
+ use axum:: Router ;
9
11
use chrono:: Local ;
10
12
use clap:: { ArgGroup , Parser , Subcommand } ;
11
13
use directories:: ProjectDirs ;
@@ -119,6 +121,9 @@ enum Cmd {
119
121
Receive {
120
122
#[ clap( long = "notifications" , short = 'n' ) ]
121
123
notifications : bool ,
124
+ /// Start a webserver to be able to send messages, useful for testing
125
+ #[ clap( long) ]
126
+ webserver : bool ,
122
127
} ,
123
128
#[ clap( about = "List groups" ) ]
124
129
ListGroups ,
@@ -181,7 +186,7 @@ fn parse_group_master_key(value: &str) -> anyhow::Result<GroupMasterKeyBytes> {
181
186
. map_err ( |_| anyhow:: format_err!( "master key should be 32 bytes long" ) )
182
187
}
183
188
184
- #[ tokio:: main( flavor = "multi_thread " ) ]
189
+ #[ tokio:: main( flavor = "current_thread " ) ]
185
190
async fn main ( ) -> anyhow:: Result < ( ) > {
186
191
env_logger:: from_env (
187
192
Env :: default ( ) . default_filter_or ( format ! ( "{}=warn" , env!( "CARGO_PKG_NAME" ) ) ) ,
@@ -232,11 +237,30 @@ async fn send<C: Store + 'static>(
232
237
Ok ( ( ) )
233
238
}
234
239
240
+ async fn process_incoming_messages < C : Store > (
241
+ mut manager : Manager < C , Registered < C > > ,
242
+ attachments_tmp_dir : & std:: path:: Path ,
243
+ notifications : bool ,
244
+ ) -> anyhow:: Result < ( ) > {
245
+ let messages = manager
246
+ . receive_messages ( ReceivingMode :: Forever )
247
+ . await
248
+ . context ( "failed to initialize messages stream" ) ?;
249
+
250
+ pin_mut ! ( messages) ;
251
+
252
+ while let Some ( content) = messages. next ( ) . await {
253
+ process_incoming_message ( & mut manager, attachments_tmp_dir, notifications, & content) . await ;
254
+ }
255
+
256
+ Ok ( ( ) )
257
+ }
258
+
235
259
// Note to developers, this is a good example of a function you can use as a source of inspiration
236
260
// to process incoming messages.
237
261
async fn process_incoming_message < C : Store > (
238
262
manager : & mut Manager < C , Registered < C > > ,
239
- attachments_tmp_dir : & Path ,
263
+ attachments_tmp_dir : & std :: path :: Path ,
240
264
notifications : bool ,
241
265
content : & Content ,
242
266
) {
@@ -423,29 +447,45 @@ fn print_message<C: Store>(
423
447
}
424
448
425
449
async fn receive < C : Store > (
426
- manager : & mut Manager < C , Registered < C > > ,
450
+ manager : Manager < C , Registered < C > > ,
427
451
notifications : bool ,
452
+ webserver : bool ,
428
453
) -> anyhow:: Result < ( ) > {
429
454
let attachments_tmp_dir = Builder :: new ( ) . prefix ( "presage-attachments" ) . tempdir ( ) ?;
430
455
info ! (
431
456
"attachments will be stored in {}" ,
432
457
attachments_tmp_dir. path( ) . display( )
433
458
) ;
434
459
435
- let messages = manager
436
- . receive_messages ( ReceivingMode :: Forever )
437
- . await
438
- . context ( "failed to initialize messages stream" ) ?;
439
- pin_mut ! ( messages) ;
460
+ if webserver {
461
+ let app = Router :: new ( )
462
+ . with_state ( manager)
463
+ . route ( "/message" , post ( web_send_message) ) ;
440
464
441
- while let Some ( content) = messages. next ( ) . await {
442
- process_incoming_message ( manager, attachments_tmp_dir. path ( ) , notifications, & content)
443
- . await ;
465
+ // run our app with hyper, listening globally on port 3000
466
+ let listener = tokio:: net:: TcpListener :: bind ( "0.0.0.0:3000" ) . await . unwrap ( ) ;
467
+ let webserver =
468
+ axum:: Server :: bind ( & "0.0.0.0:3000" . parse ( ) . unwrap ( ) ) . serve ( app. into_make_service ( ) ) ;
469
+
470
+ future:: join (
471
+ webserver,
472
+ process_incoming_messages ( manager, attachments_tmp_dir. path ( ) , notifications) ,
473
+ )
474
+ . await ;
475
+ } else {
476
+ process_incoming_messages ( manager, attachments_tmp_dir. path ( ) , notifications) . await ;
444
477
}
445
478
446
479
Ok ( ( ) )
447
480
}
448
481
482
+ async fn web_send_message < C : Store > (
483
+ manager : Manager < C , Registered < C > > ,
484
+ Path ( recipient) : Path < Uuid > ,
485
+ Path ( message) : Path < String > ,
486
+ ) {
487
+ }
488
+
449
489
async fn run < C : Store + ' static > ( subcommand : Cmd , config_store : C ) -> anyhow:: Result < ( ) > {
450
490
match subcommand {
451
491
Cmd :: Register {
@@ -499,7 +539,7 @@ async fn run<C: Store + 'static>(subcommand: Cmd, config_store: C) -> anyhow::Re
499
539
. await ;
500
540
501
541
match manager {
502
- ( Ok ( manager) , _) => {
542
+ ( Ok ( mut manager) , _) => {
503
543
let uuid = manager. whoami ( ) . await . unwrap ( ) . uuid ;
504
544
println ! ( "{uuid:?}" ) ;
505
545
}
@@ -508,9 +548,12 @@ async fn run<C: Store + 'static>(subcommand: Cmd, config_store: C) -> anyhow::Re
508
548
}
509
549
}
510
550
}
511
- Cmd :: Receive { notifications } => {
512
- let mut manager = Manager :: load_registered ( config_store) . await ?;
513
- receive ( & mut manager, notifications) . await ?;
551
+ Cmd :: Receive {
552
+ notifications,
553
+ webserver,
554
+ } => {
555
+ let manager = Manager :: load_registered ( config_store) . await ?;
556
+ receive ( manager, notifications, webserver) . await ?;
514
557
}
515
558
Cmd :: Send { uuid, message } => {
516
559
let mut manager = Manager :: load_registered ( config_store) . await ?;
@@ -622,8 +665,8 @@ async fn run<C: Store + 'static>(subcommand: Cmd, config_store: C) -> anyhow::Re
622
665
}
623
666
}
624
667
Cmd :: Whoami => {
625
- let manager = Manager :: load_registered ( config_store) . await ?;
626
- println ! ( "{:?}" , & manager. whoami( ) . await ?) ;
668
+ let mut manager = Manager :: load_registered ( config_store) . await ?;
669
+ println ! ( "{:?}" , manager. whoami( ) . await ?) ;
627
670
}
628
671
Cmd :: GetContact { ref uuid } => {
629
672
let manager = Manager :: load_registered ( config_store) . await ?;
0 commit comments