/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


package org.apache.catalina.manager;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Set;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.servlet.http.Part;

import org.apache.catalina.Container;
import org.apache.catalina.Context;
import org.apache.catalina.DistributedManager;
import org.apache.catalina.Manager;
import org.apache.catalina.Session;
import org.apache.catalina.manager.util.BaseSessionComparator;
import org.apache.catalina.manager.util.ReverseComparator;
import org.apache.catalina.manager.util.SessionUtils;
import org.apache.catalina.util.ContextName;
import org.apache.catalina.util.RequestUtil;
import org.apache.catalina.util.ServerInfo;
import org.apache.catalina.util.URLEncoder;
import org.apache.tomcat.util.res.StringManager;

/**
* Servlet that enables remote management of the web applications deployed
* within the same virtual host as this web application is.  Normally, this
* functionality will be protected by a security constraint in the web
* application deployment descriptor.  However, this requirement can be
* relaxed during testing.
* <p>
* The difference between the <code>ManagerServlet</code> and this
* Servlet is that this Servlet prints out a HTML interface which
* makes it easier to administrate.
* <p>
* However if you use a software that parses the output of
* <code>ManagerServlet</code> you won't be able to upgrade
* to this Servlet since the output are not in the
* same format ar from <code>ManagerServlet</code>
*
* @author Bip Thelin
* @author Malcolm Edgar
* @author Glenn L. Nielsen
* @see ManagerServlet
*/
public final class HTMLManagerServlet extends ManagerServlet {

    private static final long serialVersionUID = 1L;

    protected static final URLEncoder URL_ENCODER;
    protected static final String APPLICATION_MESSAGE = "message";
    protected static final String APPLICATION_ERROR = "error";

    protected static final String sessionsListJspPath  =
            "/WEB-INF/jsp/sessionsList.jsp";
    protected static final String sessionDetailJspPath =
            "/WEB-INF/jsp/sessionDetail.jsp";
    protected static final String connectorCiphersJspPath =
            "/WEB-INF/jsp/connectorCiphers.jsp";

    static {
        URL_ENCODER = new URLEncoder();
        // '/' should not be encoded in context paths
        URL_ENCODER.addSafeCharacter('/');
    }

    private boolean showProxySessions = false;

    // --------------------------------------------------------- Public Methods

    /**
     * Process a GET request for the specified resource.
     *
     * @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
     */
    @Override
    public void doGet(HttpServletRequest request,
                      HttpServletResponse response)
        throws IOException, ServletException {

        StringManager smClient = StringManager.getManager(
                Constants.Package, request.getLocales());

        // Identify the request parameters that we need
        // By obtaining the command from the pathInfo, per-command security can
        // be configured in web.xml
        String command = request.getPathInfo();

        String path = request.getParameter("path");
        ContextName cn = null;
        if (path != null) {
            cn = new ContextName(path, request.getParameter("version"));
        }

        // Prepare our output writer to generate the response message
        response.setContentType("text/html; charset=" + Constants.CHARSET);

        String message = "";
        // Process the requested command
        if (command == null || command.equals("/")) {
            // No command == list
        } else if (command.equals("/list")) {
            // List always displayed - nothing to do here
        } else if (command.equals("/sessions")) {
            try {
                doSessions(cn, request, response, smClient);
                return;
            } catch (Exception e) {
                log("HTMLManagerServlet.sessions[" + cn + "]", e);
                message = smClient.getString("managerServlet.exception",
                        e.toString());
            }
        } else if (command.equals("/sslConnectorCiphers")) {
            sslConnectorCiphers(request, response);
        } else if (command.equals("/upload") || command.equals("/deploy") ||
                command.equals("/reload") || command.equals("/undeploy") ||
                command.equals("/expire") || command.equals("/start") ||
                command.equals("/stop")) {
            message =
                smClient.getString("managerServlet.postCommand", command);
        } else {
            message =
                smClient.getString("managerServlet.unknownCommand", command);
        }

        list(request, response, message, smClient);
    }

    /**
     * Process a POST request for the specified resource.
     *
     * @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
     */
    @Override
    public void doPost(HttpServletRequest request,
                      HttpServletResponse response)
        throws IOException, ServletException {

        StringManager smClient = StringManager.getManager(
                Constants.Package, request.getLocales());

        // Identify the request parameters that we need
        // By obtaining the command from the pathInfo, per-command security can
        // be configured in web.xml
        String command = request.getPathInfo();

        String path = request.getParameter("path");
        ContextName cn = null;
        if (path != null) {
            cn = new ContextName(path, request.getParameter("version"));
        }
        String deployPath = request.getParameter("deployPath");
        ContextName deployCn = null;
        if (deployPath != null) {
            deployCn = new ContextName(deployPath,
                    request.getParameter("deployVersion"));
        }
        String deployConfig = request.getParameter("deployConfig");
        String deployWar = request.getParameter("deployWar");

        // Prepare our output writer to generate the response message
        response.setContentType("text/html; charset=" + Constants.CHARSET);

        String message = "";

        if (command == null || command.length() == 0) {
            // No command == list
            // List always displayed -> do nothing
        } else if (command.equals("/upload")) {
            message = upload(request, smClient);
        } else if (command.equals("/deploy")) {
            message = deployInternal(deployConfig, deployCn, deployWar,
                    smClient);
        } else if (command.equals("/reload")) {
            message = reload(cn, smClient);
        } else if (command.equals("/undeploy")) {
            message = undeploy(cn, smClient);
        } else if (command.equals("/expire")) {
            message = expireSessions(cn, request, smClient);
        } else if (command.equals("/start")) {
            message = start(cn, smClient);
        } else if (command.equals("/stop")) {
            message = stop(cn, smClient);
        } else if (command.equals("/findleaks")) {
            message = findleaks(smClient);
        } else {
            // Try GET
            doGet(request,response);
            return;
        }

        list(request, response, message, smClient);
    }

