@@ -139,19 +139,51 @@ bypass_ok(HttpTransact::State *s)
139139 return false;
140140}
141141
142+ // wrapper to choose between a remap next hop strategy or use parent.config
143+ // remap next hop strategy is preferred
144+ inline static bool
145+ host_override(HttpTransact::State *s)
146+ {
147+ if (s->response_action.handled) { // should be handled by the plugin
148+ return false;
149+ } else if (nullptr != s->next_hop_strategy) {
150+ // remap strategies do not support the TSHttpTxnParentProxySet API.
151+ return s->next_hop_strategy->host_override;
152+ } else if (nullptr != s->parent_params) {
153+ return s->parent_result.host_override();
154+ }
155+ return false;
156+ }
157+
158+ // wrapper to choose between a remap next hop strategy or use parent.config
159+ // remap next hop strategy is preferred
160+ inline static bool
161+ is_some(HttpTransact::State *s)
162+ {
163+ if (s->response_action.handled) {
164+ return true;
165+ } else if (nullptr != s->next_hop_strategy) {
166+ // remap strategies do not support the TSHttpTxnParentProxySet API.
167+ return s->parent_result.result == ParentResultType::SPECIFIED;
168+ } else if (nullptr != s->parent_params) {
169+ return s->parent_result.is_some();
170+ }
171+ return false;
172+ }
173+
142174// wrapper to choose between a remap next hop strategy or use parent.config
143175// remap next hop strategy is preferred
144176inline static bool
145177is_api_result(HttpTransact::State *s)
146178{
147- bool r = false;
179+ bool res = false;
148180 if (nullptr != s->next_hop_strategy) {
149181 // remap strategies do not support the TSHttpTxnParentProxySet API.
150- r = false;
182+ res = false;
151183 } else if (nullptr != s->parent_params) {
152- r = s->parent_result.is_api_result();
184+ res = s->parent_result.is_api_result();
153185 }
154- return r ;
186+ return res ;
155187}
156188
157189// wrapper to get the max_retries.
@@ -207,6 +239,8 @@ retry_type(HttpTransact::State *s)
207239inline static void
208240findParent(HttpTransact::State *s)
209241{
242+ TxnDbg(dbg_ctl_http_trans, " findParent" );
243+
210244 Metrics::Counter::increment(http_rsb.parent_count);
211245 if (s->response_action.handled) {
212246 s->parent_result.hostname = s->response_action.action.hostname;
@@ -295,6 +329,8 @@ parentExists(HttpTransact::State *s)
295329inline static void
296330nextParent(HttpTransact::State *s)
297331{
332+ TxnDbg(dbg_ctl_http_trans, " nextParent" );
333+
298334 TxnDbg(dbg_ctl_parent_down, " connection to parent %s failed, conn_state: %s, request to origin: %s" , s->parent_result.hostname,
299335 HttpDebugNames::get_server_state_name(s->current.state), s->request_data.get_host());
300336 Metrics::Counter::increment(http_rsb.parent_count);
@@ -599,10 +635,11 @@ find_server_and_update_current_info(HttpTransact::State *s)
599635 } else {
600636 findParent(s);
601637 }
602- if (!s->parent_result. is_some() || is_api_result(s) || parent_is_proxy(s)) {
638+ if (!is_some(s ) || is_api_result(s) || parent_is_proxy(s)) {
603639 TxnDbg(dbg_ctl_http_trans, " request not cacheable, so bypass parent" );
604640 s->parent_result.result = ParentResultType::DIRECT;
605641 }
642+
606643 } else if (s->txn_conf->uncacheable_requests_bypass_parent && s->txn_conf->no_dns_forward_to_parent == 0 &&
607644 !HttpTransact::is_request_cache_lookupable(s)) {
608645 // request not lookupable and cacheable, so bypass parent if the parent is not an origin server.
@@ -616,10 +653,12 @@ find_server_and_update_current_info(HttpTransact::State *s)
616653 } else {
617654 findParent(s);
618655 }
619- if (!s->parent_result.is_some() || is_api_result(s) || parent_is_proxy(s)) {
656+
657+ if (!is_some(s) || is_api_result(s) || parent_is_proxy(s)) {
620658 TxnDbg(dbg_ctl_http_trans, " request not cacheable, so bypass parent" );
621659 s->parent_result.result = ParentResultType::DIRECT;
622660 }
661+
623662 } else {
624663 switch (s->parent_result.result) {
625664 case ParentResultType::UNDEFINED:
@@ -660,14 +699,32 @@ find_server_and_update_current_info(HttpTransact::State *s)
660699 }
661700
662701 switch (s->parent_result.result) {
663- case ParentResultType::SPECIFIED:
664- s->parent_info.name = s->arena.str_store(s->parent_result.hostname, strlen(s->parent_result.hostname));
702+ case ParentResultType::SPECIFIED: {
703+ char const *const hostname = s->parent_result.hostname;
704+
705+ if (nullptr != hostname) {
706+ s->parent_info.name = s->arena.str_store(hostname, strlen(hostname));
707+
708+ // if host header override option enabled
709+ if (host_override(s)) {
710+ TxnDbg(dbg_ctl_http_trans, " overriding host header with parent %s" , hostname);
711+ if (!s->hdr_info.server_request.valid()) {
712+ s->hdr_info.client_request.value_set(static_cast<std::string_view>(MIME_FIELD_HOST), hostname);
713+ s->hdr_info.client_request.mark_target_dirty();
714+ } else {
715+ s->hdr_info.server_request.value_set(static_cast<std::string_view>(MIME_FIELD_HOST), hostname);
716+ s->hdr_info.server_request.mark_target_dirty();
717+ }
718+ }
719+ }
720+
665721 update_current_info(&s->current, &s->parent_info, ResolveInfo::PARENT_PROXY, false);
666722 update_dns_info(&s->dns_info, &s->current);
667723 ink_assert(s->dns_info.looking_up == ResolveInfo::PARENT_PROXY);
668724 s->next_hop_scheme = URL_WKSIDX_HTTP;
669725
670726 return ResolveInfo::PARENT_PROXY;
727+ }
671728 case ParentResultType::FAIL:
672729 // No more parents - need to return an error message
673730 s->current.request_to = ResolveInfo::HOST_NONE;
0 commit comments