Author: markt
Date: Thu Oct 11 14:38:50 2012
New Revision: 1397086

URL: http://svn.apache.org/viewvc?rev=1397086&view=rev
Log:
Fix WebSocket + NIO + HTTPS.
Utilise underlying read buffer rather than trying to read the exact number of 
bytes. This is more efficient for HTTP and required for HTTPS since it is not 
possible to unwrap a single byte.

Modified:
    tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeNioProcessor.java

Modified: 
tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeNioProcessor.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeNioProcessor.java?rev=1397086&r1=1397085&r2=1397086&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeNioProcessor.java 
(original)
+++ tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeNioProcessor.java 
Thu Oct 11 14:38:50 2012
@@ -18,6 +18,7 @@ package org.apache.coyote.http11.upgrade
 
 import java.io.EOFException;
 import java.io.IOException;
+import java.nio.ByteBuffer;
 import java.nio.channels.Selector;
 
 import org.apache.tomcat.util.net.NioChannel;
@@ -120,9 +121,52 @@ public class UpgradeNioProcessor extends
     private int readSocket(boolean block, byte[] bytes, int offset, int len)
             throws IOException {
 
-        int nRead = 0;
-        nioChannel.getBufHandler().getReadBuffer().clear();
-        nioChannel.getBufHandler().getReadBuffer().limit(len);
+        ByteBuffer readBuffer = nioChannel.getBufHandler().getReadBuffer();
+        int remaining = readBuffer.remaining();
+
+        // Is there enough data in the read buffer to satisfy this request?
+        if (remaining >= len) {
+            readBuffer.get(bytes, offset, len);
+            return len;
+        }
+
+        // Copy what data there is in the read buffer to the byte array
+        int leftToWrite = len;
+        int newOffset = offset;
+        if (remaining > 0) {
+            readBuffer.get(bytes, offset, remaining);
+            leftToWrite -= remaining;
+            newOffset += remaining;
+        }
+
+        // Fill the read buffer as best we can
+        readBuffer.clear();
+        int nRead = fillReadBuffer(block);
+
+        // Full as much of the remaining byte array as possible with the data
+        // that was just read
+        if (nRead > 0) {
+            readBuffer.flip();
+            readBuffer.limit(nRead);
+            if (nRead > leftToWrite) {
+                readBuffer.get(bytes, newOffset, leftToWrite);
+                leftToWrite = 0;
+            } else {
+                readBuffer.get(bytes, newOffset, nRead);
+                leftToWrite -= nRead;
+            }
+        } else if (nRead == 0) {
+            readBuffer.flip();
+            readBuffer.limit(nRead);
+        } else if (nRead == -1) {
+            throw new EOFException(sm.getString("nio.eof.error"));
+        }
+
+        return len - leftToWrite;
+    }
+
+    private int fillReadBuffer(boolean block) throws IOException {
+        int nRead;
         if (block) {
             Selector selector = null;
             try {
@@ -148,20 +192,9 @@ public class UpgradeNioProcessor extends
         } else {
             nRead = 
nioChannel.read(nioChannel.getBufHandler().getReadBuffer());
         }
-        if (nRead > 0) {
-            nioChannel.getBufHandler().getReadBuffer().flip();
-            nioChannel.getBufHandler().getReadBuffer().limit(nRead);
-            nioChannel.getBufHandler().getReadBuffer().get(bytes, offset, 
nRead);
-            return nRead;
-        } else if (nRead == -1) {
-            //return false;
-            throw new EOFException(sm.getString("nio.eof.error"));
-        } else {
-            return 0;
-        }
+        return nRead;
     }
 
-
     /*
      * Adapted from the NioOutputBuffer
      */



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

Reply via email to