Skip to content

Honour the sender's readtimeout and allow send timeouts per partnership - #636

Open
JakeHuneau wants to merge 1 commit into
OpenAS2:masterfrom
JakeHuneau:fix/send-timeouts
Open

JakeHuneau wants to merge 1 commit into
OpenAS2:masterfrom
JakeHuneau:fix/send-timeouts

Conversation

@JakeHuneau

Copy link
Copy Markdown
Collaborator

Problem

The AS2 sender's readtimeout has no effect, so a partner that takes longer than 60 seconds to return a synchronous MDN cannot be accommodated by following the documentation.

  • fix http timeout handling #208 found readtimeout mapped to the wrong HttpClient setting (the connection request timeout) and replaced it with sockettimeout in HTTPUtil.buildRequestConfig.
  • But the shipped config.xml and HowTo section 17.9 still set readtimeout. HttpSenderModule.getHttpOptions kept copying it into the options, where nothing reads it.
  • Neither sockettimeout nor connecttimeout is set by the shipped configuration, so every send uses the 60 second defaults whatever readtimeout says.

The timeouts are also only configurable on the sender module, so giving one slow partner longer means raising it for every partner.

Change

  • readtimeout is honoured as the socket timeout when sockettimeout is not set. sockettimeout wins when both are set.
  • Per-partnership timeouts: a partnership can set its own connecttimeout and sockettimeout attributes, in milliseconds:
    <attribute name="sockettimeout" value="300000"/>
    This goes through a new HttpSenderModule.getHttpOptions(Partnership), used by both AS2SenderModule and MDNSenderModule. It follows how the mutual TLS client certificate settings are already taken from the partnership.
  • Bad values: a partnership value that is not a non-negative number is ignored, with a warning naming the partnership. Otherwise it would fail every send to that partner when the request is built.

Behaviour change to be aware of: the sample openas2.properties sets module.AS2SenderModule.readtimeout=3000000, which is 50 minutes. That value now takes effect for anyone who copied it. The changelog entry points this out. I left the sample alone because the value looks deliberate, but I'm happy to lower it if you prefer.

Tests

SendTimeoutTest:

  • How the options are worked out:
    • the defaults;
    • readtimeout used as the socket timeout;
    • sockettimeout winning over readtimeout;
    • partnership overrides of both timeouts;
    • a partnership that sets nothing;
    • invalid partnership values ignored.
  • A real send through AS2SenderModule.handle to a local partner that takes 3 seconds to answer. A 400ms partnership socket timeout ends the send well before the answer. The control, without an override, waits for it.

Mutation checks: each of these changes fails a test:

  • the sender ignoring the partnership
  • readtimeout ignored again
  • the precedence reversed
  • the validation removed
  • the connect timeout override dropped

The MDNSenderModule call site is the same one-line change but is not exercised by a test, since that needs an async MDN exchange.

Test isolation: SendTimeoutTest and InterruptedSendReportStartupTest now set storageBaseDir to a folder of their own. The test configuration's pending folders (%home%/../data) are shared between test classes, and the pending files left by this test's sends changed what the startup report test could conclude.

Full suite: 254 tests pass.

Docs

HowTo section 17.9 gains sockettimeout, connecttimeout, the per-partnership attribute, and async MDN as an alternative for partners that are slow to respond. The PDF is regenerated; compared with an export of the unchanged document from the same LibreOffice, the only text added is those paragraphs (a table's repeated header row moves with the page break).

The AS2 sender's "readtimeout" had no effect. PR OpenAS2#208 found it mapped to the
wrong HttpClient setting (the connection request timeout) and replaced it with
"sockettimeout", but the shipped config.xml and HowTo section 17.9 still set
"readtimeout", which HttpSenderModule kept reading into the options and
HTTPUtil never applied. Neither "sockettimeout" nor "connecttimeout" is set by
the shipped configuration, so every send used the 60 second defaults whatever
readtimeout said, and a partner that takes longer than that to return a
synchronous MDN could not be accommodated by following the documentation.

"readtimeout" is now used as the socket timeout when "sockettimeout" is not
set; "sockettimeout" takes precedence when both are.

A partnership can also set its own "connecttimeout" and "sockettimeout"
attributes, in milliseconds, through a new HttpSenderModule.getHttpOptions(
Partnership) used by both the AS2 sender and the asynchronous MDN sender, so
one slow partner can be given longer without raising the timeout for every
partner. A value that is not a non-negative number is ignored with a warning
naming the partnership, rather than failing every send to that partner when
the request is built.

The sample openas2.properties sets module.AS2SenderModule.readtimeout to
3000000 (50 minutes); that value now takes effect for anyone who copied it,
which the changelog points out.

SendTimeoutTest covers how the options are worked out, and sends a real
message through AS2SenderModule to a local partner that takes 3 seconds to
answer: a 400ms partnership socket timeout ends the send well before that,
and without one the send waits for the answer. The test and
InterruptedSendReportStartupTest now use storage folders of their own, since
the test configuration's pending folders are shared between test classes and
the files one leaves there changed what the other's report could conclude.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant