예제 #1
0
  /**
   * Return the URL to the resource that is mapped to a specified path. The path must begin with a
   * "/" and is interpreted as relative to the current context root.
   *
   * @param path The path to the desired resource
   * @exception MalformedURLException if the path is not given in the correct form
   */
  public URL getResource(String path) throws MalformedURLException {

    DirContext resources = context.getResources();
    if (resources != null) {
      String fullPath = context.getName() + path;

      // this is the problem. Host must not be null
      String hostName = context.getParent().getName();

      try {
        resources.lookup(path);
        if (System.getSecurityManager() != null) {
          try {
            PrivilegedGetResource dp = new PrivilegedGetResource(hostName, fullPath, resources);
            return (URL) AccessController.doPrivileged(dp);
          } catch (PrivilegedActionException pe) {
            throw pe.getException();
          }
        } else {
          return new URL(
              "jndi",
              null,
              0,
              getJNDIUri(hostName, fullPath),
              new DirContextURLStreamHandler(resources));
        }
      } catch (Exception e) {
        // e.printStackTrace();
      }
    }
    return (null);
  }
예제 #2
0
  @Test
  public void testFlagFailCtxIfServletStartFails() throws Exception {
    Tomcat tomcat = getTomcatInstance();
    File docBase = new File(System.getProperty("java.io.tmpdir"));
    StandardContext context = (StandardContext) tomcat.addContext("", docBase.getAbsolutePath());

    // first we test the flag itself, which can be set on the Host and
    // Context
    assertFalse(context.getComputedFailCtxIfServletStartFails());

    StandardHost host = (StandardHost) tomcat.getHost();
    host.setFailCtxIfServletStartFails(true);
    assertTrue(context.getComputedFailCtxIfServletStartFails());
    context.setFailCtxIfServletStartFails(Boolean.FALSE);
    assertFalse(
        "flag on Context should override Host config",
        context.getComputedFailCtxIfServletStartFails());

    // second, we test the actual effect of the flag on the startup
    Wrapper servlet = Tomcat.addServlet(context, "myservlet", new FailingStartupServlet());
    servlet.setLoadOnStartup(1);

    tomcat.start();
    assertTrue("flag false should not fail deployment", context.getState().isAvailable());

    tomcat.stop();
    assertFalse(context.getState().isAvailable());

    host.removeChild(context);
    context = (StandardContext) tomcat.addContext("", docBase.getAbsolutePath());
    servlet = Tomcat.addServlet(context, "myservlet", new FailingStartupServlet());
    servlet.setLoadOnStartup(1);
    tomcat.start();
    assertFalse("flag true should fail deployment", context.getState().isAvailable());
  }
예제 #3
0
  /**
   * Bind the specified value with the specified context attribute name, replacing any existing
   * value for that name.
   *
   * @param name Attribute name to be bound
   * @param value New attribute value to be bound
   */
  public void setAttribute(String name, Object value) {

    // Name cannot be null
    if (name == null)
      throw new IllegalArgumentException(sm.getString("applicationContext.setAttribute.namenull"));

    // Null value is the same as removeAttribute()
    if (value == null) {
      removeAttribute(name);
      return;
    }

    Object oldValue = null;
    boolean replaced = false;

    // Add or replace the specified attribute
    synchronized (attributes) {
      // Check for read only attribute
      if (readOnlyAttributes.containsKey(name)) return;
      oldValue = attributes.get(name);
      if (oldValue != null) replaced = true;
      attributes.put(name, value);
    }

    // Notify interested application event listeners
    Object listeners[] = context.getApplicationListeners();
    if ((listeners == null) || (listeners.length == 0)) return;
    ServletContextAttributeEvent event = null;
    if (replaced)
      event = new ServletContextAttributeEvent(context.getServletContext(), name, oldValue);
    else event = new ServletContextAttributeEvent(context.getServletContext(), name, value);

    for (int i = 0; i < listeners.length; i++) {
      if (!(listeners[i] instanceof ServletContextAttributeListener)) continue;
      ServletContextAttributeListener listener = (ServletContextAttributeListener) listeners[i];
      try {
        if (replaced) {
          context.fireContainerEvent("beforeContextAttributeReplaced", listener);
          listener.attributeReplaced(event);
          context.fireContainerEvent("afterContextAttributeReplaced", listener);
        } else {
          context.fireContainerEvent("beforeContextAttributeAdded", listener);
          listener.attributeAdded(event);
          context.fireContainerEvent("afterContextAttributeAdded", listener);
        }
      } catch (Throwable t) {
        if (replaced) context.fireContainerEvent("afterContextAttributeReplaced", listener);
        else context.fireContainerEvent("afterContextAttributeAdded", listener);
        // FIXME - should we do anything besides log these?
        log(sm.getString("applicationContext.attributeEvent"), t);
      }
    }
  }
예제 #4
0
  /**
   * Return a <code>RequestDispatcher</code> instance that acts as a wrapper for the resource at the
   * given path. The path must begin with a "/" and is interpreted as relative to the current
   * context root.
   *
   * @param path The path to the desired resource.
   */
  public RequestDispatcher getRequestDispatcher(String path) {

    // Validate the path argument
    if (path == null) return (null);
    if (!path.startsWith("/"))
      throw new IllegalArgumentException(
          sm.getString("applicationContext.requestDispatcher.iae", path));
    if (normalize(path) == null) return (null);

    // Construct a "fake" request to be mapped by our Context
    String contextPath = context.getPath();
    if (contextPath == null) contextPath = "";
    String relativeURI = path;
    String queryString = null;
    int question = path.indexOf('?');
    if (question >= 0) {
      relativeURI = path.substring(0, question);
      queryString = path.substring(question + 1);
    }
    if (System.getSecurityManager() != null) {
      PrivilegedGetRequestDispatcher dp =
          new PrivilegedGetRequestDispatcher(contextPath, relativeURI, queryString);
      return (RequestDispatcher) AccessController.doPrivileged(dp);
    }

    // The remaining code is duplicated in PrivilegedGetRequestDispatcher,
    // we need to make sure they stay in sync
    HttpRequest request =
        new MappingRequest(context.getPath(), contextPath + relativeURI, queryString);
    /*
    request.setContext(context);
    request.setContextPath(context.getPath());
    request.setRequestURI(contextPath + relativeURI);
    request.setQueryString(queryString);
    */
    Wrapper wrapper = (Wrapper) context.map(request, true);
    if (wrapper == null) return (null);

    // Construct a RequestDispatcher to process this request
    HttpServletRequest hrequest = (HttpServletRequest) request.getRequest();
    return (RequestDispatcher)
        new ApplicationDispatcher(
            wrapper,
            hrequest.getServletPath(),
            hrequest.getPathInfo(),
            hrequest.getQueryString(),
            null);
  }
예제 #5
0
  /**
   * Return the real path for a given virtual path, if possible; otherwise return <code>null</code>.
   *
   * @param path The path to the desired resource
   */
  public String getRealPath(String path) {

    if (!context.isFilesystemBased()) return null;

    File file = new File(basePath, path);
    return (file.getAbsolutePath());
  }
  /** Release the Filter instance associated with this FilterConfig, if there is one. */
  void release() {

    unregisterJMX();

    if (this.filter != null) {
      if (Globals.IS_SECURITY_ENABLED) {
        try {
          SecurityUtil.doAsPrivilege("destroy", filter);
        } catch (java.lang.Exception ex) {
          context.getLogger().error("ApplicationFilterConfig.doAsPrivilege", ex);
        }
        SecurityUtil.remove(filter);
      } else {
        filter.destroy();
      }
      if (!context.getIgnoreAnnotations()) {
        try {
          ((StandardContext) context).getInstanceManager().destroyInstance(this.filter);
        } catch (Exception e) {
          Throwable t = ExceptionUtils.unwrapInvocationTargetException(e);
          ExceptionUtils.handleThrowable(t);
          context.getLogger().error("ApplicationFilterConfig.preDestroy", t);
        }
      }
    }
    this.filter = null;
  }