    protected String upload(HttpServletRequest request, StringManager smClient) {
        String message = "";

        try {
            while (true) {
                Part warPart = request.getPart("deployWar");
                if (warPart == null) {
                    message = smClient.getString(
                            "htmlManagerServlet.deployUploadNoFile");
                    break;
                }
                String filename = warPart.getSubmittedFileName();
                if (!filename.toLowerCase(Locale.ENGLISH).endsWith(".war")) {
                    message = smClient.getString(
                            "htmlManagerServlet.deployUploadNotWar", filename);
                    break;
                }
                // Get the filename if uploaded name includes a path
                if (filename.lastIndexOf('\\') >= 0) {
                    filename =
                        filename.substring(filename.lastIndexOf('\\') + 1);
                }
                if (filename.lastIndexOf('/') >= 0) {
                    filename =
                        filename.substring(filename.lastIndexOf('/') + 1);
                }

                // Identify the appBase of the owning Host of this Context
                // (if any)
                File file = new File(host.getAppBaseFile(), filename);
                if (file.exists()) {
                    message = smClient.getString(
                            "htmlManagerServlet.deployUploadWarExists",
                            filename);
                    break;
                }

                ContextName cn = new ContextName(filename, true);
                String name = cn.getName();

                if ((host.findChild(name) != null) && !isDeployed(name)) {
                    message = smClient.getString(
                            "htmlManagerServlet.deployUploadInServerXml",
                            filename);
                    break;
                }

                if (isServiced(name)) {
                    message = smClient.getString("managerServlet.inService", name);
                } else {
                    addServiced(name);
                    try {
                        warPart.write(file.getAbsolutePath());
                        // Perform new deployment
                        check(name);
                    } finally {
                        removeServiced(name);
                    }
                }
                break;
            }
        } catch(Exception e) {
            message = smClient.getString
                ("htmlManagerServlet.deployUploadFail", e.getMessage());
            log(message, e);
        }
        return message;
    }

    /**
     * Deploy an application for the specified path from the specified
     * web application archive.
     *
     * @param config URL of the context configuration file to be deployed
     * @param cn Name of the application to be deployed
     * @param war URL of the web application archive to be deployed
     * @return message String
     */
    protected String deployInternal(String config, ContextName cn, String war,
            StringManager smClient) {

        StringWriter stringWriter = new StringWriter();
        PrintWriter printWriter = new PrintWriter(stringWriter);

        super.deploy(printWriter, config, cn, war, false, smClient);

        return stringWriter.toString();
    }

