Reto Peter created CAMEL-23072:
----------------------------------
Summary: 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
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)