https://bz.apache.org/bugzilla/show_bug.cgi?id=68227

--- Comment #6 from WU QI <[email protected]> ---
Created attachment 40226
  --> https://bz.apache.org/bugzilla/attachment.cgi?id=40226&action=edit
Servlet-only initial-service RST reproducer for Tomcat 10.1.61, with controls
and results

I have a Servlet-only reproducer for a remaining initial-service path with the
same symptoms on unmodified Tomcat 10.1.61 (also reproduced on 10.1.55).

In light of comment 5, this case does not restart async processing at the
dispatch target and cannot enter that loop. The target is never invoked:
target=0, onComplete=0, inProgressAsyncCount=1.

Trigger:
1. The initial servlet calls startAsync() and registers an AsyncListener.
2. A latch holds that initial service call before the first response write.
3. A loopback client closes with SO_LINGER=0, then releases the latch.
4. A write/flush on the original container thread throws ClientAbortException.
5. onError calls dispatch("/target"). The target only writes "done" and
returns; it does not call startAsync().

Expected: /target is invoked once, followed by one onComplete callback and
inProgressAsyncCount returning to zero.
Actual on 10.1.55 and 10.1.61: onError=1, target=0, onComplete=0,
inProgressAsyncCount=1.

Controls on 10.1.61:
- onError calls complete() instead: onComplete=1, count=0.
- Normal dispatch without client reset: target=1, onComplete=1, count=0.

Environment: Homebrew OpenJDK 21.0.12.1, macOS arm64, Http11NioProtocol,
HTTP/1.1 over loopback. No Spring dependency, reverse proxy, container
overrides, or application-specific code.

The attached ZIP contains one Java source file, a bounded Python runner,
instructions, and the observed results. Run:
  python3 run.py 10.1.61 dispatch
The reproduced failure exits with an assertion; "complete" and "normal" are the
passing control modes. Each Java run is limited to 20 seconds and
stops/destroys its own embedded server. The 3.5-second observation window is
not a separate Servlet timeout violation claim, since dispatch has already been
requested.

Source analysis consistent with the result: CoyoteAdapter.service's error
cleanup only covers isAsyncCompleting(), whereas CoyoteAdapter.asyncDispatch
covers completing or dispatching. In this initial-service error path, the
socket closes before the ordinary asyncPostProcess completion/count cleanup.
The 10.1.61 MUST_ERROR fix does not resolve this reproduction.
https://github.com/apache/tomcat/commit/6c7da60893bd186d6cb2df7330299d7e70e68279
https://github.com/apache/tomcat/blob/68dcc40ec209c81156a9832d3527c16bac290bfd/java/org/apache/catalina/connector/CoyoteAdapter.java#L383
https://github.com/apache/tomcat/blob/68dcc40ec209c81156a9832d3527c16bac290bfd/java/org/apache/coyote/AbstractProcessorLight.java#L85

I also checked BZ 69121 (an exception from an entered dispatch target) and BZ
67235 (async-dispatch cleanup/recycling). This reproducer fails earlier, during
the initial service call, before /target is invoked.

I am adding this here to avoid a duplicate report. Please let me know if this
initial-service case should be tracked separately. No complete corrective patch
is proposed: simply firing onComplete without actually performing the requested
dispatch would not satisfy the behavior described in comment 5.

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to