    /**
     * Render a HTML list of the currently active Contexts in our virtual host,
     * and memory and server status information.
     *
     * @param request The request
     * @param response The response
     * @param message a message to display
     */
    protected void list(HttpServletRequest request,
                     HttpServletResponse response,
                     String message,
                     StringManager smClient) throws IOException {

        if (debug >= 1)
            log("list: Listing contexts for virtual host '" +
                host.getName() + "'");

        PrintWriter writer = response.getWriter();

        // HTML Header Section
        writer.print(Constants.HTML_HEADER_SECTION);

        // Body Header Section
        Object[] args = new Object[2];
        args[0] = request.getContextPath();
        args[1] = smClient.getString("htmlManagerServlet.title");
        writer.print(MessageFormat.format
                     (Constants.BODY_HEADER_SECTION, args));

        // Message Section
        args = new Object[3];
        args[0] = smClient.getString("htmlManagerServlet.messageLabel");
        if (message == null || message.length() == 0) {
            args[1] = "OK";
        } else {
            args[1] = RequestUtil.filter(message);
        }
        writer.print(MessageFormat.format(Constants.MESSAGE_SECTION, args));

        // Manager Section
        args = new Object[9];
        args[0] = smClient.getString("htmlManagerServlet.manager");
        args[1] = response.encodeURL(request.getContextPath() + "/html/list");
        args[2] = smClient.getString("htmlManagerServlet.list");
        args[3] = response.encodeURL
            (request.getContextPath() + "/" +
             smClient.getString("htmlManagerServlet.helpHtmlManagerFile"));
        args[4] = smClient.getString("htmlManagerServlet.helpHtmlManager");
        args[5] = response.encodeURL
            (request.getContextPath() + "/" +
             smClient.getString("htmlManagerServlet.helpManagerFile"));
        args[6] = smClient.getString("htmlManagerServlet.helpManager");
        args[7] = response.encodeURL
            (request.getContextPath() + "/status");
        args[8] = smClient.getString("statusServlet.title");
        writer.print(MessageFormat.format(Constants.MANAGER_SECTION, args));

        // Apps Header Section
        args = new Object[7];
        args[0] = smClient.getString("htmlManagerServlet.appsTitle");
        args[1] = smClient.getString("htmlManagerServlet.appsPath");
        args[2] = smClient.getString("htmlManagerServlet.appsVersion");
        args[3] = smClient.getString("htmlManagerServlet.appsName");
        args[4] = smClient.getString("htmlManagerServlet.appsAvailable");
        args[5] = smClient.getString("htmlManagerServlet.appsSessions");
        args[6] = smClient.getString("htmlManagerServlet.appsTasks");
        writer.print(MessageFormat.format(APPS_HEADER_SECTION, args));

        // Apps Row Section
        // Create sorted map of deployed applications by context name.
        Container children[] = host.findChildren();
        String contextNames[] = new String[children.length];
        for (int i = 0; i < children.length; i++)
            contextNames[i] = children[i].getName();

        Arrays.sort(contextNames);

        String appsStart = smClient.getString("htmlManagerServlet.appsStart");
        String appsStop = smClient.getString("htmlManagerServlet.appsStop");
        String appsReload = smClient.getString("htmlManagerServlet.appsReload");
        String appsUndeploy =
            smClient.getString("htmlManagerServlet.appsUndeploy");
        String appsExpire = smClient.getString("htmlManagerServlet.appsExpire");
        String noVersion = "<i>" +
            smClient.getString("htmlManagerServlet.noVersion") + "</i>";

        boolean isHighlighted = true;
        boolean isDeployed = true;
        String highlightColor = null;

        for (String contextName : contextNames) {
            Context ctxt = (Context) host.findChild(contextName);

            if (ctxt != null) {
                // Bugzilla 34818, alternating row colors
                isHighlighted = !isHighlighted;
                if(isHighlighted) {
                    highlightColor = "#C3F3C3";
                } else {
                    highlightColor = "#FFFFFF";
                }

                String contextPath = ctxt.getPath();
                String displayPath = contextPath;
                if (displayPath.equals("")) {
                    displayPath = "/";
                }

                StringBuilder tmp = new StringBuilder();
                tmp.append("path=");
                tmp.append(URL_ENCODER.encode(displayPath));
                if (ctxt.getWebappVersion().length() > 0) {
                    tmp.append("&version=");
                    tmp.append(URL_ENCODER.encode(ctxt.getWebappVersion()));
                }
                String pathVersion = tmp.toString();

                try {
                    isDeployed = isDeployed(contextName);
                } catch (Exception e) {
                    // Assume false on failure for safety
                    isDeployed = false;
                }

                args = new Object[7];
                args[0] = "<a href=\"" + URL_ENCODER.encode(contextPath + "/")
                        + "\">" + RequestUtil.filter(displayPath) + "</a>";
                if ("".equals(ctxt.getWebappVersion())) {
                    args[1] = noVersion;
                } else {
                    args[1] = RequestUtil.filter(ctxt.getWebappVersion());
                }
                if (ctxt.getDisplayName() == null) {
                    args[2] = "&nbsp;";
                } else {
                    args[2] = RequestUtil.filter(ctxt.getDisplayName());
                }
                args[3] = Boolean.valueOf(ctxt.getState().isAvailable());
                args[4] = RequestUtil.filter(response.encodeURL(request.getContextPath() +
                     "/html/sessions?" + pathVersion));
                Manager manager = ctxt.getManager();
                if (manager instanceof DistributedManager && showProxySessions) {
                    args[5] = Integer.valueOf(
                            ((DistributedManager)manager).getActiveSessionsFull());
                } else if (manager != null){
                    args[5] = Integer.valueOf(manager.getActiveSessions());
                } else {
                    args[5] = Integer.valueOf(0);
                }

                args[6] = highlightColor;

                writer.print
                    (MessageFormat.format(APPS_ROW_DETAILS_SECTION, args));

                args = new Object[14];
                args[0] = RequestUtil.filter(response.encodeURL(request
                        .getContextPath() + "/html/start?" + pathVersion));
                args[1] = appsStart;
                args[2] = RequestUtil.filter(response.encodeURL(request
                        .getContextPath() + "/html/stop?" + pathVersion));
                args[3] = appsStop;
                args[4] = RequestUtil.filter(response.encodeURL(request
                        .getContextPath() + "/html/reload?" + pathVersion));
                args[5] = appsReload;
                args[6] = RequestUtil.filter(response.encodeURL(request
                        .getContextPath() + "/html/undeploy?" + pathVersion));
                args[7] = appsUndeploy;
                args[8] = RequestUtil.filter(response.encodeURL(request
                        .getContextPath() + "/html/expire?" + pathVersion));
                args[9] = appsExpire;
                args[10] = smClient.getString(
                        "htmlManagerServlet.expire.explain");
                if (manager == null) {
                    args[11] = smClient.getString(
                            "htmlManagerServlet.noManager");
                } else {
                    args[11] = Integer.valueOf(
                            ctxt.getManager().getMaxInactiveInterval()/60);
                }
                args[12] = smClient.getString("htmlManagerServlet.expire.unit");
                args[13] = highlightColor;

                if (ctxt.getName().equals(this.context.getName())) {
                    writer.print(MessageFormat.format(
                        MANAGER_APP_ROW_BUTTON_SECTION, args));
                } else if (ctxt.getState().isAvailable() && isDeployed) {
                    writer.print(MessageFormat.format(
                        STARTED_DEPLOYED_APPS_ROW_BUTTON_SECTION, args));
                } else if (ctxt.getState().isAvailable() && !isDeployed) {
                    writer.print(MessageFormat.format(
                        STARTED_NONDEPLOYED_APPS_ROW_BUTTON_SECTION, args));
                } else if (!ctxt.getState().isAvailable() && isDeployed) {
                    writer.print(MessageFormat.format(
                        STOPPED_DEPLOYED_APPS_ROW_BUTTON_SECTION, args));
                } else {
                    writer.print(MessageFormat.format(
                        STOPPED_NONDEPLOYED_APPS_ROW_BUTTON_SECTION, args));
                }

            }
        }

        // Deploy Section
        args = new Object[7];
        args[0] = smClient.getString("htmlManagerServlet.deployTitle");
        args[1] = smClient.getString("htmlManagerServlet.deployServer");
        args[2] = response.encodeURL(request.getContextPath() + "/html/deploy");
        args[3] = smClient.getString("htmlManagerServlet.deployPath");
        args[4] = smClient.getString("htmlManagerServlet.deployConfig");
        args[5] = smClient.getString("htmlManagerServlet.deployWar");
        args[6] = smClient.getString("htmlManagerServlet.deployButton");
        writer.print(MessageFormat.format(DEPLOY_SECTION, args));

        args = new Object[4];
        args[0] = smClient.getString("htmlManagerServlet.deployUpload");
        args[1] = response.encodeURL(request.getContextPath() + "/html/upload");
        args[2] = smClient.getString("htmlManagerServlet.deployUploadFile");
        args[3] = smClient.getString("htmlManagerServlet.deployButton");
        writer.print(MessageFormat.format(UPLOAD_SECTION, args));

        // Diagnostics section
        args = new Object[9];
        args[0] = smClient.getString("htmlManagerServlet.diagnosticsTitle");
        args[1] = smClient.getString("htmlManagerServlet.diagnosticsLeak");
        args[2] = response.encodeURL(
                request.getContextPath() + "/html/findleaks");
        args[3] = smClient.getString("htmlManagerServlet.diagnosticsLeakWarning");
        args[4] = smClient.getString("htmlManagerServlet.diagnosticsLeakButton");
        args[5] = smClient.getString("htmlManagerServlet.diagnosticsSsl");
        args[6] = response.encodeURL(
                request.getContextPath() + "/html/sslConnectorCiphers");
        args[7] = smClient.getString("htmlManagerServlet.diagnosticsSslConnectorCipherButton");
        args[8] = smClient.getString("htmlManagerServlet.diagnosticsSslConnectorCipherText");
        writer.print(MessageFormat.format(DIAGNOSTICS_SECTION, args));

        // Server Header Section
        args = new Object[9];
        args[0] = smClient.getString("htmlManagerServlet.serverTitle");
        args[1] = smClient.getString("htmlManagerServlet.serverVersion");
        args[2] = smClient.getString("htmlManagerServlet.serverJVMVersion");
        args[3] = smClient.getString("htmlManagerServlet.serverJVMVendor");
        args[4] = smClient.getString("htmlManagerServlet.serverOSName");
        args[5] = smClient.getString("htmlManagerServlet.serverOSVersion");
        args[6] = smClient.getString("htmlManagerServlet.serverOSArch");
        args[7] = sm.getString("htmlManagerServlet.serverHostname");
        args[8] = sm.getString("htmlManagerServlet.serverIPAddress");
        writer.print(MessageFormat.format
                     (Constants.SERVER_HEADER_SECTION, args));

        // Server Row Section
        args = new Object[8];
        args[0] = ServerInfo.getServerInfo();
        args[1] = System.getProperty("java.runtime.version");
        args[2] = System.getProperty("java.vm.vendor");
        args[3] = System.getProperty("os.name");
        args[4] = System.getProperty("os.version");
        args[5] = System.getProperty("os.arch");
        try {
            InetAddress address = InetAddress.getLocalHost();
            args[6] = address.getHostName();
            args[7] = address.getHostAddress();
        } catch (UnknownHostException e) {
            args[6] = "-";
            args[7] = "-";
        }
        writer.print(MessageFormat.format(Constants.SERVER_ROW_SECTION, args));

        // HTML Tail Section
        writer.print(Constants.HTML_TAIL_SECTION);

        // Finish up the response
        writer.flush();
        writer.close();
    }

