/** * Unregister wrapper. */ private void unregisterWrapper(Wrapper wrapper) { Context context = (Context) wrapper.getParent(); String contextPath = context.getPath(); String wrapperName = wrapper.getName(); if ("/".equals(contextPath)) { contextPath = ""; } String version = context.getWebappVersion(); String hostName = context.getParent().getName(); String[] mappings = wrapper.findMappings(); for (String mapping : mappings) { mapper.removeWrapper(hostName, contextPath, version, mapping); } if(log.isDebugEnabled()) { log.debug(sm.getString("mapperListener.unregisterWrapper", wrapperName, contextPath, connector)); } }
/** * Select the appropriate child Wrapper to process this request, * based on the specified request URI. If no matching Wrapper can * be found, return an appropriate HTTP error. * * @param request Request to be processed * @param response Response to be produced * * @exception IOException if an input/output error occurred * @exception ServletException if a servlet error occurred */ @Override public final void invoke(Request request, Response response) throws IOException, ServletException { // Disallow any direct access to resources under WEB-INF or META-INF MessageBytes requestPathMB = request.getRequestPathMB(); if ((requestPathMB.startsWithIgnoreCase("/META-INF/", 0)) || (requestPathMB.equalsIgnoreCase("/META-INF")) || (requestPathMB.startsWithIgnoreCase("/WEB-INF/", 0)) || (requestPathMB.equalsIgnoreCase("/WEB-INF"))) { response.sendError(HttpServletResponse.SC_NOT_FOUND); return; } // Select the Wrapper to be used for this Request Wrapper wrapper = request.getWrapper(); if (wrapper == null || wrapper.isUnavailable()) { response.sendError(HttpServletResponse.SC_NOT_FOUND); return; } // Acknowledge the request try { response.sendAcknowledgement(); } catch (IOException ioe) { container.getLogger().error(sm.getString( "standardContextValve.acknowledgeException"), ioe); request.setAttribute(RequestDispatcher.ERROR_EXCEPTION, ioe); response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); return; } if (request.isAsyncSupported()) { request.setAsyncSupported(wrapper.getPipeline().isAsyncSupported()); } wrapper.getPipeline().getFirst().invoke(request, response); }
private void doTestDispatchWithSpaces(boolean async) throws Exception { Tomcat tomcat = getTomcatInstance(); Context context = tomcat.addContext("", null); if (async) { Servlet s = new AsyncDispatchUrlWithSpacesServlet(); Wrapper w = Tomcat.addServlet(context, "space", s); w.setAsyncSupported(true); } else { Tomcat.addServlet(context, "space", new ForwardDispatchUrlWithSpacesServlet()); } context.addServletMapping("/space/*", "space"); tomcat.start(); ByteChunk responseBody = new ByteChunk(); int rc = getUrl("http://localhost:" + getPort() + "/sp%61ce/foo%20bar", responseBody, null); Assert.assertEquals(200, rc); }
/** * Add a child Container, only if the proposed child is an implementation * of Wrapper. * * @param child Child container to be added * * @exception IllegalArgumentException if the proposed container is * not an implementation of Wrapper */ public void addChild(Container child) { if (!(child instanceof Wrapper)) throw new IllegalArgumentException (sm.getString("standardContext.notWrapper")); Wrapper wrapper = (Wrapper) child; String jspFile = wrapper.getJspFile(); if ((jspFile != null) && !jspFile.startsWith("/")) { if (isServlet22()) { log(sm.getString("standardContext.wrapper.warning", jspFile)); wrapper.setJspFile("/" + jspFile); } else { throw new IllegalArgumentException (sm.getString("standardContext.wrapper.error", jspFile)); } } super.addChild(child); }
/** * Return a <code>RequestDispatcher</code> object that acts as a * wrapper for the named servlet. * * @param name Name of the servlet for which a dispatcher is requested */ public RequestDispatcher getNamedDispatcher(String name) { // Validate the name argument if (name == null) return (null); // Create and return a corresponding request dispatcher Wrapper wrapper = (Wrapper) context.findChild(name); if (wrapper == null) return (null); ApplicationDispatcher dispatcher = new ApplicationDispatcher(wrapper, null, null, null, name); return ((RequestDispatcher) dispatcher); }
/** * Construct a new instance of this class, configured according to the * specified parameters. If both servletPath and pathInfo are * <code>null</code>, it will be assumed that this RequestDispatcher * was acquired by name, rather than by path. * * @param wrapper The Wrapper associated with the resource that will * be forwarded to or included (required) * @param requestURI The request URI to this resource (if any) * @param servletPath The revised servlet path to this resource (if any) * @param pathInfo The revised extra path information to this resource * (if any) * @param queryString Query string parameters included with this request * (if any) * @param name Servlet name (if a named dispatcher was created) * else <code>null</code> */ public ApplicationDispatcher (Wrapper wrapper, String requestURI, String servletPath, String pathInfo, String queryString, String name) { super(); // Save all of our configuration parameters this.wrapper = wrapper; this.context = (Context) wrapper.getParent(); this.requestURI = requestURI; this.servletPath = servletPath; this.pathInfo = pathInfo; this.queryString = queryString; this.name = name; if (wrapper instanceof StandardWrapper) this.support = ((StandardWrapper) wrapper).getInstanceSupport(); else this.support = new InstanceSupport(wrapper); }
/** * Remove any servlet mapping for the specified pattern, if it exists; * otherwise, no action is taken. * * @param pattern URL pattern of the mapping to remove */ @Override public void removeServletMapping(String pattern) { String name = null; synchronized (servletMappingsLock) { name = servletMappings.remove(pattern); } Wrapper wrapper = (Wrapper) findChild(name); if( wrapper != null ) { wrapper.removeMapping(pattern); } mapper.removeWrapper(pattern); fireContainerEvent("removeServletMapping", pattern); }
@Test public void testAsyncRequestURI() throws Exception { // Setup Tomcat instance Tomcat tomcat = getTomcatInstance(); // No file system docBase required Context ctx = tomcat.addContext("", null); Servlet servlet = new AsyncRequestUriServlet(); Wrapper wrapper1 = Tomcat.addServlet(ctx, "bug57559", servlet); wrapper1.setAsyncSupported(true); ctx.addServletMapping("/", "bug57559"); tomcat.start(); String uri = "/foo/%24/bar"; ByteChunk body = getUrl("http://localhost:" + getPort()+ uri); Assert.assertEquals(uri, body.toString()); }
private DefaultInstanceManager doClassUnloadingPrep() throws Exception { Tomcat tomcat = getTomcatInstance(); // Create the context (don't use addWebapp as we want to modify the // JSP Servlet settings). File appDir = new File("test/webapp-3.0"); StandardContext ctxt = (StandardContext) tomcat.addContext( null, "/test", appDir.getAbsolutePath()); // Configure the defaults and then tweak the JSP servlet settings // Note: Min value for maxLoadedJsps is 2 Tomcat.initWebappDefaults(ctxt); Wrapper w = (Wrapper) ctxt.findChild("jsp"); w.addInitParameter("maxLoadedJsps", "2"); tomcat.start(); return (DefaultInstanceManager) ctxt.getInstanceManager(); }
/** * Remove any servlet mapping for the specified pattern, if it exists; * otherwise, no action is taken. * * @param pattern * URL pattern of the mapping to remove */ @Override public void removeServletMapping(String pattern) { String name = null; synchronized (servletMappingsLock) { name = servletMappings.remove(pattern); } Wrapper wrapper = (Wrapper) findChild(name); if (wrapper != null) { wrapper.removeMapping(pattern); } mapper.removeWrapper(pattern); fireContainerEvent("removeServletMapping", pattern); }
@Test public void testCommitOnComplete() throws Exception { // Setup Tomcat instance Tomcat tomcat = getTomcatInstance(); // No file system docBase required Context ctx = tomcat.addContext("", null); AsyncStatusServlet asyncStatusServlet = new AsyncStatusServlet(HttpServletResponse.SC_BAD_REQUEST); Wrapper wrapper = Tomcat.addServlet(ctx, "asyncStatusServlet", asyncStatusServlet); wrapper.setAsyncSupported(true); ctx.addServletMapping("/asyncStatusServlet", "asyncStatusServlet"); TesterAccessLogValve alv = new TesterAccessLogValve(); ctx.getPipeline().addValve(alv); tomcat.start(); StringBuilder url = new StringBuilder(48); url.append("http://localhost:"); url.append(getPort()); url.append("/asyncStatusServlet"); int rc = getUrl(url.toString(), new ByteChunk(), null); assertEquals(HttpServletResponse.SC_BAD_REQUEST, rc); // Without this test may complete before access log has a chance to log // the request Thread.sleep(REQUEST_TIME); // Check the access log alv.validateAccessLog(1, HttpServletResponse.SC_BAD_REQUEST, 0, REQUEST_TIME); }
private void prepareApplicationWithGenericServlet(String contextPath) throws Exception { // Setup Tomcat instance Tomcat tomcat = getTomcatInstance(); // No file system docBase required Context ctx = tomcat.addContext(contextPath, null); DispatchingGenericServlet dispatch = new DispatchingGenericServlet(); Wrapper wrapper = Tomcat.addServlet(ctx, "dispatch", dispatch); wrapper.setAsyncSupported(true); ctx.addServletMapping("/dispatch", "dispatch"); CustomGenericServlet customGeneric = new CustomGenericServlet(); Wrapper wrapper2 = Tomcat.addServlet(ctx, "customGeneric", customGeneric); wrapper2.setAsyncSupported(true); ctx.addServletMapping("/target", "customGeneric"); tomcat.start(); }
/** * Add a Servlet using properties with the index * * @param properties * the properties than contain all servlet & configurators info * @param rootCtx * the tomcat root context */ public void addAceqlServlet(Properties properties, Context rootCtx) { if (properties == null) { throw new IllegalArgumentException("properties can not be null"); } String aceQLManagerServletCallName = TomcatStarterUtil.getAceQLManagerSevletName(properties); // Add the ServerSqlManager servlet to the context @SuppressWarnings("unused") Wrapper wrapper = Tomcat.addServlet(rootCtx, aceQLManagerServletCallName, new ServerSqlManager()); rootCtx.addServletMappingDecoded("/*", aceQLManagerServletCallName); TomcatStarterUtil.setInitParametersInStore(properties); // Unecessary because we must start at / because of ou Rest API // String serverSqlManagerUrlPattern = serverSqlManagerServletName; // if (!serverSqlManagerUrlPattern.startsWith("/")) { // serverSqlManagerUrlPattern = "/" + serverSqlManagerUrlPattern; // } }
@Test public void testBug56042() throws Exception { // Setup Tomcat instance Tomcat tomcat = getTomcatInstance(); // No file system docBase required Context ctx = tomcat.addContext("", null); Bug56042Servlet bug56042Servlet = new Bug56042Servlet(); Wrapper wrapper = Tomcat.addServlet(ctx, "bug56042Servlet", bug56042Servlet); wrapper.setAsyncSupported(true); ctx.addServletMapping("/bug56042Servlet", "bug56042Servlet"); tomcat.start(); StringBuilder url = new StringBuilder(48); url.append("http://localhost:"); url.append(getPort()); url.append("/bug56042Servlet"); ByteChunk res = new ByteChunk(); int rc = getUrl(url.toString(), res, null); Assert.assertEquals(HttpServletResponse.SC_BAD_REQUEST, rc); }
/** * Register wrapper. */ private void registerWrapper(Wrapper wrapper) { Context context = (Context) wrapper.getParent(); String contextPath = context.getPath(); if ("/".equals(contextPath)) { contextPath = ""; } String version = context.getWebappVersion(); String hostName = context.getParent().getName(); List<WrapperMappingInfo> wrappers = new ArrayList<WrapperMappingInfo>(); prepareWrapperMappingInfo(context, wrapper, wrappers); mapper.addWrappers(hostName, contextPath, version, wrappers); if (log.isDebugEnabled()) { log.debug(sm.getString("mapperListener.registerWrapper", wrapper.getName(), contextPath, connector)); } }
/** * Static version of {@link #addServlet(String, String, String)} * @param ctx Context to add Servlet to * @param servletName Servlet name (used in mappings) * @param servletClass The class to be used for the Servlet * @return The wrapper for the servlet */ public static Wrapper addServlet(Context ctx, String servletName, String servletClass) { // will do class for name and set init params Wrapper sw = ctx.createWrapper(); sw.setServletClass(servletClass); sw.setName(servletName); ctx.addChild(sw); return sw; }
/** * Static version of {@link #initWebappDefaults(String)} * @param ctx The context to set the defaults for */ public static void initWebappDefaults(Context ctx) { // Default servlet Wrapper servlet = addServlet( ctx, "default", "org.apache.catalina.servlets.DefaultServlet"); servlet.setLoadOnStartup(1); servlet.setOverridable(true); // JSP servlet (by class name - to avoid loading all deps) servlet = addServlet( ctx, "jsp", "org.apache.jasper.servlet.JspServlet"); servlet.addInitParameter("fork", "false"); servlet.setLoadOnStartup(3); servlet.setOverridable(true); // Servlet mappings ctx.addServletMapping("/", "default"); ctx.addServletMapping("*.jsp", "jsp"); ctx.addServletMapping("*.jspx", "jsp"); // Sessions ctx.setSessionTimeout(30); // MIME mappings for (int i = 0; i < DEFAULT_MIME_MAPPINGS.length;) { ctx.addMimeMapping(DEFAULT_MIME_MAPPINGS[i++], DEFAULT_MIME_MAPPINGS[i++]); } // Welcome files ctx.addWelcomeFile("index.html"); ctx.addWelcomeFile("index.htm"); ctx.addWelcomeFile("index.jsp"); }
/** * Validate the usage of security role names in the web application * deployment descriptor. If any problems are found, issue warning * messages (for backwards compatibility) and add the missing roles. * (To make these problems fatal instead, simply set the <code>ok</code> * instance variable to <code>false</code> as well). */ protected void validateSecurityRoles() { // Check role names used in <security-constraint> elements SecurityConstraint constraints[] = context.findConstraints(); for (int i = 0; i < constraints.length; i++) { String roles[] = constraints[i].findAuthRoles(); for (int j = 0; j < roles.length; j++) { if (!"*".equals(roles[j]) && !context.findSecurityRole(roles[j])) { log.warn(sm.getString("contextConfig.role.auth", roles[j])); context.addSecurityRole(roles[j]); } } } // Check role names used in <servlet> elements Container wrappers[] = context.findChildren(); for (int i = 0; i < wrappers.length; i++) { Wrapper wrapper = (Wrapper) wrappers[i]; String runAs = wrapper.getRunAs(); if ((runAs != null) && !context.findSecurityRole(runAs)) { log.warn(sm.getString("contextConfig.role.runas", runAs)); context.addSecurityRole(runAs); } String names[] = wrapper.findSecurityReferences(); for (int j = 0; j < names.length; j++) { String link = wrapper.findSecurityReference(names[j]); if ((link != null) && !context.findSecurityRole(link)) { log.warn(sm.getString("contextConfig.role.link", link)); context.addSecurityRole(link); } } } }
/** * hook to register that we need to scan for security annotations. * * @param wrapper * The wrapper for the Servlet that was added */ public ServletRegistration.Dynamic dynamicServletAdded(Wrapper wrapper) { Servlet s = wrapper.getServlet(); if (s != null && createdServlets.contains(s)) { // Mark the wrapper to indicate annotations need to be scanned wrapper.setServletSecurityAnnotationScanRequired(true); } return new ApplicationServletRegistration(wrapper, this); }
/** * Set the error flag. */ public boolean setError() { boolean result = errorState.compareAndSet(0, 1); if (result) { Wrapper wrapper = getRequest().getWrapper(); if (wrapper != null) { wrapper.incrementErrorCount(); } } return result; }
/** * Register context. */ private void registerContext(Context context) { String contextPath = context.getPath(); if ("/".equals(contextPath)) { contextPath = ""; } Container host = context.getParent(); javax.naming.Context resources = context.getResources(); String[] welcomeFiles = context.findWelcomeFiles(); List<WrapperMappingInfo> wrappers = new ArrayList<WrapperMappingInfo>(); for (Container container : context.findChildren()) { prepareWrapperMappingInfo(context, (Wrapper) container, wrappers); if(log.isDebugEnabled()) { log.debug(sm.getString("mapperListener.registerWrapper", container.getName(), contextPath, connector)); } } mapper.addContextVersion(host.getName(), host, contextPath, context.getWebappVersion(), context, welcomeFiles, resources, wrappers, context.getMapperContextRootRedirectEnabled(),//default false context.getMapperDirectoryRedirectEnabled());//default false if(log.isDebugEnabled()) { log.debug(sm.getString("mapperListener.registerContext", contextPath, connector)); } }
/** * hook to register that we need to scan for security annotations. * @param wrapper The wrapper for the Servlet that was added */ public ServletRegistration.Dynamic dynamicServletAdded(Wrapper wrapper) { Servlet s = wrapper.getServlet(); if (s != null && createdServlets.contains(s)) { // Mark the wrapper to indicate annotations need to be scanned wrapper.setServletSecurityAnnotationScanRequired(true); } return new ApplicationServletRegistration(wrapper, this); }
/** * Return <code>true</code> if the specified Principal has the specified * security role, within the context of this Realm; otherwise return * <code>false</code>. This method can be overridden by Realm * implementations, but the default is adequate when an instance of * <code>GenericPrincipal</code> is used to represent authenticated * Principals from this Realm. * * @param principal Principal for whom the role is to be checked * @param role Security role to be checked */ @Override public boolean hasRole(Wrapper wrapper, Principal principal, String role) { // Check for a role alias defined in a <security-role-ref> element if (wrapper != null) { String realRole = wrapper.findSecurityReference(role); if (realRole != null) role = realRole; } // Should be overridden in JAASRealm - to avoid pretty inefficient conversions if ((principal == null) || (role == null) || !(principal instanceof GenericPrincipal)) return (false); GenericPrincipal gp = (GenericPrincipal) principal; boolean result = gp.hasRole(role); if (log.isDebugEnabled()) { String name = principal.getName(); if (result) log.debug(sm.getString("realmBase.hasRoleSuccess", name, role)); else log.debug(sm.getString("realmBase.hasRoleFailure", name, role)); } return (result); }
@Test public void testBug49567() throws Exception { // Setup Tomcat instance Tomcat tomcat = getTomcatInstance(); // No file system docBase required Context ctx = tomcat.addContext("", null); Bug49567Servlet servlet = new Bug49567Servlet(); Wrapper wrapper = Tomcat.addServlet(ctx, "servlet", servlet); wrapper.setAsyncSupported(true); ctx.addServletMapping("/", "servlet"); TesterAccessLogValve alv = new TesterAccessLogValve(); ctx.getPipeline().addValve(alv); tomcat.start(); // Call the servlet once ByteChunk bc = getUrl("http://localhost:" + getPort() + "/"); assertEquals("OK", bc.toString()); // Give the async thread a chance to finish (but not too long) int counter = 0; while (!servlet.isDone() && counter < 10) { Thread.sleep(1000); counter++; } assertEquals("1false2true3true4true5false", servlet.getResult()); // Check the access log alv.validateAccessLog(1, 200, Bug49567Servlet.THREAD_SLEEP_TIME, Bug49567Servlet.THREAD_SLEEP_TIME + REQUEST_TIME); }
@Override public Map<String, ? extends ServletRegistration> getServletRegistrations() { Map<String, ApplicationServletRegistration> result = new HashMap<String, ApplicationServletRegistration>(); Container[] wrappers = context.findChildren(); for (Container wrapper : wrappers) { result.put(((Wrapper) wrapper).getName(), new ApplicationServletRegistration( (Wrapper) wrapper, context)); } return result; }
private ServletRegistration.Dynamic addServlet(String servletName, String servletClass, Servlet servlet) throws IllegalStateException { if (servletName == null || servletName.equals("")) { throw new IllegalArgumentException(sm.getString("applicationContext.invalidServletName", servletName)); } if (!context.getState().equals(LifecycleState.STARTING_PREP)) { // TODO Spec breaking enhancement to ignore this restriction throw new IllegalStateException(sm.getString("applicationContext.addServlet.ise", getContextPath())); } Wrapper wrapper = (Wrapper) context.findChild(servletName); // Assume a 'complete' ServletRegistration is one that has a class and // a name if (wrapper == null) { wrapper = context.createWrapper(); wrapper.setName(servletName); context.addChild(wrapper); } else { if (wrapper.getName() != null && wrapper.getServletClass() != null) { if (wrapper.isOverridable()) { wrapper.setOverridable(false); } else { return null; } } } if (servlet == null) { wrapper.setServletClass(servletClass); } else { wrapper.setServletClass(servlet.getClass().getName()); wrapper.setServlet(servlet); } return context.dynamicServletAdded(wrapper); }
@Test public void testStop() throws Exception { Tomcat tomcat = getTomcatInstance(); // No file system docBase required Context root = tomcat.addContext("", null); Wrapper w = Tomcat.addServlet(root, "tester", new TesterServlet()); w.setAsyncSupported(true); root.addServletMapping("/", "tester"); Connector connector = tomcat.getConnector(); tomcat.start(); ByteChunk bc = new ByteChunk(); int rc = getUrl("http://localhost:" + getPort() + "/", bc, null, null); assertEquals(200, rc); assertEquals("OK", bc.toString()); rc = -1; bc.recycle(); connector.stop(); try { rc = getUrl("http://localhost:" + getPort() + "/", bc, 1000, null, null); } catch (SocketTimeoutException ste) { // May also see this with NIO // Make sure the test passes if we do rc = 503; } assertEquals(503, rc); }
private synchronized void init(boolean limited, boolean swallow) throws Exception { if (init) return; Tomcat tomcat = getTomcatInstance(); context = tomcat.addContext("", TEMP_DIR); Wrapper w; w = Tomcat.addServlet(context, servletName, new AbortedUploadServlet()); // Tomcat.addServlet does not respect annotations, so we have // to set our own MultipartConfigElement. // Choose upload file size limit. if (limited) { w.setMultipartConfigElement(new MultipartConfigElement("", limitSize, -1, -1)); } else { w.setMultipartConfigElement(new MultipartConfigElement("")); } context.addServletMapping(URI, servletName); context.setSwallowAbortedUploads(swallow); tomcat.start(); setPort(tomcat.getConnector().getLocalPort()); init = true; }
@Test public void testBug49528() throws Exception { // Setup Tomcat instance Tomcat tomcat = getTomcatInstance(); // No file system docBase required Context ctx = tomcat.addContext("", null); Bug49528Servlet servlet = new Bug49528Servlet(); Wrapper wrapper = Tomcat.addServlet(ctx, "servlet", servlet); wrapper.setAsyncSupported(true); ctx.addServletMapping("/", "servlet"); TesterAccessLogValve alv = new TesterAccessLogValve(); ctx.getPipeline().addValve(alv); tomcat.start(); // Call the servlet once ByteChunk bc = getUrl("http://localhost:" + getPort() + "/"); assertEquals("OK", bc.toString()); // Give the async thread a chance to finish (but not too long) int counter = 0; while (!servlet.isDone() && counter < 10) { Thread.sleep(1000); counter++; } assertEquals("1false2true3true4true5false", servlet.getResult()); // Check the access log alv.validateAccessLog(1, 200, Bug49528Servlet.THREAD_SLEEP_TIME, Bug49528Servlet.THREAD_SLEEP_TIME + REQUEST_TIME); }
@Test public void testBug50352() throws Exception { resetTracker(); // Setup Tomcat instance Tomcat tomcat = getTomcatInstance(); // No file system docBase required Context ctx = tomcat.addContext("", null); AsyncStartRunnable servlet = new AsyncStartRunnable(); Wrapper wrapper = Tomcat.addServlet(ctx, "servlet", servlet); wrapper.setAsyncSupported(true); ctx.addServletMapping("/", "servlet"); TesterAccessLogValve alv = new TesterAccessLogValve(); ctx.getPipeline().addValve(alv); tomcat.start(); getUrl("http://localhost:" + getPort() + "/"); // Request may complete before listener has finished processing so wait // up to 5 seconds for the right response String expectedTrack = "Runnable-onComplete-"; int count = 0; while (!expectedTrack.equals(getTrack()) && count < 100) { Thread.sleep(50); count ++; } assertEquals(expectedTrack, getTrack()); // Check the access log alv.validateAccessLog(1, 200, AsyncStartRunnable.THREAD_SLEEP_TIME, AsyncStartRunnable.THREAD_SLEEP_TIME + REQUEST_TIME); }
@Test public void testBug53337() throws Exception { // Setup Tomcat instance Tomcat tomcat = getTomcatInstance(); // No file system docBase required Context ctx = tomcat.addContext("", null); Wrapper a = Tomcat.addServlet(ctx, "ServletA", new Bug53337ServletA()); a.setAsyncSupported(true); Wrapper b = Tomcat.addServlet(ctx, "ServletB", new Bug53337ServletB()); b.setAsyncSupported(true); Tomcat.addServlet(ctx, "ServletC", new Bug53337ServletC()); ctx.addServletMapping("/ServletA", "ServletA"); ctx.addServletMapping("/ServletB", "ServletB"); ctx.addServletMapping("/ServletC", "ServletC"); tomcat.start(); StringBuilder url = new StringBuilder(48); url.append("http://localhost:"); url.append(getPort()); url.append("/ServletA"); ByteChunk body = new ByteChunk(); int rc = getUrl(url.toString(), body, null); assertEquals(HttpServletResponse.SC_OK, rc); assertEquals("OK", body.toString()); }
@Test public void testBug53843() throws Exception { // Setup Tomcat instance Tomcat tomcat = getTomcatInstance(); // No file system docBase required Context ctx = tomcat.addContext("", null); Bug53843ServletA servletA = new Bug53843ServletA(); Wrapper a = Tomcat.addServlet(ctx, "ServletA", servletA); a.setAsyncSupported(true); Tomcat.addServlet(ctx, "ServletB", new Bug53843ServletB()); ctx.addServletMapping("/ServletA", "ServletA"); ctx.addServletMapping("/ServletB", "ServletB"); tomcat.start(); StringBuilder url = new StringBuilder(48); url.append("http://localhost:"); url.append(getPort()); url.append("/ServletA"); ByteChunk body = new ByteChunk(); int rc = getUrl(url.toString(), body, null); assertEquals(HttpServletResponse.SC_OK, rc); assertEquals("OK", body.toString()); assertTrue(servletA.isAsyncWhenExpected()); }
/** * Populate <code>wrappers</code> list with information for registration of * mappings for this wrapper in this context. * * @param context * @param wrapper * @param list */ private void prepareWrapperMappingInfo(Context context, Wrapper wrapper, List<WrapperMappingInfo> wrappers) { String wrapperName = wrapper.getName(); boolean resourceOnly = context.isResourceOnlyServlet(wrapperName); String[] mappings = wrapper.findMappings(); for (String mapping : mappings) { boolean jspWildCard = (wrapperName.equals("jsp") && mapping.endsWith("/*")); wrappers.add(new WrapperMappingInfo(mapping, wrapper, jspWildCard, resourceOnly)); } }
@Override public Map<String, ? extends ServletRegistration> getServletRegistrations() { Map<String, ApplicationServletRegistration> result = new HashMap<String, ApplicationServletRegistration>(); Container[] wrappers = context.findChildren(); for (Container wrapper : wrappers) { result.put(((Wrapper) wrapper).getName(), new ApplicationServletRegistration((Wrapper) wrapper, context)); } return result; }
/** * Calculate the key properties string to be added to an object's * {@link ObjectName} to indicate that it is associated with that container. * * @param container The container the object is associated with * @return A string suitable for appending to the ObjectName * @deprecated To be removed since to creates a circular dependency. Will * be replaced in Tomcat 8 by a new method on {@link * Container}. */ @Deprecated public static String getContainerKeyProperties(Container container) { Container c = container; StringBuilder keyProperties = new StringBuilder(); int containerCount = 0; // Work up container hierarchy, add a component to the name for // each container while (!(c instanceof Engine)) { if (c instanceof Wrapper) { keyProperties.append(",servlet="); keyProperties.append(c.getName()); } else if (c instanceof Context) { keyProperties.append(",context="); ContextName cn = new ContextName(c.getName(), false); keyProperties.append(cn.getDisplayName()); } else if (c instanceof Host) { keyProperties.append(",host="); keyProperties.append(c.getName()); } else if (c == null) { // May happen in unit testing and/or some embedding scenarios keyProperties.append(",container"); keyProperties.append(containerCount++); keyProperties.append("=null"); break; } else { // Should never happen... keyProperties.append(",container"); keyProperties.append(containerCount++); keyProperties.append('='); keyProperties.append(c.getName()); } c = c.getParent(); } return keyProperties.toString(); }
/** * Register context. */ private void registerContext(Context context) { String contextPath = context.getPath(); if ("/".equals(contextPath)) { contextPath = ""; } Container host = context.getParent(); javax.naming.Context resources = context.getResources(); String[] welcomeFiles = context.findWelcomeFiles(); List<WrapperMappingInfo> wrappers = new ArrayList<WrapperMappingInfo>(); for (Container container : context.findChildren()) { prepareWrapperMappingInfo(context, (Wrapper) container, wrappers); if (log.isDebugEnabled()) { log.debug(sm.getString("mapperListener.registerWrapper", container.getName(), contextPath, connector)); } } mapper.addContextVersion(host.getName(), host, contextPath, context.getWebappVersion(), context, welcomeFiles, resources, wrappers, context.getMapperContextRootRedirectEnabled(), context.getMapperDirectoryRedirectEnabled()); if (log.isDebugEnabled()) { log.debug(sm.getString("mapperListener.registerContext", contextPath, connector)); } }