Skip to content

Keep the Servlet header contract in the WebSocket request copies (10.x) - #1693

Open
reiern70 wants to merge 1 commit into
wicket-10.xfrom
websocket-request-headers-10.x
Open

reiern70 wants to merge 1 commit into
wicket-10.xfrom
websocket-request-headers-10.x

Conversation

@reiern70

Copy link
Copy Markdown
Contributor

Backport of #1689 to wicket-10.x, for GitHub issue #1688.

Only private fields change: japicmp has nothing to report against 10.0.0, and applications have nothing to migrate.

Verified on this branch:

  • ServletRequestCopyTest and JavaxUpgradeHttpRequestTest, 10 tests, pass.
  • mvn clean verify -Pjs-test is green on JDK 17, japicmp included.

This goes in after #1689. If #1689 changes in review, this branch gets the same change.

ServletRequestCopy, the HttpServletRequest Wicket keeps for the lifetime of
a WebSocket connection, stored the header enumerations of the request it
copied and handed the same ones out on every read. It looked them up by the
exact name the container reported, so a lowercase "origin", as sent over
HTTP/2 and by many proxies, was not found as "Origin". Each enumeration could
be read once: getHeader consumed a value, so a second call returned the next
value or null; getHeaders returned the spent enumeration; getIntHeader
consumed it as well and threw a NullPointerException for an absent header.
getHeaders returned null for an absent header, which ServletWebRequest
dereferences. getLocales had the same single-use problem.

JavaxUpgradeHttpRequest, the request every JSR 356 connection is copied
from, kept the handshake header map as it came, looked names up
case-sensitively and returned null from getHeaders and getHeaderNames when
there was nothing to return.

Both now copy the headers when they are created, into a map whose names
compare case-insensitively as the Servlet specification requires, and return
a fresh enumeration on every read, empty rather than null when there are no
values. ServletRequestCopy returns -1 from getIntHeader for an absent header
and copies the locales the same way. A name the copied request reports more
than once in different case is copied once, because that request's
getHeaders already returns all of its values; JavaxUpgradeHttpRequest merges
the values of handshake map keys that differ only in case.

An application now sees a WebSocket request that answers header lookups the
way the handshake request did. WebSocketConnectionOriginFilter no longer
rejects a connection whose Origin header arrived in lowercase.
getHeaderNames lists each name once, in case-insensitive alphabetical order.
Only private fields change; there is no API change.

GitHub issue #1688
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