blob: 884da24f8e3e9007a05a5a8264d2824cf755a6af [file] [log] [blame]
/*
* Copyright (c) 2011, Paul Merlin. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.qi4j.library.http;
import java.security.Provider;
import java.security.Security;
import java.util.Map;
import javax.servlet.Filter;
import javax.servlet.Servlet;
import javax.servlet.ServletContextListener;
import org.eclipse.jetty.server.ConnectorStatistics;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.LowResourceMonitor;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.SslConnectionFactory;
import org.eclipse.jetty.servlet.DefaultServlet;
import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.qi4j.api.common.InvalidApplicationException;
import org.qi4j.api.service.ServiceReference;
final class JettyConfigurationHelper
{
private static final Integer DEFAULT_PORT = 8080;
private static final String[] DEFAULT_WELCOME_FILES = new String[]
{
"index.html"
};
private static final String COMA = ",";
static void configureServer( Server server, JettyConfiguration config )
{
// Shutdown
Integer gracefullShudownTimeout = config.gracefullShutdownTimeout().get();
if( gracefullShudownTimeout != null )
{
server.setStopTimeout( gracefullShudownTimeout );
}
// Low resource max idle time
Integer lowResourceMaxIdleTime = config.lowResourceMaxIdleTime().get();
if( lowResourceMaxIdleTime != null )
{
LowResourceMonitor lowResourceMonitor = new LowResourceMonitor( server );
lowResourceMonitor.setLowResourcesIdleTimeout( lowResourceMaxIdleTime );
server.addBean( lowResourceMonitor );
}
// Statistics
if( config.statistics().get() )
{
server.addBean( new ConnectorStatistics() );
}
}
static void configureHttp( HttpConfiguration httpConfig, JettyConfiguration config )
{
// Date header
Boolean sendDateHeader = config.sendDateHeader().get();
if( sendDateHeader != null )
{
httpConfig.setSendDateHeader( sendDateHeader );
}
// Server version
Boolean sendServerVersion = config.sendServerVersion().get();
if( sendServerVersion != null )
{
httpConfig.setSendServerVersion( sendServerVersion );
}
// Header sizes
Integer requestHeaderSize = config.requestHeaderSize().get();
if( requestHeaderSize != null )
{
httpConfig.setRequestHeaderSize( requestHeaderSize );
}
Integer responseHeaderSize = config.responseHeaderSize().get();
if( responseHeaderSize != null )
{
httpConfig.setResponseHeaderSize( responseHeaderSize );
}
// Buffer sizes
Integer responseBufferSize = config.responseBufferSize().get();
if( responseBufferSize != null )
{
httpConfig.setOutputBufferSize( responseBufferSize );
}
}
static void configureConnector( ServerConnector connector, JettyConfiguration config )
{
// Host and Port
connector.setHost( config.hostName().get() );
Integer port = config.port().get();
if( port == null )
{
port = DEFAULT_PORT;
}
connector.setPort( port );
// Max idle times
Integer maxIdleTime = config.maxIdleTime().get();
if( maxIdleTime != null )
{
connector.setIdleTimeout( maxIdleTime );
}
}
static void configureSsl( SslConnectionFactory sslConnFactory, SecureJettyConfiguration config )
{
SslContextFactory ssl = sslConnFactory.getSslContextFactory();
boolean needBouncyCastle = false;
// KeyStore
String keystoreType = config.keystoreType().get();
String keystorePath = config.keystorePath().get();
String keystorePassword = config.keystorePassword().get();
ssl.setKeyStoreType( keystoreType );
if( "PKCS12".equals( keystoreType ) )
{
ssl.setKeyStoreProvider( "BC" ); // WARN This one needs BouncyCastle on the classpath
needBouncyCastle = true;
}
ssl.setKeyStorePath( keystorePath );
ssl.setKeyStorePassword( keystorePassword );
// Certificate alias
String certAlias = config.certAlias().get();
if( certAlias != null )
{
ssl.setCertAlias( certAlias );
}
// TrustStore
String truststoreType = config.truststoreType().get();
String truststorePath = config.truststorePath().get();
String truststorePassword = config.truststorePassword().get();
if( truststoreType != null && truststorePath != null )
{
ssl.setTrustStoreType( truststoreType );
if( "PKCS12".equals( truststoreType ) )
{
ssl.setTrustStoreProvider( "BC" );
needBouncyCastle = true;
}
ssl.setTrustStorePath( truststorePath );
ssl.setTrustStorePassword( truststorePassword );
}
// Need / Want Client Auth
Boolean want = config.wantClientAuth().get();
if( want != null )
{
ssl.setWantClientAuth( want );
}
Boolean need = config.needClientAuth().get();
if( need != null )
{
ssl.setNeedClientAuth( need );
}
// Algorithms
String secureRandomAlgo = config.secureRandomAlgorithm().get();
if( secureRandomAlgo != null )
{
ssl.setSecureRandomAlgorithm( secureRandomAlgo );
}
String cipherExcludesConfigString = config.excludeCipherSuites().get();
if( cipherExcludesConfigString != null )
{
String[] cipherExcludes = cipherExcludesConfigString.split( COMA );
if( cipherExcludes.length > 0 )
{
ssl.setExcludeCipherSuites( cipherExcludes );
}
}
String cipherIncludesConfigString = config.includeCipherSuites().get();
if( cipherIncludesConfigString != null )
{
String[] cipherIncludes = cipherIncludesConfigString.split( COMA );
if( cipherIncludes.length > 0 )
{
ssl.setIncludeCipherSuites( cipherIncludes );
}
}
// SSL Handling
Boolean cacheSslSessions = config.cacheSslSessions().get();
if( cacheSslSessions != null )
{
ssl.setSessionCachingEnabled( cacheSslSessions );
}
ssl.setRenegotiationAllowed( config.allowRenegotiation().get() );
// Validation Flags
Integer maxCertPathLength = config.maxCertPathLength().get();
if( maxCertPathLength != null )
{
ssl.setMaxCertPathLength( maxCertPathLength );
}
ssl.setValidateCerts( config.validateServerCert().get() );
ssl.setValidatePeerCerts( config.validatePeerCerts().get() );
// Validation CRL
String crlFilePath = config.crlFilePath().get();
if( crlFilePath != null && crlFilePath.length() > 0 )
{
ssl.setCrlPath( crlFilePath );
}
ssl.setEnableCRLDP( config.enableCRLDP().get() );
// Validation OCSP
ssl.setEnableOCSP( config.enableOCSP().get() );
String ocspURL = config.ocspResponderURL().get();
if( ocspURL != null )
{
ssl.setOcspResponderURL( ocspURL );
}
// Load BouncyCastle ?
if( needBouncyCastle )
{
Provider bc = Security.getProvider( "BC" );
if( bc == null )
{
try
{
Security.addProvider( (Provider) Class.forName( "org.bouncycastle.jce.provider.BouncyCastleProvider" ).newInstance() );
}
catch( Exception ex )
{
throw new InvalidApplicationException( "Need to open a PKCS#12 but was unable to register BouncyCastle, check your classpath", ex );
}
}
}
}
static void configureContext( ServletContextHandler root, JettyConfiguration config )
{
// Context path
String contextPath = config.contextPath().get();
if( contextPath != null && contextPath.length() > 0 )
{
root.setContextPath( contextPath );
}
// Root resource base
String resourcePath = config.resourcePath().get();
if( resourcePath != null && resourcePath.length() > 0 )
{
root.addServlet( DefaultServlet.class, "/" );
root.setResourceBase( resourcePath );
}
// Max form content size
Integer maxFormContentSize = config.maxFormContentSize().get();
if( maxFormContentSize != null )
{
root.setMaxFormContentSize( maxFormContentSize );
}
// Virtual hosts
String virtualHostsConfigString = config.virtualHosts().get();
if( virtualHostsConfigString != null )
{
String[] virtualHosts = virtualHostsConfigString.split( COMA );
if( virtualHosts.length > 0 )
{
root.setVirtualHosts( virtualHosts );
}
}
// Welcome files
String welcomeFilesConfigString = config.welcomeFiles().get();
if( welcomeFilesConfigString == null )
{
root.setWelcomeFiles( DEFAULT_WELCOME_FILES );
}
else
{
String[] welcomeFiles = welcomeFilesConfigString.split( COMA );
if( welcomeFiles.length == 0 )
{
root.setWelcomeFiles( DEFAULT_WELCOME_FILES );
}
else
{
root.setWelcomeFiles( welcomeFiles );
}
}
}
static void addContextListeners( ServletContextHandler root, Iterable<ServiceReference<ServletContextListener>> contextListeners )
{
// Iterate the available context listeners and add them to the server
for( ServiceReference<ServletContextListener> contextListener : contextListeners )
{
ContextListenerInfo contextListenerInfo = contextListener.metaInfo( ContextListenerInfo.class );
Map<String, String> initParams = contextListenerInfo.initParams();
for( Map.Entry<String, String> entry : initParams.entrySet() )
{
root.setInitParameter( entry.getKey(), entry.getValue() );
}
root.addEventListener( contextListener.get() );
}
}
static void addServlets( ServletContextHandler root, Iterable<ServiceReference<Servlet>> servlets )
{
// Iterate the available servlets and add it to the server
for( ServiceReference<Servlet> servlet : servlets )
{
ServletInfo servletInfo = servlet.metaInfo( ServletInfo.class );
String servletPath = servletInfo.getPath();
Servlet servletInstance = servlet.get();
ServletHolder holder = new ServletHolder( servletInstance );
holder.setInitParameters( servletInfo.initParams() );
root.addServlet( holder, servletPath );
}
}
static void addFilters( ServletContextHandler root, Iterable<ServiceReference<Filter>> filters )
{
// Iterate the available filters and add them to the server
for( ServiceReference<Filter> filter : filters )
{
FilterInfo filterInfo = filter.metaInfo( FilterInfo.class );
String filterPath = filterInfo.getPath();
Filter filterInstance = filter.get();
FilterHolder holder = new FilterHolder( filterInstance );
holder.setInitParameters( filterInfo.initParameters() );
root.addFilter( holder, filterPath, filterInfo.dispatchers() );
}
}
private JettyConfigurationHelper()
{
}
}