📄 managerservlet.java
字号:
/*
* 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.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Iterator;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import javax.naming.Binding;
import javax.naming.InitialContext;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.UnavailableException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.catalina.Container;
import org.apache.catalina.ContainerServlet;
import org.apache.catalina.Context;
import org.apache.catalina.Engine;
import org.apache.catalina.Globals;
import org.apache.catalina.Host;
import org.apache.catalina.Lifecycle;
import org.apache.catalina.Role;
import org.apache.catalina.Server;
import org.apache.catalina.ServerFactory;
import org.apache.catalina.Session;
import org.apache.catalina.UserDatabase;
import org.apache.catalina.Wrapper;
import org.apache.catalina.core.StandardServer;
import org.apache.catalina.util.RequestUtil;
import org.apache.catalina.util.ServerInfo;
import org.apache.catalina.util.StringManager;
import org.apache.tomcat.util.modeler.Registry;
/**
* Servlet that enables remote management of the web applications installed
* 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>
* This servlet examines the value returned by <code>getPathInfo()</code>
* and related query parameters to determine what action is being requested.
* The following actions and parameters (starting after the servlet path)
* are supported:
* <ul>
* <li><b>/deploy?config={config-url}</b> - Install and start a new
* web application, based on the contents of the context configuration
* file found at the specified URL. The <code>docBase</code> attribute
* of the context configuration file is used to locate the actual
* WAR or directory containing the application.</li>
* <li><b>/deploy?config={config-url}&war={war-url}/</b> - Install and start
* a new web application, based on the contents of the context
* configuration file found at <code>{config-url}</code>, overriding the
* <code>docBase</code> attribute with the contents of the web
* application archive found at <code>{war-url}</code>.</li>
* <li><b>/deploy?path=/xxx&war={war-url}</b> - Install and start a new
* web application attached to context path <code>/xxx</code>, based
* on the contents of the web application archive found at the
* specified URL.</li>
* <li><b>/list</b> - List the context paths of all currently installed web
* applications for this virtual host. Each context will be listed with
* the following format <code>path:status:sessions</code>.
* Where path is the context path. Status is either running or stopped.
* Sessions is the number of active Sessions.</li>
* <li><b>/reload?path=/xxx</b> - Reload the Java classes and resources for
* the application at the specified path.</li>
* <li><b>/resources?type=xxxx</b> - Enumerate the available global JNDI
* resources, optionally limited to those of the specified type
* (fully qualified Java class name), if available.</li>
* <li><b>/roles</b> - Enumerate the available security role names and
* descriptions from the user database connected to the <code>users</code>
* resource reference.
* <li><b>/serverinfo</b> - Display system OS and JVM properties.
* <li><b>/sessions?path=/xxx</b> - List session information about the web
* application attached to context path <code>/xxx</code> for this
* virtual host.</li>
* <li><b>/start?path=/xxx</b> - Start the web application attached to
* context path <code>/xxx</code> for this virtual host.</li>
* <li><b>/stop?path=/xxx</b> - Stop the web application attached to
* context path <code>/xxx</code> for this virtual host.</li>
* <li><b>/undeploy?path=/xxx</b> - Shutdown and remove the web application
* attached to context path <code>/xxx</code> for this virtual host,
* and remove the underlying WAR file or document base directory.
* (<em>NOTE</em> - This is only allowed if the WAR file or document
* base is stored in the <code>appBase</code> directory of this host,
* typically as a result of being placed there via the <code>/deploy</code>
* command.</li>
* </ul>
* <p>Use <code>path=/</code> for the ROOT context.</p>
* <p>The syntax of the URL for a web application archive must conform to one
* of the following patterns to be successfully deployed:</p>
* <ul>
* <li><b>file:/absolute/path/to/a/directory</b> - You can specify the absolute
* path of a directory that contains the unpacked version of a web
* application. This directory will be attached to the context path you
* specify without any changes.</li>
* <li><b>jar:file:/absolute/path/to/a/warfile.war!/</b> - You can specify a
* URL to a local web application archive file. The syntax must conform to
* the rules specified by the <code>JarURLConnection</code> class for a
* reference to an entire JAR file.</li>
* <li><b>jar:http://hostname:port/path/to/a/warfile.war!/</b> - You can specify
* a URL to a remote (HTTP-accessible) web application archive file. The
* syntax must conform to the rules specified by the
* <code>JarURLConnection</code> class for a reference to an entire
* JAR file.</li>
* </ul>
* <p>
* <b>NOTE</b> - Attempting to reload or remove the application containing
* this servlet itself will not succeed. Therefore, this servlet should
* generally be deployed as a separate web application within the virtual host
* to be managed.
* <p>
* <b>NOTE</b> - For security reasons, this application will not operate
* when accessed via the invoker servlet. You must explicitly map this servlet
* with a servlet mapping, and you will always want to protect it with
* appropriate security constraints as well.
* <p>
* The following servlet initialization parameters are recognized:
* <ul>
* <li><b>debug</b> - The debugging detail level that controls the amount
* of information that is logged by this servlet. Default is zero.
* </ul>
*
* @author Craig R. McClanahan
* @author Remy Maucherat
* @version $Revision: 467222 $ $Date: 2006-10-24 05:17:11 +0200 (mar., 24 oct. 2006) $
*/
public class ManagerServlet
extends HttpServlet implements ContainerServlet {
// ----------------------------------------------------- Instance Variables
/**
* Path where context descriptors should be deployed.
*/
protected File configBase = null;
/**
* The Context container associated with our web application.
*/
protected Context context = null;
/**
* The debugging detail level for this servlet.
*/
protected int debug = 1;
/**
* File object representing the directory into which the deploy() command
* will store the WAR and context configuration files that have been
* uploaded.
*/
protected File deployed = null;
/**
* Path used to store revisions of webapps.
*/
protected File versioned = null;
/**
* Path used to store context descriptors.
*/
protected File contextDescriptors = null;
/**
* The associated host.
*/
protected Host host = null;
/**
* The host appBase.
*/
protected File appBase = null;
/**
* MBean server.
*/
protected MBeanServer mBeanServer = null;
/**
* The associated deployer ObjectName.
*/
protected ObjectName oname = null;
/**
* The global JNDI <code>NamingContext</code> for this server,
* if available.
*/
protected javax.naming.Context global = null;
/**
* The string manager for this package.
*/
protected static StringManager sm =
StringManager.getManager(Constants.Package);
/**
* The Wrapper container associated with this servlet.
*/
protected Wrapper wrapper = null;
// ----------------------------------------------- ContainerServlet Methods
/**
* Return the Wrapper with which we are associated.
*/
public Wrapper getWrapper() {
return (this.wrapper);
}
/**
* Set the Wrapper with which we are associated.
*
* @param wrapper The new wrapper
*/
public void setWrapper(Wrapper wrapper) {
this.wrapper = wrapper;
if (wrapper == null) {
context = null;
host = null;
oname = null;
} else {
context = (Context) wrapper.getParent();
host = (Host) context.getParent();
Engine engine = (Engine) host.getParent();
try {
oname = new ObjectName(engine.getName()
+ ":type=Deployer,host=" + host.getName());
} catch (Exception e) {
// ?
}
}
// Retrieve the MBean server
mBeanServer = Registry.getRegistry(null, null).getMBeanServer();
}
// --------------------------------------------------------- Public Methods
/**
* Finalize this servlet.
*/
public void destroy() {
; // No actions necessary
}
/**
* 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
*/
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException {
// Verify that we were not accessed using the invoker servlet
if (request.getAttribute(Globals.INVOKED_ATTR) != null)
throw new UnavailableException
(sm.getString("managerServlet.cannotInvoke"));
// Identify the request parameters that we need
String command = request.getPathInfo();
if (command == null)
command = request.getServletPath();
String config = request.getParameter("config");
String path = request.getParameter("path");
String type = request.getParameter("type");
String war = request.getParameter("war");
String tag = request.getParameter("tag");
boolean update = false;
if ((request.getParameter("update") != null)
&& (request.getParameter("update").equals("true"))) {
update = true;
}
// Prepare our output writer to generate the response message
response.setContentType("text/plain; charset=" + Constants.CHARSET);
PrintWriter writer = response.getWriter();
// Process the requested command (note - "/deploy" is not listed here)
if (command == null) {
writer.println(sm.getString("managerServlet.noCommand"));
} else if (command.equals("/deploy")) {
if (war != null || config != null) {
deploy(writer, config, path, war, update);
} else {
deploy(writer, path, tag);
}
} else if (command.equals("/install")) {
// Deprecated
deploy(writer, config, path, war, false);
} else if (command.equals("/list")) {
list(writer);
} else if (command.equals("/reload")) {
reload(writer, path);
} else if (command.equals("/remove")) {
// Deprecated
undeploy(writer, path);
} else if (command.equals("/resources")) {
resources(writer, type);
} else if (command.equals("/roles")) {
roles(writer);
} else if (command.equals("/save")) {
save(writer, path);
} else if (command.equals("/serverinfo")) {
serverinfo(writer);
} else if (command.equals("/sessions")) {
sessions(writer, path);
} else if (command.equals("/start")) {
start(writer, path);
} else if (command.equals("/stop")) {
stop(writer, path);
} else if (command.equals("/undeploy")) {
undeploy(writer, path);
} else {
writer.println(sm.getString("managerServlet.unknownCommand",
command));
}
// Finish up the response
writer.flush();
writer.close();
}
/**
* Process a PUT 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
*/
public void doPut(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException {
// Verify that we were not accessed using the invoker servlet
if (request.getAttribute(Globals.INVOKED_ATTR) != null)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -