This is an automated email from the ASF dual-hosted git repository. markt pushed a commit to branch 9.0.x in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/9.0.x by this push: new c6c8c05 Add POJO support to programmatic http -> ws upgrade c6c8c05 is described below commit c6c8c05bb8e9df53e828c5c02df5b9473605ab48 Author: Mark Thomas <ma...@apache.org> AuthorDate: Wed Dec 15 20:21:43 2021 +0000 Add POJO support to programmatic http -> ws upgrade --- .../websocket/server/LocalStrings.properties | 1 + .../tomcat/websocket/server/UpgradeUtil.java | 30 +++++++++++++++++++--- .../tomcat/websocket/server/WsServerContainer.java | 11 ++++++++ webapps/docs/changelog.xml | 9 +++++++ 4 files changed, 47 insertions(+), 4 deletions(-) diff --git a/java/org/apache/tomcat/websocket/server/LocalStrings.properties b/java/org/apache/tomcat/websocket/server/LocalStrings.properties index 16fdaf2..3698b90 100644 --- a/java/org/apache/tomcat/websocket/server/LocalStrings.properties +++ b/java/org/apache/tomcat/websocket/server/LocalStrings.properties @@ -22,6 +22,7 @@ serverContainer.missingAnnotation=Cannot deploy POJO class [{0}] as it is not an serverContainer.servletContextMissing=No ServletContext was specified upgradeUtil.incompatibleRsv=Extensions were specified that have incompatible RSV bit usage +upgradeUtil.pojoMpaFail=Unable to complete method mapping for POJO class [{0}] uriTemplate.duplicateParameter=The parameter [{0}] appears more than once in the path which is not permitted uriTemplate.emptySegment=The path [{0}] contains one or more empty segments which is not permitted diff --git a/java/org/apache/tomcat/websocket/server/UpgradeUtil.java b/java/org/apache/tomcat/websocket/server/UpgradeUtil.java index 1f8cb32..8e52d66 100644 --- a/java/org/apache/tomcat/websocket/server/UpgradeUtil.java +++ b/java/org/apache/tomcat/websocket/server/UpgradeUtil.java @@ -31,6 +31,8 @@ import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import javax.websocket.DeploymentException; +import javax.websocket.Endpoint; import javax.websocket.Extension; import javax.websocket.HandshakeResponse; import javax.websocket.server.ServerEndpointConfig; @@ -43,6 +45,7 @@ import org.apache.tomcat.websocket.Transformation; import org.apache.tomcat.websocket.TransformationFactory; import org.apache.tomcat.websocket.Util; import org.apache.tomcat.websocket.WsHandshakeResponse; +import org.apache.tomcat.websocket.pojo.PojoMethodMapping; public class UpgradeUtil { @@ -197,12 +200,31 @@ public class UpgradeUtil { resp.setHeader(Constants.WS_EXTENSIONS_HEADER_NAME, responseHeaderExtensions.toString()); } - WsHandshakeRequest wsRequest = new WsHandshakeRequest(req, pathParams); - WsHandshakeResponse wsResponse = new WsHandshakeResponse(); + // Add method mapping to user properties + if (!Endpoint.class.isAssignableFrom(sec.getEndpointClass()) && + sec.getUserProperties().get(org.apache.tomcat.websocket.pojo.Constants.POJO_METHOD_MAPPING_KEY) == null) { + // This is a POJO endpoint and the application has called upgrade + // directly. Need to add the method mapping. + try { + PojoMethodMapping methodMapping = new PojoMethodMapping(sec.getEndpointClass(), + sec.getDecoders(), sec.getPath(), sc.getInstanceManager(Thread.currentThread().getContextClassLoader())); + if (methodMapping.getOnClose() != null || methodMapping.getOnOpen() != null + || methodMapping.getOnError() != null || methodMapping.hasMessageHandlers()) { + sec.getUserProperties().put( + org.apache.tomcat.websocket.pojo.Constants.POJO_METHOD_MAPPING_KEY, methodMapping); + } + } catch (DeploymentException e) { + throw new ServletException( + sm.getString("upgradeUtil.pojoMpaFail", sec.getEndpointClass().getName()), e); + } + } + WsPerSessionServerEndpointConfig perSessionServerEndpointConfig = new WsPerSessionServerEndpointConfig(sec); - sec.getConfigurator().modifyHandshake(perSessionServerEndpointConfig, - wsRequest, wsResponse); + + WsHandshakeRequest wsRequest = new WsHandshakeRequest(req, pathParams); + WsHandshakeResponse wsResponse = new WsHandshakeResponse(); + sec.getConfigurator().modifyHandshake(perSessionServerEndpointConfig, wsRequest, wsResponse); wsRequest.finished(); // Add any additional headers diff --git a/java/org/apache/tomcat/websocket/server/WsServerContainer.java b/java/org/apache/tomcat/websocket/server/WsServerContainer.java index 17d468a..74815a7 100644 --- a/java/org/apache/tomcat/websocket/server/WsServerContainer.java +++ b/java/org/apache/tomcat/websocket/server/WsServerContainer.java @@ -442,6 +442,17 @@ public class WsServerContainer extends WsWebSocketContainer * Overridden to make it visible to other classes in this package. */ @Override + protected InstanceManager getInstanceManager(ClassLoader classLoader) { + return super.getInstanceManager(classLoader); + } + + + /** + * {@inheritDoc} + * + * Overridden to make it visible to other classes in this package. + */ + @Override protected void registerSession(Object key, WsSession wsSession) { super.registerSession(key, wsSession); if (wsSession.isOpen() && diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index 85b1587..507d27c 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -131,6 +131,15 @@ </fix> </changelog> </subsection> + <subsection name="WebSocket"> + <changelog> + <add> + Add support for POJO WebSocket endpoints to the programmatic upgrade + that allows applications to opt to upgrade an HTTP connection to + WebSocket. (markt) + </add> + </changelog> + </subsection> </section> <section name="Tomcat 9.0.56 (remm)" rtext="2021-12-02"> <subsection name="Catalina"> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org