Author: remm
Date: Sun May  3 16:47:26 2015
New Revision: 1677450

URL: http://svn.apache.org/r1677450
Log:
Follow up on r1672297 which did fix the byte counter infinite loop but 
corrupted data. Now handle with a recursion the situation where bytes remain in 
the buffer but they do not produce any output and the status is underflow.

Modified:
    tomcat/trunk/java/org/apache/tomcat/util/net/SecureNio2Channel.java

Modified: tomcat/trunk/java/org/apache/tomcat/util/net/SecureNio2Channel.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/SecureNio2Channel.java?rev=1677450&r1=1677449&r2=1677450&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/SecureNio2Channel.java 
(original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/SecureNio2Channel.java Sun May 
 3 16:47:26 2015
@@ -534,31 +534,35 @@ public class SecureNio2Channel extends N
         private final Future<Integer> integer;
         private FutureRead(ByteBuffer dst) {
             this.dst = dst;
-            this.integer = sc.read(netInBuffer);
+            if (netInBuffer.position() > 0) {
+                this.integer = null;
+            } else {
+                this.integer = sc.read(netInBuffer);
+            }
         }
         @Override
         public boolean cancel(boolean mayInterruptIfRunning) {
-            return integer.cancel(mayInterruptIfRunning);
+            return (integer == null) ? false : 
integer.cancel(mayInterruptIfRunning);
         }
         @Override
         public boolean isCancelled() {
-            return integer.isCancelled();
+            return (integer == null) ? false : integer.isCancelled();
         }
         @Override
         public boolean isDone() {
-            return integer.isDone();
+            return (integer == null) ? true : integer.isDone();
         }
         @Override
         public Integer get() throws InterruptedException, ExecutionException {
-            return unwrap(integer.get().intValue());
+            return (integer == null) ? unwrap(netInBuffer.position(), -1, 
TimeUnit.MILLISECONDS) : unwrap(integer.get().intValue(), -1, 
TimeUnit.MILLISECONDS);
         }
         @Override
         public Integer get(long timeout, TimeUnit unit)
                 throws InterruptedException, ExecutionException,
                 TimeoutException {
-            return unwrap(integer.get(timeout, unit).intValue());
+            return (integer == null) ? unwrap(netInBuffer.position(), timeout, 
unit) : unwrap(integer.get(timeout, unit).intValue(), timeout, unit);
         }
-        private Integer unwrap(int nRead) throws ExecutionException {
+        private Integer unwrap(int nRead, long timeout, TimeUnit unit) throws 
ExecutionException {
             //are we in the middle of closing or closed?
             if (closing || closed)
                 return Integer.valueOf(-1);
@@ -589,7 +593,19 @@ public class SecureNio2Channel extends N
                     }
                     //if we need more network data, then bail out for now.
                     if (unwrap.getStatus() == Status.BUFFER_UNDERFLOW) {
-                        break;
+                        if (read == 0) {
+                            try {
+                                if (timeout > 0) {
+                                    return 
unwrap(sc.read(netInBuffer).get(timeout, unit).intValue(), timeout, unit);
+                                } else {
+                                    return 
unwrap(sc.read(netInBuffer).get().intValue(), -1, TimeUnit.MILLISECONDS);
+                                }
+                            } catch (InterruptedException | TimeoutException 
e) {
+                                throw new ExecutionException(e);
+                            }
+                        } else {
+                            break;
+                        }
                     }
                 } else if (unwrap.getStatus() == Status.BUFFER_OVERFLOW && 
read > 0) {
                     //buffer overflow can happen, if we have read data, then
@@ -723,7 +739,7 @@ public class SecureNio2Channel extends N
         if (!handshakeComplete) {
             throw new 
IllegalStateException(sm.getString("channel.nio.ssl.incompleteHandshake"));
         }
-        sc.read(netInBuffer, timeout, unit, attachment, new 
CompletionHandler<Integer, A>() {
+        CompletionHandler<Integer, A> readCompletionHandler = new 
CompletionHandler<Integer, A>() {
             @Override
             public void completed(Integer nBytes, A attach) {
                 if (nBytes.intValue() < 0) {
@@ -749,7 +765,12 @@ public class SecureNio2Channel extends N
                                     tasks();
                                 //if we need more network data, then bail out 
for now.
                                 if (unwrap.getStatus() == 
Status.BUFFER_UNDERFLOW) {
-                                    break;
+                                    if (read == 0) {
+                                        sc.read(netInBuffer, timeout, unit, 
attachment, this);
+                                        return;
+                                    } else {
+                                        break;
+                                    }
                                 }
                             } else if (unwrap.getStatus() == 
Status.BUFFER_OVERFLOW && read > 0) {
                                 //buffer overflow can happen, if we have read 
data, then
@@ -773,7 +794,12 @@ public class SecureNio2Channel extends N
             public void failed(Throwable exc, A attach) {
                 handler.failed(exc, attach);
             }
-        });
+        };
+        if (netInBuffer.position() > 0) {
+            
readCompletionHandler.completed(Integer.valueOf(netInBuffer.position()), 
attachment);
+        } else {
+            sc.read(netInBuffer, timeout, unit, attachment, 
readCompletionHandler);
+        }
     }
 
     @Override
@@ -790,7 +816,7 @@ public class SecureNio2Channel extends N
         if (!handshakeComplete) {
             throw new 
IllegalStateException(sm.getString("channel.nio.ssl.incompleteHandshake"));
         }
-        sc.read(netInBuffer, timeout, unit, attachment, new 
CompletionHandler<Integer, A>() {
+        CompletionHandler<Integer, A> readCompletionHandler = new 
CompletionHandler<Integer, A>() {
             @Override
             public void completed(Integer nBytes, A attach) {
                 if (nBytes.intValue() < 0) {
@@ -816,7 +842,12 @@ public class SecureNio2Channel extends N
                                     tasks();
                                 //if we need more network data, then bail out 
for now.
                                 if (unwrap.getStatus() == 
Status.BUFFER_UNDERFLOW) {
-                                    break;
+                                    if (read == 0) {
+                                        sc.read(netInBuffer, timeout, unit, 
attachment, this);
+                                        return;
+                                    } else {
+                                        break;
+                                    }
                                 }
                             } else if (unwrap.getStatus() == 
Status.BUFFER_OVERFLOW && read > 0) {
                                 //buffer overflow can happen, if we have read 
data, then
@@ -840,8 +871,12 @@ public class SecureNio2Channel extends N
             public void failed(Throwable exc, A attach) {
                 handler.failed(exc, attach);
             }
-        });
-
+        };
+        if (netInBuffer.position() > 0) {
+            
readCompletionHandler.completed(Integer.valueOf(netInBuffer.position()), 
attachment);
+        } else {
+            sc.read(netInBuffer, timeout, unit, attachment, 
readCompletionHandler);
+        }
     }
 
     @Override



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to