@@ -635,33 +635,51 @@ register_stat_callbacks()
635635 });
636636}
637637
638+ /* *
639+ Parse list of HTTP status code and return HttpStatusBitset
640+ - e.g. "204 305 403 404 414 500 501 502 503 504"
641+ */
642+ static HttpStatusBitset
643+ parse_http_status_code_list (swoc::TextView status_list)
644+ {
645+ HttpStatusBitset set;
646+
647+ auto is_sep{[](char c) { return isspace (c) || ' ,' == c || ' ;' == c; }};
648+
649+ while (!status_list.ltrim_if (is_sep).empty ()) {
650+ swoc::TextView span;
651+ swoc::TextView token{status_list.take_prefix_if (is_sep)};
652+ auto n = swoc::svtoi (token, &span);
653+ if (span.size () != token.size ()) {
654+ Error (" Invalid status code '%.*s': not a number" , static_cast <int >(token.size ()), token.data ());
655+ } else if (n <= 0 || n >= HTTP_STATUS_NUMBER) {
656+ Error (" Invalid status code '%.*s': out of range" , static_cast <int >(token.size ()), token.data ());
657+ } else {
658+ set[n] = true ;
659+ }
660+ }
661+
662+ return set;
663+ }
664+
638665static bool
639666set_negative_caching_list (const char *name, RecDataT dtype, RecData data, HttpConfigParams *c, bool update)
640667{
641668 bool ret = false ;
642669 HttpStatusBitset set;
670+
643671 // values from proxy.config.http.negative_caching_list
644672 if (0 == strcasecmp (" proxy.config.http.negative_caching_list" , name) && RECD_STRING == dtype && data.rec_string ) {
645673 // parse the list of status codes
646- swoc::TextView status_list (data.rec_string , strlen (data.rec_string ));
647- auto is_sep{[](char c) { return isspace (c) || ' ,' == c || ' ;' == c; }};
648- while (!status_list.ltrim_if (is_sep).empty ()) {
649- swoc::TextView span, token{status_list.take_prefix_if (is_sep)};
650- auto n = swoc::svtoi (token, &span);
651- if (span.size () != token.size ()) {
652- Error (" Invalid status code '%.*s' for negative caching: not a number" , static_cast <int >(token.size ()), token.data ());
653- } else if (n <= 0 || n >= HTTP_STATUS_NUMBER) {
654- Error (" Invalid status code '%.*s' for negative caching: out of range" , static_cast <int >(token.size ()), token.data ());
655- } else {
656- set[n] = true ;
657- }
658- }
674+ set = parse_http_status_code_list ({data.rec_string , strlen (data.rec_string )});
659675 }
676+
660677 // set the return value
661678 if (set != c->negative_caching_list ) {
662679 c->negative_caching_list = set;
663680 ret = ret || update;
664681 }
682+
665683 return ret;
666684}
667685
@@ -685,6 +703,47 @@ load_negative_caching_var(RecRecord const *r, void *cookie)
685703 set_negative_caching_list (r->name , r->data_type , r->data , c, false );
686704}
687705
706+ static bool
707+ set_negative_revalidating_list (const char *name, RecDataT dtype, RecData data, HttpConfigParams *c, bool update)
708+ {
709+ bool ret = false ;
710+ HttpStatusBitset set;
711+
712+ // values from proxy.config.http.negative_revalidating_list
713+ if (0 == strcasecmp (" proxy.config.http.negative_revalidating_list" , name) && RECD_STRING == dtype && data.rec_string ) {
714+ // parse the list of status codes
715+ set = parse_http_status_code_list ({data.rec_string , strlen (data.rec_string )});
716+ }
717+
718+ // set the return value
719+ if (set != c->negative_revalidating_list ) {
720+ c->negative_revalidating_list = set;
721+ ret = ret || update;
722+ }
723+
724+ return ret;
725+ }
726+
727+ // Method of getting the status code bitset
728+ static int
729+ negative_revalidating_list_cb (const char *name, RecDataT dtype, RecData data, void *cookie)
730+ {
731+ HttpConfigParams *c = static_cast <HttpConfigParams *>(cookie);
732+ // Signal an update if valid value arrived.
733+ if (set_negative_revalidating_list (name, dtype, data, c, true )) {
734+ http_config_cb (name, dtype, data, cookie);
735+ }
736+ return REC_ERR_OKAY;
737+ }
738+
739+ // Method of loading the negative caching config bitset
740+ void
741+ load_negative_revalidating_var (RecRecord const *r, void *cookie)
742+ {
743+ HttpConfigParams *c = static_cast <HttpConfigParams *>(cookie);
744+ set_negative_revalidating_list (r->name , r->data_type , r->data , c, false );
745+ }
746+
688747/* * Template for creating conversions and initialization for @c std::chrono based configuration variables.
689748 *
690749 * @tparam V The exact type of the configuration variable.
@@ -1020,6 +1079,8 @@ HttpConfig::startup()
10201079 HttpEstablishStaticConfigLongLong (c.oride .negative_revalidating_lifetime , " proxy.config.http.negative_revalidating_lifetime" );
10211080 RecRegisterConfigUpdateCb (" proxy.config.http.negative_caching_list" , &negative_caching_list_cb, &c);
10221081 RecLookupRecord (" proxy.config.http.negative_caching_list" , &load_negative_caching_var, &c, true );
1082+ RecRegisterConfigUpdateCb (" proxy.config.http.negative_revalidating_list" , &negative_revalidating_list_cb, &c);
1083+ RecLookupRecord (" proxy.config.http.negative_revalidating_list" , &load_negative_revalidating_var, &c, true );
10231084
10241085 // Buffer size and watermark
10251086 HttpEstablishStaticConfigLongLong (c.oride .default_buffer_size_index , " proxy.config.http.default_buffer_size" );
@@ -1339,7 +1400,8 @@ HttpConfig::reconfigure()
13391400 params->oride .ssl_client_sni_policy = ats_strdup (m_master.oride .ssl_client_sni_policy );
13401401 params->oride .ssl_client_alpn_protocols = ats_strdup (m_master.oride .ssl_client_alpn_protocols );
13411402
1342- params->negative_caching_list = m_master.negative_caching_list ;
1403+ params->negative_caching_list = m_master.negative_caching_list ;
1404+ params->negative_revalidating_list = m_master.negative_revalidating_list ;
13431405
13441406 params->oride .host_res_data = m_master.oride .host_res_data ;
13451407 params->oride .host_res_data .conf_value = ats_strdup (m_master.oride .host_res_data .conf_value );
0 commit comments