[
https://issues.apache.org/jira/browse/CAMEL-23072?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Reto Peter updated CAMEL-23072:
-------------------------------
Summary: camel-as2 - Receiving messages: AS2 server endpoint does not
support Expect: 100-continue — causes 3-second delay on every inbound message
(was: Receiving messages: AS2 server endpoint does not support Expect:
100-continue — causes 3-second delay on every inbound message)
> camel-as2 - Receiving messages: AS2 server endpoint does not support Expect:
> 100-continue — causes 3-second delay on every inbound message
> ------------------------------------------------------------------------------------------------------------------------------------------
>
> Key: CAMEL-23072
> URL: https://issues.apache.org/jira/browse/CAMEL-23072
> Project: Camel
> Issue Type: Bug
> Components: camel-as2
> Affects Versions: 4.18.0
> Reporter: Reto Peter
> Priority: Major
>
> h3. Summary
> The Camel AS2 server endpoint does not handle the HTTP \{{Expect:
> 100-continue}} protocol. When an AS2 client sends a request with the
> \{{Expect: 100-continue}} header (e.g., Mendelson AS2), the server never
> responds with \{{100 Continue}}. The client waits for
> its timeout (typically 3 seconds) before sending the message body anyway,
> adding a 3-second delay to every inbound AS2 message.
> This affects ALL Camel versions — the
> \{{BasicHttpServerExpectationDecorator}} has never been used in
> \{{AS2ServerConnection}}.
> h3. Root Cause
> In \{{AS2ServerConnection.RequestListenerService}}, the \{{HttpService}} is
> created using the 2-arg constructor without wrapping the request handler with
> \{{BasicHttpServerExpectationDecorator}}:
> \{code:java|title=AS2ServerConnection.java (line ~388-391)}
> registry = new RequestHandlerRegistry<>();
> HttpServerRequestHandler handler = new
> BasicHttpServerRequestHandler(registry);
> // Set up the HTTP service
> httpService = new HttpService(inhttpproc, handler);
> \{code}
> HttpCore5's \{{HttpService.handleRequest()}} only sends a \{{100 Continue}}
> response if the request handler is wrapped with
> \{{BasicHttpServerExpectationDecorator}}. Without it, the server reads the
> request headers, sees \{{Expect: 100-continue}}, but never
> acknowledges it. The client-side \{{HttpRequestExecutor}} waits for
> \{{DEFAULT_WAIT_FOR_CONTINUE}} (3 seconds) before giving up and sending the
> body.
> h3. Proposed Fix
> Wrap the handler with \{{BasicHttpServerExpectationDecorator}}:
> \{code:java|title=AS2ServerConnection.java (proposed fix)}
> registry = new RequestHandlerRegistry<>();
> HttpServerRequestHandler handler = new
> BasicHttpServerRequestHandler(registry);
> // Set up the HTTP service — wrap handler to support Expect: 100-continue
> httpService = new HttpService(inhttpproc, new
> BasicHttpServerExpectationDecorator(handler));
> \{code}
> This is a one-line change. \{{BasicHttpServerExpectationDecorator}} is part
> of HttpCore5
> (\{{org.apache.hc.core5.http.io.support.BasicHttpServerExpectationDecorator}})
> and is already on the classpath.
> When a client sends \{{Expect: 100-continue}}, the decorator automatically
> responds with \{{100 Continue}} before delegating to the actual handler,
> allowing the client to immediately send the body without waiting.
> The same fix should also be applied to \{{AS2AsyncMDNServerConnection}} if
> it has the same pattern.
> h3. How to Reproduce
> # Set up a Camel AS2 server endpoint
> # Send an AS2 message from a client that sends \{{Expect: 100-continue}}
> (e.g., Mendelson AS2 — enabled by default)
> # Observe that the message takes ~3-4 seconds to arrive instead of <1 second
> # With a network capture (Wireshark), you can see: client sends headers →
> 3-second gap → client sends body (no \{{100 Continue}} from server in between)
> h3. Impact
> Every inbound AS2 message from clients that use \{{Expect: 100-continue}}
> (which is common — Mendelson, many enterprise AS2 systems) is delayed by 3
> seconds. For high-volume systems processing hundreds of messages per day,
> this adds significant cumulative
> latency.
> h3. Additional Notes
> The same \{{AS2ServerConnection}} class also has a
> \{{RequestAcceptorThread}} that passes the \{{httpService}} directly to each
> \{{RequestHandlerThread}}:
> \{code:java}
> final Thread t = new RequestHandlerThread(this.service.httpService,
> inSocket);
> \{code}
> The fix at construction time (wrapping the handler before \{{HttpService}}
> is created) ensures all threads see the correct behavior without any
> threading concerns.
> Ideally, this could also be made configurable via an endpoint parameter
> (e.g., \{{supportExpectContinue=true/false}}) for cases where the server
> explicitly does not want to send \{{100 Continue}}.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)