Copilot commented on code in PR #12868:
URL: https://github.com/apache/trafficserver/pull/12868#discussion_r2788094745


##########
src/proxy/http/HttpTransact.cc:
##########
@@ -139,19 +139,49 @@ bypass_ok(HttpTransact::State *s)
   return false;
 }
 
+// wrapper to choose between a remap next hop strategy or use parent.config
+// remap next hop strategy is preferred
+inline static bool
+host_override(HttpTransact::State *s)
+{
+  bool res = false;
+  if (nullptr != s->next_hop_strategy) {
+    // remap strategies do not support the TSHttpTxnParentProxySet API.
+    res = s->next_hop_strategy->host_override;
+  } else if (nullptr != s->parent_params) {
+    res = s->parent_result.host_override();
+  }
+  return res;
+}
+
+// wrapper to choose between a remap next hop strategy or use parent.config
+// remap next hop strategy is preferred
+inline static bool
+is_some(HttpTransact::State *s)
+{
+  bool res = false;
+  if (nullptr != s->next_hop_strategy) {
+    // remap strategies do not support the TSHttpTxnParentProxySet API.
+    res = s->parent_result.result == ParentResultType::SPECIFIED;
+  } else if (nullptr != s->parent_params) {
+    res = s->parent_result.is_some();
+  }

Review Comment:
   Similar to host_override(), is_some() falls back to parent_result.is_some() 
whenever parent_params is non-null, which can assert if response_action.handled 
set a SPECIFIED result without a parent_result.rec. Consider adding a 
response_action.handled branch that treats SPECIFIED as "some" without 
consulting rec.



##########
src/proxy/http/HttpTransact.cc:
##########
@@ -659,6 +699,22 @@ find_server_and_update_current_info(HttpTransact::State *s)
     }
   }
 
+  if (s->parent_result.result == ParentResultType::SPECIFIED && 
host_override(s)) {
+    char const *const hostname = s->parent_result.hostname;
+    TxnDbg(dbg_ctl_http_trans, "overriding host header with parent %s", 
hostname);
+    if (!s->hdr_info.server_request.valid()) {
+      
s->hdr_info.client_request.value_set(static_cast<std::string_view>(MIME_FIELD_HOST),
 hostname);
+      s->hdr_info.client_request.mark_target_dirty();
+    } else {
+      
s->hdr_info.server_request.value_set(static_cast<std::string_view>(MIME_FIELD_HOST),
 hostname);
+      s->hdr_info.server_request.mark_target_dirty();
+    }
+
+    if (nullptr != hostname) {
+      s->parent_info.name = s->arena.str_store(hostname, strlen(hostname));
+    }
+  }
+
   switch (s->parent_result.result) {
   case ParentResultType::SPECIFIED:
     s->parent_info.name = s->arena.str_store(s->parent_result.hostname, 
strlen(s->parent_result.hostname));

Review Comment:
   In the host_override block, hostname is used with "%s" logging and passed to 
value_set() before any nullptr check. If hostname is ever null (e.g., via 
TSHttpTxnResponseActionSet), this is undefined behavior. Consider guarding 
hostname up front (and skipping override if null) or logging with a safe 
fallback string.
   ```suggestion
       if (hostname != nullptr) {
         TxnDbg(dbg_ctl_http_trans, "overriding host header with parent %s", 
hostname);
         if (!s->hdr_info.server_request.valid()) {
           
s->hdr_info.client_request.value_set(static_cast<std::string_view>(MIME_FIELD_HOST),
 hostname);
           s->hdr_info.client_request.mark_target_dirty();
         } else {
           
s->hdr_info.server_request.value_set(static_cast<std::string_view>(MIME_FIELD_HOST),
 hostname);
           s->hdr_info.server_request.mark_target_dirty();
         }
         s->parent_info.name = s->arena.str_store(hostname, strlen(hostname));
       } else {
         TxnDbg(dbg_ctl_http_trans, "host override requested but parent 
hostname is null, skipping host header override");
       }
     }
   
     switch (s->parent_result.result) {
     case ParentResultType::SPECIFIED:
       if (s->parent_result.hostname != nullptr) {
         s->parent_info.name = s->arena.str_store(s->parent_result.hostname, 
strlen(s->parent_result.hostname));
       }
   ```



##########
src/proxy/http/HttpTransact.cc:
##########
@@ -139,19 +139,49 @@ bypass_ok(HttpTransact::State *s)
   return false;
 }
 
+// wrapper to choose between a remap next hop strategy or use parent.config
+// remap next hop strategy is preferred
+inline static bool
+host_override(HttpTransact::State *s)
+{
+  bool res = false;
+  if (nullptr != s->next_hop_strategy) {
+    // remap strategies do not support the TSHttpTxnParentProxySet API.
+    res = s->next_hop_strategy->host_override;
+  } else if (nullptr != s->parent_params) {
+    res = s->parent_result.host_override();
+  }

Review Comment:
   The new host_override() wrapper ignores response_action.handled, so when a 
plugin sets TSHttpTxnResponseActionSet (and parent_result.rec may be 
null/stale), calling parent_result.host_override() can trigger 
ParentResult::is_some() assertions. Consider handling response_action.handled 
explicitly here (e.g., return false, or base behavior solely on 
parent_result.result without touching rec).



##########
src/proxy/http/HttpTransact.cc:
##########
@@ -659,6 +699,22 @@ find_server_and_update_current_info(HttpTransact::State *s)
     }
   }
 
+  if (s->parent_result.result == ParentResultType::SPECIFIED && 
host_override(s)) {
+    char const *const hostname = s->parent_result.hostname;
+    TxnDbg(dbg_ctl_http_trans, "overriding host header with parent %s", 
hostname);
+    if (!s->hdr_info.server_request.valid()) {
+      
s->hdr_info.client_request.value_set(static_cast<std::string_view>(MIME_FIELD_HOST),
 hostname);
+      s->hdr_info.client_request.mark_target_dirty();
+    } else {
+      
s->hdr_info.server_request.value_set(static_cast<std::string_view>(MIME_FIELD_HOST),
 hostname);
+      s->hdr_info.server_request.mark_target_dirty();
+    }
+
+    if (nullptr != hostname) {
+      s->parent_info.name = s->arena.str_store(hostname, strlen(hostname));
+    }

Review Comment:
   This assignment to parent_info.name is redundant because the SPECIFIED case 
immediately below unconditionally overwrites parent_info.name from 
parent_result.hostname. Consider removing this write (or refactoring so the 
hostname is stored exactly once) to avoid confusion and double arena 
allocations.
   ```suggestion
   
   ```



##########
src/proxy/http/HttpTransact.cc:
##########
@@ -594,15 +628,19 @@ find_server_and_update_current_info(HttpTransact::State 
*s)
     TxnDbg(dbg_ctl_http_trans, "request is from localhost, so bypass parent");
     s->parent_result.result = ParentResultType::DIRECT;
   } else if (s->method == HTTP_WKSIDX_CONNECT && 
s->http_config_param->disable_ssl_parenting) {
+    /// BNO

Review Comment:
   Stray "/// BNO" comment looks like a debugging artifact and doesn’t describe 
behavior. It should be removed or replaced with a meaningful explanation of the 
CONNECT/disable_ssl_parenting logic.
   ```suggestion
       // For CONNECT (typically HTTPS tunneling) with disable_ssl_parenting 
enabled, avoid sending
       // the request to a forward parent proxy. We still run parent selection 
to honor any origin
       // server mappings, but if there is no usable parent, the result comes 
from an API override,
       // or the selected parent is itself a proxy, we bypass the parent and go 
DIRECT instead.
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to