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()); } }
@Override public Map<String, ? extends FilterRegistration> getFilterRegistrations() { ensureNotProgramaticListener(); final Map<String, FilterRegistration> ret = new HashMap<String, FilterRegistration>(); for (Map.Entry<String, FilterInfo> entry : deploymentInfo.getFilters().entrySet()) { ret.put(entry.getKey(), new FilterRegistrationImpl(entry.getValue(), deployment)); } return ret; }
@Override public FilterRegistration getFilterRegistration(final String filterName) { ensureNotProgramaticListener(); final FilterInfo filterInfo = deploymentInfo.getFilters().get(filterName); if (filterInfo == null) { return null; } return new FilterRegistrationImpl(filterInfo, deployment); }
@Override public FilterRegistration.Dynamic addFilter( final String filterName, final Class<? extends Filter> filterClass) { ensureNotProgramaticListener(); ensureNotInitialized(); if (deploymentInfo.getFilters().containsKey(filterName)) { return null; } FilterInfo filter = new FilterInfo(filterName, filterClass); deploymentInfo.addFilter(filter); deployment.getFilters().addFilter(filter); return new FilterRegistrationImpl(filter, deployment); }
@Override public FilterRegistration.Dynamic addFilter(final String filterName, final Filter filter) { ensureNotProgramaticListener(); ensureNotInitialized(); if (deploymentInfo.getFilters().containsKey(filterName)) { return null; } FilterInfo f = new FilterInfo(filterName, filter.getClass(), new ImmediateInstanceFactory<Filter>(filter)); deploymentInfo.addFilter(f); deployment.getFilters().addFilter(f); return new FilterRegistrationImpl(f, deployment); }
@Override public FilterRegistration.Dynamic addFilter(final String filterName, final String className) { ensureNotProgramaticListener(); ensureNotInitialized(); if (deploymentInfo.getFilters().containsKey(filterName)) { return null; } try { FilterInfo filter = new FilterInfo( filterName, (Class<? extends Filter>) deploymentInfo.getClassLoader().loadClass(className)); deploymentInfo.addFilter(filter); deployment.getFilters().addFilter(filter); return new FilterRegistrationImpl(filter, deployment); } catch (ClassNotFoundException e) { throw UndertowServletMessages.MESSAGES.cannotLoadClass(className, e); } }
/** * Sets up the handlers in the servlet chain. We setup a chain for every path + extension match * possibility. (i.e. if there a m path mappings and n extension mappings we have n*m chains). * * <p>If a chain consists of only the default servlet then we add it as an async handler, so that * resources can be served up directly without using blocking operations. * * <p>TODO: this logic is a bit convoluted at the moment, we should look at simplifying it * * @param servletContext * @param threadSetupAction * @param listeners */ private ServletPathMatches setupServletChains( final ServletContextImpl servletContext, final CompositeThreadSetupAction threadSetupAction, final ApplicationListeners listeners) { final List<Lifecycle> lifecycles = new ArrayList<Lifecycle>(); // create the default servlet ServletChain defaultHandler = null; ServletHandler defaultServlet = null; final Map<String, ManagedFilter> managedFilterMap = new LinkedHashMap<String, ManagedFilter>(); final Map<String, ServletHandler> allServlets = new HashMap<String, ServletHandler>(); final Map<String, ServletHandler> extensionServlets = new HashMap<String, ServletHandler>(); final Map<String, ServletHandler> pathServlets = new HashMap<String, ServletHandler>(); final Set<String> pathMatches = new HashSet<String>(); final Set<String> extensionMatches = new HashSet<String>(); DeploymentInfo deploymentInfo = deployment.getDeploymentInfo(); for (Map.Entry<String, FilterInfo> entry : deploymentInfo.getFilters().entrySet()) { final ManagedFilter mf = new ManagedFilter(entry.getValue(), servletContext); managedFilterMap.put(entry.getValue().getName(), mf); lifecycles.add(mf); } for (FilterMappingInfo mapping : deploymentInfo.getFilterMappings()) { if (mapping.getMappingType() == FilterMappingInfo.MappingType.URL) { String path = mapping.getMapping(); if (!path.startsWith("*.")) { pathMatches.add(path); } else { extensionMatches.add(path.substring(2)); } } } for (Map.Entry<String, ServletInfo> entry : deploymentInfo.getServlets().entrySet()) { ServletInfo servlet = entry.getValue(); final ManagedServlet managedServlet = new ManagedServlet(servlet, servletContext); lifecycles.add(managedServlet); final ServletHandler handler = new ServletHandler(managedServlet); allServlets.put(entry.getKey(), handler); for (String path : entry.getValue().getMappings()) { if (path.equals("/")) { // the default servlet pathMatches.add("/*"); if (pathServlets.containsKey("/*")) { throw UndertowServletMessages.MESSAGES.twoServletsWithSameMapping(path); } defaultServlet = handler; defaultHandler = servletChain(handler, managedServlet); } else if (!path.startsWith("*.")) { pathMatches.add(path); if (pathServlets.containsKey(path)) { throw UndertowServletMessages.MESSAGES.twoServletsWithSameMapping(path); } pathServlets.put(path, handler); } else { String ext = path.substring(2); extensionMatches.add(ext); extensionServlets.put(ext, handler); } } } if (defaultServlet == null) { final DefaultServletConfig config = deploymentInfo.getDefaultServletConfig() == null ? new DefaultServletConfig() : deploymentInfo.getDefaultServletConfig(); DefaultServlet defaultInstance = new DefaultServlet(deployment, config, deploymentInfo.getWelcomePages()); final ManagedServlet managedDefaultServlet = new ManagedServlet( new ServletInfo( "io.undertow.DefaultServlet", DefaultServlet.class, new ImmediateInstanceFactory<Servlet>(defaultInstance)), servletContext); lifecycles.add(managedDefaultServlet); pathMatches.add("/*"); defaultServlet = new ServletHandler(managedDefaultServlet); defaultHandler = new ServletChain(defaultServlet, managedDefaultServlet); } final ServletPathMatches.Builder builder = ServletPathMatches.builder(); for (final String path : pathMatches) { ServletHandler targetServlet = resolveServletForPath(path, pathServlets); final Map<DispatcherType, List<ManagedFilter>> noExtension = new HashMap<DispatcherType, List<ManagedFilter>>(); final Map<String, Map<DispatcherType, List<ManagedFilter>>> extension = new HashMap<String, Map<DispatcherType, List<ManagedFilter>>>(); for (String ext : extensionMatches) { extension.put(ext, new HashMap<DispatcherType, List<ManagedFilter>>()); } for (final FilterMappingInfo filterMapping : deploymentInfo.getFilterMappings()) { ManagedFilter filter = managedFilterMap.get(filterMapping.getFilterName()); if (filterMapping.getMappingType() == FilterMappingInfo.MappingType.SERVLET) { if (targetServlet != null) { if (filterMapping .getMapping() .equals(targetServlet.getManagedServlet().getServletInfo().getName())) { addToListMap(noExtension, filterMapping.getDispatcher(), filter); for (Map<DispatcherType, List<ManagedFilter>> l : extension.values()) { addToListMap(l, filterMapping.getDispatcher(), filter); } } } } else { if (filterMapping.getMapping().isEmpty() || !filterMapping.getMapping().startsWith("*.")) { if (isFilterApplicable(path, filterMapping.getMapping())) { addToListMap(noExtension, filterMapping.getDispatcher(), filter); for (Map<DispatcherType, List<ManagedFilter>> l : extension.values()) { addToListMap(l, filterMapping.getDispatcher(), filter); } } } else { addToListMap( extension.get(filterMapping.getMapping().substring(2)), filterMapping.getDispatcher(), filter); } } } final ServletChain initialHandler; if (noExtension.isEmpty()) { if (targetServlet != null) { initialHandler = servletChain(targetServlet, targetServlet.getManagedServlet()); } else { initialHandler = defaultHandler; } } else { FilterHandler handler; if (targetServlet != null) { handler = new FilterHandler(noExtension, targetServlet); } else { handler = new FilterHandler(noExtension, defaultServlet); } initialHandler = servletChain( handler, targetServlet == null ? defaultServlet.getManagedServlet() : targetServlet.getManagedServlet()); } if (path.endsWith("/*")) { String prefix = path.substring(0, path.length() - 2); builder.addPrefixMatch(prefix, initialHandler); for (Map.Entry<String, Map<DispatcherType, List<ManagedFilter>>> entry : extension.entrySet()) { ServletHandler pathServlet = targetServlet; if (pathServlet == null) { pathServlet = extensionServlets.get(entry.getKey()); } if (pathServlet == null) { pathServlet = defaultServlet; } HttpHandler handler = pathServlet; if (!entry.getValue().isEmpty()) { handler = new FilterHandler(entry.getValue(), handler); } builder.addExtensionMatch( prefix, entry.getKey(), servletChain(handler, pathServlet.getManagedServlet())); } } else if (path.isEmpty()) { builder.addExactMatch("/", initialHandler); } else { builder.addExactMatch(path, initialHandler); } } // now setup name based mappings // these are used for name based dispatch for (Map.Entry<String, ServletHandler> entry : allServlets.entrySet()) { final Map<DispatcherType, List<ManagedFilter>> filters = new HashMap<DispatcherType, List<ManagedFilter>>(); for (final FilterMappingInfo filterMapping : deploymentInfo.getFilterMappings()) { ManagedFilter filter = managedFilterMap.get(filterMapping.getFilterName()); if (filterMapping.getMappingType() == FilterMappingInfo.MappingType.SERVLET) { if (filterMapping.getMapping().equals(entry.getKey())) { addToListMap(filters, filterMapping.getDispatcher(), filter); } } } if (filters.isEmpty()) { builder.addNameMatch( entry.getKey(), servletChain(entry.getValue(), entry.getValue().getManagedServlet())); } else { builder.addNameMatch( entry.getKey(), servletChain( new FilterHandler(filters, entry.getValue()), entry.getValue().getManagedServlet())); } } builder.setDefaultServlet(defaultHandler); deployment.addLifecycleObjects(lifecycles); return builder.build(); }