This is an automated email from the ASF dual-hosted git repository. remm pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/master by this push: new 1554030 Improve Connector creation 1554030 is described below commit 15540305ab97b12156536d26e17895b750f12a38 Author: remm <r...@apache.org> AuthorDate: Tue Apr 7 18:56:08 2020 +0200 Improve Connector creation Remove unneeded reflection. More importantly remove AJP specific hack in favor of a new default method in ProtocolHandler. No behavior change for existing API. --- java/org/apache/catalina/connector/Connector.java | 39 ++++++++++---------- java/org/apache/coyote/ProtocolHandler.java | 43 ++++++++++++++++++++++ .../org/apache/coyote/ajp/AbstractAjpProtocol.java | 8 +++- webapps/docs/changelog.xml | 4 ++ 4 files changed, 74 insertions(+), 20 deletions(-) diff --git a/java/org/apache/catalina/connector/Connector.java b/java/org/apache/catalina/connector/Connector.java index 20118f7..ca7b909 100644 --- a/java/org/apache/catalina/connector/Connector.java +++ b/java/org/apache/catalina/connector/Connector.java @@ -35,7 +35,6 @@ import org.apache.coyote.AbstractProtocol; import org.apache.coyote.Adapter; import org.apache.coyote.ProtocolHandler; import org.apache.coyote.UpgradeProtocol; -import org.apache.coyote.ajp.AbstractAjpProtocol; import org.apache.coyote.http11.AbstractHttp11JsseProtocol; import org.apache.juli.logging.Log; import org.apache.juli.logging.LogFactory; @@ -64,40 +63,42 @@ public class Connector extends LifecycleMBeanBase { // ------------------------------------------------------------ Constructor + /** * Defaults to using HTTP/1.1 NIO implementation. */ public Connector() { - this("org.apache.coyote.http11.Http11NioProtocol"); + this("HTTP/1.1"); } public Connector(String protocol) { - if ("HTTP/1.1".equals(protocol) || protocol == null) { - protocolHandlerClassName = "org.apache.coyote.http11.Http11NioProtocol"; - } else if ("AJP/1.3".equals(protocol)) { - protocolHandlerClassName = "org.apache.coyote.ajp.AjpNioProtocol"; - } else { - protocolHandlerClassName = protocol; - } - - // Instantiate protocol handler ProtocolHandler p = null; try { - Class<?> clazz = Class.forName(protocolHandlerClassName); - p = (ProtocolHandler) clazz.getConstructor().newInstance(); + p = ProtocolHandler.create(protocol); } catch (Exception e) { log.error(sm.getString( "coyoteConnector.protocolHandlerInstantiationFailed"), e); - } finally { - this.protocolHandler = p; } - + if (p != null) { + protocolHandler = p; + protocolHandlerClassName = protocolHandler.getClass().getName(); + } else { + protocolHandler = null; + protocolHandlerClassName = protocol; + } // Default for Connector depends on this system property setThrowOnFailure(Boolean.getBoolean("org.apache.catalina.startup.EXIT_ON_INIT_FAILURE")); } + public Connector(ProtocolHandler protocolHandler) { + protocolHandlerClassName = protocolHandler.getClass().getName(); + this.protocolHandler = protocolHandler; + // Default for Connector depends on this system property + setThrowOnFailure(Boolean.getBoolean("org.apache.catalina.startup.EXIT_ON_INIT_FAILURE")); + } + // ----------------------------------------------------- Instance Variables @@ -946,9 +947,9 @@ public class Connector extends LifecycleMBeanBase { * @return a new Servlet response object */ public Response createResponse() { - if (protocolHandler instanceof AbstractAjpProtocol<?>) { - int packetSize = ((AbstractAjpProtocol<?>) protocolHandler).getPacketSize(); - return new Response(packetSize - org.apache.coyote.ajp.Constants.SEND_HEAD_LEN); + int size = protocolHandler.getDesiredBufferSize(); + if (size > 0) { + return new Response(size); } else { return new Response(); } diff --git a/java/org/apache/coyote/ProtocolHandler.java b/java/org/apache/coyote/ProtocolHandler.java index b467558..57a3086 100644 --- a/java/org/apache/coyote/ProtocolHandler.java +++ b/java/org/apache/coyote/ProtocolHandler.java @@ -16,6 +16,7 @@ */ package org.apache.coyote; +import java.lang.reflect.InvocationTargetException; import java.util.concurrent.Executor; import java.util.concurrent.ScheduledExecutorService; @@ -179,4 +180,46 @@ public interface ProtocolHandler { * @return the protocols */ public UpgradeProtocol[] findUpgradeProtocols(); + + + /** + * Some protocols, like AJP, have a packet length that + * shouldn't be exceeded, and this can be used to adjust the buffering + * used by the application layer. + * @return the desired buffer size, or -1 if not relevant + */ + public default int getDesiredBufferSize() { + return -1; + } + + + /** + * Create a new ProtocolHandler for the given protocol. + * @param protocol the protocol + * @return the newly instantiated protocol handler + * @throws ClassNotFoundException + * @throws InstantiationException + * @throws IllegalAccessException + * @throws IllegalArgumentException + * @throws InvocationTargetException + * @throws NoSuchMethodException + * @throws SecurityException + */ + public static ProtocolHandler create(String protocol) + throws ClassNotFoundException, InstantiationException, IllegalAccessException, + IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException { + if (protocol == null || "HTTP/1.1".equals(protocol) + || org.apache.coyote.http11.Http11NioProtocol.class.getName().equals(protocol)) { + return new org.apache.coyote.http11.Http11NioProtocol(); + } else if ("AJP/1.3".equals(protocol) + || org.apache.coyote.ajp.AjpNioProtocol.class.getName().equals(protocol)) { + return new org.apache.coyote.ajp.AjpNioProtocol(); + } else { + // Instantiate protocol handler + Class<?> clazz = Class.forName(protocol); + return (ProtocolHandler) clazz.getConstructor().newInstance(); + } + } + + } diff --git a/java/org/apache/coyote/ajp/AbstractAjpProtocol.java b/java/org/apache/coyote/ajp/AbstractAjpProtocol.java index abf8e60..93f0bab 100644 --- a/java/org/apache/coyote/ajp/AbstractAjpProtocol.java +++ b/java/org/apache/coyote/ajp/AbstractAjpProtocol.java @@ -207,7 +207,7 @@ public abstract class AbstractAjpProtocol<S> extends AbstractProtocol<S> { private int packetSize = Constants.MAX_PACKET_SIZE; public int getPacketSize() { return packetSize; } public void setPacketSize(int packetSize) { - if(packetSize < Constants.MAX_PACKET_SIZE) { + if (packetSize < Constants.MAX_PACKET_SIZE) { this.packetSize = Constants.MAX_PACKET_SIZE; } else { this.packetSize = packetSize; @@ -215,6 +215,12 @@ public abstract class AbstractAjpProtocol<S> extends AbstractProtocol<S> { } + @Override + public int getDesiredBufferSize() { + return getPacketSize() - Constants.SEND_HEAD_LEN; + } + + // --------------------------------------------- SSL is not supported in AJP @Override diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index 02bda5e..ab27bb6 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -62,6 +62,10 @@ <code>Loader</code> interface as it is duplicated on the <code>Context</code> interface. (markt) </scode> + <fix> + Reduce reflection use and remove AJP specific code in the Connector. + (remm/markt/fhanik) + </fix> </changelog> </subsection> <subsection name="Coyote"> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org