From: markt Date: Wed, 4 May 2011 18:32:05 +0000 (+0000) Subject: Improve handling of too large packets in AJP connectors X-Git-Url: https://git.internetallee.de/?a=commitdiff_plain;h=42924305060ae33acceb8ec9ab26d91aab2c37f5;p=tomcat7.0 Improve handling of too large packets in AJP connectors - Explicitly check the packet size rather than waiting to see if it fails - Provide a better debug message when it does fail - Once we know we have a bad request, don't try to process it git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@1099556 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/java/org/apache/coyote/ajp/AjpAprProcessor.java b/java/org/apache/coyote/ajp/AjpAprProcessor.java index f3b9e8c7b..434b2f242 100644 --- a/java/org/apache/coyote/ajp/AjpAprProcessor.java +++ b/java/org/apache/coyote/ajp/AjpAprProcessor.java @@ -263,17 +263,19 @@ public class AjpAprProcessor extends AbstractAjpProcessor { error = true; } - // Setting up filters, and parse some request headers - rp.setStage(org.apache.coyote.Constants.STAGE_PREPARE); - try { - prepareRequest(); - } catch (Throwable t) { - ExceptionUtils.handleThrowable(t); - log.debug(sm.getString("ajpprocessor.request.prepare"), t); - // 400 - Internal Server Error - response.setStatus(400); - adapter.log(request, response, 0); - error = true; + if (!error) { + // Setting up filters, and parse some request headers + rp.setStage(org.apache.coyote.Constants.STAGE_PREPARE); + try { + prepareRequest(); + } catch (Throwable t) { + ExceptionUtils.handleThrowable(t); + log.debug(sm.getString("ajpprocessor.request.prepare"), t); + // 400 - Internal Server Error + response.setStatus(400); + adapter.log(request, response, 0); + error = true; + } } // Process the request in the adapter @@ -621,6 +623,14 @@ public class AjpAprProcessor extends AbstractAjpProcessor { return true; } else { + if (messageLength > message.getBuffer().length) { + // Message too long for the buffer + // Need to trigger a 400 response + throw new IllegalArgumentException(sm.getString( + "ajpprocessor.header.tooLong", + Integer.valueOf(messageLength), + Integer.valueOf(message.getBuffer().length))); + } read(messageLength); inputBuffer.get(message.getBuffer(), headerLength, messageLength); return true; diff --git a/java/org/apache/coyote/ajp/AjpProcessor.java b/java/org/apache/coyote/ajp/AjpProcessor.java index c4023d2c9..10355d65f 100644 --- a/java/org/apache/coyote/ajp/AjpProcessor.java +++ b/java/org/apache/coyote/ajp/AjpProcessor.java @@ -274,17 +274,19 @@ public class AjpProcessor extends AbstractAjpProcessor { error = true; } - // Setting up filters, and parse some request headers - rp.setStage(org.apache.coyote.Constants.STAGE_PREPARE); - try { - prepareRequest(); - } catch (Throwable t) { - ExceptionUtils.handleThrowable(t); - log.debug(sm.getString("ajpprocessor.request.prepare"), t); - // 400 - Internal Server Error - response.setStatus(400); - adapter.log(request, response, 0); - error = true; + if (!error) { + // Setting up filters, and parse some request headers + rp.setStage(org.apache.coyote.Constants.STAGE_PREPARE); + try { + prepareRequest(); + } catch (Throwable t) { + ExceptionUtils.handleThrowable(t); + log.debug(sm.getString("ajpprocessor.request.prepare"), t); + // 400 - Internal Server Error + response.setStatus(400); + adapter.log(request, response, 0); + error = true; + } } if (endpoint.isPaused()) { @@ -570,6 +572,14 @@ public class AjpProcessor extends AbstractAjpProcessor { return true; } else { + if (messageLength > buf.length) { + // Message too long for the buffer + // Need to trigger a 400 response + throw new IllegalArgumentException(sm.getString( + "ajpprocessor.header.tooLong", + Integer.valueOf(messageLength), + Integer.valueOf(buf.length))); + } read(buf, headerLength, messageLength); return true; } diff --git a/java/org/apache/coyote/ajp/LocalStrings.properties b/java/org/apache/coyote/ajp/LocalStrings.properties index 3025aa843..62d230e4f 100644 --- a/java/org/apache/coyote/ajp/LocalStrings.properties +++ b/java/org/apache/coyote/ajp/LocalStrings.properties @@ -34,6 +34,7 @@ ajpprotocol.request.register=Error registering request processor in JMX ajpprocessor.failedflush=Failed to flush AJP message ajpprocessor.failedsend=Failed to send AJP message ajpprocessor.header.error=Header message parsing failed +ajpprocessor.header.tooLong=Header message of length [{0}] received but the packetSize is only [{1}] ajpprocessor.request.prepare=Error preparing request ajpprocessor.request.process=Error processing request ajpprocessor.certs.fail=Certificate conversion failed diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index 560bf19c2..7792e81d3 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -147,6 +147,10 @@ handshake fails with the HTTP-APR connector. Patch provided by Mike Glazer. (markt) + + Improve handling in AJP connectors of the case where too large a AJP + packet is received. (markt) +