You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by re...@apache.org on 2015/05/03 18:47:27 UTC

svn commit: r1677450 - /tomcat/trunk/java/org/apache/tomcat/util/net/SecureNio2Channel.java

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-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org