    /**
     * Reload the web application at the specified context path.
     *
     * @see ManagerServlet#reload(PrintWriter, ContextName, StringManager)
     *
     * @param cn Name of the application to be restarted
     * @param smClient  StringManager for the client's locale
     * @return message String
     */
    protected String reload(ContextName cn, StringManager smClient) {

        StringWriter stringWriter = new StringWriter();
        PrintWriter printWriter = new PrintWriter(stringWriter);

        super.reload(printWriter, cn, smClient);

        return stringWriter.toString();
    }

    /**
     * Undeploy the web application at the specified context path.
     *
     * @see ManagerServlet#undeploy(PrintWriter, ContextName, StringManager)
     *
     * @param cn Name of the application to be undeployed
     * @param smClient  StringManager for the client's locale
     * @return message String
     */
    protected String undeploy(ContextName cn, StringManager smClient) {

        StringWriter stringWriter = new StringWriter();
        PrintWriter printWriter = new PrintWriter(stringWriter);

        super.undeploy(printWriter, cn, smClient);

        return stringWriter.toString();
    }

    /**
     * Display session information and invoke list.
     *
     * @see ManagerServlet#sessions(PrintWriter, ContextName, int,
     *          StringManager)
     *
     * @param cn Name of the application to list session information
     * @param idle Expire all sessions with idle time &ge; idle for this context
     * @param smClient  StringManager for the client's locale
     * @return message String
     */
    protected String sessions(ContextName cn, int idle, StringManager smClient) {

        StringWriter stringWriter = new StringWriter();
        PrintWriter printWriter = new PrintWriter(stringWriter);

        super.sessions(printWriter, cn, idle, smClient);

        return stringWriter.toString();
    }

    /**
     * Start the web application at the specified context path.
     *
     * @see ManagerServlet#start(PrintWriter, ContextName, StringManager)
     *
     * @param cn Name of the application to be started
     * @param smClient  StringManager for the client's locale
     * @return message String
     */
    protected String start(ContextName cn, StringManager smClient) {

        StringWriter stringWriter = new StringWriter();
        PrintWriter printWriter = new PrintWriter(stringWriter);

        super.start(printWriter, cn, smClient);

        return stringWriter.toString();
    }

    /**
     * Stop the web application at the specified context path.
     *
     * @see ManagerServlet#stop(PrintWriter, ContextName, StringManager)
     *
     * @param cn Name of the application to be stopped
     * @param smClient  StringManager for the client's locale
     * @return message String
     */
    protected String stop(ContextName cn, StringManager smClient) {

        StringWriter stringWriter = new StringWriter();
        PrintWriter printWriter = new PrintWriter(stringWriter);

        super.stop(printWriter, cn, smClient);

        return stringWriter.toString();
    }

    /**
     * Find potential memory leaks caused by web application reload.
     *
     * @see ManagerServlet#findleaks(boolean, PrintWriter, StringManager)
     *
     * @param smClient  StringManager for the client's locale
     *
     * @return message String
     */
    protected String findleaks(StringManager smClient) {

        StringBuilder msg = new StringBuilder();

        StringWriter stringWriter = new StringWriter();
        PrintWriter printWriter = new PrintWriter(stringWriter);

        super.findleaks(false, printWriter, smClient);

        String writerText = stringWriter.toString();

        if (writerText.length() > 0) {
            if (!writerText.startsWith("FAIL -")) {
                msg.append(smClient.getString(
                        "htmlManagerServlet.findleaksList"));
            }
            msg.append(writerText);
        } else {
            msg.append(smClient.getString("htmlManagerServlet.findleaksNone"));
        }

        return msg.toString();
    }


