/**
* Copyright (c) 2013-2016, The SeedStack authors <http://seedstack.org>
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.seedstack.seed.undertow.internal;
import io.undertow.Handlers;
import io.undertow.Undertow;
import io.undertow.UndertowOptions;
import io.undertow.server.handlers.PathHandler;
import io.undertow.servlet.api.DeploymentManager;
import org.seedstack.seed.SeedException;
import org.seedstack.seed.crypto.CryptoConfig;
import org.seedstack.seed.crypto.spi.SSLProvider;
import org.seedstack.seed.undertow.UndertowConfig;
import org.seedstack.seed.web.WebConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xnio.Options;
import org.xnio.SslClientAuthMode;
import javax.net.ssl.SSLContext;
import javax.servlet.ServletException;
import java.util.Optional;
class ServerFactory {
private static final Logger LOGGER = LoggerFactory.getLogger(ServerFactory.class);
Undertow createServer(DeploymentManager manager, WebConfig.ServerConfig serverConfig, UndertowConfig undertowConfig, SSLProvider sslProvider) {
PathHandler path = null;
try {
path = Handlers.path(Handlers.redirect(serverConfig.getContextPath()))
.addPrefixPath(serverConfig.getContextPath(), manager.start());
} catch (ServletException e) {
LOGGER.error(e.getMessage(), e);
}
Undertow.Builder builder = Undertow.builder();
if (serverConfig.isHttps()) {
configureHttps(builder, serverConfig, sslProvider);
} else {
configureHttp(builder, serverConfig);
}
if (serverConfig.isHttp2()) {
LOGGER.info("HTTP/2 support is enabled");
builder.setServerOption(UndertowOptions.ENABLE_HTTP2, serverConfig.isHttp2());
}
return configureUndertow(builder, undertowConfig).setHandler(path).build();
}
private Undertow.Builder configureUndertow(Undertow.Builder builder, UndertowConfig undertowConfig) {
undertowConfig.getBufferSize().ifPresent(builder::setBufferSize);
undertowConfig.getIoThreads().ifPresent(builder::setIoThreads);
undertowConfig.getWorkerThreads().ifPresent(builder::setWorkerThreads);
undertowConfig.getDirectBuffers().ifPresent(builder::setDirectBuffers);
return builder;
}
private Undertow.Builder configureHttp(Undertow.Builder builder, WebConfig.ServerConfig serverConfig) {
return builder.addHttpListener(serverConfig.getPort(), serverConfig.getHost());
}
private Undertow.Builder configureHttps(Undertow.Builder builder, WebConfig.ServerConfig serverConfig, SSLProvider sslProvider) {
Optional<SSLContext> sslContext = sslProvider.sslContext();
CryptoConfig.SSLConfig sslConfig = sslProvider.sslConfig();
if (sslContext.isPresent()) {
return builder
.addHttpsListener(serverConfig.getPort(), serverConfig.getHost(), sslContext.get())
.setSocketOption(Options.SSL_CLIENT_AUTH_MODE, SslClientAuthMode.valueOf(sslConfig.getClientAuthMode().toString()));
} else {
throw SeedException.createNew(UndertowErrorCode.MISSING_SSL_CONTEXT)
.put("ksName", sslConfig.getKeyStore())
.put("tsName", sslConfig.getTrustStore())
.put("alias", sslConfig.getAlias());
}
}
}