📄 managerbase.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.session;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.PrivilegedAction;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import javax.management.MBeanRegistration;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import org.apache.catalina.Container;
import org.apache.catalina.Engine;
import org.apache.catalina.Globals;
import org.apache.catalina.Manager;
import org.apache.catalina.Session;
import org.apache.catalina.core.StandardContext;
import org.apache.catalina.core.StandardHost;
import org.apache.catalina.util.StringManager;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
import org.apache.tomcat.util.modeler.Registry;
/**
* Minimal implementation of the <b>Manager</b> interface that supports
* no session persistence or distributable capabilities. This class may
* be subclassed to create more sophisticated Manager implementations.
*
* @author Craig R. McClanahan
* @version $Revision: 505593 $ $Date: 2007-02-10 01:54:56 +0100 (sam., 10 févr. 2007) $
*/
public abstract class ManagerBase implements Manager, MBeanRegistration {
protected Log log = LogFactory.getLog(ManagerBase.class);
// ----------------------------------------------------- Instance Variables
protected DataInputStream randomIS=null;
protected String devRandomSource="/dev/urandom";
/**
* The default message digest algorithm to use if we cannot use
* the requested one.
*/
protected static final String DEFAULT_ALGORITHM = "MD5";
/**
* The message digest algorithm to be used when generating session
* identifiers. This must be an algorithm supported by the
* <code>java.security.MessageDigest</code> class on your platform.
*/
protected String algorithm = DEFAULT_ALGORITHM;
/**
* The Container with which this Manager is associated.
*/
protected Container container;
/**
* Return the MessageDigest implementation to be used when
* creating session identifiers.
*/
protected MessageDigest digest = null;
/**
* The distributable flag for Sessions created by this Manager. If this
* flag is set to <code>true</code>, any user attributes added to a
* session controlled by this Manager must be Serializable.
*/
protected boolean distributable;
/**
* A String initialization parameter used to increase the entropy of
* the initialization of our random number generator.
*/
protected String entropy = null;
/**
* The descriptive information string for this implementation.
*/
private static final String info = "ManagerBase/1.0";
/**
* The default maximum inactive interval for Sessions created by
* this Manager.
*/
protected int maxInactiveInterval = 60;
/**
* The session id length of Sessions created by this Manager.
*/
protected int sessionIdLength = 16;
/**
* The descriptive name of this Manager implementation (for logging).
*/
protected static String name = "ManagerBase";
/**
* A random number generator to use when generating session identifiers.
*/
protected Random random = null;
/**
* The Java class name of the random number generator class to be used
* when generating session identifiers.
*/
protected String randomClass = "java.security.SecureRandom";
/**
* The longest time (in seconds) that an expired session had been alive.
*/
protected int sessionMaxAliveTime;
/**
* Average time (in seconds) that expired sessions had been alive.
*/
protected int sessionAverageAliveTime;
/**
* Number of sessions that have expired.
*/
protected int expiredSessions = 0;
/**
* The set of currently active Sessions for this Manager, keyed by
* session identifier.
*/
protected Map sessions = new ConcurrentHashMap();
// Number of sessions created by this manager
protected int sessionCounter=0;
protected int maxActive=0;
// number of duplicated session ids - anything >0 means we have problems
protected int duplicates=0;
protected boolean initialized=false;
/**
* Processing time during session expiration.
*/
protected long processingTime = 0;
/**
* Iteration count for background processing.
*/
private int count = 0;
/**
* Frequency of the session expiration, and related manager operations.
* Manager operations will be done once for the specified amount of
* backgrondProcess calls (ie, the lower the amount, the most often the
* checks will occur).
*/
protected int processExpiresFrequency = 6;
/**
* The string manager for this package.
*/
protected static StringManager sm =
StringManager.getManager(Constants.Package);
/**
* The property change support for this component.
*/
protected PropertyChangeSupport support = new PropertyChangeSupport(this);
// ------------------------------------------------------------- Security classes
private class PrivilegedSetRandomFile implements PrivilegedAction{
public Object run(){
try {
File f=new File( devRandomSource );
if( ! f.exists() ) return null;
randomIS= new DataInputStream( new FileInputStream(f));
randomIS.readLong();
if( log.isDebugEnabled() )
log.debug( "Opening " + devRandomSource );
return randomIS;
} catch (IOException ex){
return null;
}
}
}
// ------------------------------------------------------------- Properties
/**
* Return the message digest algorithm for this Manager.
*/
public String getAlgorithm() {
return (this.algorithm);
}
/**
* Set the message digest algorithm for this Manager.
*
* @param algorithm The new message digest algorithm
*/
public void setAlgorithm(String algorithm) {
String oldAlgorithm = this.algorithm;
this.algorithm = algorithm;
support.firePropertyChange("algorithm", oldAlgorithm, this.algorithm);
}
/**
* Return the Container with which this Manager is associated.
*/
public Container getContainer() {
return (this.container);
}
/**
* Set the Container with which this Manager is associated.
*
* @param container The newly associated Container
*/
public void setContainer(Container container) {
Container oldContainer = this.container;
this.container = container;
support.firePropertyChange("container", oldContainer, this.container);
}
/** Returns the name of the implementation class.
*/
public String getClassName() {
return this.getClass().getName();
}
/**
* Return the MessageDigest object to be used for calculating
* session identifiers. If none has been created yet, initialize
* one the first time this method is called.
*/
public synchronized MessageDigest getDigest() {
if (this.digest == null) {
long t1=System.currentTimeMillis();
if (log.isDebugEnabled())
log.debug(sm.getString("managerBase.getting", algorithm));
try {
this.digest = MessageDigest.getInstance(algorithm);
} catch (NoSuchAlgorithmException e) {
log.error(sm.getString("managerBase.digest", algorithm), e);
try {
this.digest = MessageDigest.getInstance(DEFAULT_ALGORITHM);
} catch (NoSuchAlgorithmException f) {
log.error(sm.getString("managerBase.digest",
DEFAULT_ALGORITHM), e);
this.digest = null;
}
}
if (log.isDebugEnabled())
log.debug(sm.getString("managerBase.gotten"));
long t2=System.currentTimeMillis();
if( log.isDebugEnabled() )
log.debug("getDigest() " + (t2-t1));
}
return (this.digest);
}
/**
* Return the distributable flag for the sessions supported by
* this Manager.
*/
public boolean getDistributable() {
return (this.distributable);
}
/**
* Set the distributable flag for the sessions supported by this
* Manager. If this flag is set, all user data objects added to
* sessions associated with this manager must implement Serializable.
*
* @param distributable The new distributable flag
*/
public void setDistributable(boolean distributable) {
boolean oldDistributable = this.distributable;
this.distributable = distributable;
support.firePropertyChange("distributable",
new Boolean(oldDistributable),
new Boolean(this.distributable));
}
/**
* Return the entropy increaser value, or compute a semi-useful value
* if this String has not yet been set.
*/
public String getEntropy() {
// Calculate a semi-useful value if this has not been set
if (this.entropy == null) {
// Use APR to get a crypto secure entropy value
byte[] result = new byte[32];
boolean apr = false;
try {
String methodName = "random";
Class paramTypes[] = new Class[2];
paramTypes[0] = result.getClass();
paramTypes[1] = int.class;
Object paramValues[] = new Object[2];
paramValues[0] = result;
paramValues[1] = new Integer(32);
Method method = Class.forName("org.apache.tomcat.jni.OS")
.getMethod(methodName, paramTypes);
method.invoke(null, paramValues);
apr = true;
} catch (Throwable t) {
// Ignore
}
if (apr) {
setEntropy(new String(result));
} else {
setEntropy(this.toString());
}
}
return (this.entropy);
}
/**
* Set the entropy increaser value.
*
* @param entropy The new entropy increaser value
*/
public void setEntropy(String entropy) {
String oldEntropy = entropy;
this.entropy = entropy;
support.firePropertyChange("entropy", oldEntropy, this.entropy);
}
/**
* Return descriptive information about this Manager implementation and
* the corresponding version number, in the format
* <code><description>/<version></code>.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -