Example #1
0
  @Override
  public void start() {
    embedded = new Tomcat();
    AuthConfigFactory.setFactory(new AuthConfigFactoryImpl());

    Context context = embedded.addContext(getContextPath(), "/");
    context.addParameter("contextConfigLocation", getContextResource());
    context.addApplicationListener(ContextLoaderListener.class.getName());

    embedded.getHost().setAppBase("");

    // Each servlet should get an unique name, otherwise all servers will reuse
    // one and the same servlet instance.  Note that name clashes with servlets
    // created somewhere else are still possible.
    String servletName =
        getServletName() == null
            ? "ipf-servlet-" + SERVLET_COUNTER.getAndIncrement()
            : getServletName();

    wrapper = context.createWrapper();
    wrapper.setName(servletName);
    wrapper.setServletClass(getServlet().getClass().getName());

    for (Map.Entry<String, String> parameters : getInitParameters().entrySet()) {
      wrapper.addInitParameter(parameters.getKey(), parameters.getValue());
    }

    context.addChild(wrapper);
    context.addServletMapping(getServletPath(), servletName);

    /*
    VirtualWebappLoader loader = new VirtualWebappLoader(this.getClass().getClassLoader());
    loader.setVirtualClasspath(System.getProperty("java.class.path"));
    context.setLoader(loader);
    */
    Connector connector = embedded.getConnector();
    connector.setPort(getPort());
    if (isSecure()) {
      connector.setSecure(true);
      connector.setScheme("https");
      connector.setProperty("SSLEnabled", "true");
      connector.setProperty("sslProtocol", "TLS");
      connector.setProperty("keystoreFile", getKeystoreFile());
      connector.setProperty("keystorePass", getKeystorePass());
      connector.setProperty("truststoreFile", getTruststoreFile());
      connector.setProperty("truststorePass", getTruststorePass());
      if (getClientAuthType() == ClientAuthType.MUST) {
        connector.setProperty("clientAuth", "true");
      } else if (getClientAuthType() == ClientAuthType.WANT) {
        connector.setProperty("clientAuth", "want");
      }
    }

    try {
      embedded.start();
      wrapper.allocate();
      log.info("Started embedded Tomcat server");
    } catch (Exception e) {
      throw new AssertionError(e);
    }
  }
Example #2
0
  /**
   * Serve the specified request, creating the corresponding response. After the first time a
   * particular servlet class is requested, it will be served directly (like any registered servlet)
   * because it will have been registered and mapped in our associated Context.
   *
   * @param request The servlet request we are processing
   * @param response The servlet response we are creating
   * @exception IOException if an input/output error occurs
   * @exception ServletException if a servlet-specified error occurs
   */
  public void serveRequest(HttpServletRequest request, HttpServletResponse response)
      throws IOException, ServletException {

    // Disallow calling this servlet via a named dispatcher
    if (request.getAttribute(Globals.NAMED_DISPATCHER_ATTR) != null)
      throw new ServletException(sm.getString("invokerServlet.notNamed"));

    // Identify the input parameters and our "included" state
    String inRequestURI = null;
    String inServletPath = null;
    String inPathInfo = null;
    boolean included = (request.getAttribute(Globals.REQUEST_URI_ATTR) != null);

    if (included) {
      inRequestURI = (String) request.getAttribute(Globals.REQUEST_URI_ATTR);
      inServletPath = (String) request.getAttribute(Globals.SERVLET_PATH_ATTR);
      inPathInfo = (String) request.getAttribute(Globals.PATH_INFO_ATTR);
    } else {
      inRequestURI = request.getRequestURI();
      inServletPath = request.getServletPath();
      inPathInfo = request.getPathInfo();
    }
    if (debug >= 1) {
      log("included='" + included + "', requestURI='" + inRequestURI + "'");
      log("  servletPath='" + inServletPath + "', pathInfo='" + inPathInfo + "'");
    }

    // Make sure a servlet name or class name was specified
    if (inPathInfo == null) {
      if (debug >= 1) log("Invalid pathInfo '" + inPathInfo + "'");
      if (included)
        throw new ServletException(sm.getString("invokerServlet.invalidPath", inRequestURI));
      else {
        response.sendError(HttpServletResponse.SC_NOT_FOUND, inRequestURI);
        return;
      }
    }

    // Identify the outgoing servlet name or class, and outgoing path info
    String pathInfo = inPathInfo;
    String servletClass = pathInfo.substring(1);
    int slash = servletClass.indexOf('/');
    //        if (debug >= 2)
    //            log("  Calculating with servletClass='" + servletClass +
    //                "', pathInfo='" + pathInfo + "', slash=" + slash);
    if (slash >= 0) {
      pathInfo = servletClass.substring(slash);
      servletClass = servletClass.substring(0, slash);
    } else {
      pathInfo = "";
    }

    if (servletClass.startsWith("org.apache.catalina")) {
      response.sendError(HttpServletResponse.SC_NOT_FOUND, inRequestURI);
      return;
    }

    if (debug >= 1)
      log("Processing servlet '" + servletClass + "' with path info '" + pathInfo + "'");
    String name = "org.apache.catalina.INVOKER." + servletClass;
    String pattern = inServletPath + "/" + servletClass + "/*";
    Wrapper wrapper = null;

    // Synchronize to avoid race conditions when multiple requests
    // try to initialize the same servlet at the same time
    synchronized (this) {

      // Are we referencing an existing servlet class or name?
      wrapper = (Wrapper) context.findChild(servletClass);
      if (wrapper == null) wrapper = (Wrapper) context.findChild(name);
      if (wrapper != null) {
        if (debug >= 1)
          log(
              "Using wrapper for servlet '"
                  + wrapper.getName()
                  + "' with mapping '"
                  + pattern
                  + "'");
        context.addServletMapping(pattern, wrapper.getName());
      }

      // No, create a new wrapper for the specified servlet class
      else {

        if (debug >= 1)
          log("Creating wrapper for '" + servletClass + "' with mapping '" + pattern + "'");

        try {
          wrapper = context.createWrapper();
          wrapper.setName(name);
          wrapper.setLoadOnStartup(1);
          wrapper.setServletClass(servletClass);
          context.addChild(wrapper);
          context.addServletMapping(pattern, name);
        } catch (Throwable t) {
          log(sm.getString("invokerServlet.cannotCreate", inRequestURI), t);
          context.removeServletMapping(pattern);
          context.removeChild(wrapper);
          if (included)
            throw new ServletException(
                sm.getString("invokerServlet.cannotCreate", inRequestURI), t);
          else {
            response.sendError(HttpServletResponse.SC_NOT_FOUND, inRequestURI);
            return;
          }
        }
      }
    }

    // Create a request wrapper to pass on to the invoked servlet
    InvokerHttpRequest wrequest = new InvokerHttpRequest(request);
    wrequest.setRequestURI(inRequestURI);
    StringBuffer sb = new StringBuffer(inServletPath);
    sb.append("/");
    sb.append(servletClass);
    wrequest.setServletPath(sb.toString());
    if ((pathInfo == null) || (pathInfo.length() < 1)) {
      wrequest.setPathInfo(null);
      wrequest.setPathTranslated(null);
    } else {
      wrequest.setPathInfo(pathInfo);
      wrequest.setPathTranslated(getServletContext().getRealPath(pathInfo));
    }

    // Allocate a servlet instance to perform this request
    Servlet instance = null;
    try {
      //            if (debug >= 2)
      //                log("  Allocating servlet instance");
      instance = wrapper.allocate();
    } catch (ServletException e) {
      log(sm.getString("invokerServlet.allocate", inRequestURI), e);
      context.removeServletMapping(pattern);
      context.removeChild(wrapper);
      Throwable rootCause = e.getRootCause();
      if (rootCause == null) rootCause = e;
      if (rootCause instanceof ClassNotFoundException) {
        response.sendError(HttpServletResponse.SC_NOT_FOUND, inRequestURI);
        return;
      } else if (rootCause instanceof IOException) {
        throw (IOException) rootCause;
      } else if (rootCause instanceof RuntimeException) {
        throw (RuntimeException) rootCause;
      } else if (rootCause instanceof ServletException) {
        throw (ServletException) rootCause;
      } else {
        throw new ServletException(
            sm.getString("invokerServlet.allocate", inRequestURI), rootCause);
      }
    } catch (Throwable e) {
      log(sm.getString("invokerServlet.allocate", inRequestURI), e);
      context.removeServletMapping(pattern);
      context.removeChild(wrapper);
      throw new ServletException(sm.getString("invokerServlet.allocate", inRequestURI), e);
    }

    // After loading the wrapper, restore some of the fields when including
    if (included) {
      wrequest.setRequestURI(request.getRequestURI());
      wrequest.setPathInfo(request.getPathInfo());
      wrequest.setServletPath(request.getServletPath());
    }

    // Invoke the service() method of the allocated servlet
    try {
      String jspFile = wrapper.getJspFile();
      if (jspFile != null) request.setAttribute(Globals.JSP_FILE_ATTR, jspFile);
      else request.removeAttribute(Globals.JSP_FILE_ATTR);
      request.setAttribute(Globals.INVOKED_ATTR, request.getServletPath());
      //            if (debug >= 2)
      //                log("  Calling service() method, jspFile=" +
      //                    jspFile);
      instance.service(wrequest, response);
      request.removeAttribute(Globals.INVOKED_ATTR);
      request.removeAttribute(Globals.JSP_FILE_ATTR);
    } catch (IOException e) {
      //            if (debug >= 2)
      //                log("  service() method IOException", e);
      request.removeAttribute(Globals.INVOKED_ATTR);
      request.removeAttribute(Globals.JSP_FILE_ATTR);
      try {
        wrapper.deallocate(instance);
      } catch (Throwable f) {;
      }
      throw e;
    } catch (UnavailableException e) {
      //            if (debug >= 2)
      //                log("  service() method UnavailableException", e);
      context.removeServletMapping(pattern);
      request.removeAttribute(Globals.INVOKED_ATTR);
      request.removeAttribute(Globals.JSP_FILE_ATTR);
      try {
        wrapper.deallocate(instance);
      } catch (Throwable f) {;
      }
      throw e;
    } catch (ServletException e) {
      //            if (debug >= 2)
      //                log("  service() method ServletException", e);
      request.removeAttribute(Globals.INVOKED_ATTR);
      request.removeAttribute(Globals.JSP_FILE_ATTR);
      try {
        wrapper.deallocate(instance);
      } catch (Throwable f) {;
      }
      throw e;
    } catch (RuntimeException e) {
      //            if (debug >= 2)
      //                log("  service() method RuntimeException", e);
      request.removeAttribute(Globals.INVOKED_ATTR);
      request.removeAttribute(Globals.JSP_FILE_ATTR);
      try {
        wrapper.deallocate(instance);
      } catch (Throwable f) {;
      }
      throw e;
    } catch (Throwable e) {
      //            if (debug >= 2)
      //                log("  service() method Throwable", e);
      request.removeAttribute(Globals.INVOKED_ATTR);
      request.removeAttribute(Globals.JSP_FILE_ATTR);
      try {
        wrapper.deallocate(instance);
      } catch (Throwable f) {;
      }
      throw new ServletException("Invoker service() exception", e);
    }

    // Deallocate the allocated servlet instance
    try {
      //            if (debug >= 2)
      //                log("  deallocate servlet instance");
      wrapper.deallocate(instance);
    } catch (ServletException e) {
      log(sm.getString("invokerServlet.deallocate", inRequestURI), e);
      throw e;
    } catch (Throwable e) {
      log(sm.getString("invokerServlet.deallocate", inRequestURI), e);
      throw new ServletException(sm.getString("invokerServlet.deallocate", inRequestURI), e);
    }
  }