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


##########
src/proxy/http/HttpSM.cc:
##########
@@ -2145,6 +2145,16 @@ HttpSM::state_read_server_response_header(int event, 
void *data)
     // If there is a post body in transit, give up on it
     if (tunnel.is_tunnel_alive()) {
       tunnel.abort_tunnel();
+      // abort_tunnel() cancels I/O but does not close VCs or clean up
+      // vc_table entries.  When a request transform is active the
+      // post_transform_info entry still references the TransformVConnection
+      // with in_tunnel=true, which causes cleanup_entry() to skip
+      // do_io_close() — leaking the VC.  Close it explicitly here.
+      if (post_transform_info.entry != nullptr) {
+        post_transform_info.entry->vc->do_io_close();
+        vc_table.cleanup_entry(post_transform_info.entry);
+        post_transform_info.entry = nullptr;
+      }

Review Comment:
   `vc_table.cleanup_entry()` only calls `do_io_close()` when `entry->in_tunnel 
== false` (see HttpVCTable.cc:114-121). This new code unconditionally calls 
`do_io_close()` before `cleanup_entry()`, which would double-close the VC if 
`post_transform_info.entry` ever exists with `in_tunnel == false` on this path. 
Guard the explicit close so it only happens for the `in_tunnel` case that 
`cleanup_entry()` skips.



##########
tests/gold_tests/slow_post/quick_server.test.py:
##########
@@ -105,22 +116,30 @@ def run(self):
         http_utils = os.path.join(tools_dir, 'http_utils.py')
         tr.Setup.CopyAs(self._init_file, Test.RunDirectory)
         tr.Setup.CopyAs(http_utils, Test.RunDirectory)
-        tr.Setup.CopyAs(self._slow_post_client, Test.RunDirectory)
         tr.Setup.CopyAs(self._quick_server, Test.RunDirectory)
 
-        client_command = (f'{sys.executable} {self._slow_post_client} '
-                          '127.0.0.1 '
-                          f'{self._ts.Variables.port} ')
-        if not self._should_abort_request:
-            client_command += '--finish-request '
-        p = tr.Processes.Default
-        p.Command = client_command
-        if self._should_abort_request or self._should_abort_response_headers:
-            p.Streams.All += Testers.ExcludesExpression('HTTP/1.1 200 OK', 
'Verify response was received')
+        if self._use_request_transform:
+            tr.Setup.CopyAs(self._partial_post_client, Test.RunDirectory)
+            p = tr.Processes.Default
+            p.Command = (f'{sys.executable} {self._partial_post_client} '
+                         f'127.0.0.1 {self._ts.Variables.port}')
+            p.ReturnCode = 0
+            p.Streams.All += Testers.ContainsExpression('HTTP/1.1', 'Verify 
client received an HTTP response')

Review Comment:
   This assertion currently checks for the substring `HTTP/1.1`, but the 
partial POST client can legitimately exit via a connection reset path (and 
after the suggested client output change, that path won't contain `HTTP/1.1`). 
Update the expression/description to accept either an actual HTTP status line 
or the explicit reset marker.



-- 
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