You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by re...@apache.org on 2020/04/07 16:56:26 UTC

[tomcat] branch master updated: Improve Connector creation

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 <re...@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-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org