diff --git a/java/org/apache/catalina/connector/LocalStrings.properties b/java/org/apache/catalina/connector/LocalStrings.properties
index cef14110b397..3cb608c373bf 100644
--- a/java/org/apache/catalina/connector/LocalStrings.properties
+++ b/java/org/apache/catalina/connector/LocalStrings.properties
@@ -46,6 +46,7 @@ coyoteRequest.attributeEvent=Exception thrown by attributes event listener
coyoteRequest.authenticate.ise=Cannot call authenticate() after the response has been committed
coyoteRequest.changeSessionId=Cannot change session ID. There is no session associated with this request.
coyoteRequest.chunkedPostTooLarge=Parameters were not parsed because the size of the posted data was too big. Because this request was a chunked request, it could not be processed further. Use the maxPostSize attribute of the connector to resolve this if the application should accept large POSTs.
+coyoteRequest.deletePartFailed=Failed to deleted temporary file used for part [{0}]
coyoteRequest.getContextPath.ise=Unable to find match between the canonical context path [{0}] and the URI presented by the user agent [{1}]
coyoteRequest.getInputStream.ise=getReader() has already been called for this request
coyoteRequest.getReader.ise=getInputStream() has already been called for this request
diff --git a/java/org/apache/catalina/connector/Request.java b/java/org/apache/catalina/connector/Request.java
index 3722803cdebf..3bf8f6b17c48 100644
--- a/java/org/apache/catalina/connector/Request.java
+++ b/java/org/apache/catalina/connector/Request.java
@@ -484,8 +484,9 @@ public void recycle() {
for (Part part: parts) {
try {
part.delete();
- } catch (IOException ignored) {
- // ApplicationPart.delete() never throws an IOEx
+ } catch (Throwable t) {
+ ExceptionUtils.handleThrowable(t);
+ log.warn(sm.getString("coyoteRequest.deletePartFailed", part.getName()), t);
}
}
parts = null;
@@ -536,8 +537,9 @@ public void recycle() {
asyncSupported = null;
if (asyncContext!=null) {
asyncContext.recycle();
+ asyncContext = null;
}
- asyncContext = null;
+
pathParameters.clear();
}
diff --git a/java/org/apache/catalina/core/ApplicationHttpRequest.java b/java/org/apache/catalina/core/ApplicationHttpRequest.java
index 99feca76784d..7a261fcd50ee 100644
--- a/java/org/apache/catalina/core/ApplicationHttpRequest.java
+++ b/java/org/apache/catalina/core/ApplicationHttpRequest.java
@@ -45,7 +45,7 @@
import org.apache.tomcat.util.buf.MessageBytes;
import org.apache.tomcat.util.http.Parameters;
import org.apache.tomcat.util.res.StringManager;
-
+import org.apache.tomcat.util.ExceptionUtils;
/**
* Wrapper around a javax.servlet.http.HttpServletRequest
@@ -645,7 +645,12 @@ public boolean isRequestedSessionIdValid() {
*/
public void recycle() {
if (session != null) {
- session.endAccess();
+ try {
+ session.endAccess();
+ } catch (Throwable t) {
+ ExceptionUtils.handleThrowable(t);
+ context.getLogger().warn(sm.getString("applicationHttpRequest.sessionEndAccessFail"), t);
+ }
}
}
diff --git a/java/org/apache/catalina/core/LocalStrings.properties b/java/org/apache/catalina/core/LocalStrings.properties
index 4dead61c475e..1f9e4d9badcc 100644
--- a/java/org/apache/catalina/core/LocalStrings.properties
+++ b/java/org/apache/catalina/core/LocalStrings.properties
@@ -58,6 +58,7 @@ applicationFilterRegistration.nullInitParam=Unable to set initialisation paramet
applicationFilterRegistration.nullInitParams=Unable to set initialisation parameters for filter due to null name and/or value. Name [{0}], Value [{1}]
applicationHttpRequest.fragmentInDispatchPath=The fragment in dispatch path [{0}] has been removed
+applicationHttpRequest.sessionEndAccessFail=Exception triggered ending access to session while recycling request
applicationRequest.badParent=Cannot locate parent Request implementation
applicationRequest.badRequest=Request is not a javax.servlet.ServletRequestWrapper
diff --git a/java/org/apache/catalina/core/LocalStrings_es.properties b/java/org/apache/catalina/core/LocalStrings_es.properties
index 7e77eee0c5ec..f110fd976b1a 100644
--- a/java/org/apache/catalina/core/LocalStrings_es.properties
+++ b/java/org/apache/catalina/core/LocalStrings_es.properties
@@ -51,6 +51,8 @@ applicationFilterConfig.jmxUnregisterFail=Ha fallado el desregistro JMX para el
applicationFilterRegistration.nullInitParam=No puedo poner el parámetro de inicialización para el filtro debido a un nombre nulo y/o valor. Nombre [{0}], Valor [{1}]
applicationFilterRegistration.nullInitParams=No puedo poner los parámetros de inicialización para el filtro debido a un nombre nulo y/o valor. Nombre [{0}], Valor [{1}]
+applicationHttpRequest.sessionEndAccessFail=Excepcin disparada acabando acceso a sesin mientras se reciclaba el requerimiento
+
applicationRequest.badParent=No puedo localizar la implementación de Requerimiento padre
applicationRequest.badRequest=El requerimiento no es un javax.servlet.ServletRequestWrapper
diff --git a/java/org/apache/catalina/core/LocalStrings_fr.properties b/java/org/apache/catalina/core/LocalStrings_fr.properties
index e3143caf0fef..40670d874bb9 100644
--- a/java/org/apache/catalina/core/LocalStrings_fr.properties
+++ b/java/org/apache/catalina/core/LocalStrings_fr.properties
@@ -57,6 +57,7 @@ applicationFilterRegistration.nullInitParam=Impossible de fixer le paramètre d'
applicationFilterRegistration.nullInitParams=Impossible de fixer les paramètres d''initialisation du filtre, à cause d''un nom ou d''une valeur nulle, nom [{0}], valeur [{1}]
applicationHttpRequest.fragmentInDispatchPath=Le fragment dans le chemin de dispatch [{0}] a été enlevé
+applicationHttpRequest.sessionEndAccessFail=Exception lance durant l'arrt de l'accs la session durant le recyclage de la requte
applicationRequest.badParent=Impossible de trouver l''implémentation requête parente (parent request)
applicationRequest.badRequest=La requête n''est pas une "javax.servlet.ServletRequestWrapper"
diff --git a/java/org/apache/catalina/core/LocalStrings_ja.properties b/java/org/apache/catalina/core/LocalStrings_ja.properties
index e53a7a35904e..7839144450e1 100644
--- a/java/org/apache/catalina/core/LocalStrings_ja.properties
+++ b/java/org/apache/catalina/core/LocalStrings_ja.properties
@@ -57,6 +57,7 @@ applicationFilterRegistration.nullInitParam=NULLの名前や値のためにフ
applicationFilterRegistration.nullInitParams=キー [{0}] または値 [{1}] のいずれかが null のためフィルターの初期化パラメータを設定できませんでした。
applicationHttpRequest.fragmentInDispatchPath=ディスパッチパス [{0}] 中のフラグメントは除去されました
+applicationHttpRequest.sessionEndAccessFail=Exception triggered ending access to session while recycling request
applicationRequest.badParent=親のリクエスト実装を配置できません
applicationRequest.badRequest=リクエストがjavax.servlet.ServletRequestWrapperではありません
diff --git a/java/org/apache/catalina/core/LocalStrings_ko.properties b/java/org/apache/catalina/core/LocalStrings_ko.properties
index 4862bc0c2bc4..66b216717cc0 100644
--- a/java/org/apache/catalina/core/LocalStrings_ko.properties
+++ b/java/org/apache/catalina/core/LocalStrings_ko.properties
@@ -55,6 +55,7 @@ applicationFilterRegistration.nullInitParam=이름 또는 값 또는 둘 다 널
applicationFilterRegistration.nullInitParams=널인 이름 또는 값 때문에, 필터의 초기화 파라미터를 설정할 수 없습니다. 이름: [{0}], 값: [{1}]
applicationHttpRequest.fragmentInDispatchPath=디스패치 경로 [{0}](으)로부터 URI fragment를 제거했습니다.
+applicationHttpRequest.sessionEndAccessFail=Exception triggered ending access to session while recycling request
applicationServletRegistration.setServletSecurity.iae=[{1}](이)라는 이름의 컨텍스트에 배치된 서블릿 [{0}]을(를) 위해, 널 constraint가 지정되었습니다.
applicationServletRegistration.setServletSecurity.ise=컨텍스트가 이미 초기화되었기에, [{1}](이)라는 이름의 컨텍스트에 배치된 서블릿 [{0}]에 security constraint들이 추가될 수 없습니다.
diff --git a/java/org/apache/catalina/core/LocalStrings_zh_CN.properties b/java/org/apache/catalina/core/LocalStrings_zh_CN.properties
index 3aaf6d7b6300..db8625348e14 100644
--- a/java/org/apache/catalina/core/LocalStrings_zh_CN.properties
+++ b/java/org/apache/catalina/core/LocalStrings_zh_CN.properties
@@ -56,6 +56,7 @@ applicationFilterRegistration.nullInitParam=由于名称和/或值为空,无
applicationFilterRegistration.nullInitParams=由于name和(或)value为null,无法为过滤器设置初始化参数。name为 [{0}],value为 [{1}]
applicationHttpRequest.fragmentInDispatchPath=调度路径[{0}]中的片段已被删除
+applicationHttpRequest.sessionEndAccessFail=Exception triggered ending access to session while recycling request
applicationServletRegistration.setServletSecurity.iae=为部署到名为[{1}]的上下文的Servlet[{0}]指定的空约束
applicationServletRegistration.setServletSecurity.ise=无法将安全性约束添加到已部署到名称为[{1}]的上下文的servlet [{0}]中,因为上下文已被初始化
diff --git a/java/org/apache/coyote/http11/InternalAprInputBuffer.java b/java/org/apache/coyote/http11/InternalAprInputBuffer.java
index 3921015507c1..4b31a422c75b 100644
--- a/java/org/apache/coyote/http11/InternalAprInputBuffer.java
+++ b/java/org/apache/coyote/http11/InternalAprInputBuffer.java
@@ -484,7 +484,7 @@ private boolean parseHeader() throws IOException {
headers.removeHeader(headers.size() - 1);
skipLine(lineStart, start);
return true;
- } else if (chr != Constants.HT && HttpParser.isControl(chr)) {
+ } else if (HttpParser.isControl(chr) && chr != Constants.HT) {
// Invalid value
// Delete the header (it will be the most recent one)
headers.removeHeader(headers.size() - 1);
diff --git a/java/org/apache/coyote/http11/InternalInputBuffer.java b/java/org/apache/coyote/http11/InternalInputBuffer.java
index 20dfb8edb3aa..1c7b39123d46 100644
--- a/java/org/apache/coyote/http11/InternalInputBuffer.java
+++ b/java/org/apache/coyote/http11/InternalInputBuffer.java
@@ -435,7 +435,7 @@ private boolean parseHeader() throws IOException {
// Invalid value - also need to delete header
skipLine(lineStart, start, true);
return true;
- } else if (chr != Constants.HT && HttpParser.isControl(chr)) {
+ } else if (HttpParser.isControl(chr) && chr != Constants.HT) {
// Invalid value - also need to delete header
skipLine(lineStart, start, true);
return true;
diff --git a/java/org/apache/coyote/http11/InternalNioInputBuffer.java b/java/org/apache/coyote/http11/InternalNioInputBuffer.java
index 4609a050a1f4..66e237ae2c3c 100644
--- a/java/org/apache/coyote/http11/InternalNioInputBuffer.java
+++ b/java/org/apache/coyote/http11/InternalNioInputBuffer.java
@@ -670,7 +670,7 @@ private HeaderParseStatus parseHeader()
} else if (prevChr == Constants.CR) {
// Invalid value - also need to delete header
return skipLine(true);
- } else if (chr != Constants.HT && HttpParser.isControl(chr)) {
+ } else if (HttpParser.isControl(chr) && chr != Constants.HT) {
// Invalid value - also need to delete header
return skipLine(true);
} else if (chr == Constants.SP || chr == Constants.HT) {
diff --git a/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java b/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java
index 5697512bdeae..8401510a1eef 100644
--- a/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java
+++ b/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java
@@ -31,6 +31,7 @@
import org.apache.tomcat.util.buf.MessageBytes;
import org.apache.tomcat.util.http.MimeHeaders;
import org.apache.tomcat.util.res.StringManager;
+import org.apache.tomcat.util.http.parser.HttpParser;
/**
* Chunked input filter. Parses chunked data according to
@@ -506,6 +507,9 @@ private boolean parseHeader() throws IOException {
if (chr == Constants.COLON) {
colon = true;
+ } else if (!HttpParser.isToken(chr)) {
+ // Non-token characters are illegal in header names
+ throw new IOException(sm.getString("chunkedInputFilter.invalidTrailerHeaderName"));
} else {
trailingHeaders.append(chr);
}
@@ -567,7 +571,9 @@ private boolean parseHeader() throws IOException {
if (chr == Constants.CR || chr == Constants.LF) {
parseCRLF(true);
eol = true;
- } else if (chr == Constants.SP) {
+ } else if (HttpParser.isControl(chr) && chr != Constants.HT) {
+ throw new IOException(sm.getString("chunkedInputFilter.invalidTrailerHeaderValue"));
+ } else if (chr == Constants.SP || chr == Constants.HT) {
trailingHeaders.append(chr);
} else {
trailingHeaders.append(chr);
diff --git a/java/org/apache/coyote/http11/filters/LocalStrings.properties b/java/org/apache/coyote/http11/filters/LocalStrings.properties
index c0dc9d1b10f7..aa1b19d83922 100644
--- a/java/org/apache/coyote/http11/filters/LocalStrings.properties
+++ b/java/org/apache/coyote/http11/filters/LocalStrings.properties
@@ -21,6 +21,8 @@ chunkedInputFilter.invalidCrlfCRCR=Invalid end of line sequence (CRCR)
chunkedInputFilter.invalidCrlfNoCR=Invalid end of line sequence (No CR before LF)
chunkedInputFilter.invalidCrlfNoData=Invalid end of line sequence (no data available to read)
chunkedInputFilter.invalidHeader=Invalid chunk header
+chunkedInputFilter.invalidTrailerHeaderName=Invalid trailer header name (non-token character in name)
+chunkedInputFilter.invalidTrailerHeaderValue=Invalid trailer header value (control character in value)
chunkedInputFilter.maxExtension=maxExtensionSize exceeded
chunkedInputFilter.maxTrailer=maxTrailerSize exceeded
diff --git a/java/org/apache/tomcat/util/buf/B2CConverter.java b/java/org/apache/tomcat/util/buf/B2CConverter.java
index 0b58d3f38216..b298c6092713 100644
--- a/java/org/apache/tomcat/util/buf/B2CConverter.java
+++ b/java/org/apache/tomcat/util/buf/B2CConverter.java
@@ -27,12 +27,16 @@
import java.util.Locale;
import org.apache.tomcat.util.res.StringManager;
+import org.apache.juli.logging.Log;
+import org.apache.juli.logging.LogFactory;
+import org.apache.tomcat.util.ExceptionUtils;
/**
* NIO based character decoder.
*/
public class B2CConverter {
+ private static final Log log = LogFactory.getLog(B2CConverter.class);
private static final StringManager sm =
StringManager.getManager(Constants.Package);
@@ -133,7 +137,12 @@ public B2CConverter(String encoding, boolean replaceOnError)
* Reset the decoder state.
*/
public void recycle() {
- decoder.reset();
+ try {
+ decoder.reset();
+ } catch (Throwable t) {
+ ExceptionUtils.handleThrowable(t);
+ log.warn(sm.getString("b2cConverter.decoderResetFail", decoder.charset()), t);
+ }
leftovers.position(0);
}
diff --git a/java/org/apache/tomcat/util/buf/C2BConverter.java b/java/org/apache/tomcat/util/buf/C2BConverter.java
index b57d47a46f49..7c2806a8a6ab 100644
--- a/java/org/apache/tomcat/util/buf/C2BConverter.java
+++ b/java/org/apache/tomcat/util/buf/C2BConverter.java
@@ -22,11 +22,17 @@
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CoderResult;
import java.nio.charset.CodingErrorAction;
+import org.apache.juli.logging.Log;
+import org.apache.juli.logging.LogFactory;
+import org.apache.tomcat.util.ExceptionUtils;
+import org.apache.tomcat.util.res.StringManager;
/**
* NIO based character encoder.
*/
public final class C2BConverter {
+ private static final Log log = LogFactory.getLog(C2BConverter.class);
+ private static final StringManager sm = StringManager.getManager(C2BConverter.class);
CharsetEncoder encoder = null;
ByteBuffer bb = null;
@@ -51,7 +57,12 @@ public C2BConverter(String encoding) throws IOException {
* Reset the encoder state.
*/
public void recycle() {
- encoder.reset();
+ try {
+ encoder.reset();
+ } catch (Throwable t) {
+ ExceptionUtils.handleThrowable(t);
+ log.warn(sm.getString("c2bConverter.decoderResetFail", encoder.charset()), t);
+ }
leftovers.position(0);
}
diff --git a/java/org/apache/tomcat/util/buf/LocalStrings.properties b/java/org/apache/tomcat/util/buf/LocalStrings.properties
index 76859b5d64f5..e472bfc0994d 100644
--- a/java/org/apache/tomcat/util/buf/LocalStrings.properties
+++ b/java/org/apache/tomcat/util/buf/LocalStrings.properties
@@ -13,9 +13,11 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+b2cConverter.decoderResetFail=Failed to reset instance of decoder for character set [{0}]
b2cConverter.unknownEncoding=The character encoding [{0}] is not supported
c2bConverter.recycleFailed=Failed to recycle the C2B Converter. Creating new BufferedWriter, WriteConvertor and IntermediateOutputStream.
+c2bConverter.encoderResetFail=Failed to reset instance of encoder for character set [{0}]
encodedSolidusHandling.invalid=The value [{0}] is not recognised
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 67bdde886522..ceaa6f7857fa 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -145,6 +145,10 @@
Avoid protocol relative redirects in FORM authentication. (markt)
+
+ Improve handling of failures within recycle()
methods.
+ (markt)
+
@@ -339,6 +343,9 @@
Add additional debug logging for I/O issues when communicating with the
user agent. (markt)
+
+ Align validation of HTTP trailer fields with standard fields. (markt)
+