From 2c0f7413f6a1dd0ceb3fc2e09e2ef15bb556a67d Mon Sep 17 00:00:00 2001 From: Matthew Vivian Date: Tue, 16 May 2023 11:06:57 +0100 Subject: [PATCH] WIP: Upgrades Jetty 9.4.43.v20210629 to 10.0.15 Remaining Issues: - JSP compilation failure caused by: https://github.com/apache/tomcat/commit/224fb6c06528180213b6af28b28dee44029565d7#diff-ef02fd9c3f90ca4838d3cdaa051489556eca75d537fc396022e0ed456c24d895R329 - `WebSocketClientConnectionHandler.onConnect` assumes that `session.getRemoteAddress()` supplies an `InetSocketAddress` which might not always be true. What's the best approach in our context? Fixed in this commit: - Websocket server Maven artifact renamed from `websocket-server` to `websocket-jetty-server` - `WebSocketServlet` renamed to `JettyWebSocketServlet` - `WebSocketServletFactory` renamed to `JettyWebSocketServletFactory` See: https://www.eclipse.org/jetty/documentation/jetty-10/programming-guide/index.html#pg-migration-94-to-10 - `GzipHandler` is no longer part of `ServletContextHandler` https://github.com/eclipse/jetty.project/issues/4765 - Renamed `setWebInfClassesDirs` to `setWebInfClassesResources` https://github.com/eclipse/jetty.project/issues/4506 - Split `SslContextFactory` into Client and Server https://github.com/eclipse/jetty.project/issues/3464 --- plugins/pom.xml | 2 +- pom.xml | 2 +- xmppserver/pom.xml | 4 +-- .../container/AdminConsolePlugin.java | 4 +-- .../container/PluginServletContext.java | 35 +++++++++++++++++++ .../openfire/http/HttpBindManager.java | 12 +++---- .../spi/EncryptionArtifactFactory.java | 4 +-- .../websocket/OpenfireWebSocketServlet.java | 20 +++++------ .../WebSocketClientConnectionHandler.java | 3 +- 9 files changed, 58 insertions(+), 28 deletions(-) diff --git a/plugins/pom.xml b/plugins/pom.xml index c0d4e3398e..a222c17464 100644 --- a/plugins/pom.xml +++ b/plugins/pom.xml @@ -122,7 +122,7 @@ 4.8.0-SNAPSHOT - 9.4.43.v20210629 + 10.0.15 diff --git a/pom.xml b/pom.xml index 61628315b7..19e2afcf4f 100644 --- a/pom.xml +++ b/pom.xml @@ -118,7 +118,7 @@ - 9.4.43.v20210629 + 10.0.15 1.2.5 2.2.1 1.70 diff --git a/xmppserver/pom.xml b/xmppserver/pom.xml index a6eb4fcdc6..04bb8c6c7f 100644 --- a/xmppserver/pom.xml +++ b/xmppserver/pom.xml @@ -148,8 +148,6 @@ org.jivesoftware.openfire.admin - 11 - 11 true @@ -247,7 +245,7 @@ org.eclipse.jetty.websocket - websocket-server + websocket-jetty-server ${jetty.version} diff --git a/xmppserver/src/main/java/org/jivesoftware/openfire/container/AdminConsolePlugin.java b/xmppserver/src/main/java/org/jivesoftware/openfire/container/AdminConsolePlugin.java index 1c13182e75..07b49951e0 100644 --- a/xmppserver/src/main/java/org/jivesoftware/openfire/container/AdminConsolePlugin.java +++ b/xmppserver/src/main/java/org/jivesoftware/openfire/container/AdminConsolePlugin.java @@ -210,7 +210,7 @@ protected void startup() { final ConnectionManagerImpl connectionManager = ( (ConnectionManagerImpl) XMPPServer.getInstance().getConnectionManager() ); final ConnectionConfiguration configuration = connectionManager.getListener( ConnectionType.WEBADMIN, true ).generateConnectionConfiguration(); - final SslContextFactory sslContextFactory = new EncryptionArtifactFactory( configuration ).getSslContextFactory(); + final SslContextFactory.Server sslContextFactory = new EncryptionArtifactFactory( configuration ).getSslContextFactory(); final HttpConfiguration httpsConfig = new HttpConfiguration(); httpsConfig.setSendServerVersion( false ); @@ -496,7 +496,7 @@ private void createWebAppContext() { new JettyWebXmlConfiguration() }); final URL classes = getClass().getProtectionDomain().getCodeSource().getLocation(); - context.getMetaData().setWebInfClassesDirs(Collections.singletonList(Resource.newResource(classes))); + context.getMetaData().setWebInfClassesResources(Collections.singletonList(Resource.newResource(classes))); // The index.html includes a redirect to the index.jsp and doesn't bypass // the context security when in development mode diff --git a/xmppserver/src/main/java/org/jivesoftware/openfire/container/PluginServletContext.java b/xmppserver/src/main/java/org/jivesoftware/openfire/container/PluginServletContext.java index 3dccbc788a..5b0d59fd67 100644 --- a/xmppserver/src/main/java/org/jivesoftware/openfire/container/PluginServletContext.java +++ b/xmppserver/src/main/java/org/jivesoftware/openfire/container/PluginServletContext.java @@ -257,6 +257,11 @@ public ServletRegistration.Dynamic addServlet( String s, Class T createServlet( Class aClass ) throws ServletException { @@ -382,4 +387,34 @@ public String getVirtualServerName() { return proxy.getVirtualServerName(); } + + @Override + public int getSessionTimeout() { + return proxy.getSessionTimeout(); + } + + @Override + public void setSessionTimeout(int sessionTimeout) { + proxy.setSessionTimeout(sessionTimeout); + } + + @Override + public String getRequestCharacterEncoding() { + return proxy.getRequestCharacterEncoding(); + } + + @Override + public void setRequestCharacterEncoding(String encoding) { + proxy.setRequestCharacterEncoding(encoding); + } + + @Override + public String getResponseCharacterEncoding() { + return proxy.getResponseCharacterEncoding(); + } + + @Override + public void setResponseCharacterEncoding(String encoding) { + proxy.setResponseCharacterEncoding(encoding); + } } diff --git a/xmppserver/src/main/java/org/jivesoftware/openfire/http/HttpBindManager.java b/xmppserver/src/main/java/org/jivesoftware/openfire/http/HttpBindManager.java index 59c44dc95f..fc23b33682 100644 --- a/xmppserver/src/main/java/org/jivesoftware/openfire/http/HttpBindManager.java +++ b/xmppserver/src/main/java/org/jivesoftware/openfire/http/HttpBindManager.java @@ -479,7 +479,7 @@ private Connector createSSLConnector( final Server httpBindServer ) { final ConnectionManagerImpl connectionManager = ((ConnectionManagerImpl) XMPPServer.getInstance().getConnectionManager()); final ConnectionConfiguration configuration = connectionManager.getListener( ConnectionType.BOSH_C2S, true ).generateConnectionConfiguration(); - final SslContextFactory sslContextFactory = new EncryptionArtifactFactory(configuration).getSslContextFactory(); + final SslContextFactory.Server sslContextFactory = new EncryptionArtifactFactory(configuration).getSslContextFactory(); final HttpConfiguration httpsConfig = new HttpConfiguration(); httpsConfig.setSecureScheme("https"); @@ -645,12 +645,7 @@ public boolean isThisOriginAllowed(String origin) { */ protected Handler createBoshHandler() { - final int options; - if(isHttpCompressionEnabled()) { - options = ServletContextHandler.SESSIONS | ServletContextHandler.GZIP; - } else { - options = ServletContextHandler.SESSIONS; - } + final int options = ServletContextHandler.SESSIONS; final ServletContextHandler context = new ServletContextHandler( null, "/http-bind", options ); // Ensure the JSP engine is initialized correctly (in order to be able to cope with Tomcat/Jasper precompiled JSPs). @@ -667,9 +662,10 @@ protected Handler createBoshHandler() // Add compression filter when needed. if (isHttpCompressionEnabled()) { - final GzipHandler gzipHandler = context.getGzipHandler(); + final GzipHandler gzipHandler = new GzipHandler(); gzipHandler.addIncludedPaths("/*"); gzipHandler.addIncludedMethods(HttpMethod.POST.asString()); + context.insertHandler(gzipHandler); } return context; diff --git a/xmppserver/src/main/java/org/jivesoftware/openfire/spi/EncryptionArtifactFactory.java b/xmppserver/src/main/java/org/jivesoftware/openfire/spi/EncryptionArtifactFactory.java index c3a89701bf..b56fe7b28d 100644 --- a/xmppserver/src/main/java/org/jivesoftware/openfire/spi/EncryptionArtifactFactory.java +++ b/xmppserver/src/main/java/org/jivesoftware/openfire/spi/EncryptionArtifactFactory.java @@ -42,7 +42,7 @@ public class EncryptionArtifactFactory // lazy loaded factory objects. These re-usable objects should be lazy loaded, preventing initialization in situations where they're never going to be used. private transient KeyManagerFactory keyManagerFactory; - private transient SslContextFactory sslContextFactory; + private transient SslContextFactory.Server sslContextFactory; /** * Creates a new instance of the factory. @@ -266,7 +266,7 @@ public SSLEngine createClientModeSSLEngine() throws UnrecoverableKeyException, N return sslEngine; } - public synchronized SslContextFactory getSslContextFactory() + public synchronized SslContextFactory.Server getSslContextFactory() { if ( sslContextFactory != null ) { diff --git a/xmppserver/src/main/java/org/jivesoftware/openfire/websocket/OpenfireWebSocketServlet.java b/xmppserver/src/main/java/org/jivesoftware/openfire/websocket/OpenfireWebSocketServlet.java index eb4e26f604..6d7183d57e 100644 --- a/xmppserver/src/main/java/org/jivesoftware/openfire/websocket/OpenfireWebSocketServlet.java +++ b/xmppserver/src/main/java/org/jivesoftware/openfire/websocket/OpenfireWebSocketServlet.java @@ -15,9 +15,8 @@ */ package org.jivesoftware.openfire.websocket; -import org.eclipse.jetty.websocket.common.extensions.compress.PerMessageDeflateExtension; -import org.eclipse.jetty.websocket.servlet.WebSocketServlet; -import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory; +import org.eclipse.jetty.websocket.server.JettyWebSocketServlet; +import org.eclipse.jetty.websocket.server.JettyWebSocketServletFactory; import org.jivesoftware.openfire.SessionManager; import org.jivesoftware.openfire.XMPPServer; import org.jivesoftware.openfire.http.HttpBindManager; @@ -43,7 +42,7 @@ * forwarded to this plugin/servlet, which will in turn create a new {@link WebSocketClientConnectionHandler} * for each new connection. */ -public class OpenfireWebSocketServlet extends WebSocketServlet { +public class OpenfireWebSocketServlet extends JettyWebSocketServlet { private static final long serialVersionUID = 1074354600476010708L; private static final Logger Log = LoggerFactory.getLogger(OpenfireWebSocketServlet.class); @@ -92,14 +91,15 @@ protected void service(HttpServletRequest request, HttpServletResponse response) } @Override - public void configure(WebSocketServletFactory factory) + public void configure(JettyWebSocketServletFactory factory) { if (WebSocketClientConnectionHandler.isCompressionEnabled()) { - factory.getExtensionFactory().register("permessage-deflate", PerMessageDeflateExtension.class); + factory.getAvailableExtensionNames().add("permessage-deflate"); } final int messageSize = JiveGlobals.getIntProperty("xmpp.parser.buffer.size", 1048576); - factory.getPolicy().setMaxTextMessageBufferSize(messageSize * 5); - factory.getPolicy().setMaxTextMessageSize(messageSize); + factory.setInputBufferSize(messageSize * 5); + factory.setOutputBufferSize(messageSize * 5); + factory.setMaxTextMessageSize(messageSize); // Jetty's idle policy cannot be modified - it will bluntly kill the connection. Ensure that it's longer than // the maximum amount of idle-time that Openfire allows for its client connections! @@ -110,7 +110,7 @@ public void configure(WebSocketServletFactory factory) } else { maxJettyIdleMs = propValue.plus(Duration.of(30, ChronoUnit.SECONDS)).toMillis(); } - factory.getPolicy().setIdleTimeout(maxJettyIdleMs); + factory.setIdleTimeout(Duration.ofMillis(maxJettyIdleMs)); factory.setCreator((req, resp) -> { try { @@ -125,7 +125,7 @@ public void configure(WebSocketServletFactory factory) } catch (Exception e) { Log.warn("Unable to load websocket factory", e); } - Log.warn("Failed to create websocket for {}:{} make a request at {}", req.getRemoteAddress(), req.getRemotePort(), req.getRequestPath() ); + Log.warn("Failed to create websocket for {}:{} make a request at {}", req.getHttpServletRequest().getRemoteAddr(), req.getHttpServletRequest().getRemotePort(), req.getRequestPath() ); return null; }); } diff --git a/xmppserver/src/main/java/org/jivesoftware/openfire/websocket/WebSocketClientConnectionHandler.java b/xmppserver/src/main/java/org/jivesoftware/openfire/websocket/WebSocketClientConnectionHandler.java index 1540c91f08..f6f4b58a32 100644 --- a/xmppserver/src/main/java/org/jivesoftware/openfire/websocket/WebSocketClientConnectionHandler.java +++ b/xmppserver/src/main/java/org/jivesoftware/openfire/websocket/WebSocketClientConnectionHandler.java @@ -38,6 +38,7 @@ import org.xmpp.packet.StreamError; import java.io.IOException; +import java.net.InetSocketAddress; import java.time.Duration; import java.time.Instant; import java.time.temporal.ChronoUnit; @@ -103,7 +104,7 @@ public void onConnect(Session session) lastReceived = Instant.now(); wsSession = session; final PacketDeliverer backupDeliverer = ClientConnectionHandler.BACKUP_PACKET_DELIVERY_ENABLED.getValue() ? new OfflinePacketDeliverer() : null; - wsConnection = new WebSocketConnection(this, backupDeliverer, session.getRemoteAddress()); + wsConnection = new WebSocketConnection(this, backupDeliverer, (InetSocketAddress) session.getRemoteAddress()); // TODO can't assume InetSocketAddress websocketFramePingTask = new WebsocketFramePingTask(); if (KEEP_ALIVE_FRAME_PING_ENABLED_PROPERTY.getValue()) { // Run the task every 10% of the interval, to get the timing roughly in-line with the configured interval.