예제 #7
0
  /**
   * Merge the context initialization parameters specified in the application deployment descriptor
   * with the application parameters described in the server configuration, respecting the <code>
   * override</code> property of the application parameters appropriately.
   */
  private void mergeParameters() {

    if (parameters != null) return;
    HashMap results = new HashMap();
    String names[] = context.findParameters();
    for (int i = 0; i < names.length; i++) results.put(names[i], context.findParameter(names[i]));
    ApplicationParameter params[] = context.findApplicationParameters();
    for (int i = 0; i < params.length; i++) {
      if (params[i].getOverride()) {
        if (results.get(params[i].getName()) == null)
          results.put(params[i].getName(), params[i].getValue());
      } else {
        results.put(params[i].getName(), params[i].getValue());
      }
    }
    parameters = results;
  }
예제 #8
0
  /**
   * Return the MIME type of the specified file, or <code>null</code> if the MIME type cannot be
   * determined.
   *
   * @param file Filename for which to identify a MIME type
   */
  public String getMimeType(String file) {

    if (file == null) return (null);
    int period = file.lastIndexOf(".");
    if (period < 0) return (null);
    String extension = file.substring(period + 1);
    if (extension.length() < 1) return (null);
    return (context.findMimeMapping(extension));
  }
  private void registerJMX() {
    String parentName = context.getName();
    if (!parentName.startsWith("/")) {
      parentName = "/" + parentName;
    }

    String hostName = context.getParent().getName();
    hostName = (hostName == null) ? "DEFAULT" : hostName;

    // domain == engine name
    String domain = context.getParent().getParent().getName();

    String webMod = "//" + hostName + parentName;
    String onameStr = null;
    String filterName = filterDef.getFilterName();
    if (Util.objectNameValueNeedsQuote(filterName)) {
      filterName = ObjectName.quote(filterName);
    }
    if (context instanceof StandardContext) {
      StandardContext standardContext = (StandardContext) context;
      onameStr =
          domain
              + ":j2eeType=Filter,WebModule="
              + webMod
              + ",name="
              + filterName
              + ",J2EEApplication="
              + standardContext.getJ2EEApplication()
              + ",J2EEServer="
              + standardContext.getJ2EEServer();
    } else {
      onameStr = domain + ":j2eeType=Filter,name=" + filterName + ",WebModule=" + webMod;
    }
    try {
      oname = new ObjectName(onameStr);
      Registry.getRegistry(null, null).registerComponent(this, oname, null);
    } catch (Exception ex) {
      log.info(
          sm.getString(
              "applicationFilterConfig.jmxRegisterFail", getFilterClass(), getFilterName()),
          ex);
    }
  }
예제 #10
0
  /**
   * 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);
  }
예제 #11
0
  /**
   * Return the requested resource as an <code>InputStream</code>. The path must be specified
   * according to the rules described under <code>getResource</code>. If no such resource can be
   * identified, return <code>null</code>.
   *
   * @param path The path to the desired resource.
   */
  public InputStream getResourceAsStream(String path) {

    DirContext resources = context.getResources();
    if (resources != null) {
      try {
        Object resource = resources.lookup(path);
        if (resource instanceof Resource) return (((Resource) resource).streamContent());
      } catch (Exception e) {
      }
    }
    return (null);
  }
예제 #12
0
  /**
   * Return a Set containing the resource paths of resources member of the specified collection.
   * Each path will be a String starting with a "/" character. The returned set is immutable.
   *
   * @param path Collection path
   */
  public Set getResourcePaths(String path) {

    DirContext resources = context.getResources();
    if (resources != null) {
      if (System.getSecurityManager() != null) {
        PrivilegedAction dp = new PrivilegedGetResourcePaths(resources, path);
        return ((Set) AccessController.doPrivileged(dp));
      } else {
        return (getResourcePathsInternal(resources, path));
      }
    }
    return (null);
  }
예제 #13
0
  /**
   * Return a <code>ServletContext</code> object that corresponds to a specified URI on the server.
   * This method allows servlets to gain access to the context for various parts of the server, and
   * as needed obtain <code>RequestDispatcher</code> objects or resources from the context. The
   * given path must be absolute (beginning with a "/"), and is interpreted based on our virtual
   * host's document root.
   *
   * @param uri Absolute URI of a resource on the server
   */
  public ServletContext getContext(String uri) {

    // Validate the format of the specified argument
    if ((uri == null) || (!uri.startsWith("/"))) return (null);

    // Return the current context if requested
    String contextPath = context.getPath();
    if (!contextPath.endsWith("/")) contextPath = contextPath + "/";
    if ((contextPath.length() > 0) && (uri.startsWith(contextPath))) {
      return (this);
    }

    // Return other contexts only if allowed
    if (!context.getCrossContext()) return (null);
    try {
      Host host = (Host) context.getParent();
      Context child = host.map(uri);
      if (child != null) return (child.getServletContext());
      else return (null);
    } catch (Throwable t) {
      return (null);
    }
  }
예제 #14
0
  /**
   * Remove the context attribute with the specified name, if any.
   *
   * @param name Name of the context attribute to be removed
   */
  public void removeAttribute(String name) {

    Object value = null;
    boolean found = false;

    // Remove the specified attribute
    synchronized (attributes) {
      // Check for read only attribute
      if (readOnlyAttributes.containsKey(name)) return;
      found = attributes.containsKey(name);
      if (found) {
        value = attributes.get(name);
        attributes.remove(name);
      } else {
        return;
      }
    }

    // Notify interested application event listeners
    Object listeners[] = context.getApplicationListeners();
    if ((listeners == null) || (listeners.length == 0)) return;
    ServletContextAttributeEvent event =
        new ServletContextAttributeEvent(context.getServletContext(), name, value);
    for (int i = 0; i < listeners.length; i++) {
      if (!(listeners[i] instanceof ServletContextAttributeListener)) continue;
      ServletContextAttributeListener listener = (ServletContextAttributeListener) listeners[i];
      try {
        context.fireContainerEvent("beforeContextAttributeRemoved", listener);
        listener.attributeRemoved(event);
        context.fireContainerEvent("afterContextAttributeRemoved", listener);
      } catch (Throwable t) {
        context.fireContainerEvent("afterContextAttributeRemoved", listener);
        // FIXME - should we do anything besides log these?
        log(sm.getString("applicationContext.attributeEvent"), t);
      }
    }
  }
  @Test
  public void testBug51653b() throws Exception {
    // Set up a container
    Tomcat tomcat = getTomcatInstance();

    // No file system docBase required
    Context ctx = tomcat.addContext("", null);

    // Traces order of events across multiple components
    StringBuilder trace = new StringBuilder();

    // Add the page that generates the error
    Tomcat.addServlet(ctx, "test", new Bug51653ErrorTrigger());
    ctx.addServletMapping("/test", "test");

    // Add the error page
    Tomcat.addServlet(ctx, "errorPage", new Bug51653ErrorPage(trace));
    ctx.addServletMapping("/error", "errorPage");
    // And the handling for 404 responses
    ErrorPage errorPage = new ErrorPage();
    errorPage.setErrorCode(Response.SC_NOT_FOUND);
    errorPage.setLocation("/error");
    ctx.addErrorPage(errorPage);

    // Add the request listener
    Bug51653RequestListener reqListener = new Bug51653RequestListener(trace);
    ((StandardContext) ctx).addApplicationEventListener(reqListener);

    tomcat.start();

    // Request a page that does not exist
    int rc = getUrl("http://localhost:" + getPort() + "/test", new ByteChunk(), null);

    // Need to allow time (but not too long in case the test fails) for
    // ServletRequestListener to complete
    int i = 20;
    while (i > 0) {
      if (trace.toString().endsWith("Destroy")) {
        break;
      }
      Thread.sleep(250);
      i--;
    }

    assertEquals(Response.SC_NOT_FOUND, rc);
    assertEquals("InitErrorDestroy", trace.toString());
  }
