From 3dc61ee8a0c43d04b26ee273a75551dc084872a2 Mon Sep 17 00:00:00 2001 From: remm Date: Fri, 27 Apr 2007 22:03:57 +0000 Subject: [PATCH] - Add code to check that at least one read is made that goes down to the connector for each read event. - It is an error to not read bytes as long as some are reported as available. - Generate a read event if bytes are available after processing the begin event (for API lawyers out there). - Not tested yet, sorry. In theory, previously working code shouldn't have to be modified at all. git-svn-id: https://svn.apache.org/repos/asf/tomcat/tc6.0.x/trunk@533240 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/catalina/connector/CoyoteAdapter.java | 20 ++++++++++++++++++-- java/org/apache/catalina/connector/InputBuffer.java | 20 ++++++++++++++++++-- java/org/apache/catalina/connector/Request.java | 18 ++++++++++++++++++ 3 files changed, 54 insertions(+), 4 deletions(-) diff --git a/java/org/apache/catalina/connector/CoyoteAdapter.java b/java/org/apache/catalina/connector/CoyoteAdapter.java index ac0f63034..808f1c76f 100644 --- a/java/org/apache/catalina/connector/CoyoteAdapter.java +++ b/java/org/apache/catalina/connector/CoyoteAdapter.java @@ -118,6 +118,7 @@ public class CoyoteAdapter if (request.getWrapper() != null) { boolean error = false; + boolean read = false; try { if (status == SocketStatus.OPEN) { if (response.isClosed()) { @@ -128,6 +129,8 @@ public class CoyoteAdapter } else { request.getEvent().setEventType(CometEvent.EventType.READ); request.getEvent().setEventSubType(null); + read = true; + request.resetDidRead(); } } else if (status == SocketStatus.DISCONNECT) { request.getEvent().setEventType(CometEvent.EventType.ERROR); @@ -167,6 +170,11 @@ public class CoyoteAdapter } if (response.isClosed() || !request.isComet()) { res.action(ActionCode.ACTION_COMET_END, null); + } else if (!error && read && (!request.didRead() || request.getAvailable())) { + // If this was a read and not all bytes have been read, or if no data + // was read from the connector, then it is an error + error = true; + log.error(sm.getString("coyoteAdapter.read")); } return (!error); } catch (Throwable t) { @@ -240,8 +248,16 @@ public class CoyoteAdapter if (request.isComet()) { if (!response.isClosed() && !response.isError()) { - comet = true; - res.action(ActionCode.ACTION_COMET_BEGIN, null); + if (request.getAvailable()) { + // Invoke a read event right away if there are available bytes + if (event(req, res, SocketStatus.OPEN)) { + comet = true; + res.action(ActionCode.ACTION_COMET_BEGIN, null); + } + } else { + comet = true; + res.action(ActionCode.ACTION_COMET_BEGIN, null); + } } else { // Clear the filter chain, as otherwise it will not be reset elsewhere // since this is a Comet request diff --git a/java/org/apache/catalina/connector/InputBuffer.java b/java/org/apache/catalina/connector/InputBuffer.java index 08829e5c4..5f1796078 100644 --- a/java/org/apache/catalina/connector/InputBuffer.java +++ b/java/org/apache/catalina/connector/InputBuffer.java @@ -99,6 +99,12 @@ public class InputBuffer extends Reader /** + * Flag which if a read was performed. + */ + private boolean didRead = false; + + + /** * Byte chunk used to input bytes. */ private ByteChunk inputChunk = new ByteChunk(); @@ -257,8 +263,7 @@ public class InputBuffer extends Reader } - public int available() - throws IOException { + public int available() { int available = 0; if (state == BYTE_STATE) { available = bb.getLength(); @@ -273,6 +278,16 @@ public class InputBuffer extends Reader } + public boolean didRead() { + return didRead(); + } + + + public void resetDidRead() { + didRead = false; + } + + // ------------------------------------------------- Bytes Handling Methods @@ -294,6 +309,7 @@ public class InputBuffer extends Reader return -1; state = BYTE_STATE; + didRead = true; int result = coyoteRequest.doRead(bb); diff --git a/java/org/apache/catalina/connector/Request.java b/java/org/apache/catalina/connector/Request.java index ea33f366a..b0a84e95c 100644 --- a/java/org/apache/catalina/connector/Request.java +++ b/java/org/apache/catalina/connector/Request.java @@ -2240,6 +2240,24 @@ public class Request } + /** + * Return true if bytes are available. + */ + public boolean getAvailable() { + return (inputBuffer.available() > 0); + } + + + public boolean didRead() { + return inputBuffer.didRead(); + } + + + public void resetDidRead() { + inputBuffer.resetDidRead(); + } + + // ------------------------------------------------------ Protected Methods -- 2.11.0