This is an automated email from the ASF dual-hosted git repository.

cmcfarlen pushed a commit to branch 10.2.x
in repository https://gitbox.apache.org/repos/asf/trafficserver.git

commit 8554f669dbff910b3b5f519845a352e192b9939f
Author: Brian Neradt <[email protected]>
AuthorDate: Tue Mar 3 11:17:56 2026 -0500

    Fix failed assertion in build_response for 1xx races (#12866)
    
    This failed assertion was seen sometimes when running the cache-tests.
    
    When a 1xx informational response (such as 103 Early Hints) is forwarded
    to the client, its headers are copied into client_response and sent via
    an asynchronous tunnel. The tunnel completion handler
    (tunnel_handler_100_continue) destroys client_response when the tunnel
    finishes. However, if the final server response arrives and
    build_response is called before the tunnel completes, client_response is
    still valid, triggering the assertion `!new_hdr->valid()` in
    copy_header_fields.
    
    This patch addresses this by defensively destroying outgoing_response in
    build_response if it is already valid before calling copy_header_fields.
    The header data from the 1xx has already been serialized into the tunnel
    buffer and is no longer needed, so this should be safe.
    
    (cherry picked from commit 28c0f7148b44cf17e42810c85b4af228f8313d9b)
---
 src/proxy/http/HttpTransact.cc | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/src/proxy/http/HttpTransact.cc b/src/proxy/http/HttpTransact.cc
index 8137257f26..e2365fb366 100644
--- a/src/proxy/http/HttpTransact.cc
+++ b/src/proxy/http/HttpTransact.cc
@@ -8043,6 +8043,12 @@ HttpTransact::build_response(State *s, HTTPHdr 
*base_response, HTTPHdr *outgoing
     HttpTransactHeaders::build_base_response(outgoing_response, status_code, 
reason_phrase, strlen(reason_phrase), s->current.now);
   } else {
     if ((status_code == HTTPStatus::NONE) || (status_code == 
base_response->status_get())) {
+      // Preemptively clean up the response in case a prior 1xx informational
+      // response was forwarded to the client. Otherwise, copy_header_fields
+      // will fail an assertion that the new header is not yet valid.
+      if (outgoing_response->valid()) {
+        outgoing_response->destroy();
+      }
       HttpTransactHeaders::copy_header_fields(base_response, 
outgoing_response, s->txn_conf->fwd_proxy_auth_to_parent);
 
       if (s->txn_conf->insert_age_in_response) {

Reply via email to