Author: markt
Date: Mon Mar 18 20:56:39 2013
New Revision: 1457990

URL: http://svn.apache.org/r1457990
Log:
Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=54711
Fix multiple issues with OutputStream and Writer
Based on a patch by Nick Williams

Modified:
    tomcat/trunk/java/org/apache/tomcat/websocket/WsRemoteEndpointImplBase.java

Modified: 
tomcat/trunk/java/org/apache/tomcat/websocket/WsRemoteEndpointImplBase.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/websocket/WsRemoteEndpointImplBase.java?rev=1457990&r1=1457989&r2=1457990&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/websocket/WsRemoteEndpointImplBase.java 
(original)
+++ tomcat/trunk/java/org/apache/tomcat/websocket/WsRemoteEndpointImplBase.java 
Mon Mar 18 20:56:39 2013
@@ -730,6 +730,8 @@ public abstract class WsRemoteEndpointIm
 
         private final WsRemoteEndpointImplBase endpoint;
         private final ByteBuffer buffer = ByteBuffer.allocate(8192);
+        private final Object closeLock = new Object();
+        private volatile boolean closed = false;
 
         public WsOutputStream(WsRemoteEndpointImplBase endpoint) {
             this.endpoint = endpoint;
@@ -737,6 +739,11 @@ public abstract class WsRemoteEndpointIm
 
         @Override
         public void write(int b) throws IOException {
+            if (closed) {
+                throw new IllegalStateException(
+                        sm.getString("wsRemoteEndpoint.closedOutputStream"));
+            }
+
             if (buffer.remaining() == 0) {
                 flush();
             }
@@ -745,10 +752,25 @@ public abstract class WsRemoteEndpointIm
 
         @Override
         public void write(byte[] b, int off, int len) throws IOException {
+            if (closed) {
+                throw new IllegalStateException(
+                        sm.getString("wsRemoteEndpoint.closedOutputStream"));
+            }
+            if (len == 0) {
+                return;
+            }
+            if ((off < 0) || (off > b.length) || (len < 0) ||
+                ((off + len) > b.length) || ((off + len) < 0)) {
+                throw new IndexOutOfBoundsException();
+            }
+
+            if (buffer.remaining() == 0) {
+                flush();
+            }
             int remaining = buffer.remaining();
             int written = 0;
 
-            while (remaining < len) {
+            while (remaining < len - written) {
                 buffer.put(b, off + written, remaining);
                 written += remaining;
                 flush();
@@ -759,15 +781,28 @@ public abstract class WsRemoteEndpointIm
 
         @Override
         public void flush() throws IOException {
+            if (closed) {
+                throw new IllegalStateException(
+                        sm.getString("wsRemoteEndpoint.closedOutputStream"));
+            }
+
             doWrite(false);
         }
 
         @Override
         public void close() throws IOException {
+            synchronized (closeLock) {
+                if (closed) {
+                    return;
+                }
+                closed = true;
+            }
+
             doWrite(true);
         }
 
         private void doWrite(boolean last) throws IOException {
+            buffer.flip();
             endpoint.sendPartialBytes(buffer, last);
             buffer.clear();
         }
@@ -778,6 +813,8 @@ public abstract class WsRemoteEndpointIm
 
         private final WsRemoteEndpointImplBase endpoint;
         private final CharBuffer buffer = CharBuffer.allocate(8192);
+        private final Object closeLock = new Object();
+        private volatile boolean closed = false;
 
         public WsWriter(WsRemoteEndpointImplBase endpoint) {
             this.endpoint = endpoint;
@@ -785,10 +822,25 @@ public abstract class WsRemoteEndpointIm
 
         @Override
         public void write(char[] cbuf, int off, int len) throws IOException {
+            if (closed) {
+                throw new IllegalStateException(
+                        sm.getString("wsRemoteEndpoint.closedWriter"));
+            }
+            if (len == 0) {
+                return;
+            }
+            if ((off < 0) || (off > cbuf.length) || (len < 0) ||
+                    ((off + len) > cbuf.length) || ((off + len) < 0)) {
+                throw new IndexOutOfBoundsException();
+            }
+
+            if (buffer.remaining() == 0) {
+                flush();
+            }
             int remaining = buffer.remaining();
             int written = 0;
 
-            while (remaining < len) {
+            while (remaining < len - written) {
                 buffer.put(cbuf, off + written, remaining);
                 written += remaining;
                 flush();
@@ -799,11 +851,23 @@ public abstract class WsRemoteEndpointIm
 
         @Override
         public void flush() throws IOException {
+            if (closed) {
+                throw new IllegalStateException(
+                        sm.getString("wsRemoteEndpoint.closedWriter"));
+            }
+
             doWrite(false);
         }
 
         @Override
         public void close() throws IOException {
+            synchronized (closeLock) {
+                if (closed) {
+                    return;
+                }
+                closed = true;
+            }
+
             doWrite(true);
         }
 



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

Reply via email to