    protected void sslConnectorCiphers(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {
        request.setAttribute("cipherList", getConnectorCiphers());
        getServletContext().getRequestDispatcher(
                connectorCiphersJspPath).forward(request, response);
    }

    /**
     * @see javax.servlet.Servlet#getServletInfo()
     */
    @Override
    public String getServletInfo() {
        return "HTMLManagerServlet, Copyright (c) 1999-2015, The Apache Software Foundation";
    }

    /**
     * @see javax.servlet.GenericServlet#init()
     */
    @Override
    public void init() throws ServletException {
        super.init();

        // Set our properties from the initialization parameters
        String value = null;
        value = getServletConfig().getInitParameter("showProxySessions");
        showProxySessions = Boolean.parseBoolean(value);
    }

    // ------------------------------------------------ Sessions administration

    /**
     *
     * Extract the expiration request parameter
     *
     * @param cn Name of the application from which to expire sessions
     * @param req
     * @param smClient  StringManager for the client's locale
     */
    protected String expireSessions(ContextName cn, HttpServletRequest req,
            StringManager smClient) {
        int idle = -1;
        String idleParam = req.getParameter("idle");
        if (idleParam != null) {
            try {
                idle = Integer.parseInt(idleParam);
            } catch (NumberFormatException e) {
                log("Could not parse idle parameter to an int: " + idleParam);
            }
        }
        return sessions(cn, idle, smClient);
    }

    /**
     *
     * @param req
     * @param resp
     * @param smClient  StringManager for the client's locale
     * @throws ServletException
     * @throws IOException
     */
    protected void doSessions(ContextName cn, HttpServletRequest req,
            HttpServletResponse resp, StringManager smClient)
            throws ServletException, IOException {
        req.setAttribute("path", cn.getPath());
        req.setAttribute("version", cn.getVersion());
        String action = req.getParameter("action");
        if (debug >= 1) {
            log("sessions: Session action '" + action +
                    "' for web application '" + cn.getDisplayName() + "'");
        }
        if ("sessionDetail".equals(action)) {
            String sessionId = req.getParameter("sessionId");
            displaySessionDetailPage(req, resp, cn, sessionId, smClient);
            return;
        } else if ("invalidateSessions".equals(action)) {
            String[] sessionIds = req.getParameterValues("sessionIds");
            int i = invalidateSessions(cn, sessionIds, smClient);
            req.setAttribute(APPLICATION_MESSAGE, "" + i + " sessions invalidated.");
        } else if ("removeSessionAttribute".equals(action)) {
            String sessionId = req.getParameter("sessionId");
            String name = req.getParameter("attributeName");
            boolean removed =
                removeSessionAttribute(cn, sessionId, name, smClient);
            String outMessage = removed ? "Session attribute '" + name + "' removed." : "Session did not contain any attribute named '" + name + "'";
            req.setAttribute(APPLICATION_MESSAGE, outMessage);
            displaySessionDetailPage(req, resp, cn, sessionId, smClient);
            return;
        } // else
        displaySessionsListPage(cn, req, resp, smClient);
    }

    protected List<Session> getSessionsForName(ContextName cn,
            StringManager smClient) {
        if ((cn == null) || !(cn.getPath().startsWith("/") ||
                cn.getPath().equals(""))) {
            String path = null;
            if (cn != null) {
                path = cn.getPath();
            }
            throw new IllegalArgumentException(smClient.getString(
                    "managerServlet.invalidPath",
                    RequestUtil.filter(path)));
        }

        Context ctxt = (Context) host.findChild(cn.getName());
        if (null == ctxt) {
            throw new IllegalArgumentException(smClient.getString(
                    "managerServlet.noContext",
                    RequestUtil.filter(cn.getDisplayName())));
        }
        Manager manager = ctxt.getManager();
        List<Session> sessions = new ArrayList<>();
        sessions.addAll(Arrays.asList(manager.findSessions()));
        if (manager instanceof DistributedManager && showProxySessions) {
            // Add dummy proxy sessions
            Set<String> sessionIds =
                ((DistributedManager) manager).getSessionIdsFull();
            // Remove active (primary and backup) session IDs from full list
            for (Session session : sessions) {
                sessionIds.remove(session.getId());
            }
            // Left with just proxy sessions - add them
            for (String sessionId : sessionIds) {
                sessions.add(new DummyProxySession(sessionId));
            }
        }
        return sessions;
    }

    protected Session getSessionForNameAndId(ContextName cn, String id,
            StringManager smClient) {

        List<Session> sessions = getSessionsForName(cn, smClient);
        if (sessions == null || sessions.isEmpty()) return null;
        for(Session session : sessions) {
            if (session.getId().equals(id)) {
                return session;
            }
        }
        return null;
    }

    /**
     *
     * @param cn Name of the application for which the sessions will be listed
     * @param req
     * @param resp
     * @param smClient  StringManager for the client's locale
     * @throws ServletException
     * @throws IOException
     */
    protected void displaySessionsListPage(ContextName cn,
            HttpServletRequest req, HttpServletResponse resp,
            StringManager smClient)
            throws ServletException, IOException {
        List<Session> sessions = getSessionsForName(cn, smClient);
        String sortBy = req.getParameter("sort");
        String orderBy = null;
        if (null != sortBy && !"".equals(sortBy.trim())) {
            Comparator<Session> comparator = getComparator(sortBy);
            if (comparator != null) {
                orderBy = req.getParameter("order");
                if ("DESC".equalsIgnoreCase(orderBy)) {
                    comparator = new ReverseComparator(comparator);
                    orderBy = "ASC";
                } else {
                    orderBy = "DESC";
                }
                try {
                    Collections.sort(sessions, comparator);
                } catch (IllegalStateException ise) {
                    // at least 1 of the sessions is invalidated
                    req.setAttribute(APPLICATION_ERROR, "Can't sort session list: one session is invalidated");
                }
            } else {
                log("WARNING: unknown sort order: " + sortBy);
            }
        }
        // keep sort order
        req.setAttribute("sort", sortBy);
        req.setAttribute("order", orderBy);
        req.setAttribute("activeSessions", sessions);
        //strong>NOTE</strong> - This header will be overridden
        // automatically if a <code>RequestDispatcher.forward()</code> call is
        // ultimately invoked.
        resp.setHeader("Pragma", "No-cache"); // HTTP 1.0
        resp.setHeader("Cache-Control", "no-cache,no-store,max-age=0"); // HTTP 1.1
        resp.setDateHeader("Expires", 0); // 0 means now
        getServletContext().getRequestDispatcher(sessionsListJspPath).include(req, resp);
    }

    /**
     *
     * @param req
     * @param resp
     * @param smClient  StringManager for the client's locale
     * @throws ServletException
     * @throws IOException
     */
    protected void displaySessionDetailPage(HttpServletRequest req,
            HttpServletResponse resp, ContextName cn, String sessionId,
            StringManager smClient) throws ServletException, IOException {
        Session session = getSessionForNameAndId(cn, sessionId, smClient);
        //strong>NOTE</strong> - This header will be overridden
        // automatically if a <code>RequestDispatcher.forward()</code> call is
        // ultimately invoked.
        resp.setHeader("Pragma", "No-cache"); // HTTP 1.0
        resp.setHeader("Cache-Control", "no-cache,no-store,max-age=0"); // HTTP 1.1
        resp.setDateHeader("Expires", 0); // 0 means now
        req.setAttribute("currentSession", session);
        getServletContext().getRequestDispatcher(resp.encodeURL(sessionDetailJspPath)).include(req, resp);
    }

    /**
     * Invalidate HttpSessions
     * @param cn Name of the application for which sessions are to be
     *           invalidated
     * @param sessionIds
     * @param smClient  StringManager for the client's locale
     * @return number of invalidated sessions
     * @throws IOException
     */
    protected int invalidateSessions(ContextName cn, String[] sessionIds,
            StringManager smClient) throws IOException {
        if (null == sessionIds) {
            return 0;
        }
        int nbAffectedSessions = 0;
        for (int i = 0; i < sessionIds.length; ++i) {
            String sessionId = sessionIds[i];
            HttpSession session =
                getSessionForNameAndId(cn, sessionId, smClient).getSession();
            if (null == session) {
                // Shouldn't happen, but let's play nice...
                if (debug >= 1) {
                    log("WARNING: can't invalidate null session " + sessionId);
                }
                continue;
            }
            try {
                session.invalidate();
                ++nbAffectedSessions;
                if (debug >= 1) {
                    log("Invalidating session id " + sessionId);
                }
            } catch (IllegalStateException ise) {
                if (debug >= 1) {
                    log("Can't invalidate already invalidated session id " + sessionId);
                }
            }
        }
        return nbAffectedSessions;
    }

    /**
     * Removes an attribute from an HttpSession
     * @param cn Name of the application hosting the session from which the
     *           attribute is to be removed
     * @param sessionId
     * @param attributeName
     * @param smClient  StringManager for the client's locale
     * @return true if there was an attribute removed, false otherwise
     * @throws IOException
     */
    protected boolean removeSessionAttribute(ContextName cn, String sessionId,
            String attributeName, StringManager smClient) throws IOException {
        HttpSession session =
            getSessionForNameAndId(cn, sessionId, smClient).getSession();
        if (null == session) {
            // Shouldn't happen, but let's play nice...
            if (debug >= 1) {
                log("WARNING: can't remove attribute '" + attributeName + "' for null session " + sessionId);
            }
            return false;
        }
        boolean wasPresent = (null != session.getAttribute(attributeName));
        try {
            session.removeAttribute(attributeName);
        } catch (IllegalStateException ise) {
            if (debug >= 1) {
                log("Can't remote attribute '" + attributeName + "' for invalidated session id " + sessionId);
            }
        }
        return wasPresent;
    }

    protected Comparator<Session> getComparator(String sortBy) {
        Comparator<Session> comparator = null;
        if ("CreationTime".equalsIgnoreCase(sortBy)) {
            comparator = new BaseSessionComparator<Date>() {
                @Override
                public Comparable<Date> getComparableObject(Session session) {
                    return new Date(session.getCreationTime());
                }
            };
        } else if ("id".equalsIgnoreCase(sortBy)) {
            comparator = new BaseSessionComparator<String>() {
                @Override
                public Comparable<String> getComparableObject(Session session) {
                    return session.getId();
                }
            };
        } else if ("LastAccessedTime".equalsIgnoreCase(sortBy)) {
            comparator = new BaseSessionComparator<Date>() {
                @Override
                public Comparable<Date> getComparableObject(Session session) {
                    return new Date(session.getLastAccessedTime());
                }
            };
        } else if ("MaxInactiveInterval".equalsIgnoreCase(sortBy)) {
            comparator = new BaseSessionComparator<Integer>() {
                @Override
                public Comparable<Integer> getComparableObject(Session session) {
                    return Integer.valueOf(session.getMaxInactiveInterval());
                }
            };
        } else if ("new".equalsIgnoreCase(sortBy)) {
            comparator = new BaseSessionComparator<Boolean>() {
                @Override
                public Comparable<Boolean> getComparableObject(Session session) {
                    return Boolean.valueOf(session.getSession().isNew());
                }
            };
        } else if ("locale".equalsIgnoreCase(sortBy)) {
            comparator = new BaseSessionComparator<String>() {
                @Override
                public Comparable<String> getComparableObject(Session session) {
                    return JspHelper.guessDisplayLocaleFromSession(session);
                }
            };
        } else if ("user".equalsIgnoreCase(sortBy)) {
            comparator = new BaseSessionComparator<String>() {
                @Override
                public Comparable<String> getComparableObject(Session session) {
                    return JspHelper.guessDisplayUserFromSession(session);
                }
            };
        } else if ("UsedTime".equalsIgnoreCase(sortBy)) {
            comparator = new BaseSessionComparator<Date>() {
                @Override
                public Comparable<Date> getComparableObject(Session session) {
                    return new Date(SessionUtils.getUsedTimeForSession(session));
                }
            };
        } else if ("InactiveTime".equalsIgnoreCase(sortBy)) {
            comparator = new BaseSessionComparator<Date>() {
                @Override
                public Comparable<Date> getComparableObject(Session session) {
                    return new Date(SessionUtils.getInactiveTimeForSession(session));
                }
            };
        } else if ("TTL".equalsIgnoreCase(sortBy)) {
            comparator = new BaseSessionComparator<Date>() {
                @Override
                public Comparable<Date> getComparableObject(Session session) {
                    return new Date(SessionUtils.getTTLForSession(session));
                }
            };
        }
        //TODO: complete this to TTL, etc.
        return comparator;
    }

    // ------------------------------------------------------ Private Constants

    // These HTML sections are broken in relatively small sections, because of
    // limited number of substitutions MessageFormat can process
    // (maximum of 10).

    private static final String APPS_HEADER_SECTION =
        "<table border=\"1\" cellspacing=\"0\" cellpadding=\"3\">\n" +
        "<tr>\n" +
        " <td colspan=\"6\" class=\"title\">{0}</td>\n" +
        "</tr>\n" +
        "<tr>\n" +
        " <td class=\"header-left\"><small>{1}</small></td>\n" +
        " <td class=\"header-left\"><small>{2}</small></td>\n" +
        " <td class=\"header-center\"><small>{3}</small></td>\n" +
        " <td class=\"header-center\"><small>{4}</small></td>\n" +
        " <td class=\"header-left\"><small>{5}</small></td>\n" +
        " <td class=\"header-left\"><small>{6}</small></td>\n" +
        "</tr>\n";

    private static final String APPS_ROW_DETAILS_SECTION =
        "<tr>\n" +
        " <td class=\"row-left\" bgcolor=\"{6}\" rowspan=\"2\"><small>{0}</small></td>\n" +
        " <td class=\"row-left\" bgcolor=\"{6}\" rowspan=\"2\"><small>{1}</small></td>\n" +
        " <td class=\"row-left\" bgcolor=\"{6}\" rowspan=\"2\"><small>{2}</small></td>\n" +
        " <td class=\"row-center\" bgcolor=\"{6}\" rowspan=\"2\"><small>{3}</small></td>\n" +
        " <td class=\"row-center\" bgcolor=\"{6}\" rowspan=\"2\">" +
        "<small><a href=\"{4}\">{5}</a></small></td>\n";

    private static final String MANAGER_APP_ROW_BUTTON_SECTION =
        " <td class=\"row-left\" bgcolor=\"{13}\">\n" +
        "  <small>\n" +
        "  &nbsp;{1}&nbsp;\n" +
        "  &nbsp;{3}&nbsp;\n" +
        "  &nbsp;{5}&nbsp;\n" +
        "  &nbsp;{7}&nbsp;\n" +
        "  </small>\n" +
        " </td>\n" +
        "</tr><tr>\n" +
        " <td class=\"row-left\" bgcolor=\"{13}\">\n" +
        "  <form method=\"POST\" action=\"{8}\">\n" +
        "  <small>\n" +
        "  &nbsp;<input type=\"submit\" value=\"{9}\">&nbsp;{10}&nbsp;<input type=\"text\" name=\"idle\" size=\"5\" value=\"{11}\">&nbsp;{12}&nbsp;\n" +
        "  </small>\n" +
        "  </form>\n" +
        " </td>\n" +
        "</tr>\n";

    private static final String STARTED_DEPLOYED_APPS_ROW_BUTTON_SECTION =
        " <td class=\"row-left\" bgcolor=\"{13}\">\n" +
        "  &nbsp;<small>{1}</small>&nbsp;\n" +
        "  <form class=\"inline\" method=\"POST\" action=\"{2}\">" +
        "  <small><input type=\"submit\" value=\"{3}\"></small>" +
        "  </form>\n" +
        "  <form class=\"inline\" method=\"POST\" action=\"{4}\">" +
        "  <small><input type=\"submit\" value=\"{5}\"></small>" +
        "  </form>\n" +
        "  <form class=\"inline\" method=\"POST\" action=\"{6}\">" +
        "  <small><input type=\"submit\" value=\"{7}\"></small>" +
        "  </form>\n" +
        " </td>\n" +
        " </tr><tr>\n" +
        " <td class=\"row-left\" bgcolor=\"{13}\">\n" +
        "  <form method=\"POST\" action=\"{8}\">\n" +
        "  <small>\n" +
        "  &nbsp;<input type=\"submit\" value=\"{9}\">&nbsp;{10}&nbsp;<input type=\"text\" name=\"idle\" size=\"5\" value=\"{11}\">&nbsp;{12}&nbsp;\n" +
        "  </small>\n" +
        "  </form>\n" +
        " </td>\n" +
        "</tr>\n";

    private static final String STOPPED_DEPLOYED_APPS_ROW_BUTTON_SECTION =
        " <td class=\"row-left\" bgcolor=\"{13}\" rowspan=\"2\">\n" +
        "  <form class=\"inline\" method=\"POST\" action=\"{0}\">" +
        "  <small><input type=\"submit\" value=\"{1}\"></small>" +
        "  </form>\n" +
        "  &nbsp;<small>{3}</small>&nbsp;\n" +
        "  &nbsp;<small>{5}</small>&nbsp;\n" +
        "  <form class=\"inline\" method=\"POST\" action=\"{6}\">" +
        "  <small><input type=\"submit\" value=\"{7}\"></small>" +
        "  </form>\n" +
        " </td>\n" +
        "</tr>\n<tr></tr>\n";

    private static final String STARTED_NONDEPLOYED_APPS_ROW_BUTTON_SECTION =
        " <td class=\"row-left\" bgcolor=\"{13}\">\n" +
        "  &nbsp;<small>{1}</small>&nbsp;\n" +
        "  <form class=\"inline\" method=\"POST\" action=\"{2}\">" +
        "  <small><input type=\"submit\" value=\"{3}\"></small>" +
        "  </form>\n" +
        "  <form class=\"inline\" method=\"POST\" action=\"{4}\">" +
        "  <small><input type=\"submit\" value=\"{5}\"></small>" +
        "  </form>\n" +
        "  &nbsp;<small>{7}</small>&nbsp;\n" +
        " </td>\n" +
        " </tr><tr>\n" +
        " <td class=\"row-left\" bgcolor=\"{13}\">\n" +
        "  <form method=\"POST\" action=\"{8}\">\n" +
        "  <small>\n" +
        "  &nbsp;<input type=\"submit\" value=\"{9}\">&nbsp;{10}&nbsp;<input type=\"text\" name=\"idle\" size=\"5\" value=\"{11}\">&nbsp;{12}&nbsp;\n" +
        "  </small>\n" +
        "  </form>\n" +
        " </td>\n" +
        "</tr>\n";

    private static final String STOPPED_NONDEPLOYED_APPS_ROW_BUTTON_SECTION =
        " <td class=\"row-left\" bgcolor=\"{13}\" rowspan=\"2\">\n" +
        "  <form class=\"inline\" method=\"POST\" action=\"{0}\">" +
        "  <small><input type=\"submit\" value=\"{1}\"></small>" +
        "  </form>\n" +
        "  &nbsp;<small>{3}</small>&nbsp;\n" +
        "  &nbsp;<small>{5}</small>&nbsp;\n" +
        "  &nbsp;<small>{7}</small>&nbsp;\n" +
        " </td>\n" +
        "</tr>\n<tr></tr>\n";

    private static final String DEPLOY_SECTION =
        "</table>\n" +
        "<br>\n" +
        "<table border=\"1\" cellspacing=\"0\" cellpadding=\"3\">\n" +
        "<tr>\n" +
        " <td colspan=\"2\" class=\"title\">{0}</td>\n" +
        "</tr>\n" +
        "<tr>\n" +
        " <td colspan=\"2\" class=\"header-left\"><small>{1}</small></td>\n" +
        "</tr>\n" +
        "<tr>\n" +
        " <td colspan=\"2\">\n" +
        "<form method=\"post\" action=\"{2}\">\n" +
        "<table cellspacing=\"0\" cellpadding=\"3\">\n" +
        "<tr>\n" +
        " <td class=\"row-right\">\n" +
        "  <small>{3}</small>\n" +
        " </td>\n" +
        " <td class=\"row-left\">\n" +
        "  <input type=\"text\" name=\"deployPath\" size=\"20\">\n" +
        " </td>\n" +
        "</tr>\n" +
        "<tr>\n" +
        " <td class=\"row-right\">\n" +
        "  <small>{4}</small>\n" +
        " </td>\n" +
        " <td class=\"row-left\">\n" +
        "  <input type=\"text\" name=\"deployConfig\" size=\"20\">\n" +
        " </td>\n" +
        "</tr>\n" +
        "<tr>\n" +
        " <td class=\"row-right\">\n" +
        "  <small>{5}</small>\n" +
        " </td>\n" +
        " <td class=\"row-left\">\n" +
        "  <input type=\"text\" name=\"deployWar\" size=\"40\">\n" +
        " </td>\n" +
        "</tr>\n" +
        "<tr>\n" +
        " <td class=\"row-right\">\n" +
        "  &nbsp;\n" +
        " </td>\n" +
        " <td class=\"row-left\">\n" +
        "  <input type=\"submit\" value=\"{6}\">\n" +
        " </td>\n" +
        "</tr>\n" +
        "</table>\n" +
        "</form>\n" +
        "</td>\n" +
        "</tr>\n";

    private static final String UPLOAD_SECTION =
        "<tr>\n" +
        " <td colspan=\"2\" class=\"header-left\"><small>{0}</small></td>\n" +
        "</tr>\n" +
        "<tr>\n" +
        " <td colspan=\"2\">\n" +
        "<form method=\"post\" action=\"{1}\" " +
        "enctype=\"multipart/form-data\">\n" +
        "<table cellspacing=\"0\" cellpadding=\"3\">\n" +
        "<tr>\n" +
        " <td class=\"row-right\">\n" +
        "  <small>{2}</small>\n" +
        " </td>\n" +
        " <td class=\"row-left\">\n" +
        "  <input type=\"file\" name=\"deployWar\" size=\"40\">\n" +
        " </td>\n" +
        "</tr>\n" +
        "<tr>\n" +
        " <td class=\"row-right\">\n" +
        "  &nbsp;\n" +
        " </td>\n" +
        " <td class=\"row-left\">\n" +
        "  <input type=\"submit\" value=\"{3}\">\n" +
        " </td>\n" +
        "</tr>\n" +
        "</table>\n" +
        "</form>\n" +
        "</td>\n" +
        "</tr>\n" +
        "</table>\n" +
        "<br>\n" +
        "\n";

    private static final String DIAGNOSTICS_SECTION =
        "<table border=\"1\" cellspacing=\"0\" cellpadding=\"3\">\n" +
        "<tr>\n" +
        " <td colspan=\"2\" class=\"title\">{0}</td>\n" +
        "</tr>\n" +
        "<tr>\n" +
        " <td colspan=\"2\" class=\"header-left\"><small>{1}</small></td>\n" +
        "</tr>\n" +
        "<tr>\n" +
        " <td colspan=\"2\">\n" +
        "<form method=\"post\" action=\"{2}\">\n" +
        "<table cellspacing=\"0\" cellpadding=\"3\">\n" +
        "<tr>\n" +
        " <td class=\"row-left\">\n" +
        "  <input type=\"submit\" value=\"{4}\">\n" +
        " </td>\n" +
        " <td class=\"row-left\">\n" +
        "  <small>{3}</small>\n" +
        " </td>\n" +
        "</tr>\n" +
        "</table>\n" +
        "</form>\n" +
        "</td>\n" +
        "</tr>\n" +
        "<tr>\n" +
        " <td colspan=\"2\" class=\"header-left\"><small>{5}</small></td>\n" +
        "</tr>\n" +
        "<tr>\n" +
        " <td colspan=\"2\">\n" +
        "<form method=\"post\" action=\"{6}\">\n" +
        "<table cellspacing=\"0\" cellpadding=\"3\">\n" +
        "<tr>\n" +
        " <td class=\"row-left\">\n" +
        "  <input type=\"submit\" value=\"{7}\">\n" +
        " </td>\n" +
        " <td class=\"row-left\">\n" +
        "  <small>{8}</small>\n" +
        " </td>\n" +
        "</tr>\n" +
        "</table>\n" +
        "</form>\n" +
        "</td>\n" +
        "</tr>\n" +
        "</table>\n" +
        "<br>";
}
