Note: This proposal has been withdrawn at least for Tomcat 10.0

During the Tomcat 10 development cycle, one of the goals is to remove redundant object attributes and simplify. A major area of duplication was TLS configuration. Moving to a related topic, the rest of the Connector configuration is the biggest offender. While it (thankfully) works, it sets configuration properties through a chain of objects using reflection and weird constructor initialization. For example, setting the connection timeout on the Connector element in server.xml will call setConnectionTimeout on AbstractProtocol using reflection, then setConnectionTimeout on AbstractEndpoint, then setSoTimeout on SocketProperties.

in practical terms, this replaces:

<Connector port="8080" protocol="org.apache.coyote.http11.Http11Nio2Protocol" connectionTimeout="20000"
   socket.directBuffer="false" redirectPort="8443" maxConnections="150">
   <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
</Connector>

<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol" SSLEnabled="true" scheme="https" secure="true"
   socket.directBuffer="true" socket.directSslBuffer="true"
   sslImplementationName="org.apache.tomcat.util.net.openssl.OpenSSLImplementation">
   <SSLHostConfig honorCipherOrder="false">
     <Certificate certificateKeyFile="${catalina.home}/conf/newkey.txt.pem"
       certificateFile="${catalina.home}/conf/newcert.pem" type="RSA" />
   </SSLHostConfig>
   <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
</Connector>


with:

<Connector redirectPort="8443">
  <Protocol>
    <Endpoint className="org.apache.tomcat.util.net.Nio2Endpoint"
        port="8080" maxConnections="150">
      <SocketProperties soTimeout="20000" directBuffer="false" />
    </Endpoint>
    <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
  </Protocol>
</Connector>

<Connector scheme="https" secure="true">
  <Protocol>
    <Endpoint port="8443" SSLEnabled="true"
      sslImplementationName="org.apache.tomcat.util.net.openssl.OpenSSLImplementation">
     <SocketProperties directBuffer="true" directSslBuffer="true" />
      <SSLHostConfig honorCipherOrder="false">
        <Certificate certificateKeyFile="${catalina.home}/conf/newkey.txt.pem"
           certificateFile="${catalina.home}/conf/newcert.pem" type="RSA" />
      </SSLHostConfig>
    </Endpoint>
    <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
  </Protocol>
</Connector>


The XML now respects the actual object structure (and said objects can be regular beans) so that the digester uses fewer hacks. All the attribute pass-through can now be removed to a large extent. For embedded, this is the same situation but the user has more objects to manipulate.

On the downside the server.xml is not exactly easier. Especially the mundane port configuration is now on the very much nested Endpoint element (it clearly does belong there of course). A hard topic is that the various attributes which were all on the Connector element (except TLS, from a recent change) while they are now located on the object to which they belong (this is a good idea but people will need to get used to it ...).

On the upside, a lot of boilerplate code can be removed, including the ProtocolHandler subclasses since it does not need a class tied to its endpoint type. Only the endpoint class is used to select between NIO, NIO2 and APR. Sensible defaults could also help mitigate the problems described above.

  • No labels