Commit d5e71a00 authored by James Page's avatar James Page

Imported Upstream version 7.0.28

parent e1540c55
......@@ -15,7 +15,7 @@
limitations under the License.
================================================================================
$Id: BUILDING.txt 1232451 2012-01-17 16:00:07Z kkolinko $
$Id: BUILDING.txt 1348360 2012-06-09 11:17:55Z kkolinko $
====================================================
Building The Apache Tomcat @VERSION_MAJOR_MINOR@ Servlet/JSP Container
......@@ -223,24 +223,12 @@ The output of this command will be found in the following directories:
ant release
(7) Enabling Checkstyle
(7) Tests
Tomcat comes with a Checkstyle configuration that tests its source code
for certain conventions, like presence of the license header.
To enable Checkstyle checks during Tomcat build, add the following property
to build.properties file:
execute.validate=true
* NOTE: Checkstyle is licensed under LGPL. Using Checkstyle during Tomcat
build is optional and is off by default.
(8) Running the tests
(7.1) Running Tomcat tests
The tests are not run when a release is built. There is separate command
for running the tests.
Tomcat includes a number of junit tests. The tests are not run when a
release is built. There is separate command to run them.
To run the testsuite use the following command:
......@@ -256,8 +244,6 @@ directory:
output/build/logs
(8.1) Testing with APR connector
By default the testsuite is run three times to test 3 different
implementations of Tomcat connectors: BIO, NIO and APR. (If you are not
familiar with Tomcat connectors, see config/http.html in documentation for
......@@ -283,7 +269,7 @@ tcnative-1.dll file into ${tomcat.source}/bin/native/ and it will be copied
into the above directory when the build runs.
(8.2) Running a single test class
(7.2) Running a single test
It is possible to run a single JUnit test class by adding the "test.entry"
property to the build.properties file. The property specifies the name of
......@@ -294,7 +280,7 @@ For example:
test.entry=org.apache.catalina.util.TestServerInfo
(8.3) Other options
(7.3) Other configuration options
1. It is possible to enable generation of access log file when the tests
are run. This is off by default and can be enabled by the following
......@@ -320,3 +306,52 @@ For example:
files:
junit.formatter.usefile=false
(8) Source code checks
(8.1) Checkstyle
* NOTE: Checkstyle is licensed under LGPL. Using Checkstyle during Tomcat
build is optional and is off by default.
Tomcat comes with a Checkstyle configuration that tests its source code
for certain conventions, like presence of the license header.
To enable Checkstyle, add the following property to build.properties file:
execute.validate=true
Once Checkstyle is enabled, the check will be performed automatically
during the build. The check is run before compilation of the source code.
It is possible to run the check separately. The command is:
cd ${tomcat.source}
ant validate
To speed-up repeated runs of this check, a cache is configured. The cache
is located in the following directory:
output/res/checkstyle
(8.2) End-of-line conventions check
You usually would not need to run this check. You can skip this section.
Apache Tomcat project has convention that all of its textual source files,
stored in Subversion repository, are marked with Subversion property
"svn:eol-style" with value of "native". This convention makes the editing
of source code on different platforms easier.
This test is used by developers to check that the source code adheres to
this convention. It verifies that the ends of lines in textual files are
appropriate for the operating system where it is run. The idea is to run
this check regularly on two different platforms and notify developers when
an inconsistency is detected.
The command to run this test is:
cd ${tomcat.source}
ant validate-eoln
......@@ -714,6 +714,7 @@ For the following XML Schemas for Java EE Deployment Descriptors:
- javaee_6.xsd
- javaee_web_services_1_3.xsd
- javaee_web_services_client_1_3.xsd
- jsp_2_2.xsd
- web-app_3_0.xsd
- web-common_3_0.xsd
- web-fragment_3_0.xsd
......
......@@ -29,8 +29,8 @@ The original XML Schemas for Java EE Deployment Descriptors:
- javaee_6.xsd
- javaee_web_services_1_3.xsd
- javaee_web_services_client_1_3.xsd
- jsp_2_2.xsd
- web-app_3_0.xsd
- web-common_3_0.xsd
- web-fragment_3_0.xsd
- jsp_2_2.xsd
may be obtained from http://java.sun.com/xml/ns/javaee/
This diff is collapsed.
================================================================================
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.
================================================================================
=================================
Apache Tomcat 7.0 Patch Proposals
=================================
RELEASE SHOWSTOPPERS:
PATCHES ACCEPTED TO BACKPORT:
[ start all new proposals below, under PATCHES PROPOSED. ]
PATCHES PROPOSED TO BACKPORT:
[ New proposals should be added at the end of the list ]
* For https://issues.apache.org/bugzilla/show_bug.cgi?id=53119
Prevent possible overflow exception with buffer in
AjpNioProcessor.output() if it is called again after previous write
failed with IOException.
I have not observed it, but it is from analogy with AjpAprProcessor fix
in r1344253.
http://svn.apache.org/viewvc?view=revision&revision=1346365
+1: kkolinko
-1:
......@@ -93,12 +93,12 @@ rem set TITLE=Tomcat.Cluster#1.Server#1 [%DATE% %TIME%]
rem
rem
rem
rem $Id: catalina.bat 1202062 2011-11-15 06:50:02Z mturk $
rem $Id: catalina.bat 1344732 2012-05-31 14:08:02Z kkolinko $
rem ---------------------------------------------------------------------------
rem Suppress Terminate batch job on CTRL+C
if not ""%1"" == ""run"" goto mainEntry
if ""%TEMP%"" == """" goto mainEntry
if "%TEMP%" == "" goto mainEntry
if exist "%TEMP%\%~nx0.run" goto mainEntry
echo Y>"%TEMP%\%~nx0.run"
if not exist "%TEMP%\%~nx0.run" goto mainEntry
......
......@@ -21,13 +21,13 @@
# modules that Tomcat depends on. Copy this file to "build.properties"
# in the top-level source directory, and customize it as needed.
#
# $Id: build.properties.default 1307817 2012-03-31 14:40:30Z markt $
# $Id: build.properties.default 1350468 2012-06-15 06:11:47Z markt $
# -----------------------------------------------------------------------------
# ----- Version Control Flags -----
version.major=7
version.minor=0
version.build=27
version.build=28
version.patch=0
version.suffix=
......@@ -132,7 +132,7 @@ jdt.loc.1=http://archive.eclipse.org/eclipse/downloads/drops/${jdt.release}/ecj-
jdt.loc.2=http://download.eclipse.org/eclipse/downloads/drops/${jdt.release}/ecj-${jdt.version}.jar
# ----- Tomcat native library -----
tomcat-native.version=1.1.23
tomcat-native.version=1.1.24
tomcat-native.home=${base.path}/tomcat-native-${tomcat-native.version}
tomcat-native.tar.gz=${tomcat-native.home}/tomcat-native.tar.gz
tomcat-native.loc.1=${base-tomcat.loc.1}/tomcat-connectors/native/${tomcat-native.version}/source/tomcat-native-${tomcat-native.version}-src.tar.gz
......
......@@ -438,7 +438,9 @@
</target>
<target name="validate" depends="download-validate" if="${execute.validate}">
<target name="validate" if="${execute.validate}"
depends="build-prepare,compile-prepare,download-validate"
description="Uses Checkstyle tool to perform style check for the source code">
<!-- Required so we can cache checkstyle results -->
<mkdir dir="${tomcat.output}/res/checkstyle"/>
......@@ -467,6 +469,9 @@
<!-- Exclude these else Gump runs validate on them -->
<exclude name="**/org/apache/tomcat/dbcp/**"/>
<exclude name="**/tomcat-deps/**"/>
<!-- Exclude simple test files -->
<exclude name="test/webapp-3.0/bug53257/*.txt"/>
<exclude name="test/webapp-3.0-fragments/WEB-INF/classes/*.txt"/>
</fileset>
<fileset dir="modules/jdbc-pool" >
<exclude name=".*/**"/>
......
......@@ -24,7 +24,7 @@
// * Read access to the web application's document root directory
// * Read, write and delete access to the web application's working directory
//
// $Id: catalina.policy 1220297 2011-12-17 22:55:28Z markt $
// $Id: catalina.policy 1347048 2012-06-06 18:47:00Z markt $
// ============================================================================
......@@ -188,6 +188,9 @@ grant {
// Applications using Comet need to be able to access this package
permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.comet";
// Applications using WebSocket need to be able to access this package
permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.websocket";
};
......
......@@ -91,6 +91,7 @@ annotations-api.jar,el-api.jar,jsp-api.jar,servlet-api.jar,\
catalina.jar,catalina-ant.jar,catalina-ha.jar,catalina-tribes.jar,\
jasper.jar,jasper-el.jar,ecj-*.jar,\
tomcat-api.jar,tomcat-util.jar,tomcat-coyote.jar,tomcat-dbcp.jar,\
tomcat-jni.jar,tomcat-spdy.jar,\
tomcat-i18n-en.jar,tomcat-i18n-es.jar,tomcat-i18n-fr.jar,tomcat-i18n-ja.jar,\
tomcat-juli-adapters.jar,catalina-jmx-remote.jar,catalina-ws.jar,\
tomcat-jdbc.jar,\
......
......@@ -20,6 +20,7 @@ package org.apache.catalina;
import java.net.URL;
import java.util.Locale;
import java.util.Set;
import javax.servlet.ServletContainerInitializer;
......@@ -58,7 +59,7 @@ import org.apache.tomcat.util.http.mapper.Mapper;
* <p>
*
* @author Craig R. McClanahan
* @version $Id: Context.java 1200158 2011-11-10 05:32:22Z kkolinko $
* @version $Id: Context.java 1350247 2012-06-14 14:04:20Z markt $
*/
public interface Context extends Container {
......@@ -69,7 +70,9 @@ public interface Context extends Container {
/**
* The LifecycleEvent type sent when a context is reloaded.
* @deprecated Will be removed in Tomcat 8.0.x onwards.
*/
@Deprecated
public static final String RELOAD_EVENT = "reload";
/**
......@@ -167,7 +170,9 @@ public interface Context extends Container {
/**
* Return the Locale to character set mapper for this Context.
* @deprecated Use {@link #getCharset(Locale)}
*/
@Deprecated
public CharsetMapper getCharsetMapper();
......@@ -175,10 +180,21 @@ public interface Context extends Container {
* Set the Locale to character set mapper for this Context.
*
* @param mapper The new mapper
*
* @deprecated
*/
@Deprecated
public void setCharsetMapper(CharsetMapper mapper);
/**
* Obtain the character set name to use with the given Locale. Note that
* different Contexts may have different mappings of Locale to character
* set.
*/
public String getCharset(Locale locale);
/**
* Return the URL of the XML descriptor for this context.
*/
......@@ -1399,7 +1415,7 @@ public interface Context extends Container {
public void setSendRedirectBody(boolean enable);
/**
* Dtermines if the context is configured to included a response body as
* Determines if the context is configured to include a response body as
* part of a redirect response.
*/
public boolean getSendRedirectBody();
......
......@@ -47,7 +47,7 @@ import org.apache.juli.logging.LogFactory;
*
* @author Craig R. McClanahan
* @author Remy Maucherat
* @version $Id: DigestAuthenticator.java 1189224 2011-10-26 14:02:40Z kkolinko $
* @version $Id: DigestAuthenticator.java 1349321 2012-06-12 13:26:10Z markt $
*/
public class DigestAuthenticator extends AuthenticatorBase {
......@@ -580,7 +580,23 @@ public class DigestAuthenticator extends AuthenticatorBase {
uriQuery = request.getRequestURI() + "?" + query;
}
if (!uri.equals(uriQuery)) {
return false;
// Some clients (older Android) use an absolute URI for
// DIGEST but a relative URI in the request line.
// request. 2.3.5 < fixed Android version <= 4.0.3
String host = request.getHeader("host");
String scheme = request.getScheme();
if (host != null && !uriQuery.startsWith(scheme)) {
StringBuilder absolute = new StringBuilder();
absolute.append(scheme);
absolute.append("://");
absolute.append(host);
absolute.append(uriQuery);
if (!uri.equals(absolute.toString())) {
return false;
}
} else {
return false;
}
}
}
......@@ -642,7 +658,9 @@ public class DigestAuthenticator extends AuthenticatorBase {
if (cnonce == null || nc == null) {
return false;
}
if (nc.length() != 8) {
// RFC 2617 says nc must be 8 digits long. Older Android clients
// use 6. 2.3.5 < fixed Android version <= 4.0.3
if (nc.length() < 6 || nc.length() > 8) {
return false;
}
long count;
......
......@@ -43,7 +43,7 @@ import org.apache.tomcat.util.res.StringManager;
*
* @author Craig R. McClanahan
* @author Remy Maucherat
* @version $Id: Connector.java 1229558 2012-01-10 14:36:06Z rjung $
* @version $Id: Connector.java 1350306 2012-06-14 15:59:15Z kkolinko $
*/
......@@ -411,6 +411,24 @@ public class Connector extends LifecycleMBeanBase {
}
/**
* Return the maximum number of headers that are allowed by the container. A
* value of less than 0 means no limit.
*/
public int getMaxHeaderCount() {
return ((Integer) getProperty("maxHeaderCount")).intValue();
}
/**
* Set the maximum number of headers in a request that are allowed by the
* container. A value of less than 0 means no limit.
*
* @param maxHeaderCount The new setting
*/
public void setMaxHeaderCount(int maxHeaderCount) {
setProperty("maxHeaderCount", String.valueOf(maxHeaderCount));
}
/**
* Return the maximum number of parameters (GET plus POST) that will be
* automatically parsed by the container. A value of less than 0 means no
......
......@@ -55,7 +55,7 @@ import org.apache.tomcat.util.res.StringManager;
*
* @author Craig R. McClanahan
* @author Remy Maucherat
* @version $Id: CoyoteAdapter.java 1297024 2012-03-05 12:15:21Z markt $
* @version $Id: CoyoteAdapter.java 1335700 2012-05-08 19:07:09Z markt $
*/
public class CoyoteAdapter implements Adapter {
......@@ -719,7 +719,19 @@ public class CoyoteAdapter implements Adapter {
}
}
}
if (!mapRequired && request.getContext().getPaused()) {
// Found a matching context but it is paused. Mapping data will
// be wrong since some Wrappers may not be registered at this
// point.
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// Should never happen
}
// Reset mapping
request.getMappingData().recycle();
mapRequired = true;
}
}
// Possible redirect
......
......@@ -445,7 +445,12 @@ public class MapperListener extends LifecycleMBeanBase
if (obj instanceof Wrapper) {
unregisterWrapper((Wrapper) obj);
} else if (obj instanceof Context) {
unregisterContext((Context) obj);
Context c = (Context) obj;
// Only unregister if not paused. If paused, need to keep
// registration in place to prevent 404's during reload
if (!c.getPaused()) {
unregisterContext(c);
}
} else if (obj instanceof Host) {
unregisterHost((Host) obj);
}
......
......@@ -100,7 +100,7 @@ import org.apache.tomcat.util.res.StringManager;
*
* @author Remy Maucherat
* @author Craig R. McClanahan
* @version $Id: Request.java 1301262 2012-03-15 23:05:15Z markt $
* @version $Id: Request.java 1335733 2012-05-08 20:07:23Z markt $
*/
public class Request
......@@ -2665,6 +2665,7 @@ public class Request
}
Parameters parameters = coyoteRequest.getParameters();
parameters.setLimit(getConnector().getMaxParameterCount());
boolean success = false;
try {
......
......@@ -45,7 +45,6 @@ import org.apache.catalina.Globals;
import org.apache.catalina.Session;
import org.apache.catalina.Wrapper;
import org.apache.catalina.security.SecurityUtil;
import org.apache.catalina.util.CharsetMapper;
import org.apache.catalina.util.DateTool;
import org.apache.catalina.util.RequestUtil;
import org.apache.catalina.util.SessionConfig;
......@@ -65,7 +64,7 @@ import org.apache.tomcat.util.res.StringManager;
*
* @author Remy Maucherat
* @author Craig R. McClanahan
* @version $Id: Response.java 1300161 2012-03-13 14:45:54Z markt $
* @version $Id: Response.java 1350247 2012-06-14 14:04:20Z markt $
*/
public class Response
......@@ -885,12 +884,10 @@ public class Response
return;
}
CharsetMapper cm = getContext().getCharsetMapper();
String charset = cm.getCharset( locale );
if ( charset != null ){
String charset = getContext().getCharset(locale);
if (charset != null) {
coyoteResponse.setCharacterEncoding(charset);
}
}
......@@ -1672,7 +1669,7 @@ public class Response
redirectURLCC.recycle();
// Add the scheme
String scheme = request.getScheme();
try {
try {
redirectURLCC.append(scheme, 0, scheme.length());
redirectURLCC.append(':');
redirectURLCC.append(location, 0, location.length());
......@@ -1731,6 +1728,8 @@ public class Response
redirectURLCC.append('/');
}
redirectURLCC.append(location, 0, location.length());
normalize(redirectURLCC);
} catch (IOException e) {
IllegalArgumentException iae =
new IllegalArgumentException(location);
......@@ -1748,6 +1747,77 @@ public class Response
}
/*
* Removes /./ and /../ sequences from absolute URLs.
* Code borrowed heavily from CoyoteAdapter.normalize()
*/
private void normalize(CharChunk cc) {
if (cc.endsWith("/.") || cc.endsWith("/..")) {
try {
cc.append('/');
} catch (IOException e) {
throw new IllegalArgumentException(cc.toString(), e);
}
}
char[] c = cc.getChars();
int start = cc.getStart();
int end = cc.getEnd();
int index = 0;
int startIndex = 0;
// Advance past the first three / characters (should place index just
// scheme://host[:port]
for (int i = 0; i < 3; i++) {
startIndex = cc.indexOf('/', startIndex + 1);
}
// Remove /./
index = startIndex;
while (true) {
index = cc.indexOf("/./", 0, 3, index);
if (index < 0) {
break;
}
copyChars(c, start + index, start + index + 2,
end - start - index - 2);
end = end - 2;
cc.setEnd(end);
}
// Remove /../
index = startIndex;
int pos;
while (true) {
index = cc.indexOf("/../", 0, 4, index);
if (index < 0) {
break;
}
// Prevent from going outside our context
if (index == startIndex) {
throw new IllegalArgumentException();
}
int index2 = -1;
for (pos = start + index - 1; (pos >= 0) && (index2 < 0); pos --) {
if (c[pos] == (byte) '/') {
index2 = pos;
}
}
copyChars(c, start + index2, start + index + 3,
end - start - index - 3);
end = end + index2 - index - 3;
cc.setEnd(end);
index = index2;
}
}
private void copyChars(char[] c, int dest, int src, int len) {
for (int pos = 0; pos < len; pos++) {
c[pos + dest] = c[pos + src];
}
}
/**
* Determine if an absolute URL has a path component
......
......@@ -77,6 +77,10 @@
description="The port number on which this connector is listening to requests. If the special value for port of zero is used then this method will report the actual port bound."
type="int"/>
<attribute name="maxHeaderCount"
description="The maximum number of headers that are allowed by the container. 100 by default. A value of less than 0 means no limit."
type="int"/>
<attribute name="maxKeepAliveRequests"
description="Maximum number of Keep-Alive requests to honor per connection"
type="int"/>
......
......@@ -14,14 +14,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.catalina.core;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
......@@ -86,7 +84,7 @@ import org.apache.tomcat.util.res.StringManager;
*
* @author Craig R. McClanahan
* @author Remy Maucherat
* @version $Id: ApplicationContext.java 1239053 2012-02-01 10:52:00Z markt $
* @version $Id: ApplicationContext.java 1345359 2012-06-01 21:42:24Z kkolinko $
*/
public class ApplicationContext
......@@ -536,9 +534,9 @@ public class ApplicationContext
String hostName = context.getParent().getName();
try {
resources.lookup(normPath);
return new URL
("jndi", "", 0, getJNDIUri(hostName, fullPath),
new DirContextURLStreamHandler(resources));
URI uri = new URI("jndi", getJNDIUri(hostName, fullPath), null);
return new URL(null, uri.toString(),
new DirContextURLStreamHandler(resources));
} catch (NamingException e) {
// Ignore