diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 1d5c4b4..8a09644 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -257,9 +257,7 @@ jobs: echo "Running integration tests on Lucee ${{ matrix.lucee }}..." FAILED=false RESULTS="" - # test-session-access parked pending LDEV-6277 (wsClient.getSession() not exposed) — - # re-add once the Java fix lands - for test in test-websocket-client test-lifecycle-callbacks test-return-value-send test-wsclient-broadcast test-wsclients-plural test-binary-send test-close test-onfirstopen-rearm test-onopen-async test-request-timeout; do + for test in test-websocket-client test-lifecycle-callbacks test-return-value-send test-wsclient-broadcast test-wsclients-plural test-binary-send test-close test-session-access test-onfirstopen-rearm test-onopen-async test-request-timeout; do echo "" echo "==============================================" echo "Running ${test}" @@ -352,7 +350,7 @@ jobs: echo '```' >> $GITHUB_STEP_SUMMARY cat /tmp/integration-results.txt >> $GITHUB_STEP_SUMMARY || true echo '```' >> $GITHUB_STEP_SUMMARY - for test in test-websocket-client test-lifecycle-callbacks test-return-value-send test-wsclient-broadcast test-wsclients-plural test-binary-send test-close test-onfirstopen-rearm test-onopen-async test-request-timeout; do + for test in test-websocket-client test-lifecycle-callbacks test-return-value-send test-wsclient-broadcast test-wsclients-plural test-binary-send test-close test-session-access test-onfirstopen-rearm test-onopen-async test-request-timeout; do if [ -f /tmp/${test}.txt ] && grep -q "FAILED" /tmp/${test}.txt; then echo "" >> $GITHUB_STEP_SUMMARY echo "#### ${test}" >> $GITHUB_STEP_SUMMARY diff --git a/CHANGELOG.md b/CHANGELOG.md index fec4d3f..74dd569 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## 3.0.0.21 (unreleased) +- [LDEV-6277](https://luceeserver.atlassian.net/browse/LDEV-6277) — expose `wsClient.getSession()` so listeners can reach the underlying JSR-356 `Session` (`getId()`, `getUserProperties()`, `getRequestParameterMap()`) - [LDEV-6221](https://luceeserver.atlassian.net/browse/LDEV-6221) — improve reflection fallback warning message to explain why and that a servlet engine restart is needed ## 3.0.0.20 diff --git a/README.md b/README.md index f360f82..0fd4b54 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,7 @@ LUCEE_EXTENSIONS=org.lucee:websocket-extension:3.0.0.20-SNAPSHOT - **Listener components** — CFML components with `onOpen`, `onMessage`, `onClose`, `onError`, `onFirstOpen`, `onLastClose` lifecycle methods. - **Async open handler** — optional `onOpenAsync` runs in parallel with `onOpen` for long-running init work. +- **JSR-356 Session access** — `wsClient.getSession()` exposes the underlying `javax.websocket.Session` / `jakarta.websocket.Session` for per-connection state (`getUserProperties()`), connection identity (`getId()`), and handshake data (`getRequestParameterMap()`). - **`websocketInfo()` BIF** — returns `version`, `mapping`, `config`, `configFile`, `log`, and an `instances[]` array of active sessions with their component + session metadata. - **Extension hot-upgrade** — upgrade the `.lex` in-place via `inject()` without restarting the servlet container. - **Configurable timeouts** — `idleTimeout` and `requestTimeout` per web context via `websocket.json`. diff --git a/source/java/src/org/lucee/extension/websocket/client/AbsWSClient.java b/source/java/src/org/lucee/extension/websocket/client/AbsWSClient.java index bd24251..f1cd843 100644 --- a/source/java/src/org/lucee/extension/websocket/client/AbsWSClient.java +++ b/source/java/src/org/lucee/extension/websocket/client/AbsWSClient.java @@ -44,6 +44,7 @@ public abstract class AbsWSClient implements Objects { protected Key IS_CLOSE; protected Key SIZE; protected Key GET_CLIENTS; + protected Key GET_SESSION; protected final WebSocketEndpointFactory factory; private String className; @@ -61,6 +62,7 @@ public AbsWSClient(WebSocketEndpointFactory factory, String className) { IS_CLOSE = caster.toKey("isClose"); SIZE = caster.toKey("size"); GET_CLIENTS = caster.toKey("getClients"); + GET_SESSION = caster.toKey("getSession"); } @Override diff --git a/source/java/src/org/lucee/extension/websocket/client/WSClient.java b/source/java/src/org/lucee/extension/websocket/client/WSClient.java index 6f40474..399420b 100644 --- a/source/java/src/org/lucee/extension/websocket/client/WSClient.java +++ b/source/java/src/org/lucee/extension/websocket/client/WSClient.java @@ -19,7 +19,7 @@ public final class WSClient extends AbsWSClient { public WSClient(WebSocketEndpointFactory factory, Object session) { super(factory, "WSClient"); this.session = session; - keys = new Key[] { BROADCAST_MESSAGE, CLOSE, IS_OPEN, SEND_MESSAGE }; + keys = new Key[] { BROADCAST_MESSAGE, CLOSE, GET_SESSION, IS_OPEN, SEND_MESSAGE }; } @Override @@ -51,6 +51,10 @@ else if (CLOSE.equals(name)) { throw caster.toPageException(e); } } + else if (GET_SESSION.equals(name)) { + checkArgs(name, args, 0); + return session; + } throw exception.createExpressionException("WSClient does not have the function [" + name + "]"); } @@ -78,6 +82,9 @@ else if (CLOSE.equals(name)) { throw caster.toPageException(e); } } + else if (GET_SESSION.equals(name)) { + return session; + } throw exception.createExpressionException("WSClient does not have the function [" + name + "]"); } @@ -95,6 +102,8 @@ public String toString() { + "\n\tclose():void;" + + "\n\tgetSession():Session;" + + "\n}"; }