package io.undertow.servlet.core;
import io.undertow.Handlers;
import io.undertow.predicate.Predicates;
import io.undertow.security.api.AuthenticationMechanism;
import io.undertow.security.api.AuthenticationMechanismFactory;
import io.undertow.security.api.NotificationReceiver;
import io.undertow.security.api.SecurityContextFactory;
import io.undertow.security.handlers.AuthenticationMechanismsHandler;
import io.undertow.security.handlers.NotificationReceiverHandler;
import io.undertow.security.handlers.SecurityInitialHandler;
import io.undertow.security.idm.IdentityManager;
import io.undertow.security.impl.BasicAuthenticationMechanism;
import io.undertow.security.impl.CachedAuthenticatedSessionMechanism;
import io.undertow.security.impl.ClientCertAuthenticationMechanism;
import io.undertow.security.impl.DigestAuthenticationMechanism;
import io.undertow.security.impl.ExternalAuthenticationMechanism;
import io.undertow.security.impl.GenericHeaderAuthenticationMechanism;
import io.undertow.security.impl.SecurityContextFactoryImpl;
import io.undertow.server.HandlerWrapper;
import io.undertow.server.HttpHandler;
import io.undertow.server.HttpServerExchange;
import io.undertow.server.handlers.HttpContinueReadHandler;
import io.undertow.server.handlers.PredicateHandler;
import io.undertow.server.handlers.form.FormEncodedDataDefinition;
import io.undertow.server.handlers.form.FormParserFactory;
import io.undertow.server.session.SessionListener;
import io.undertow.server.session.SessionManager;
import io.undertow.servlet.ServletExtension;
import io.undertow.servlet.UndertowServletLogger;
import io.undertow.servlet.UndertowServletMessages;
import io.undertow.servlet.api.AuthMethodConfig;
import io.undertow.servlet.api.Deployment;
import io.undertow.servlet.api.DeploymentInfo;
import io.undertow.servlet.api.DeploymentManager;
import io.undertow.servlet.api.ErrorPage;
import io.undertow.servlet.api.FilterInfo;
import io.undertow.servlet.api.HttpMethodSecurityInfo;
import io.undertow.servlet.api.InstanceHandle;
import io.undertow.servlet.api.ListenerInfo;
import io.undertow.servlet.api.LoginConfig;
import io.undertow.servlet.api.MetricsCollector;
import io.undertow.servlet.api.MimeMapping;
import io.undertow.servlet.api.SecurityConstraint;
import io.undertow.servlet.api.SecurityInfo.EmptyRoleSemantic;
import io.undertow.servlet.api.ServletContainer;
import io.undertow.servlet.api.ServletContainerInitializerInfo;
import io.undertow.servlet.api.ServletInfo;
import io.undertow.servlet.api.ServletSecurityInfo;
import io.undertow.servlet.api.ServletSessionConfig;
import io.undertow.servlet.api.ServletStackTraces;
import io.undertow.servlet.api.SessionPersistenceManager;
import io.undertow.servlet.api.ThreadSetupHandler;
import io.undertow.servlet.api.WebResourceCollection;
import io.undertow.servlet.handlers.CrawlerSessionManagerHandler;
import io.undertow.servlet.handlers.RedirectDirHandler;
import io.undertow.servlet.handlers.SendErrorPageHandler;
import io.undertow.servlet.handlers.ServletDispatchingHandler;
import io.undertow.servlet.handlers.ServletHandler;
import io.undertow.servlet.handlers.ServletInitialHandler;
import io.undertow.servlet.handlers.SessionRestoringHandler;
import io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler;
import io.undertow.servlet.handlers.security.SSLInformationAssociationHandler;
import io.undertow.servlet.handlers.security.SecurityPathMatches;
import io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler;
import io.undertow.servlet.handlers.security.ServletAuthenticationConstraintHandler;
import io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler;
import io.undertow.servlet.handlers.security.ServletFormAuthenticationMechanism;
import io.undertow.servlet.handlers.security.ServletSecurityConstraintHandler;
import io.undertow.servlet.predicate.DispatcherTypePredicate;
import io.undertow.servlet.spec.ServletContextImpl;
import io.undertow.servlet.spec.SessionCookieConfigImpl;
import io.undertow.util.MimeMappings;
import javax.servlet.ServletContainerInitializer;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletException;
import java.io.File;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.ServiceLoader;
import java.util.Set;
import java.util.TreeMap;
import static javax.servlet.http.HttpServletRequest.BASIC_AUTH;
import static javax.servlet.http.HttpServletRequest.CLIENT_CERT_AUTH;
import static javax.servlet.http.HttpServletRequest.DIGEST_AUTH;
import static javax.servlet.http.HttpServletRequest.FORM_AUTH;
public class DeploymentManagerImpl implements DeploymentManager {
private final DeploymentInfo originalDeployment;
private final ServletContainer servletContainer;
private volatile DeploymentImpl deployment;
private volatile State state = State.UNDEPLOYED;
public DeploymentManagerImpl(final DeploymentInfo deployment, final ServletContainer servletContainer) {
this.originalDeployment = deployment;
this.servletContainer = servletContainer;
}
@Override
public void deploy() {
final DeploymentInfo deploymentInfo = originalDeployment.clone();
if (deploymentInfo.getServletStackTraces() == ServletStackTraces.ALL) {
UndertowServletLogger.REQUEST_LOGGER.servletStackTracesAll(deploymentInfo.getDeploymentName());
}
deploymentInfo.validate();
final DeploymentImpl deployment = new DeploymentImpl(this, deploymentInfo, servletContainer);
this.deployment = deployment;
final ServletContextImpl servletContext = new ServletContextImpl(servletContainer, deployment);
deployment.setServletContext(servletContext);
handleExtensions(deploymentInfo, servletContext);
final List<ThreadSetupHandler> setup = new ArrayList<>();
setup.add(ServletRequestContextThreadSetupAction.INSTANCE);
setup.add(new ContextClassLoaderSetupAction(deploymentInfo.getClassLoader()));
setup.addAll(deploymentInfo.getThreadSetupActions());
deployment.setThreadSetupActions(setup);
deployment.getServletPaths().setWelcomePages(deploymentInfo.getWelcomePages());
if (deploymentInfo.getDefaultEncoding() != null) {
deployment.setDefaultCharset(Charset.forName(deploymentInfo.getDefaultEncoding()));
}
if(deploymentInfo.getDefaultRequestEncoding() != null) {
deployment.setDefaultRequestCharset(Charset.forName(deploymentInfo.getDefaultRequestEncoding()));
} else if (deploymentInfo.getDefaultEncoding() != null) {
deployment.setDefaultRequestCharset(Charset.forName(deploymentInfo.getDefaultEncoding()));
}
if(deploymentInfo.getDefaultResponseEncoding() != null) {
deployment.setDefaultResponseCharset(Charset.forName(deploymentInfo.getDefaultResponseEncoding()));
} else if (deploymentInfo.getDefaultEncoding() != null) {
deployment.setDefaultResponseCharset(Charset.forName(deploymentInfo.getDefaultEncoding()));
}
handleDeploymentSessionConfig(deploymentInfo, servletContext);
deployment.setSessionManager(deploymentInfo.getSessionManagerFactory().createSessionManager(deployment));
deployment.getSessionManager().setDefaultSessionTimeout(deploymentInfo.getDefaultSessionTimeout());
try {
deployment.createThreadSetupAction(new ThreadSetupHandler.Action<Void, Object>() {
@Override
public Void call(HttpServerExchange exchange, Object ignore) throws Exception {
final ApplicationListeners listeners = createListeners();
deployment.setApplicationListeners(listeners);
createServletsAndFilters(deployment, deploymentInfo);
initializeTempDir(servletContext, deploymentInfo);
for (final ServletContainerInitializerInfo sci : deploymentInfo.getServletContainerInitializers()) {
final InstanceHandle<? extends ServletContainerInitializer> instance = sci.getInstanceFactory().createInstance();
try {
instance.getInstance().onStartup(sci.getHandlesTypes(), servletContext);
} finally {
instance.release();
}
}
listeners.start();
deployment.getSessionManager().registerSessionListener(new SessionListenerBridge(deployment, listeners, servletContext));
for(SessionListener listener : deploymentInfo.getSessionListeners()) {
deployment.getSessionManager().registerSessionListener(listener);
}
initializeErrorPages(deployment, deploymentInfo);
initializeMimeMappings(deployment, deploymentInfo);
listeners.contextInitialized();
HttpHandler wrappedHandlers = ServletDispatchingHandler.INSTANCE;
wrappedHandlers = wrapHandlers(wrappedHandlers, deploymentInfo.getInnerHandlerChainWrappers());
wrappedHandlers = new RedirectDirHandler(wrappedHandlers, deployment.getServletPaths());
if(!deploymentInfo.isSecurityDisabled()) {
HttpHandler securityHandler = setupSecurityHandlers(wrappedHandlers);
wrappedHandlers = new PredicateHandler(DispatcherTypePredicate.REQUEST, securityHandler, wrappedHandlers);
}
HttpHandler outerHandlers = wrapHandlers(wrappedHandlers, deploymentInfo.getOuterHandlerChainWrappers());
outerHandlers = new SendErrorPageHandler(outerHandlers);
wrappedHandlers = new PredicateHandler(DispatcherTypePredicate.REQUEST, outerHandlers, wrappedHandlers);
wrappedHandlers = handleDevelopmentModePersistentSessions(wrappedHandlers, deploymentInfo, deployment.getSessionManager(), servletContext);
MetricsCollector metrics = deploymentInfo.getMetricsCollector();
if(metrics != null) {
wrappedHandlers = new MetricsChainHandler(wrappedHandlers, metrics, deployment);
}
if( deploymentInfo.getCrawlerSessionManagerConfig() != null ) {
wrappedHandlers = new CrawlerSessionManagerHandler(deploymentInfo.getCrawlerSessionManagerConfig(), wrappedHandlers);
}
final ServletInitialHandler servletInitialHandler = SecurityActions.createServletInitialHandler(deployment.getServletPaths(), wrappedHandlers, deployment, servletContext);
HttpHandler initialHandler = wrapHandlers(servletInitialHandler, deployment.getDeploymentInfo().getInitialHandlerChainWrappers());
initialHandler = new HttpContinueReadHandler(initialHandler);
if(deploymentInfo.getUrlEncoding() != null) {
initialHandler = Handlers.urlDecodingHandler(deploymentInfo.getUrlEncoding(), initialHandler);
}
deployment.setInitialHandler(initialHandler);
deployment.setServletHandler(servletInitialHandler);
deployment.getServletPaths().invalidate();
servletContext.initDone();
return null;
}
}).call(null, null);
} catch (Exception e) {
throw new RuntimeException(e);
}
deployment.getServletPaths().initData();
for(ServletContextListener listener : deploymentInfo.getDeploymentCompleteListeners()) {
listener.contextInitialized(new ServletContextEvent(servletContext));
}
state = State.DEPLOYED;
}
private void createServletsAndFilters(final DeploymentImpl deployment, final DeploymentInfo deploymentInfo) {
for (Map.Entry<String, ServletInfo> servlet : deploymentInfo.getServlets().entrySet()) {
deployment.getServlets().addServlet(servlet.getValue());
}
for (Map.Entry<String, FilterInfo> filter : deploymentInfo.getFilters().entrySet()) {
deployment.getFilters().addFilter(filter.getValue());
}
}
private void handleExtensions(final DeploymentInfo deploymentInfo, final ServletContextImpl servletContext) {
Set<String> loadedExtensions = new HashSet<>();
for (ServletExtension extension : ServiceLoader.load(ServletExtension.class, deploymentInfo.getClassLoader())) {
loadedExtensions.add(extension.getClass().getName());
extension.handleDeployment(deploymentInfo, servletContext);
}
if (ServletExtension.class.getClassLoader() != null && !ServletExtension.class.getClassLoader().equals(deploymentInfo.getClassLoader())) {
for (ServletExtension extension : ServiceLoader.load(ServletExtension.class)) {
if (!loadedExtensions.contains(extension.getClass().getName())) {
extension.handleDeployment(deploymentInfo, servletContext);
}
}
}
for (ServletExtension extension : ServletExtensionHolder.getServletExtensions()) {
if (!loadedExtensions.contains(extension.getClass().getName())) {
extension.handleDeployment(deploymentInfo, servletContext);
}
}
for(ServletExtension extension : deploymentInfo.getServletExtensions()) {
extension.handleDeployment(deploymentInfo, servletContext);
}
}
private HttpHandler setupSecurityHandlers(HttpHandler initialHandler) {
final DeploymentInfo deploymentInfo = deployment.getDeploymentInfo();
final LoginConfig loginConfig = deploymentInfo.getLoginConfig();
HttpHandler current = initialHandler;
current = new SSLInformationAssociationHandler(current);
final SecurityPathMatches securityPathMatches = buildSecurityConstraints();
securityPathMatches.logWarningsAboutUncoveredMethods();
current = new ServletAuthenticationCallHandler(current);
for(HandlerWrapper wrapper : deploymentInfo.getSecurityWrappers()) {
current = wrapper.wrap(current);
}
if(deploymentInfo.isDisableCachingForSecuredPages()) {
current = Handlers.predicate(Predicates.authRequired(), Handlers.disableCache(current), current);
}
if (!securityPathMatches.isEmpty()) {
current = new ServletAuthenticationConstraintHandler(current);
}
current = new ServletConfidentialityConstraintHandler(deploymentInfo.getConfidentialPortManager(), current);
if (!securityPathMatches.isEmpty()) {
current = new ServletSecurityConstraintHandler(securityPathMatches, current);
}
HandlerWrapper initialSecurityWrapper = deploymentInfo.getInitialSecurityWrapper();
String mechName = null;
if (initialSecurityWrapper == null) {
final Map<String, AuthenticationMechanismFactory> factoryMap = new HashMap<>(deploymentInfo.getAuthenticationMechanisms());
final IdentityManager identityManager = deploymentInfo.getIdentityManager();
if(!factoryMap.containsKey(BASIC_AUTH)) {
factoryMap.put(BASIC_AUTH, BasicAuthenticationMechanism.FACTORY);
}
if(!factoryMap.containsKey(FORM_AUTH)) {
factoryMap.put(FORM_AUTH, ServletFormAuthenticationMechanism.FACTORY);
}
if(!factoryMap.containsKey(DIGEST_AUTH)) {
factoryMap.put(DIGEST_AUTH, DigestAuthenticationMechanism.FACTORY);
}
if(!factoryMap.containsKey(CLIENT_CERT_AUTH)) {
factoryMap.put(CLIENT_CERT_AUTH, ClientCertAuthenticationMechanism.FACTORY);
}
if(!factoryMap.containsKey(ExternalAuthenticationMechanism.NAME)) {
factoryMap.put(ExternalAuthenticationMechanism.NAME, ExternalAuthenticationMechanism.FACTORY);
}
if(!factoryMap.containsKey(GenericHeaderAuthenticationMechanism.NAME)) {
factoryMap.put(GenericHeaderAuthenticationMechanism.NAME, GenericHeaderAuthenticationMechanism.FACTORY);
}
List<AuthenticationMechanism> authenticationMechanisms = new LinkedList<>();
if(deploymentInfo.isUseCachedAuthenticationMechanism()) {
authenticationMechanisms.add(new CachedAuthenticatedSessionMechanism(identityManager));
}
if (loginConfig != null || deploymentInfo.getJaspiAuthenticationMechanism() != null) {
FormEncodedDataDefinition formEncodedDataDefinition = new FormEncodedDataDefinition();
String reqEncoding = deploymentInfo.getDefaultRequestEncoding();
if(reqEncoding == null) {
reqEncoding = deploymentInfo.getDefaultEncoding();
}
if (reqEncoding != null) {
formEncodedDataDefinition.setDefaultEncoding(reqEncoding);
}
FormParserFactory parser = FormParserFactory.builder(false)
.addParser(formEncodedDataDefinition)
.build();
List<AuthMethodConfig> authMethods = Collections.<AuthMethodConfig>emptyList();
if(loginConfig != null) {
authMethods = loginConfig.getAuthMethods();
}
for(AuthMethodConfig method : authMethods) {
AuthenticationMechanismFactory factory = factoryMap.get(method.getName());
if(factory == null) {
throw UndertowServletMessages.MESSAGES.unknownAuthenticationMechanism(method.getName());
}
if(mechName == null) {
mechName = method.getName();
}
final Map<String, String> properties = new HashMap<>();
properties.put(AuthenticationMechanismFactory.CONTEXT_PATH, deploymentInfo.getContextPath());
properties.put(AuthenticationMechanismFactory.REALM, loginConfig.getRealmName());
properties.put(AuthenticationMechanismFactory.ERROR_PAGE, loginConfig.getErrorPage());
properties.put(AuthenticationMechanismFactory.LOGIN_PAGE, loginConfig.getLoginPage());
properties.putAll(method.getProperties());
String name = method.getName().toUpperCase(Locale.US);
name = name.equals(FORM_AUTH) ? FORM_AUTH : name;
name = name.equals(BASIC_AUTH) ? BASIC_AUTH : name;
name = name.equals(DIGEST_AUTH) ? DIGEST_AUTH : name;
name = name.equals(CLIENT_CERT_AUTH) ? CLIENT_CERT_AUTH : name;
authenticationMechanisms.add(factory.create(name, identityManager, parser, properties));
}
}
deployment.setAuthenticationMechanisms(authenticationMechanisms);
if(deploymentInfo.getJaspiAuthenticationMechanism() == null) {
current = new AuthenticationMechanismsHandler(current, authenticationMechanisms);
} else {
current = new AuthenticationMechanismsHandler(current, Collections.<AuthenticationMechanism>singletonList(deploymentInfo.getJaspiAuthenticationMechanism()));
}
current = new CachedAuthenticatedSessionHandler(current, this.deployment.getServletContext());
}
List<NotificationReceiver> notificationReceivers = deploymentInfo.getNotificationReceivers();
if (!notificationReceivers.isEmpty()) {
current = new NotificationReceiverHandler(current, notificationReceivers);
}
if (initialSecurityWrapper == null) {
SecurityContextFactory contextFactory = deploymentInfo.getSecurityContextFactory();
if (contextFactory == null) {
contextFactory = SecurityContextFactoryImpl.INSTANCE;
}
current = new SecurityInitialHandler(deploymentInfo.getAuthenticationMode(), deploymentInfo.getIdentityManager(), mechName,
contextFactory, current);
} else {
current = initialSecurityWrapper.wrap(current);
}
return current;
}
private SecurityPathMatches buildSecurityConstraints() {
SecurityPathMatches.Builder builder = SecurityPathMatches.builder(deployment.getDeploymentInfo());
final Set<String> urlPatterns = new HashSet<>();
for (SecurityConstraint constraint : deployment.getDeploymentInfo().getSecurityConstraints()) {
builder.addSecurityConstraint(constraint);
for (WebResourceCollection webResources : constraint.getWebResourceCollections()) {
urlPatterns.addAll(webResources.getUrlPatterns());
}
}
for (final ServletInfo servlet : deployment.getDeploymentInfo().getServlets().values()) {
final ServletSecurityInfo securityInfo = servlet.getServletSecurityInfo();
if (securityInfo != null) {
final Set<String> mappings = new HashSet<>(servlet.getMappings());
mappings.removeAll(urlPatterns);
if (!mappings.isEmpty()) {
final Set<String> methods = new HashSet<>();
for (HttpMethodSecurityInfo method : securityInfo.getHttpMethodSecurityInfo()) {
methods.add(method.getMethod());
if (method.getRolesAllowed().isEmpty() && method.getEmptyRoleSemantic() == EmptyRoleSemantic.PERMIT) {
continue;
}
SecurityConstraint newConstraint = new SecurityConstraint()
.addRolesAllowed(method.getRolesAllowed())
.setTransportGuaranteeType(method.getTransportGuaranteeType())
.addWebResourceCollection(new WebResourceCollection().addUrlPatterns(mappings)
.addHttpMethod(method.getMethod()));
builder.addSecurityConstraint(newConstraint);
}
if (!securityInfo.getRolesAllowed().isEmpty()
|| securityInfo.getEmptyRoleSemantic() != EmptyRoleSemantic.PERMIT
|| methods.isEmpty()) {
SecurityConstraint newConstraint = new SecurityConstraint()
.setEmptyRoleSemantic(securityInfo.getEmptyRoleSemantic())
.addRolesAllowed(securityInfo.getRolesAllowed())
.setTransportGuaranteeType(securityInfo.getTransportGuaranteeType())
.addWebResourceCollection(new WebResourceCollection().addUrlPatterns(mappings)
.addHttpMethodOmissions(methods));
builder.addSecurityConstraint(newConstraint);
}
}
}
}
return builder.build();
}
private void initializeTempDir(final ServletContextImpl servletContext, final DeploymentInfo deploymentInfo) {
if (deploymentInfo.getTempDir() != null) {
servletContext.setAttribute(ServletContext.TEMPDIR, deploymentInfo.getTempDir());
} else {
servletContext.setAttribute(ServletContext.TEMPDIR, new File(SecurityActions.getSystemProperty("java.io.tmpdir")));
}
}
private void initializeMimeMappings(final DeploymentImpl deployment, final DeploymentInfo deploymentInfo) {
final Map<String, String> mappings = new HashMap<>(MimeMappings.DEFAULT_MIME_MAPPINGS);
for (MimeMapping mapping : deploymentInfo.getMimeMappings()) {
mappings.put(mapping.getExtension().toLowerCase(Locale.ENGLISH), mapping.getMimeType());
}
deployment.setMimeExtensionMappings(mappings);
}
private void initializeErrorPages(final DeploymentImpl deployment, final DeploymentInfo deploymentInfo) {
final Map<Integer, String> codes = new HashMap<>();
final Map<Class<? extends Throwable>, String> exceptions = new HashMap<>();
String defaultErrorPage = null;
for (final ErrorPage page : deploymentInfo.getErrorPages()) {
if (page.getExceptionType() != null) {
exceptions.put(page.getExceptionType(), page.getLocation());
} else if (page.getErrorCode() != null) {
codes.put(page.getErrorCode(), page.getLocation());
} else {
if (defaultErrorPage != null) {
throw UndertowServletMessages.MESSAGES.moreThanOneDefaultErrorPage(defaultErrorPage, page.getLocation());
} else {
defaultErrorPage = page.getLocation();
}
}
}
deployment.setErrorPages(new ErrorPages(codes, exceptions, defaultErrorPage));
}
private ApplicationListeners createListeners() {
final List<ManagedListener> managedListeners = new ArrayList<>();
for (final ListenerInfo listener : deployment.getDeploymentInfo().getListeners()) {
managedListeners.add(new ManagedListener(listener, listener.isProgramatic()));
}
return new ApplicationListeners(managedListeners, deployment.getServletContext());
}
private static HttpHandler wrapHandlers(final HttpHandler wrapee, final List<HandlerWrapper> wrappers) {
HttpHandler current = wrapee;
for (HandlerWrapper wrapper : wrappers) {
current = wrapper.wrap(current);
}
return current;
}
@Override
public HttpHandler start() throws ServletException {
try {
return deployment.createThreadSetupAction(new ThreadSetupHandler.Action<HttpHandler, Object>() {
@Override
public HttpHandler call(HttpServerExchange exchange, Object ignore) throws ServletException {
deployment.getSessionManager().start();
ArrayList<Lifecycle> lifecycles = new ArrayList<>(deployment.getLifecycleObjects());
for (Lifecycle object : lifecycles) {
object.start();
}
HttpHandler root = deployment.getHandler();
final TreeMap<Integer, List<ManagedServlet>> loadOnStartup = new TreeMap<>();
for (Map.Entry<String, ServletHandler> entry : deployment.getServlets().getServletHandlers().entrySet()) {
ManagedServlet servlet = entry.getValue().getManagedServlet();
Integer loadOnStartupNumber = servlet.getServletInfo().getLoadOnStartup();
if (loadOnStartupNumber != null) {
if (loadOnStartupNumber < 0) {
continue;
}
List<ManagedServlet> list = loadOnStartup.get(loadOnStartupNumber);
if (list == null) {
loadOnStartup.put(loadOnStartupNumber, list = new ArrayList<>());
}
list.add(servlet);
}
}
for (Map.Entry<Integer, List<ManagedServlet>> load : loadOnStartup.entrySet()) {
for (ManagedServlet servlet : load.getValue()) {
servlet.createServlet();
}
}
if (deployment.getDeploymentInfo().isEagerFilterInit()) {
for (ManagedFilter filter : deployment.getFilters().getFilters().values()) {
filter.createFilter();
}
}
state = State.STARTED;
return root;
}
}).call(null, null);
} catch (ServletException|RuntimeException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public void stop() throws ServletException {
try {
deployment.createThreadSetupAction(new ThreadSetupHandler.Action<Void, Object>() {
@Override
public Void call(HttpServerExchange exchange, Object ignore) throws ServletException {
for (Lifecycle object : deployment.getLifecycleObjects()) {
try {
object.stop();
} catch (Throwable t) {
UndertowServletLogger.ROOT_LOGGER.failedToDestroy(object, t);
}
}
deployment.getSessionManager().stop();
state = State.DEPLOYED;
return null;
}
}).call(null, null);
} catch (ServletException|RuntimeException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private HttpHandler handleDevelopmentModePersistentSessions(HttpHandler next, final DeploymentInfo deploymentInfo, final SessionManager sessionManager, final ServletContextImpl servletContext) {
final SessionPersistenceManager sessionPersistenceManager = deploymentInfo.getSessionPersistenceManager();
if (sessionPersistenceManager != null) {
SessionRestoringHandler handler = new SessionRestoringHandler(deployment.getDeploymentInfo().getDeploymentName(), sessionManager, servletContext, next, sessionPersistenceManager);
deployment.addLifecycleObjects(handler);
return handler;
}
return next;
}
public void handleDeploymentSessionConfig(DeploymentInfo deploymentInfo, ServletContextImpl servletContext) {
SessionCookieConfigImpl sessionCookieConfig = servletContext.getSessionCookieConfig();
ServletSessionConfig sc = deploymentInfo.getServletSessionConfig();
if (sc != null) {
sessionCookieConfig.setName(sc.getName());
sessionCookieConfig.setComment(sc.getComment());
sessionCookieConfig.setDomain(sc.getDomain());
sessionCookieConfig.setHttpOnly(sc.isHttpOnly());
sessionCookieConfig.setMaxAge(sc.getMaxAge());
if(sc.getPath() != null) {
sessionCookieConfig.setPath(sc.getPath());
} else {
sessionCookieConfig.setPath(deploymentInfo.getContextPath());
}
sessionCookieConfig.setSecure(sc.isSecure());
if (sc.getSessionTrackingModes() != null) {
servletContext.setDefaultSessionTrackingModes(new HashSet<>(sc.getSessionTrackingModes()));
}
}
}
@Override
public void undeploy() {
try {
deployment.createThreadSetupAction(new ThreadSetupHandler.Action<Void, Object>() {
@Override
public Void call(HttpServerExchange exchange, Object ignore) throws ServletException {
for(ServletContextListener listener : deployment.getDeploymentInfo().getDeploymentCompleteListeners()) {
try {
listener.contextDestroyed(new ServletContextEvent(deployment.getServletContext()));
} catch (Throwable t) {
UndertowServletLogger.REQUEST_LOGGER.failedToDestroy(listener, t);
}
}
deployment.destroy();
deployment = null;
state = State.UNDEPLOYED;
return null;
}
}).call(null, null);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public State getState() {
return state;
}
@Override
public Deployment getDeployment() {
return deployment;
}
}