@@ -6,7 +6,7 @@ use std::collections::HashMap;
6
6
use std:: sync:: Arc ;
7
7
8
8
use mithril_common:: api_version:: APIVersionProvider ;
9
- use mithril_common:: MITHRIL_ORIGIN_TAG_HEADER ;
9
+ use mithril_common:: { MITHRIL_CLIENT_TYPE_HEADER , MITHRIL_ORIGIN_TAG_HEADER } ;
10
10
11
11
use crate :: aggregator_client:: { AggregatorClient , AggregatorHTTPClient } ;
12
12
#[ cfg( feature = "unstable" ) ]
@@ -29,6 +29,8 @@ use crate::snapshot_client::SnapshotClient;
29
29
use crate :: utils:: AncillaryVerifier ;
30
30
use crate :: MithrilResult ;
31
31
32
+ const DEFAULT_CLIENT_TYPE : & str = "LIBRARY" ;
33
+
32
34
#[ cfg( target_family = "wasm" ) ]
33
35
const fn one_week_in_seconds ( ) -> u32 {
34
36
604800
@@ -151,6 +153,7 @@ pub struct ClientBuilder {
151
153
aggregator_endpoint : Option < String > ,
152
154
genesis_verification_key : String ,
153
155
origin_tag : Option < String > ,
156
+ client_type : Option < String > ,
154
157
#[ cfg( feature = "fs" ) ]
155
158
ancillary_verification_key : Option < String > ,
156
159
aggregator_client : Option < Arc < dyn AggregatorClient > > ,
@@ -172,6 +175,7 @@ impl ClientBuilder {
172
175
aggregator_endpoint : Some ( endpoint. to_string ( ) ) ,
173
176
genesis_verification_key : genesis_verification_key. to_string ( ) ,
174
177
origin_tag : None ,
178
+ client_type : None ,
175
179
#[ cfg( feature = "fs" ) ]
176
180
ancillary_verification_key : None ,
177
181
aggregator_client : None ,
@@ -195,6 +199,7 @@ impl ClientBuilder {
195
199
aggregator_endpoint : None ,
196
200
genesis_verification_key : genesis_verification_key. to_string ( ) ,
197
201
origin_tag : None ,
202
+ client_type : None ,
198
203
#[ cfg( feature = "fs" ) ]
199
204
ancillary_verification_key : None ,
200
205
aggregator_client : None ,
@@ -343,6 +348,14 @@ impl ClientBuilder {
343
348
if let Some ( origin_tag) = self . origin_tag . clone ( ) {
344
349
headers. insert ( MITHRIL_ORIGIN_TAG_HEADER . to_string ( ) , origin_tag) ;
345
350
}
351
+ if let Some ( client_type) = self . client_type . clone ( ) {
352
+ headers. insert ( MITHRIL_CLIENT_TYPE_HEADER . to_string ( ) , client_type) ;
353
+ } else if !headers. contains_key ( MITHRIL_CLIENT_TYPE_HEADER ) {
354
+ headers. insert (
355
+ MITHRIL_CLIENT_TYPE_HEADER . to_string ( ) ,
356
+ DEFAULT_CLIENT_TYPE . to_string ( ) ,
357
+ ) ;
358
+ }
346
359
347
360
headers
348
361
}
@@ -410,11 +423,9 @@ impl ClientBuilder {
410
423
self
411
424
}
412
425
413
- /// Add a [feedback receiver][FeedbackReceiver] to receive [events][crate::feedback::MithrilEvent]
414
- /// for tasks that can have a long duration (ie: snapshot download or a long certificate chain
415
- /// validation).
416
- pub fn add_feedback_receiver ( mut self , receiver : Arc < dyn FeedbackReceiver > ) -> Self {
417
- self . feedback_receivers . push ( receiver) ;
426
+ /// Set the client type.
427
+ pub fn with_client_type ( mut self , client_type : Option < String > ) -> Self {
428
+ self . client_type = client_type;
418
429
self
419
430
}
420
431
@@ -423,15 +434,30 @@ impl ClientBuilder {
423
434
self . options = options;
424
435
self
425
436
}
437
+
438
+ /// Add a [feedback receiver][FeedbackReceiver] to receive [events][crate::feedback::MithrilEvent]
439
+ /// for tasks that can have a long duration (ie: snapshot download or a long certificate chain
440
+ /// validation).
441
+ pub fn add_feedback_receiver ( mut self , receiver : Arc < dyn FeedbackReceiver > ) -> Self {
442
+ self . feedback_receivers . push ( receiver) ;
443
+ self
444
+ }
426
445
}
427
446
428
447
#[ cfg( test) ]
429
448
mod tests {
430
449
use super :: * ;
431
450
451
+ fn default_headers ( ) -> HashMap < String , String > {
452
+ HashMap :: from ( [ (
453
+ MITHRIL_CLIENT_TYPE_HEADER . to_string ( ) ,
454
+ DEFAULT_CLIENT_TYPE . to_string ( ) ,
455
+ ) ] )
456
+ }
457
+
432
458
#[ tokio:: test]
433
459
async fn compute_http_headers_returns_options_http_headers ( ) {
434
- let http_headers = HashMap :: from ( [ ( "Key" . to_string ( ) , "Value" . to_string ( ) ) ] ) ;
460
+ let http_headers = default_headers ( ) ;
435
461
let client_builder = ClientBuilder :: new ( "" ) . with_options ( ClientOptions {
436
462
http_headers : Some ( http_headers. clone ( ) ) ,
437
463
} ) ;
@@ -443,25 +469,20 @@ mod tests {
443
469
444
470
#[ tokio:: test]
445
471
async fn compute_http_headers_with_origin_tag_returns_options_http_headers_with_origin_tag ( ) {
446
- let http_headers = HashMap :: from ( [ ( "Key" . to_string ( ) , "Value" . to_string ( ) ) ] ) ;
472
+ let http_headers = default_headers ( ) ;
447
473
let client_builder = ClientBuilder :: new ( "" )
448
474
. with_options ( ClientOptions {
449
475
http_headers : Some ( http_headers. clone ( ) ) ,
450
476
} )
451
477
. with_origin_tag ( Some ( "CLIENT_TAG" . to_string ( ) ) ) ;
478
+ let mut expected_headers = http_headers. clone ( ) ;
479
+ expected_headers. insert (
480
+ MITHRIL_ORIGIN_TAG_HEADER . to_string ( ) ,
481
+ "CLIENT_TAG" . to_string ( ) ,
482
+ ) ;
452
483
453
484
let computed_headers = client_builder. compute_http_headers ( ) ;
454
-
455
- assert_eq ! (
456
- computed_headers,
457
- HashMap :: from( [
458
- ( "Key" . to_string( ) , "Value" . to_string( ) ) ,
459
- (
460
- MITHRIL_ORIGIN_TAG_HEADER . to_string( ) ,
461
- "CLIENT_TAG" . to_string( )
462
- )
463
- ] )
464
- ) ;
485
+ assert_eq ! ( computed_headers, expected_headers) ;
465
486
}
466
487
467
488
#[ tokio:: test]
@@ -495,4 +516,110 @@ mod tests {
495
516
assert_eq ! ( Some ( http_headers) , builder. options. http_headers) ;
496
517
assert_eq ! ( None , builder. origin_tag) ;
497
518
}
519
+
520
+ #[ tokio:: test]
521
+ async fn compute_http_headers_with_client_type_returns_options_http_headers_with_client_type ( ) {
522
+ let http_headers = HashMap :: from ( [ ( "Key" . to_string ( ) , "Value" . to_string ( ) ) ] ) ;
523
+ let client_builder = ClientBuilder :: new ( "" )
524
+ . with_options ( ClientOptions {
525
+ http_headers : Some ( http_headers. clone ( ) ) ,
526
+ } )
527
+ . with_client_type ( Some ( "CLIENT_TYPE" . to_string ( ) ) ) ;
528
+
529
+ let computed_headers = client_builder. compute_http_headers ( ) ;
530
+
531
+ assert_eq ! (
532
+ computed_headers,
533
+ HashMap :: from( [
534
+ ( "Key" . to_string( ) , "Value" . to_string( ) ) ,
535
+ (
536
+ MITHRIL_CLIENT_TYPE_HEADER . to_string( ) ,
537
+ "CLIENT_TYPE" . to_string( )
538
+ )
539
+ ] )
540
+ ) ;
541
+ }
542
+
543
+ #[ tokio:: test]
544
+ async fn compute_http_headers_with_options_containing_client_type_returns_client_type ( ) {
545
+ let http_headers = HashMap :: from ( [ (
546
+ MITHRIL_CLIENT_TYPE_HEADER . to_string ( ) ,
547
+ "client type from options" . to_string ( ) ,
548
+ ) ] ) ;
549
+ let client_builder = ClientBuilder :: new ( "" ) . with_options ( ClientOptions {
550
+ http_headers : Some ( http_headers. clone ( ) ) ,
551
+ } ) ;
552
+
553
+ let computed_headers = client_builder. compute_http_headers ( ) ;
554
+
555
+ assert_eq ! ( computed_headers, http_headers) ;
556
+ }
557
+
558
+ #[ tokio:: test]
559
+ async fn test_with_client_type_not_overwrite_other_client_options_attributes ( ) {
560
+ let builder = ClientBuilder :: new ( "" )
561
+ . with_options ( ClientOptions { http_headers : None } )
562
+ . with_client_type ( Some ( "TEST" . to_string ( ) ) ) ;
563
+ assert_eq ! ( None , builder. options. http_headers) ;
564
+ assert_eq ! ( Some ( "TEST" . to_string( ) ) , builder. client_type) ;
565
+
566
+ let http_headers = HashMap :: from ( [ ( "Key" . to_string ( ) , "Value" . to_string ( ) ) ] ) ;
567
+ let builder = ClientBuilder :: new ( "" )
568
+ . with_options ( ClientOptions {
569
+ http_headers : Some ( http_headers. clone ( ) ) ,
570
+ } )
571
+ . with_client_type ( Some ( "TEST" . to_string ( ) ) ) ;
572
+ assert_eq ! ( Some ( http_headers) , builder. options. http_headers) ;
573
+ assert_eq ! ( Some ( "TEST" . to_string( ) ) , builder. client_type) ;
574
+ }
575
+
576
+ #[ tokio:: test]
577
+ async fn test_given_a_none_client_type_compute_http_headers_will_set_client_type_to_default_value (
578
+ ) {
579
+ let builder_without_client_type = ClientBuilder :: new ( "" ) ;
580
+ let computed_headers = builder_without_client_type. compute_http_headers ( ) ;
581
+
582
+ assert_eq ! (
583
+ computed_headers,
584
+ HashMap :: from( [ (
585
+ MITHRIL_CLIENT_TYPE_HEADER . to_string( ) ,
586
+ DEFAULT_CLIENT_TYPE . to_string( )
587
+ ) ] )
588
+ ) ;
589
+
590
+ let builder_with_none_client_type = ClientBuilder :: new ( "" ) . with_client_type ( None ) ;
591
+ let computed_headers = builder_with_none_client_type. compute_http_headers ( ) ;
592
+
593
+ assert_eq ! (
594
+ computed_headers,
595
+ HashMap :: from( [ (
596
+ MITHRIL_CLIENT_TYPE_HEADER . to_string( ) ,
597
+ DEFAULT_CLIENT_TYPE . to_string( )
598
+ ) ] )
599
+ ) ;
600
+ }
601
+
602
+ #[ tokio:: test]
603
+ async fn test_compute_http_headers_will_compute_client_type_header_from_struct_attribute_over_options (
604
+ ) {
605
+ let http_headers = HashMap :: from ( [ (
606
+ MITHRIL_CLIENT_TYPE_HEADER . to_string ( ) ,
607
+ "client type from options" . to_string ( ) ,
608
+ ) ] ) ;
609
+ let client_builder = ClientBuilder :: new ( "" )
610
+ . with_options ( ClientOptions {
611
+ http_headers : Some ( http_headers. clone ( ) ) ,
612
+ } )
613
+ . with_client_type ( Some ( "client type" . to_string ( ) ) ) ;
614
+
615
+ let computed_headers = client_builder. compute_http_headers ( ) ;
616
+
617
+ assert_eq ! (
618
+ computed_headers,
619
+ HashMap :: from( [ (
620
+ MITHRIL_CLIENT_TYPE_HEADER . to_string( ) ,
621
+ "client type" . to_string( )
622
+ ) ] )
623
+ ) ;
624
+ }
498
625
}
0 commit comments