oscerd opened a new pull request, #26207:
URL: https://github.com/apache/camel/pull/26207

   ## Issue
   
   [CAMEL-24435](https://issues.apache.org/jira/browse/CAMEL-24435)
   
   ## Problem
   
   `AS2ServerConnection.RequestHandlerThread.run()` creates its `HttpContext` 
once, **outside** the
   request loop, and reuses it for every request handled on that connection:
   
   ```java
   final HttpContext context = HttpCoreContext.create();
   while (!Thread.interrupted()) {
       this.httpService.handleRequest(this.serverConnection, context);
       ...
       String recipientAddress = 
coreContext.getAttribute(AS2AsynchronousMDNManager.RECIPIENT_ADDRESS, 
String.class);
       if (recipientAddress != null && config != null) {
           // Send the MDN asynchronously.
   ```
   
   `ResponseMDN` sets `RECIPIENT_ADDRESS` and `ASYNCHRONOUS_MDN` on that 
context while handling a request
   that carried `Receipt-Delivery-Option`, and nothing removed them afterwards. 
A later request on the
   same connection that did **not** ask for an asynchronous receipt therefore 
still found a non-null
   recipient address, and the handler dispatched a second asynchronous MDN — 
carrying whatever report was
   still stored under `ASYNCHRONOUS_MDN` — to the address supplied by the 
*earlier* request.
   
   ## Fix
   
   Both attributes are removed in a `finally` after every request. Using 
`finally` rather than clearing
   at the end of the send block also covers the paths that skip the send — in 
particular a request URI
   with no registered consumer configuration, where `config` is null and the 
old code left the address
   behind untouched.
   
   ### Also clears `CURRENT_CONSUMER_CONFIG`
   
   The same `finally` clears the `CURRENT_CONSUMER_CONFIG` ThreadLocal, which 
is not in the issue text
   but has the identical defect. `setupConfigurationForRequest` returns early 
**without** setting it when
   a path has no registered configuration:
   
   ```java
   if (config == null) {
       LOG.warn("No AS2 consumer configuration found for canonical path: {} 
...", requestUriPath);
       return null;
   }
   ...
   CURRENT_CONSUMER_CONFIG.set(wrapper);
   ```
   
   so the thread kept the previous request's wrapper. On its own that cannot 
trigger a send, but paired
   with a *new* legitimate recipient address it would have signed the MDN with 
the previous path's key.
   Clearing only the context attributes would have left that half of the leak 
in place.
   
   The post-processing block is extracted into `handleAsynchronousMDN` so the 
`finally` reads clearly;
   the logic inside is unchanged.
   
   ## Test
   
   `AS2AsyncMdnContextReuseTest` sends two messages through one 
`as2://client/send` route, so both travel
   over the same pooled connection to the server:
   
   1. the first carries `receiptDeliveryOption` → exactly one MDN must reach 
the receipt endpoint;
   2. the second does not → the receipt endpoint must see **no** further MDN.
   
   The second assertion uses `setAssertPeriod(5s)` so a leaked delivery has 
time to arrive rather than
   the test passing simply by being quick.
   
   Verified both ways: against the unfixed `camel-as2-api` the test fails with
   `mock://receipts Received message count. Expected: <0> but was: <1>`, and it 
passes with the fix.
   
   `components/camel-as2` suite green (API + Component). Full reactor build 
clean.
   
   ## Documentation
   
   No upgrade-guide entry: the previous behaviour was sending an MDN nobody 
asked for, to an address from
   an unrelated earlier request. There is nothing for a user to migrate.
   
   ---
   _Claude Code on behalf of oscerd_
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)


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