예제 #16
0
  @Test
  public void testSRLAfterError() throws Exception {
    // Set up a container
    Tomcat tomcat = getTomcatInstance();

    // No file system docBase required
    Context ctx = tomcat.addContext("", null);

    // Add the error page
    Tomcat.addServlet(ctx, "error", new ErrorServlet());
    ctx.addServletMapping("/error", "error");

    final List<String> result = new ArrayList<>();

    // Add the request listener
    ServletRequestListener servletRequestListener =
        new ServletRequestListener() {

          @Override
          public void requestDestroyed(ServletRequestEvent sre) {
            result.add("Visit requestDestroyed");
          }

          @Override
          public void requestInitialized(ServletRequestEvent sre) {
            result.add("Visit requestInitialized");
          }
        };
    ((StandardContext) ctx).addApplicationEventListener(servletRequestListener);

    tomcat.start();

    // Request a page that triggers an error
    ByteChunk bc = new ByteChunk();
    int rc = getUrl("http://localhost:" + getPort() + "/error?errorCode=400", bc, null);

    Assert.assertEquals(400, rc);
    Assert.assertTrue(result.contains("Visit requestInitialized"));
    Assert.assertTrue(result.contains("Visit requestDestroyed"));
  }
  /**
   * Set the filter definition we are configured for. This has the side effect of instantiating an
   * instance of the corresponding filter class.
   *
   * @param filterDef The new filter definition
   * @exception ClassCastException if the specified class does not implement the <code>
   *     javax.servlet.Filter</code> interface
   * @exception ClassNotFoundException if the filter class cannot be found
   * @exception IllegalAccessException if the filter class cannot be publicly instantiated
   * @exception InstantiationException if an exception occurs while instantiating the filter object
   * @exception ServletException if thrown by the filter's init() method
   * @throws NamingException
   * @throws InvocationTargetException
   */
  void setFilterDef(FilterDef filterDef)
      throws ClassCastException, ClassNotFoundException, IllegalAccessException,
          InstantiationException, ServletException, InvocationTargetException, NamingException {

    this.filterDef = filterDef;
    if (filterDef == null) {

      // Release any previously allocated filter instance
      if (this.filter != null) {
        if (Globals.IS_SECURITY_ENABLED) {
          try {
            SecurityUtil.doAsPrivilege("destroy", filter);
          } catch (java.lang.Exception ex) {
            context.getLogger().error("ApplicationFilterConfig.doAsPrivilege", ex);
          }
          SecurityUtil.remove(filter);
        } else {
          filter.destroy();
        }
        if (!context.getIgnoreAnnotations()) {
          try {
            ((StandardContext) context).getInstanceManager().destroyInstance(this.filter);
          } catch (Exception e) {
            Throwable t = ExceptionUtils.unwrapInvocationTargetException(e);
            ExceptionUtils.handleThrowable(t);
            context.getLogger().error("ApplicationFilterConfig.preDestroy", t);
          }
        }
      }
      this.filter = null;

    } else {
      // Allocate a new filter instance if necessary
      if (filterDef.getFilter() == null) {
        getFilter();
      }
    }
  }
예제 #18
0
 @Test(expected = IllegalArgumentException.class)
 public void testAddPreDestroyMethodConflicts() {
   StandardContext standardContext = new StandardContext();
   standardContext.addPreDestroyMethod("a", "a");
   standardContext.addPreDestroyMethod("a", "b");
 }
예제 #19
0
 private void testSetPath(String value, String expectedValue) {
   StandardContext context = new StandardContext();
   context.setPath(value);
   Assert.assertEquals(expectedValue, context.getPath());
 }
예제 #20
0
 /**
  * Return the resources object that is mapped to a specified path. The path must begin with a "/"
  * and is interpreted as relative to the current context root.
  */
 public DirContext getResources() {
   return context.getResources();
 }
예제 #21
0
  /** Return the display name of this web application. */
  public String getServletContextName() {

    return (context.getDisplayName());
  }
예제 #22
0
 private void internalLog(Exception exception, String message) {
   Logger logger = context.getLogger();
   if (logger != null) logger.log(exception, message);
 }
예제 #23
0
  private void internalLog(String message, Throwable throwable) {

    Logger logger = context.getLogger();
    if (logger != null) logger.log(message, throwable);
  }