Author: markt Date: Fri Dec 11 10:07:14 2015 New Revision: 1719315 URL: http://svn.apache.org/viewvc?rev=1719315&view=rev Log: Partial fix for https://bz.apache.org/bugzilla/show_bug.cgi?id=57489 Failure to send a WebSocket message should trigger the closure of the session.
Modified: tomcat/trunk/java/org/apache/tomcat/websocket/LocalStrings.properties tomcat/trunk/java/org/apache/tomcat/websocket/WsRemoteEndpointImplBase.java tomcat/trunk/java/org/apache/tomcat/websocket/WsSession.java Modified: tomcat/trunk/java/org/apache/tomcat/websocket/LocalStrings.properties URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/websocket/LocalStrings.properties?rev=1719315&r1=1719314&r2=1719315&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/websocket/LocalStrings.properties (original) +++ tomcat/trunk/java/org/apache/tomcat/websocket/LocalStrings.properties Fri Dec 11 10:07:14 2015 @@ -71,6 +71,7 @@ wsFrame.wrongRsv=The client frame set th wsFrameClient.ioe=Failure while reading data sent by server +wsRemoteEndpoint.acquireTimeout=The current message was not fully sent within the specified timeout wsRemoteEndpoint.closed=Message will not be sent because the WebSocket session has been closed wsRemoteEndpoint.closedDuringMessage=The remainder of the message will not be sent because the WebSocket session has been closed wsRemoteEndpoint.closedOutputStream=This method may not be called as the OutputStream has been closed 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=1719315&r1=1719314&r2=1719315&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/websocket/WsRemoteEndpointImplBase.java (original) +++ tomcat/trunk/java/org/apache/tomcat/websocket/WsRemoteEndpointImplBase.java Fri Dec 11 10:07:14 2015 @@ -33,6 +33,8 @@ import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; +import javax.websocket.CloseReason; +import javax.websocket.CloseReason.CloseCodes; import javax.websocket.DeploymentException; import javax.websocket.EncodeException; import javax.websocket.Encoder; @@ -291,16 +293,26 @@ public abstract class WsRemoteEndpointIm long timeout = timeoutExpiry - System.currentTimeMillis(); try { if (!messagePartInProgress.tryAcquire(timeout, TimeUnit.MILLISECONDS)) { - throw new SocketTimeoutException(); + String msg = sm.getString("wsRemoteEndpoint.acquireTimeout"); + wsSession.doClose(new CloseReason(CloseCodes.GOING_AWAY, msg), + new CloseReason(CloseCodes.CLOSED_ABNORMALLY, msg)); + throw new SocketTimeoutException(msg); } } catch (InterruptedException e) { - throw new IOException(sm.getString("wsRemoteEndpoint.sendInterupt"), e); + String msg = sm.getString("wsRemoteEndpoint.sendInterupt"); + wsSession.doClose(new CloseReason(CloseCodes.GOING_AWAY, msg), + new CloseReason(CloseCodes.CLOSED_ABNORMALLY, msg)); + throw new IOException(msg, e); } for (MessagePart mp : messageParts) { writeMessagePart(mp); if (!bsh.getSendResult().isOK()) { - throw new IOException (bsh.getSendResult().getException()); + messagePartInProgress.release(); + Throwable t = bsh.getSendResult().getException(); + wsSession.doClose(new CloseReason(CloseCodes.GOING_AWAY, t.getMessage()), + new CloseReason(CloseCodes.CLOSED_ABNORMALLY, t.getMessage())); + throw new IOException (t); } // The BlockingSendHandler doesn't call end message so update the // flags. Modified: tomcat/trunk/java/org/apache/tomcat/websocket/WsSession.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/websocket/WsSession.java?rev=1719315&r1=1719314&r2=1719315&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/websocket/WsSession.java (original) +++ tomcat/trunk/java/org/apache/tomcat/websocket/WsSession.java Fri Dec 11 10:07:14 2015 @@ -464,8 +464,7 @@ public class WsSession implements Sessio * Need internal close method as spec requires that the local endpoint * receives a 1006 on timeout. */ - private void doClose(CloseReason closeReasonMessage, - CloseReason closeReasonLocal) { + protected void doClose(CloseReason closeReasonMessage, CloseReason closeReasonLocal) { // Double-checked locking. OK because state is volatile if (state != State.OPEN) { return; @@ -519,6 +518,7 @@ public class WsSession implements Sessio fireEndpointOnError(e); } if (state == State.OPEN) { + state = State.OUTPUT_CLOSED; sendCloseMessage(closeReason); } fireEndpointOnClose(closeReason); --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org