@@ -389,6 +389,20 @@ static struct string_list *fields_sent(void)
389389 return & fields_list ;
390390}
391391
392+ static struct string_list * fields_checked (void )
393+ {
394+ static struct string_list fields_list = STRING_LIST_INIT_NODUP ;
395+ static int initialized ;
396+
397+ if (!initialized ) {
398+ fields_list .cmp = strcasecmp ;
399+ fields_from_config (& fields_list , "promisor.checkFields" );
400+ initialized = 1 ;
401+ }
402+
403+ return & fields_list ;
404+ }
405+
392406/*
393407 * Struct for promisor remotes involved in the "promisor-remote"
394408 * protocol capability.
@@ -534,6 +548,61 @@ enum accept_promisor {
534548 ACCEPT_ALL
535549};
536550
551+ static int match_field_against_config (const char * field , const char * value ,
552+ struct promisor_info * config_info )
553+ {
554+ if (config_info -> filter && !strcasecmp (field , promisor_field_filter ))
555+ return !strcmp (config_info -> filter , value );
556+ else if (config_info -> token && !strcasecmp (field , promisor_field_token ))
557+ return !strcmp (config_info -> token , value );
558+
559+ return 0 ;
560+ }
561+
562+ static int all_fields_match (struct promisor_info * advertised ,
563+ struct string_list * config_info ,
564+ int in_list )
565+ {
566+ struct string_list * fields = fields_checked ();
567+ struct string_list_item * item_checked ;
568+
569+ for_each_string_list_item (item_checked , fields ) {
570+ int match = 0 ;
571+ const char * field = item_checked -> string ;
572+ const char * value = NULL ;
573+ struct string_list_item * item ;
574+
575+ if (!strcasecmp (field , promisor_field_filter ))
576+ value = advertised -> filter ;
577+ else if (!strcasecmp (field , promisor_field_token ))
578+ value = advertised -> token ;
579+
580+ if (!value )
581+ return 0 ;
582+
583+ if (in_list ) {
584+ for_each_string_list_item (item , config_info ) {
585+ struct promisor_info * p = item -> util ;
586+ if (match_field_against_config (field , value , p )) {
587+ match = 1 ;
588+ break ;
589+ }
590+ }
591+ } else {
592+ item = string_list_lookup (config_info , advertised -> name );
593+ if (item ) {
594+ struct promisor_info * p = item -> util ;
595+ match = match_field_against_config (field , value , p );
596+ }
597+ }
598+
599+ if (!match )
600+ return 0 ;
601+ }
602+
603+ return 1 ;
604+ }
605+
537606static int should_accept_remote (enum accept_promisor accept ,
538607 struct promisor_info * advertised ,
539608 struct string_list * config_info )
@@ -544,7 +613,7 @@ static int should_accept_remote(enum accept_promisor accept,
544613 const char * remote_url = advertised -> url ;
545614
546615 if (accept == ACCEPT_ALL )
547- return 1 ;
616+ return all_fields_match ( advertised , config_info , 1 ) ;
548617
549618 /* Get config info for that promisor remote */
550619 item = string_list_lookup (config_info , remote_name );
@@ -556,7 +625,7 @@ static int should_accept_remote(enum accept_promisor accept,
556625 p = item -> util ;
557626
558627 if (accept == ACCEPT_KNOWN_NAME )
559- return 1 ;
628+ return all_fields_match ( advertised , config_info , 0 ) ;
560629
561630 if (accept != ACCEPT_KNOWN_URL )
562631 BUG ("Unhandled 'enum accept_promisor' value '%d'" , accept );
@@ -567,7 +636,7 @@ static int should_accept_remote(enum accept_promisor accept,
567636 }
568637
569638 if (!strcmp (p -> url , remote_url ))
570- return 1 ;
639+ return all_fields_match ( advertised , config_info , 0 ) ;
571640
572641 warning (_ ("known remote named '%s' but with URL '%s' instead of '%s'" ),
573642 remote_name , p -> url , remote_url );
@@ -605,6 +674,10 @@ static struct promisor_info *parse_one_advertised_remote(const char *remote_info
605674 info -> name = url_percent_decode (p );
606675 else if (skip_field_name_prefix (elem , promisor_field_url , & p ))
607676 info -> url = url_percent_decode (p );
677+ else if (skip_field_name_prefix (elem , promisor_field_filter , & p ))
678+ info -> filter = url_percent_decode (p );
679+ else if (skip_field_name_prefix (elem , promisor_field_token , & p ))
680+ info -> token = url_percent_decode (p );
608681 }
609682
610683 string_list_clear (& elem_list , 0 );
@@ -646,11 +719,6 @@ static void filter_promisor_remote(struct repository *repo,
646719 if (accept == ACCEPT_NONE )
647720 return ;
648721
649- if (accept != ACCEPT_ALL ) {
650- promisor_config_info_list (repo , & config_info , NULL );
651- string_list_sort (& config_info );
652- }
653-
654722 /* Parse remote info received */
655723
656724 string_list_split (& remote_info , info , ";" , -1 );
@@ -663,6 +731,11 @@ static void filter_promisor_remote(struct repository *repo,
663731 if (!advertised )
664732 continue ;
665733
734+ if (!config_info .nr ) {
735+ promisor_config_info_list (repo , & config_info , fields_checked ());
736+ string_list_sort (& config_info );
737+ }
738+
666739 if (should_accept_remote (accept , advertised , & config_info ))
667740 strvec_push (accepted , advertised -> name );
668741
0 commit comments