Add configurable request header size to the HTTP Listener - #393
Open
pacmano1 wants to merge 3 commits into
Open
Conversation
pacmano1
requested review from
a team,
gibson9583,
jonbartels,
kayyagari,
kpalang,
mgaffigan,
ssrowe and
tonygermano
July 29, 2026 03:29
kryskool
approved these changes
Jul 29, 2026
mgaffigan
requested changes
Jul 30, 2026
mgaffigan
left a comment
Contributor
There was a problem hiding this comment.
Non-blocking: Does this really need to be a connector level config? Seems like it could be a much smaller change when coming from mirth.properties.
pacmano1
force-pushed
the
feat/http-listener-request-header-size
branch
from
July 31, 2026 16:12
cd4a6ba to
82dcd36
Compare
mgaffigan
previously approved these changes
Jul 31, 2026
tonygermano
reviewed
Aug 1, 2026
Jetty caps the combined size of all request headers at 8192 bytes and answers anything larger with 431 Request Header Fields Too Large, before the channel sees the request. Add a per-connector Request Header Size setting so that limit can be raised. The value is a String so it can carry a template, resolved at channel start the same way host, port and timeout already are. Channels saved without the element fall back to 8192, so existing channels behave exactly as before. A non-positive size is clamped to the default because Jetty treats it as no limit at all rather than rejecting requests, and the connector panel cannot vet a channel that arrives through the REST API or an import. Signed-off-by: Finnegan's Owner <44065187+pacmano1@users.noreply.github.com>
A request header size that does not resolve to a positive number now fails the connector instead of falling back to the default. Falling back was a silent loss of the limit. Someone setting a cap lower than the default to bound memory use, or to keep header size within what a downstream component expects, would have had the higher default quietly restored. Passing 0 as the NumberUtils default means a value that cannot be parsed, an unresolved template, zero and a negative all fail through the same branch, and the message carries the value as it resolved. Only requestHeaderSize is changed. The pre-existing port, timeout and responseStatusCode fallbacks in this file have live channels behind them and tightening those is a separate change. Signed-off-by: Finnegan's Owner <44065187+pacmano1@users.noreply.github.com>
configureReceiver built the Jetty HttpConfiguration inline, so an implementation overriding it had to repeat those settings and would not pick up later additions to them. Moving construction into a protected createHttpConfig lets a subclass build its listener from the current defaults instead. TLSHttpConfiguration in the NovaMap TLS manager plugin is the case in point: it extends this class, and its TLS branch already repeats setSendServerVersion and setSendXPoweredBy while missing the request header size entirely. No behaviour change. Signed-off-by: Finnegan's Owner <44065187+pacmano1@users.noreply.github.com>
pacmano1
force-pushed
the
feat/http-listener-request-header-size
branch
from
August 1, 2026 19:58
82dcd36 to
22f16c0
Compare
mgaffigan
approved these changes
Aug 1, 2026
tonygermano
approved these changes
Aug 2, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #392.
Jetty caps the combined size of all request headers at 8192 bytes and answers anything larger with
431 Request Header Fields Too Largeduring header parsing, so the channel never sees the request. This adds a per-connector Request Header Size field.The value is a String and resolves through the template replacer at channel start, like
host,portandtimeoutalready do.Invalid values fail the connector
Addressing @mgaffigan's review. A value that does not resolve to a positive number now fails the connector at start rather than falling back to 8192:
Falling back was a silent loss of the limit. Someone setting a cap lower than the default, to bound memory use or to stay within what a downstream component expects, would have had the higher default quietly restored.
Passing
0as theNumberUtilsdefault is what makes this one branch instead of two. An unparseable value, an unresolved template, zero and a negative all land on 0 and fail the same way, and the message carries the value as it resolved, so a broken substitution shows up as the literal${...}text rather than a number.Only
requestHeaderSizechanged. The pre-existingport,timeoutandresponseStatusCodefallbacks in this file have live channels behind them, so tightening those is a separate change.Addressing @tonygermano's review, the Jetty
HttpConfigurationis now built in aprotected createHttpConfig(HttpReceiver)rather than inline inconfigureReceiver. An implementation that overridesconfigureReceivercan build its listener from the current defaults instead of repeating them, and picks up later additions for free. No behaviour change.TLSHttpConfigurationin the NovaMap TLS manager plugin extends this class and is the case in point: its non-TLS branch already delegates tosuperand gets the setting, while its TLS branch repeats two of the settings and misses the header size. Raised there as tls-manager-plugin#44; TLS listeners keep ignoring the setting until that lands.Existing channels
Nothing happens to them on upgrade. A channel saved before this feature has no
requestHeaderSizeelement, and XStream leaves the field null when it loads one, sogetRequestHeaderSize()returns 8192 and the channel deploys and runs exactly as it did before. No migration runs and no stored channel is modified.Open such a channel in the editor and the field shows 8192. That is the getter's answer rather than something read from the channel, so the element is only written the first time someone saves it. Until then an export of that channel still has no element.
The strict check only applies to a value that is actually present, so an absent one can never fail a deploy.
How to verify
Run on a live engine, HTTP Listener on port 9000, context path
/test.10000${headerSize}with$gc('headerSize','10000')in the deploy script0pushed via the REST APIConnectorTaskException: Invalid request header size: 0${headerSize}with the deploy script clearedConnectorTaskException: Invalid request header size: ${headerSize}The ~55-byte gap between the configured value and the observed boundary is the request line plus
Host,User-AgentandAccept.The last three cannot be reached through the connector panel, which rejects them, so they were pushed through the REST API the way an import or an API-created channel would arrive.
Tests
12 across three classes: a real Jetty connector for 431 versus 200, a real receiver covering the resolution path including zero, negative, unparseable and an unresolved template, and a serialized-XML round trip proving a channel with no element still gets 8192. Removing the throw fails four tests; changing the default constant fails a third class.