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)

Reply via email to