Author: markt
Date: Mon Feb 20 20:32:34 2012
New Revision: 1291432

URL: http://svn.apache.org/viewvc?rev=1291432&view=rev
Log:
Improve handling of larger messages

Modified:
    tomcat/trunk/java/org/apache/catalina/websocket/MessageInbound.java
    tomcat/trunk/java/org/apache/catalina/websocket/WsOutbound.java

Modified: tomcat/trunk/java/org/apache/catalina/websocket/MessageInbound.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/websocket/MessageInbound.java?rev=1291432&r1=1291431&r2=1291432&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/websocket/MessageInbound.java 
(original)
+++ tomcat/trunk/java/org/apache/catalina/websocket/MessageInbound.java Mon Feb 
20 20:32:34 2012
@@ -24,8 +24,10 @@ import java.nio.CharBuffer;
 
 public abstract class MessageInbound extends StreamInbound {
 
-    // TODO: Make buffer sizes configurable
-    // TODO: Allow buffers to expand
+    // 2MB - like maxPostSize
+    private int byteBufferMaxSize = 2097152;
+    private int charBufferMaxSize = 2097152;
+
     ByteBuffer bb = ByteBuffer.allocate(8192);
     CharBuffer cb = CharBuffer.allocate(8192);
 
@@ -34,6 +36,9 @@ public abstract class MessageInbound ext
         int read = 0;
         while (read > -1) {
             bb.position(bb.position() + read);
+            if (bb.remaining() == 0) {
+                resizeByteBuffer();
+            }
             read = is.read(bb.array(), bb.position(), bb.remaining());
         }
         bb.flip();
@@ -46,6 +51,9 @@ public abstract class MessageInbound ext
         int read = 0;
         while (read > -1) {
             cb.position(cb.position() + read);
+            if (cb.remaining() == 0) {
+                resizeCharBuffer();
+            }
             read = r.read(cb.array(), cb.position(), cb.remaining());
         }
         cb.limit(cb.position());
@@ -54,6 +62,60 @@ public abstract class MessageInbound ext
         cb.clear();
     }
 
+    private void resizeByteBuffer() throws IOException {
+        int maxSize = getByteBufferMaxSize();
+        if (bb.limit() >= maxSize) {
+            // TODO i18n
+            throw new IOException("Buffer not big enough for message");
+        }
+
+        long newSize = bb.limit() * 2;
+        if (newSize > maxSize) {
+            newSize = maxSize;
+        }
+
+        // Cast is safe. newSize < maxSize and maxSize is an int
+        ByteBuffer newBuffer = ByteBuffer.allocate((int) newSize);
+        bb.rewind();
+        newBuffer.put(bb);
+        bb = newBuffer;
+    }
+
+    private void resizeCharBuffer() throws IOException {
+        int maxSize = getCharBufferMaxSize();
+        if (cb.limit() >= maxSize) {
+            // TODO i18n
+            throw new IOException("Buffer not big enough for message");
+        }
+
+        long newSize = cb.limit() * 2;
+        if (newSize > maxSize) {
+            newSize = maxSize;
+        }
+
+        // Cast is safe. newSize < maxSize and maxSize is an int
+        CharBuffer newBuffer = CharBuffer.allocate((int) newSize);
+        cb.rewind();
+        newBuffer.put(cb);
+        cb = newBuffer;
+    }
+
+    public int getByteBufferMaxSize() {
+        return byteBufferMaxSize;
+    }
+
+    public void setByteBufferMaxSize(int byteBufferMaxSize) {
+        this.byteBufferMaxSize = byteBufferMaxSize;
+    }
+
+    public int getCharBufferMaxSize() {
+        return charBufferMaxSize;
+    }
+
+    public void setCharBufferMaxSize(int charBufferMaxSize) {
+        this.charBufferMaxSize = charBufferMaxSize;
+    }
+
     protected abstract void onBinaryMessage(ByteBuffer message)
             throws IOException;
     protected abstract void onTextMessage(CharBuffer message)

Modified: tomcat/trunk/java/org/apache/catalina/websocket/WsOutbound.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/websocket/WsOutbound.java?rev=1291432&r1=1291431&r2=1291432&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/websocket/WsOutbound.java (original)
+++ tomcat/trunk/java/org/apache/catalina/websocket/WsOutbound.java Mon Feb 20 
20:32:34 2012
@@ -25,7 +25,7 @@ import org.apache.tomcat.util.buf.B2CCon
 
 public class WsOutbound {
 
-    private static final int DEFAULT_BUFFER_SIZE = 2048;
+    private static final int DEFAULT_BUFFER_SIZE = 8192;
 
     private UpgradeOutbound upgradeOutbound;
     private ByteBuffer bb;
@@ -37,9 +37,7 @@ public class WsOutbound {
     public WsOutbound(UpgradeOutbound upgradeOutbound) {
         this.upgradeOutbound = upgradeOutbound;
         // TODO: Make buffer size configurable
-        // Byte buffer needs to be 4* char buffer to be sure that char buffer
-        // can always we written into Byte buffer
-        this.bb = ByteBuffer.allocate(DEFAULT_BUFFER_SIZE * 4);
+        this.bb = ByteBuffer.allocate(DEFAULT_BUFFER_SIZE);
         this.cb = CharBuffer.allocate(DEFAULT_BUFFER_SIZE);
     }
 
@@ -170,8 +168,16 @@ public class WsOutbound {
     protected void doWriteText(CharBuffer buffer, boolean finalFragment)
             throws IOException {
         buffer.flip();
-        B2CConverter.UTF_8.newEncoder().encode(buffer, bb, true);
-        doWriteBinary(bb, finalFragment);
+
+        do {
+            B2CConverter.UTF_8.newEncoder().encode(buffer, bb, true);
+            if (buffer.hasRemaining()) {
+                doWriteBinary(bb, false);
+            } else {
+                doWriteBinary(bb, finalFragment);
+            }
+        } while (buffer.hasRemaining());
+
         // Reset
         cb.clear();
     }



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

Reply via email to