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