Jetty 10.0.x 4814 configuring connection factory (#4815)

* Issue #4814 Configuring Connection Factory

Redo of this PR without Attributes improvements (moved to #4816).
Add a ConnectionFactory.Configuring interface to all connectors to be configured during doStart.
I have some concern about shared HttpConfigurations.

Signed-off-by: Greg Wilkins <gregw@webtide.com>

* updates from review

Signed-off-by: Greg Wilkins <gregw@webtide.com>
This commit is contained in:
Greg Wilkins 2020-04-29 11:45:08 +02:00 committed by GitHub
parent 4a4626614c
commit 81c46638cd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 51 additions and 6 deletions

View File

@ -311,6 +311,11 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co
@Override @Override
protected void doStart() throws Exception protected void doStart() throws Exception
{ {
getConnectionFactories().stream()
.filter(ConnectionFactory.Configuring.class::isInstance)
.map(ConnectionFactory.Configuring.class::cast)
.forEach(configuring -> configuring.configure(this));
_shutdown = new Graceful.Shutdown(this) _shutdown = new Graceful.Shutdown(this)
{ {
@Override @Override

View File

@ -125,4 +125,16 @@ public interface ConnectionFactory
*/ */
Detection detect(ByteBuffer buffer); Detection detect(ByteBuffer buffer);
} }
/**
* A ConnectionFactory that can configure the connector.
*/
interface Configuring extends ConnectionFactory
{
/**
* Called during {@link Connector#start()}.
* @param connector The connector to configure
*/
void configure(Connector connector);
}
} }

View File

@ -32,7 +32,7 @@ import org.eclipse.jetty.util.annotation.Name;
import org.eclipse.jetty.util.component.ContainerLifeCycle; import org.eclipse.jetty.util.component.ContainerLifeCycle;
import org.eclipse.jetty.util.ssl.SslContextFactory; import org.eclipse.jetty.util.ssl.SslContextFactory;
public class SslConnectionFactory extends AbstractConnectionFactory implements ConnectionFactory.Detecting public class SslConnectionFactory extends AbstractConnectionFactory implements ConnectionFactory.Detecting, ConnectionFactory.Configuring
{ {
private static final int TLS_ALERT_FRAME_TYPE = 0x15; private static final int TLS_ALERT_FRAME_TYPE = 0x15;
private static final int TLS_HANDSHAKE_FRAME_TYPE = 0x16; private static final int TLS_HANDSHAKE_FRAME_TYPE = 0x16;
@ -42,6 +42,7 @@ public class SslConnectionFactory extends AbstractConnectionFactory implements C
private final String _nextProtocol; private final String _nextProtocol;
private boolean _directBuffersForEncryption = false; private boolean _directBuffersForEncryption = false;
private boolean _directBuffersForDecryption = false; private boolean _directBuffersForDecryption = false;
private boolean _ensureSecureRequestCustomizer = true;
public SslConnectionFactory() public SslConnectionFactory()
{ {
@ -91,6 +92,21 @@ public class SslConnectionFactory extends AbstractConnectionFactory implements C
return _nextProtocol; return _nextProtocol;
} }
public boolean isEnsureSecureRequestCustomizer()
{
return _ensureSecureRequestCustomizer;
}
/**
* @param ensureSecureRequestCustomizer True if this factory ensures that all {@link HttpConfiguration}s on
* associated {@link Connector}s have an {@link SecureRequestCustomizer} instance.
* @see ConnectionFactory.Configuring
*/
public void setEnsureSecureRequestCustomizer(boolean ensureSecureRequestCustomizer)
{
_ensureSecureRequestCustomizer = ensureSecureRequestCustomizer;
}
@Override @Override
protected void doStart() throws Exception protected void doStart() throws Exception
{ {
@ -104,6 +120,19 @@ public class SslConnectionFactory extends AbstractConnectionFactory implements C
setInputBufferSize(session.getPacketBufferSize()); setInputBufferSize(session.getPacketBufferSize());
} }
@Override
public void configure(Connector connector)
{
if (isEnsureSecureRequestCustomizer())
{
connector.getContainedBeans(HttpConfiguration.class).forEach(configuration ->
{
if (configuration.getCustomizer(SecureRequestCustomizer.class) == null)
configuration.addCustomizer(new SecureRequestCustomizer());
});
}
}
@Override @Override
public Detection detect(ByteBuffer buffer) public Detection detect(ByteBuffer buffer)
{ {

View File

@ -43,7 +43,6 @@ import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.server.HttpConfiguration; import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.HttpConnectionFactory; import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.SecureRequestCustomizer;
import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.SocketCustomizationListener; import org.eclipse.jetty.server.SocketCustomizationListener;
@ -81,16 +80,16 @@ public class SslConnectionFactoryTest
httpConfig.setSecureScheme("https"); httpConfig.setSecureScheme("https");
httpConfig.setSecurePort(8443); httpConfig.setSecurePort(8443);
httpConfig.setOutputBufferSize(32768); httpConfig.setOutputBufferSize(32768);
HttpConfiguration httpsConfig = new HttpConfiguration(httpConfig);
httpsConfig.addCustomizer(new SecureRequestCustomizer());
SslContextFactory.Server sslContextFactory = new SslContextFactory.Server(); SslContextFactory.Server sslContextFactory = new SslContextFactory.Server();
sslContextFactory.setKeyStorePath(keystoreFile.getAbsolutePath()); sslContextFactory.setKeyStorePath(keystoreFile.getAbsolutePath());
sslContextFactory.setKeyStorePassword("storepwd"); sslContextFactory.setKeyStorePassword("storepwd");
SslConnectionFactory sslConnectionFactory = new SslConnectionFactory(sslContextFactory, HttpVersion.HTTP_1_1.asString());
sslConnectionFactory.setEnsureSecureRequestCustomizer(true);
ServerConnector https = _connector = new ServerConnector(_server, ServerConnector https = _connector = new ServerConnector(_server,
new SslConnectionFactory(sslContextFactory, HttpVersion.HTTP_1_1.asString()), sslConnectionFactory,
new HttpConnectionFactory(httpsConfig)); new HttpConnectionFactory());
https.setPort(0); https.setPort(0);
https.setIdleTimeout(30000); https.setIdleTimeout(30000);