You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2023/11/08 15:53:44 UTC
(tomcat) 01/03: Differentiate request cancellation from a bad request
This is an automated email from the ASF dual-hosted git repository.
markt pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tomcat.git
commit c2b60ded7b961aa30201c32a11a9e7c4ee632302
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Wed Nov 8 14:59:41 2023 +0000
Differentiate request cancellation from a bad request
Introduce BadRequestException as a sub-class of IOException and the
super class of ClientAbortException. This allows Tomcat to differentiate
between an invalid request (e.g. invalid HTTP headers) and a request
that the user cancelled before it completed.
---
...bortException.java => BadRequestException.java} | 22 ++++++++++------------
.../catalina/connector/ClientAbortException.java | 4 +---
.../org/apache/catalina/connector/InputBuffer.java | 6 ++++--
java/org/apache/catalina/connector/Request.java | 8 ++++----
.../catalina/core/ApplicationDispatcher.java | 6 +++---
.../apache/catalina/core/StandardWrapperValve.java | 6 +++---
6 files changed, 25 insertions(+), 27 deletions(-)
diff --git a/java/org/apache/catalina/connector/ClientAbortException.java b/java/org/apache/catalina/connector/BadRequestException.java
similarity index 67%
copy from java/org/apache/catalina/connector/ClientAbortException.java
copy to java/org/apache/catalina/connector/BadRequestException.java
index ca40f014d6..71a792d7fb 100644
--- a/java/org/apache/catalina/connector/ClientAbortException.java
+++ b/java/org/apache/catalina/connector/BadRequestException.java
@@ -19,11 +19,9 @@ package org.apache.catalina.connector;
import java.io.IOException;
/**
- * Extend IOException to identify it as being caused by an abort of a request by a remote client.
- *
- * @author Glenn L. Nielsen
+ * Extend IOException to identify it as being caused by a bad request from a remote client.
*/
-public final class ClientAbortException extends IOException {
+public class BadRequestException extends IOException {
private static final long serialVersionUID = 1L;
@@ -31,40 +29,40 @@ public final class ClientAbortException extends IOException {
// ------------------------------------------------------------ Constructors
/**
- * Construct a new ClientAbortException with no other information.
+ * Construct a new BadRequestException with no other information.
*/
- public ClientAbortException() {
+ public BadRequestException() {
super();
}
/**
- * Construct a new ClientAbortException for the specified message.
+ * Construct a new BadRequestException for the specified message.
*
* @param message Message describing this exception
*/
- public ClientAbortException(String message) {
+ public BadRequestException(String message) {
super(message);
}
/**
- * Construct a new ClientAbortException for the specified throwable.
+ * Construct a new BadRequestException for the specified throwable.
*
* @param throwable Throwable that caused this exception
*/
- public ClientAbortException(Throwable throwable) {
+ public BadRequestException(Throwable throwable) {
super(throwable);
}
/**
- * Construct a new ClientAbortException for the specified message and throwable.
+ * Construct a new BadRequestException for the specified message and throwable.
*
* @param message Message describing this exception
* @param throwable Throwable that caused this exception
*/
- public ClientAbortException(String message, Throwable throwable) {
+ public BadRequestException(String message, Throwable throwable) {
super(message, throwable);
}
}
diff --git a/java/org/apache/catalina/connector/ClientAbortException.java b/java/org/apache/catalina/connector/ClientAbortException.java
index ca40f014d6..aee20c1d67 100644
--- a/java/org/apache/catalina/connector/ClientAbortException.java
+++ b/java/org/apache/catalina/connector/ClientAbortException.java
@@ -16,14 +16,12 @@
*/
package org.apache.catalina.connector;
-import java.io.IOException;
-
/**
* Extend IOException to identify it as being caused by an abort of a request by a remote client.
*
* @author Glenn L. Nielsen
*/
-public final class ClientAbortException extends IOException {
+public final class ClientAbortException extends BadRequestException {
private static final long serialVersionUID = 1L;
diff --git a/java/org/apache/catalina/connector/InputBuffer.java b/java/org/apache/catalina/connector/InputBuffer.java
index 8e70688e0a..c24f5efbb5 100644
--- a/java/org/apache/catalina/connector/InputBuffer.java
+++ b/java/org/apache/catalina/connector/InputBuffer.java
@@ -291,10 +291,12 @@ public class InputBuffer extends Reader implements ByteChunk.ByteInputChannel, A
try {
return coyoteRequest.doRead(this);
+ } catch (BadRequestException bre) {
+ coyoteRequest.setErrorException(bre);
+ throw bre;
} catch (IOException ioe) {
coyoteRequest.setErrorException(ioe);
- // An IOException on a read is almost always due to
- // the remote client aborting the request.
+ // Any other IOException on a read is almost always due to the remote client aborting the request.
throw new ClientAbortException(ioe);
}
}
diff --git a/java/org/apache/catalina/connector/Request.java b/java/org/apache/catalina/connector/Request.java
index bda5dc2da4..a0df03b587 100644
--- a/java/org/apache/catalina/connector/Request.java
+++ b/java/org/apache/catalina/connector/Request.java
@@ -3048,10 +3048,10 @@ public class Request implements HttpServletRequest {
context.getLogger().debug(sm.getString("coyoteRequest.parseParameters"), e);
}
response.getCoyoteResponse().action(ActionCode.CLOSE_NOW, null);
- if (e instanceof ClientAbortException) {
+ if (e instanceof BadRequestException) {
parametersParseException = new InvalidParameterException(e);
} else {
- parametersParseException = new InvalidParameterException(new ClientAbortException(e));
+ parametersParseException = new InvalidParameterException(new BadRequestException(e));
}
return;
}
@@ -3070,10 +3070,10 @@ public class Request implements HttpServletRequest {
context.getLogger().debug(sm.getString("coyoteRequest.parseParameters"), e);
}
response.getCoyoteResponse().action(ActionCode.CLOSE_NOW, null);
- if (e instanceof ClientAbortException) {
+ if (e instanceof BadRequestException) {
parametersParseException = new InvalidParameterException(e);
} else {
- parametersParseException = new InvalidParameterException(new ClientAbortException(e));
+ parametersParseException = new InvalidParameterException(new BadRequestException(e));
}
return;
}
diff --git a/java/org/apache/catalina/core/ApplicationDispatcher.java b/java/org/apache/catalina/core/ApplicationDispatcher.java
index 2ad146bcc2..5e49d45166 100644
--- a/java/org/apache/catalina/core/ApplicationDispatcher.java
+++ b/java/org/apache/catalina/core/ApplicationDispatcher.java
@@ -38,7 +38,7 @@ import org.apache.catalina.AsyncDispatcher;
import org.apache.catalina.Context;
import org.apache.catalina.Globals;
import org.apache.catalina.Wrapper;
-import org.apache.catalina.connector.ClientAbortException;
+import org.apache.catalina.connector.BadRequestException;
import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.RequestFacade;
import org.apache.catalina.connector.Response;
@@ -534,7 +534,7 @@ final class ApplicationDispatcher implements AsyncDispatcher, RequestDispatcher
filterChain.doFilter(request, response);
}
// Servlet Service Method is called by the FilterChain
- } catch (ClientAbortException e) {
+ } catch (BadRequestException e) {
ioException = e;
} catch (IOException e) {
wrapper.getLogger().error(sm.getString("applicationDispatcher.serviceException", wrapper.getName()), e);
@@ -545,7 +545,7 @@ final class ApplicationDispatcher implements AsyncDispatcher, RequestDispatcher
wrapper.unavailable(e);
} catch (ServletException e) {
Throwable rootCause = StandardWrapper.getRootCause(e);
- if (!(rootCause instanceof ClientAbortException)) {
+ if (!(rootCause instanceof BadRequestException)) {
wrapper.getLogger().error(sm.getString("applicationDispatcher.serviceException", wrapper.getName()),
rootCause);
}
diff --git a/java/org/apache/catalina/core/StandardWrapperValve.java b/java/org/apache/catalina/core/StandardWrapperValve.java
index 1c3e5c31d0..0cf0cd4fd8 100644
--- a/java/org/apache/catalina/core/StandardWrapperValve.java
+++ b/java/org/apache/catalina/core/StandardWrapperValve.java
@@ -31,7 +31,7 @@ import org.apache.catalina.Container;
import org.apache.catalina.Context;
import org.apache.catalina.Globals;
import org.apache.catalina.LifecycleException;
-import org.apache.catalina.connector.ClientAbortException;
+import org.apache.catalina.connector.BadRequestException;
import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.Response;
import org.apache.catalina.valves.ValveBase;
@@ -169,7 +169,7 @@ final class StandardWrapperValve extends ValveBase {
}
}
- } catch (ClientAbortException | CloseNowException e) {
+ } catch (BadRequestException | CloseNowException e) {
if (container.getLogger().isDebugEnabled()) {
container.getLogger().debug(
sm.getString("standardWrapper.serviceException", wrapper.getName(), context.getName()), e);
@@ -190,7 +190,7 @@ final class StandardWrapperValve extends ValveBase {
// do not want to do exception(request, response, e) processing
} catch (ServletException e) {
Throwable rootCause = StandardWrapper.getRootCause(e);
- if (!(rootCause instanceof ClientAbortException)) {
+ if (!(rootCause instanceof BadRequestException)) {
container.getLogger().error(sm.getString("standardWrapper.serviceExceptionRoot", wrapper.getName(),
context.getName(), e.getMessage()), rootCause);
}
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org