Commit 995d4e4e authored by Emmanuel Bourg's avatar Emmanuel Bourg

New upstream version 8.0.39

parent 35c4f84d
......@@ -614,3 +614,63 @@ QCuUl/v3Zly66jThcNS/U6S9VXBtQRxDZtkL8pSzmJxaFvvnZgkQ/hlvJ8f9ccS7
2/KQU94=
=yvcP
-----END PGP PUBLIC KEY BLOCK-----
pub 4096R/D63011C7 2013-09-19
Key fingerprint = 713D A88B E509 1153 5FE7 16F5 208B 0AB1 D630 11C7
uid Violeta Georgieva Georgieva (CODE SIGNING KEY) <violetagg@apache.org>
sig 3 D63011C7 2013-09-19 Violeta Georgieva Georgieva (CODE SIGNING KEY) <violetagg@apache.org>
sub 4096R/30480593 2013-09-19
sig D63011C7 2013-09-19 Violeta Georgieva Georgieva (CODE SIGNING KEY) <violetagg@apache.org>
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v2.0.21 (MingW32)
mQINBFI6WiwBEAD+kkswnsY8eaqvYkS+ZB5MJr7juWrv9Lw9OGsIXFlTvD1XK01c
E8k4+uA2sOtaXQ5wTMdc5N3YzAXqFxplWuafQgEvhyTTq37M5YCxvtYEZy/EHQYT
iok5H97lMRKbhLdZB+wkdsa0P/L1FveCUiEawKY/Rrfi+UeRAneSV+m7S+RrPphZ
M9aNSczqYKfAqlpUAlUcrF/bt59vjhepoHcE4ev6SB+PCs0vbvX4iTvvZCTk1lZ9
InS2wdK80Jz9pRB0Uf3LEnZxt9e3RkIFdQOCcEISmNlBKQQKFG+zCpIAbVoMLKEw
rXWl8mLzGzBbhGmLpFroem3Ln1YiAxUqnPR/MoBquYnpTINwePgwKVWyQ1TXG2MF
Z7DPayBMN+G51rfLS/8iy35pAnNeqbWQjavdUis6/0aRMv5EYMFMAerutQ5v99bA
rGj6OL3R6repJLOGT4YWcD/Tw+eU1lMWxbq8BbbRU9Fd0iVFhFyKB/DQSxofvTCe
PdWXRrptrE0/SmvuoTRVPmB21WyJenKdNmVOQ6U+W1Rs+5IKAdWWrGPcUt0qTrRC
SL8vAQ7MejYLovFtRHslJRs7T3ratpRcQUNOx1jytJhmSUJktNWZWNHqBTe/eOAU
Yr+QAkQVQXvRVWzHkDHQRTOFmNYIDZYRkzSP19sBWRnYdCs6CbIVPgMJVwARAQAB
tEVWaW9sZXRhIEdlb3JnaWV2YSBHZW9yZ2lldmEgKENPREUgU0lHTklORyBLRVkp
IDx2aW9sZXRhZ2dAYXBhY2hlLm9yZz6JAjcEEwEKACEFAlI6WiwCGwMFCwkIBwMF
FQoJCAsFFgIDAQACHgECF4AACgkQIIsKsdYwEccMXA/+KMQKWfw2T2CXLhqvQLoh
Irj1Vi9leAttKqKp2NCHLK1jf1qKzUx5U81VvizIGUsDXGlAvnnavrj+hmQqZdsO
CoJAo7ViIR1ZhNca1tFK4Sy03wdpNyUkvxVuC+3peXmwhjPJoqU2ONCuDl/bCczl
QAQpgZCMO93h45U9H6JkjqK01aDorQHxvXo+Ap2IViQvDkNtJ515vG2k5K+x2XHw
Tv19wr5N2rz407TWKzS5hh7QHRgg+PZs/zPf1YHD7Tg5K6vvmZd+5EsDrse6tZXy
mzz2+8Yg1SNa765Aq6p1uAQf5NKeej/25TbRYT7RyIlgDXPcPrKxy0cKzpqFqCFs
jJEcN3NlQq+f1tOvUk8cQQS0G+Qws3EU7I74z8KaUfqmO/5ROrXLS50cKC9CODO0
UFY8FbJDGzS5cFSBlqXYLeQvaOMg0LsV6wZLu6brxEsRYjSpwM8yBFO4bMcTxt4P
VYtinNZ+6ude8mMz6BK/0/XbAL6rc5jwO2xj7GTCFNRTWOa8IGtwqg3qnAiHcg/V
bTBQCOmzMujHBXLnZu6vg79BwzE7Ikq634D6HEwi1bC3XuVz+7NqdUQAGPSapwUo
+0wC5DVwdjhe1zWcf2Zc45HWsx0HaGW28x/tBrw78fgwrSSyV2xunbxGpVaaysTy
Oini8V70uLofn1SHtxvEQCm5Ag0EUjpaLAEQAKV7FnaAcxkzDa7zjrAgLRho44KM
+lBt28+5KO3Jye1Lpf2+4aspu0PXkGW2Twv2tBQNZYs2CWF+vnHNUDuU8TkSpPt+
2PRSZrQ0K+IpQF/qY3Wf+LYWFNXk5/wHJLGiQv/008svtupng6Ov39JwCNQ1iG3d
nSWfnqHwQULyE7JcZf1It94G43+6NBvKakstOdK7d40dVhmRIKDdJkWhN3MKrGab
FGFAF2Nb57IugQ9QO6Ve/BnjKZmJg7TyUZk27LVTC0aUQgGgDOvsF2Iw95IplCZ/
jVbwdBGjeCStvI3c0DB+E2xwJ0g2Wf/CBLvmU9GKOW0toBfRUXFbfzNTJfW8kglt
pDuELsVY5vHHxgujdDInHuTW1930zUw0cNA2+ai3sf+UGejh0e3nGfy1uOK3YQ6H
2YWgqXlOkri9pMlE0NJo/3PW9QDu0YRplGl65k+GtHD2La1akq5V5Et0VNaOypBP
OqnUM08LofAS126Kerm7uBSUQDDV6t1VTOBgPW5cJF9I8kdp04pzj4qb/3fuOuGc
kBRfmO/Vkug8U81w/TnxX6EYGy5fyA4JFBJl++waPS/9dXhVnA0qXEivzw9gNQvC
uXYcM3nm4yUrOouC/OlC1cS+6Wxjrx6qn3NnsVzMCtefNK93+TdheZ0cJrMhJKkW
v+qttOzPIleqvDK9ABEBAAGJAh8EGAEKAAkFAlI6WiwCGwwACgkQIIsKsdYwEcdN
tQ/+L8cw9Z9tfrqovO1fGFQwCSaomShsbjoUb5AR3Hj3OuPGwXd8J62mrw+RnGN+
0w2RyTz52izYvcoB1jmMFQwqi7vM5KCbw6KA8oRX58WSqiWCIwpbUuTODvJrSXjX
pz/J/d+PVZi8T1HAu5HxDqNC1XR+eUd1xA9Pgnmmw99+0rmzES7xexWADXo/RRPH
mDCxGK3UKMHDYJLTx8D3MacMitzQulxVo9xWwH1C7ioL3o5zCv2mfIl32WNjqwpD
h4gNpnAGRthizeYTgyJM9nCrSWgeE+izGZ9F0g5uXzhyk1f6jlUmXiwjMu/XOcJO
5Rr1e42bWITuP49nB2QbdSqVvVscwCd5TEpOnQtVNZGsss/wQHXDmGSVrYYUQwO/
cUrU+hTti1IJXgyFi7F1oxde+LCUxXmizKGoY96dVN+TYH5c17ub1/4/DYpOmcly
tsQ2TOV0BqK4rgKLGfg2mA4zIFOdqXeGefLQVAF5fFzjFKKDi0ewp3sqy+ed6mKY
1M/HmRX/YzIouFZ3ChFPIpeY23XxJC0BXkWR4pS7qxnelrWBZ+UbleNr9uHat5rC
B77712dCT9zz85b380DnuMkrgz4HCnHuTcbHXIF1J604lars6ZrjtBvX+OsRHt7V
f72qKJufP+n01xliW68LP4v93auM8nuE4kkEJ8ncHyuDq/Q=
=fM0q
-----END PGP PUBLIC KEY BLOCK-----
......@@ -25,7 +25,7 @@
# ----- Version Control Flags -----
version.major=8
version.minor=0
version.build=38
version.build=39
version.patch=0
version.suffix=
......@@ -148,8 +148,8 @@ wsdl4j-lib.jar=${wsdl4j-lib.home}/wsdl4j-${wsdl4j-lib.version}.jar
# ----- Eclipse JDT, version 4.5 or later -----#
# See https://wiki.apache.org/tomcat/JDTCoreBatchCompiler before updating
jdt.version=4.5
jdt.release=R-4.5-201506032000
jdt.version=4.5.1
jdt.release=R-4.5.1-201509040015
jdt.home=${base.path}/ecj-${jdt.version}
jdt.jar=${jdt.home}/ecj-${jdt.version}.jar
# The download will be moved to the archive area eventually. We are taking care of that in advance.
......
......@@ -378,7 +378,6 @@
<patternset id="files.tomcat-util-scan">
<include name="org/apache/tomcat/util/descriptor/**" />
<include name="org/apache/tomcat/util/digester/**" />
<include name="org/apache/tomcat/util/file/**" />
<include name="org/apache/tomcat/util/scan/**" />
</patternset>
......
......@@ -122,6 +122,13 @@ public interface Container extends Lifecycle {
public Log getLogger();
/**
* Return the logger name that the container will use.
* @return the abbreviated name of this container for logging messages
*/
public String getLogName();
/**
* Obtain the JMX name for this container.
*
......
......@@ -76,7 +76,7 @@ import java.util.Set;
* including:
* - which ResourceSet to write to
* - unexpected behaviour when deleting a resource from one ResourceSet since
* that may unmask a resource in a lower priority ResouceSet so what was a
* that may unmask a resource in a lower priority ResourceSet so what was a
* delete looks like a replace with the user having no idea where the 'new'
* resource came from
* - how to handle PUT when the target is read-only but it could be written to
......
......@@ -292,43 +292,24 @@ public class CoyoteAdapter implements Adapter {
if (!asyncConImpl.timeout()) {
asyncConImpl.setErrorState(null, false);
}
} else if (status==SocketStatus.ASYNC_READ_ERROR) {
// A async read error is an IO error which means the socket
// needs to be closed so set success to false to trigger a
// close
} else if (status==SocketStatus.ERROR) {
// An I/O error occurred on a non-container thread which means
// that the socket needs to be closed so set success to false to
// trigger a close
success = false;
Throwable t = (Throwable)req.getAttribute(
RequestDispatcher.ERROR_EXCEPTION);
Throwable t = (Throwable)req.getAttribute(RequestDispatcher.ERROR_EXCEPTION);
req.getAttributes().remove(RequestDispatcher.ERROR_EXCEPTION);
ReadListener readListener = req.getReadListener();
if (readListener != null) {
ClassLoader oldCL = null;
try {
oldCL = request.getContext().bind(false, null);
readListener.onError(t);
} finally {
request.getContext().unbind(false, oldCL);
ClassLoader oldCL = null;
try {
oldCL = request.getContext().bind(false, null);
if (req.getReadListener() != null) {
req.getReadListener().onError(t);
}
}
if (t != null) {
asyncConImpl.setErrorState(t, true);
}
} else if (status==SocketStatus.ASYNC_WRITE_ERROR) {
// A async write error is an IO error which means the socket
// needs to be closed so set success to false to trigger a
// close
success = false;
Throwable t = (Throwable)req.getAttribute(
RequestDispatcher.ERROR_EXCEPTION);
req.getAttributes().remove(RequestDispatcher.ERROR_EXCEPTION);
if (res.getWriteListener() != null) {
ClassLoader oldCL = null;
try {
oldCL = request.getContext().bind(false, null);
if (res.getWriteListener() != null) {
res.getWriteListener().onError(t);
} finally {
request.getContext().unbind(false, oldCL);
}
} finally {
request.getContext().unbind(false, oldCL);
}
if (t != null) {
asyncConImpl.setErrorState(t, true);
......
......@@ -117,11 +117,11 @@
<!-- Common -->
<attribute name="maxThreads"
description="The maximum number of request processing threads to be created"
description="The maximum number of request processing threads to be created for the internal Executor. -1 indicates an external Executor is being used."
type="int"/>
<attribute name="minSpareThreads"
description="The number of request processing threads that will be created"
description="The number of request processing threads that will be created for the internal Executor. -1 indicates an external Executor is being used."
type="int"/>
<!-- Common -->
......@@ -188,7 +188,7 @@
<!-- Common -->
<attribute name="threadPriority"
description="The thread priority for processors"
description="The thread priority for processors using the internal Executor. -1 indicates an external Executor is being used."
type="int"/>
<attribute name="URIEncoding"
......
......@@ -607,7 +607,7 @@ public class ApplicationContext implements ServletContext {
/*
* Returns null if the input path is not valid or a path that will be
* acceptable to resoucres.getResource().
* acceptable to resources.getResource().
*/
private String validateResourcePath(String path, boolean allowEmptyPath) {
if (path == null) {
......
......@@ -360,12 +360,40 @@ public abstract class ContainerBase extends LifecycleMBeanBase
if (logger != null)
return (logger);
logger = LogFactory.getLog(logName());
logger = LogFactory.getLog(getLogName());
return (logger);
}
/**
* @return the abbreviated name of this container for logging messages
*/
@Override
public String getLogName() {
if (logName != null) {
return logName;
}
String loggerName = null;
Container current = this;
while (current != null) {
String name = current.getName();
if ((name == null) || (name.equals(""))) {
name = "/";
} else if (name.startsWith("##")) {
name = "/" + name;
}
loggerName = "[" + name + "]"
+ ((loggerName != null) ? ("." + loggerName) : "");
current = current.getParent();
}
logName = ContainerBase.class.getName() + "." + loggerName;
return logName;
}
/**
* Return the Cluster with which this Container is associated. If there is
* no associated Cluster, return the Cluster associated with our parent
......@@ -1187,33 +1215,6 @@ public abstract class ContainerBase extends LifecycleMBeanBase
}
/**
* Return the abbreviated name of this container for logging messages
*/
protected String logName() {
if (logName != null) {
return logName;
}
String loggerName = null;
Container current = this;
while (current != null) {
String name = current.getName();
if ((name == null) || (name.equals(""))) {
name = "/";
} else if (name.startsWith("##")) {
name = "/" + name;
}
loggerName = "[" + name + "]"
+ ((loggerName != null) ? ("." + loggerName) : "");
current = current.getParent();
}
logName = ContainerBase.class.getName() + "." + loggerName;
return logName;
}
// -------------------- JMX and Registration --------------------
@Override
......
......@@ -498,8 +498,10 @@ public final class StandardServer extends LifecycleMBeanBase implements Server {
log.warn("StandardServer.await: read: ", e);
ch = -1;
}
if (ch < 32) // Control character or EOF terminates loop
// Control character or EOF (-1) terminates loop
if (ch < 32 || ch == 127) {
break;
}
command.append((char) ch);
expected--;
}
......
......@@ -13,7 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
webappClassLoader.addExports=When running on Java 9 you need to add "-XaddExports:java.rmi/sun.rmi.transport=ALL-UNNAMED" to the JVM command line arguments to enable RMI Target memory leak detection. Alternatively, you can suppress this warning by disabling RMI Target memory leak detection.
webappClassLoader.addExports=When running on Java 9 you need to add "--add-exports java.rmi/sun.rmi.transport=ALL-UNNAMED" to the JVM command line arguments to enable RMI Target memory leak detection. Alternatively, you can suppress this warning by disabling RMI Target memory leak detection.
webappClassLoader.addPermisionNoCanonicalFile=Unable to obtain a canonical file path from the URL [{0}]
webappClassLoader.addPermisionNoProtocol=The protocol [{0}] in the URL [{1}] is not supported so no read permission was granted for resources located at this URL
webappClassLoader.illegalJarPath=Illegal JAR entry detected with name {0}
......
......@@ -66,7 +66,7 @@ public class JmxRemoteLifecycleListener implements LifecycleListener {
private static final Log log = LogFactory.getLog(JmxRemoteLifecycleListener.class);
protected static final StringManager sm =
StringManager.getManager(Constants.Package);
StringManager.getManager(JmxRemoteLifecycleListener.class);
protected String rmiBindAddress = null;
protected int rmiRegistryPortPlatform = -1;
......@@ -264,6 +264,10 @@ public class JmxRemoteLifecycleListener implements LifecycleListener {
serverCsf = new RmiClientLocalhostSocketFactory(serverCsf);
}
env.put("jmx.remote.rmi.server.credential.types", new String[] {
String[].class.getName(),
String.class.getName() });
// Populate the env properties used to create the server
if (serverCsf != null) {
env.put(RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE, serverCsf);
......@@ -328,7 +332,7 @@ public class JmxRemoteLifecycleListener implements LifecycleListener {
cs = new RMIConnectorServer(serviceUrl, theEnv, server,
ManagementFactory.getPlatformMBeanServer());
cs.start();
registry.bind("jmxrmi", server);
registry.bind("jmxrmi", server.toStub());
log.info(sm.getString("jmxRemoteLifecycleListener.start",
Integer.toString(theRmiRegistryPort),
Integer.toString(theRmiServerPort), serverName));
......
......@@ -274,14 +274,14 @@ public class MBeanFactory {
*/
private String createConnector(String parent, String address, int port, boolean isAjp, boolean isSSL)
throws Exception {
Connector retobj = new Connector();
// Set the protocol
String protocol = isAjp ? "AJP/1.3" : "HTTP/1.1";
Connector retobj = new Connector(protocol);
if ((address!=null) && (address.length()>0)) {
retobj.setProperty("address", address);
}
// Set port number
retobj.setPort(port);
// Set the protocol
retobj.setProtocol(isAjp ? "AJP/1.3" : "HTTP/1.1");
// Set SSL
retobj.setSecure(isSSL);
retobj.setScheme(isSSL ? "https" : "http");
......
......@@ -240,6 +240,9 @@ public class FailedContext extends LifecycleMBeanBase implements Context {
@Override
public Log getLogger() { return null; }
@Override
public String getLogName() { return null; }
@Override
public Manager getManager() { return null; }
@Override
......
......@@ -258,7 +258,6 @@ public abstract class AbstractReplicatedMap<K,V>
* @throws ChannelException
*/
protected void ping(long timeout) throws ChannelException {
//send out a map membership message, only wait for the first reply
MapMessage msg = new MapMessage(this.mapContextName,
MapMessage.MSG_PING,
false,
......@@ -971,7 +970,7 @@ public abstract class AbstractReplicatedMap<K,V>
//make sure we don't retrieve from ourselves
msg = new MapMessage(getMapContextName(), MapMessage.MSG_RETRIEVE_BACKUP, false,
(Serializable) key, null, null, null,null);
Response[] resp = getRpcChannel().send(entry.getBackupNodes(),msg, RpcChannel.FIRST_REPLY, Channel.SEND_OPTIONS_DEFAULT, getRpcTimeout());
Response[] resp = getRpcChannel().send(entry.getBackupNodes(),msg, RpcChannel.FIRST_REPLY, getChannelSendOptions(), getRpcTimeout());
if (resp == null || resp.length == 0 || resp[0].getMessage() == null) {
//no responses
log.warn(sm.getString("abstractReplicatedMap.unable.retrieve", key));
......
......@@ -217,7 +217,9 @@ public class AccessLogValve extends AbstractAccessLogValve {
/**
* Should we rotate the logs
* Should we rotate the access log.
*
* @return <code>true</code> if the access log should be rotated
*/
public boolean isRotatable() {
return rotatable;
......@@ -225,9 +227,9 @@ public class AccessLogValve extends AbstractAccessLogValve {
/**
* Set the value is we should we rotate the logs
* Configure whether the access log should be rotated.
*
* @param rotatable true is we should rotate.
* @param rotatable true if the log should be rotated
*/
public void setRotatable(boolean rotatable) {
this.rotatable = rotatable;
......
......@@ -47,6 +47,7 @@ import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.Response;
import org.apache.catalina.util.URLEncoder;
import org.apache.catalina.valves.ValveBase;
import org.apache.juli.logging.LogFactory;
import org.apache.tomcat.util.buf.CharChunk;
import org.apache.tomcat.util.buf.MessageBytes;
import org.apache.tomcat.util.buf.UriUtil;
......@@ -143,6 +144,14 @@ public class RewriteValve extends ValveBase {
this.enabled = enabled;
}
@Override
protected void initInternal() throws LifecycleException {
super.initInternal();
containerLog = LogFactory.getLog(getContainer().getLogName() + ".rewrite");
}
@Override
protected synchronized void startInternal() throws LifecycleException {
......@@ -155,11 +164,11 @@ public class RewriteValve extends ValveBase {
context = true;
is = ((Context) getContainer()).getServletContext()
.getResourceAsStream("/WEB-INF/" + resourcePath);
if (container.getLogger().isDebugEnabled()) {
if (containerLog.isDebugEnabled()) {
if (is == null) {
container.getLogger().debug("No configuration resource found: /WEB-INF/" + resourcePath);
containerLog.debug("No configuration resource found: /WEB-INF/" + resourcePath);
} else {
container.getLogger().debug("Read configuration from: /WEB-INF/" + resourcePath);
containerLog.debug("Read configuration from: /WEB-INF/" + resourcePath);
}
}
} else if (getContainer() instanceof Host) {
......@@ -170,21 +179,21 @@ public class RewriteValve extends ValveBase {
// Use getResource and getResourceAsStream
is = getClass().getClassLoader()
.getResourceAsStream(resourceName);
if (is != null && container.getLogger().isDebugEnabled()) {
container.getLogger().debug("Read configuration from CL at " + resourceName);
if (is != null && containerLog.isDebugEnabled()) {
containerLog.debug("Read configuration from CL at " + resourceName);
}
} else {
if (container.getLogger().isDebugEnabled()) {
container.getLogger().debug("Read configuration from " + file.getAbsolutePath());
if (containerLog.isDebugEnabled()) {
containerLog.debug("Read configuration from " + file.getAbsolutePath());
}
is = new FileInputStream(file);
}
if ((is == null) && (container.getLogger().isDebugEnabled())) {
container.getLogger().debug("No configuration resource found: " + resourceName +
if ((is == null) && (containerLog.isDebugEnabled())) {
containerLog.debug("No configuration resource found: " + resourceName +
" in " + getConfigBase() + " or in the classloader");
}
} catch (Exception e) {
container.getLogger().error("Error opening configuration", e);
containerLog.error("Error opening configuration", e);
}
}
......@@ -197,12 +206,12 @@ public class RewriteValve extends ValveBase {
BufferedReader reader = new BufferedReader(isr)) {
parse(reader);
} catch (IOException ioe) {
container.getLogger().error("Error closing configuration", ioe);
containerLog.error("Error closing configuration", ioe);
} finally {
try {
is.close();
} catch (IOException e) {
container.getLogger().error("Error closing configuration", e);
containerLog.error("Error closing configuration", e);
}
}
......@@ -210,6 +219,9 @@ public class RewriteValve extends ValveBase {
public void setConfiguration(String configuration)
throws Exception {
if (containerLog == null) {
containerLog = LogFactory.getLog(getContainer().getLogName() + ".rewrite");
}
maps.clear();
parse(new BufferedReader(new StringReader(configuration)));
}
......@@ -238,8 +250,8 @@ public class RewriteValve extends ValveBase {
Object result = parse(line);
if (result instanceof RewriteRule) {
RewriteRule rule = (RewriteRule) result;
if (container.getLogger().isDebugEnabled()) {
container.getLogger().debug("Add rule with pattern " + rule.getPatternString()
if (containerLog.isDebugEnabled()) {
containerLog.debug("Add rule with pattern " + rule.getPatternString()
+ " and substitution " + rule.getSubstitutionString());
}
for (int i = (conditions.size() - 1); i > 0; i--) {
......@@ -248,9 +260,9 @@ public class RewriteValve extends ValveBase {
}
}
for (int i = 0; i < conditions.size(); i++) {
if (container.getLogger().isDebugEnabled()) {
if (containerLog.isDebugEnabled()) {
RewriteCond cond = conditions.get(i);
container.getLogger().debug("Add condition " + cond.getCondPattern()
containerLog.debug("Add condition " + cond.getCondPattern()
+ " test " + cond.getTestString() + " to rule with pattern "
+ rule.getPatternString() + " and substitution "
+ rule.getSubstitutionString() + (cond.isOrnext() ? " [OR]" : "")
......@@ -271,7 +283,7 @@ public class RewriteValve extends ValveBase {
}
}
} catch (IOException e) {
container.getLogger().error("Error reading configuration", e);
containerLog.error("Error reading configuration", e);
}
}
this.rules = rules.toArray(new RewriteRule[0]);
......@@ -338,8 +350,8 @@ public class RewriteValve extends ValveBase {
CharSequence test = (rule.isHost()) ? host : urlDecoded;
CharSequence newtest = rule.evaluate(test, resolver);
if (newtest != null && !test.equals(newtest.toString())) {
if (container.getLogger().isDebugEnabled()) {
container.getLogger().debug("Rewrote " + test + " as " + newtest
if (containerLog.isDebugEnabled()) {
containerLog.debug("Rewrote " + test + " as " + newtest
+ " with rule pattern " + rule.getPatternString());
}
if (rule.isHost()) {
......
......@@ -113,6 +113,9 @@ public abstract class AbstractArchiveResource extends AbstractResource {
@Override
public long getContentLength() {
if (isDirectory()) {
return -1;
}
return resource.getSize();
}
......@@ -167,6 +170,11 @@ public abstract class AbstractArchiveResource extends AbstractResource {
Long.valueOf(len)));
}
if (len < 0) {
// Content is not applicable here (e.g. is a directory)
return null;
}
int size = (int) len;
byte[] result = new byte[size];
......@@ -215,6 +223,9 @@ public abstract class AbstractArchiveResource extends AbstractResource {
@Override
protected final InputStream doGetInputStream() {
if (isDirectory()) {
return null;
}
return getJarInputStreamWrapper();
}
......
......@@ -98,15 +98,13 @@ public class Cache {
// efficiency (younger entries may be evicted before older
// ones) for speed since this is on the critical path for
// request processing
long targetSize =
maxSize * (100 - TARGET_FREE_PERCENT_GET) / 100;
long newSize = evict(
targetSize, resourceCache.values().iterator());
long targetSize = maxSize * (100 - TARGET_FREE_PERCENT_GET) / 100;
long newSize = evict(targetSize, resourceCache.values().iterator());
if (newSize > maxSize) {
// Unable to create sufficient space for this resource
// Remove it from the cache
removeCacheEntry(path);
log.warn(sm.getString("cache.addFail", path));
log.warn(sm.getString("cache.addFail", path, root.getContext().getName()));
}
}
} else {
......@@ -158,10 +156,8 @@ public class Cache {
// efficiency (younger entries may be evicted before older
// ones) for speed since this is on the critical path for
// request processing
long targetSize =
maxSize * (100 - TARGET_FREE_PERCENT_GET) / 100;
long newSize = evict(
targetSize, resourceCache.values().iterator());
long targetSize = maxSize * (100 - TARGET_FREE_PERCENT_GET) / 100;
long newSize = evict(targetSize, resourceCache.values().iterator());
if (newSize > maxSize) {
// Unable to create sufficient space for this resource
// Remove it from the cache
......@@ -204,9 +200,12 @@ public class Cache {
}
private boolean noCache(String path) {
// Don't cache resources used by the class loader (it has its own cache)
if (path.startsWith("/WEB-INF/classes/") ||
path.startsWith("/WEB-INF/lib/")) {
// Don't cache classes. The class loader handles this.
// Don't cache JARs. The ResourceSet handles this.
if ((path.endsWith(".class") &&
(path.startsWith("/WEB-INF/classes/") || path.startsWith("/WEB-INF/lib/")))
||
(path.startsWith("/WEB-INF/lib/") && path.endsWith(".jar"))) {
return true;
}
return false;
......
......@@ -89,7 +89,7 @@ public class EmptyResource implements WebResource {
@Override
public long getContentLength() {
return 0;
return -1;
}
@Override
......
......@@ -111,6 +111,10 @@ public class FileResource extends AbstractResource {
@Override
public long getContentLength() {
if (isDirectory()) {
return -1;
}
return resource.length();
}
......@@ -153,6 +157,11 @@ public class FileResource extends AbstractResource {
Long.valueOf(len)));
}
if (len < 0) {
// Content is not applicable here (e.g. is a directory)
return null;
}
int size = (int) len;
byte[] result = new byte[size];
......@@ -170,6 +179,7 @@ public class FileResource extends AbstractResource {
getLog().debug(sm.getString("abstractResource.getContentFail",
getWebappPath()), ioe);
}
return null;
}
return result;
......
......@@ -20,7 +20,7 @@ abstractResource.getContentTooLarge=Unable to return [{0}] as a byte array since
abstractResourceSet.checkPath=The requested path [{0}] is not valid. It must begin with "/".
cache.addFail=Unable to add the resource at [{0}] to the cache because there was insufficient free space available after evicting expired cache entries - consider increasing the maximum size of the cache
cache.addFail=Unable to add the resource at [{0}] to the cache for web application [{1}] because there was insufficient free space available after evicting expired cache entries - consider increasing the maximum size of the cache
cache.backgroundEvictFail=The background cache eviction process was unable to free [{0}] percent of the cache for Context [{1}] - consider increasing the maximum size of the cache. After eviction approximately [{2}] KB of data remained in the cache.
cache.objectMaxSizeTooBig=The value of [{0}]kB for objectMaxSize is larger than the limit of maxSize/20 so has been reduced to [{1}]kB
cache.objectMaxSizeTooBigBytes=The value specified for the maximum object size to cache [{0}]kB is greater than Integer.MAX_VALUE bytes which is the maximum size that can be cached. The limit will be set to Integer.MAX_VALUE bytes.
......
......@@ -19,6 +19,8 @@ package org.apache.coyote;
import java.io.IOException;
import java.util.concurrent.Executor;
import javax.servlet.RequestDispatcher;
import org.apache.juli.logging.Log;
import org.apache.tomcat.util.net.AbstractEndpoint;
import org.apache.tomcat.util.net.AbstractEndpoint.Handler.SocketState;
......@@ -88,7 +90,10 @@ public abstract class AbstractProcessor<S> implements ActionHook, Processor<S> {
response.setStatus(500);
}
getLog().info(sm.getString("abstractProcessor.nonContainerThreadError"), t);
getEndpoint().processSocket(socketWrapper, SocketStatus.CLOSE_NOW, true);
// Set the request attribute so that the async onError() event is
// fired when the error event is processed
request.setAttribute(RequestDispatcher.ERROR_EXCEPTION, t);
getEndpoint().processSocket(socketWrapper, SocketStatus.ERROR, true);
}
}
......