--- a/java/org/apache/catalina/connector/Connector.java +++ b/java/org/apache/catalina/connector/Connector.java @@ -35,7 +35,6 @@ 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,48 @@ // ------------------------------------------------------------ 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"; + protocolHandlerClassName = org.apache.coyote.http11.Http11NioProtocol.class.getName(); + this.protocolHandler = new org.apache.coyote.http11.Http11NioProtocol(); } else if ("AJP/1.3".equals(protocol)) { - protocolHandlerClassName = "org.apache.coyote.ajp.AjpNioProtocol"; + protocolHandlerClassName = org.apache.coyote.ajp.AjpNioProtocol.class.getName(); + this.protocolHandler = new 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(); + } catch (Exception e) { + log.error(sm.getString( + "coyoteConnector.protocolHandlerInstantiationFailed"), e); + } finally { + this.protocolHandler = p; + } } - - // Instantiate protocol handler - ProtocolHandler p = null; - try { - Class clazz = Class.forName(protocolHandlerClassName); - p = (ProtocolHandler) clazz.getConstructor().newInstance(); - } catch (Exception e) { - log.error(sm.getString( - "coyoteConnector.protocolHandlerInstantiationFailed"), e); - } finally { - this.protocolHandler = p; - } - // 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 +953,9 @@ * @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..ce40d74 100644 --- a/java/org/apache/coyote/ProtocolHandler.java +++ b/java/org/apache/coyote/ProtocolHandler.java @@ -179,4 +179,16 @@ * @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; + } + } 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 @@ 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 @@ } + @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 @@ Loader interface as it is duplicated on the Context interface. (markt) + + Reduce reflection use and remove AJP specific code in the Connector. + (remm/markt/fhanik) +