You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2014/06/27 16:07:42 UTC
svn commit: r1606103 - in /tomcat/trunk/java/org/apache/tomcat/websocket: ./
server/
Author: markt
Date: Fri Jun 27 14:07:41 2014
New Revision: 1606103
URL: http://svn.apache.org/r1606103
Log:
Plumbing to enable transformation / extension processing for outgoing server messages.
Modified:
tomcat/trunk/java/org/apache/tomcat/websocket/PerMessageDeflate.java
tomcat/trunk/java/org/apache/tomcat/websocket/Transformation.java
tomcat/trunk/java/org/apache/tomcat/websocket/WsFrameBase.java
tomcat/trunk/java/org/apache/tomcat/websocket/WsRemoteEndpointImplBase.java
tomcat/trunk/java/org/apache/tomcat/websocket/WsSession.java
tomcat/trunk/java/org/apache/tomcat/websocket/WsWebSocketContainer.java
tomcat/trunk/java/org/apache/tomcat/websocket/server/WsFrameServer.java
tomcat/trunk/java/org/apache/tomcat/websocket/server/WsHttpUpgradeHandler.java
tomcat/trunk/java/org/apache/tomcat/websocket/server/WsRemoteEndpointImplServer.java
Modified: tomcat/trunk/java/org/apache/tomcat/websocket/PerMessageDeflate.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/websocket/PerMessageDeflate.java?rev=1606103&r1=1606102&r2=1606103&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/websocket/PerMessageDeflate.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/websocket/PerMessageDeflate.java Fri Jun 27 14:07:41 2014
@@ -283,4 +283,15 @@ public class PerMessageDeflate implement
return next.validateRsvBits(i | RSV_BITMASK);
}
}
+
+
+ @Override
+ public List<MessagePart> sendMessagePart(List<MessagePart> messageParts) {
+ // TODO: Implement compression of sent messages
+ if (next == null) {
+ return messageParts;
+ } else {
+ return next.sendMessagePart(messageParts);
+ }
+ }
}
Modified: tomcat/trunk/java/org/apache/tomcat/websocket/Transformation.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/websocket/Transformation.java?rev=1606103&r1=1606102&r2=1606103&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/websocket/Transformation.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/websocket/Transformation.java Fri Jun 27 14:07:41 2014
@@ -18,18 +18,44 @@ package org.apache.tomcat.websocket;
import java.io.IOException;
import java.nio.ByteBuffer;
+import java.util.List;
import javax.websocket.Extension;
/**
* The internal representation of the transformation that a WebSocket extension
* performs on a message.
- *
- * TODO Add support for transformation of outgoing data as well as incoming.
*/
public interface Transformation {
/**
+ * Sets the next transformation in the pipeline.
+ */
+ void setNext(Transformation t);
+
+ /**
+ * Validate that the RSV bit(s) required by this transformation are not
+ * being used by another extension. The implementation is expected to set
+ * any bits it requires before passing the set of in-use bits to the next
+ * transformation.
+ *
+ * @param i The RSV bits marked as in use so far as an int in the
+ * range zero to seven with RSV1 as the MSB and RSV3 as the
+ * LSB
+ *
+ * @return <code>true</code> if the combination of RSV bits used by the
+ * transformations in the pipeline do not conflict otherwise
+ * <code>false</code>
+ */
+ boolean validateRsvBits(int i);
+
+ /**
+ * Obtain the extension that describes the information to be returned to the
+ * client.
+ */
+ Extension getExtensionResponse();
+
+ /**
* Obtain more input data.
*
* @param opCode The opcode for the frame currently being processed
@@ -56,29 +82,16 @@ public interface Transformation {
boolean validateRsv(int rsv, byte opCode);
/**
- * Obtain the extension that describes the information to be returned to the
- * client.
- */
- Extension getExtensionResponse();
-
- /**
- * Sets the next transformation in the pipeline.
- */
- void setNext(Transformation t);
-
- /**
- * Validate that the RSV bit(s) required by this transformation are not
- * being used by another extension. The implementation is expected to set
- * any bits it requires before passing the set of in-use bits to the next
- * transformation.
+ * Takes the provided list of messages, transforms them, passes the
+ * transformed list on to the next transformation (if any) and then returns
+ * the resulting list of message parts after all of the transformations have
+ * been applied.
*
- * @param i The RSV bits marked as in use so far as an int in the
- * range zero to seven with RSV1 as the MSB and RSV3 as the
- * LSB
+ * @param messageParts The list of messages to be transformed
*
- * @return <code>true</code> if the combination of RSV bits used by the
- * transformations in the pipeline do not conflict otherwise
- * <code>false</code>
+ * @return The list of messages after this any any subsequent
+ * transformations have been applied. The size of the returned list
+ * may be bigger or smaller than the size of the input list
*/
- boolean validateRsvBits(int i);
+ List<MessagePart> sendMessagePart(List<MessagePart> messageParts);
}
Modified: tomcat/trunk/java/org/apache/tomcat/websocket/WsFrameBase.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/websocket/WsFrameBase.java?rev=1606103&r1=1606102&r2=1606103&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/websocket/WsFrameBase.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/websocket/WsFrameBase.java Fri Jun 27 14:07:41 2014
@@ -22,6 +22,7 @@ import java.nio.CharBuffer;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CoderResult;
import java.nio.charset.CodingErrorAction;
+import java.util.List;
import javax.websocket.CloseReason;
import javax.websocket.CloseReason.CloseCodes;
@@ -691,6 +692,11 @@ public abstract class WsFrameBase {
}
+ protected Transformation getTransformation() {
+ return transformation;
+ }
+
+
private static enum State {
NEW_FRAME, PARTIAL_HEADER, DATA
}
@@ -757,6 +763,14 @@ public abstract class WsFrameBase {
return TransformationResult.OVERFLOW;
}
}
+
+
+ @Override
+ public List<MessagePart> sendMessagePart(List<MessagePart> messageParts) {
+ // TODO Masking should move to this method
+ // NO-OP send so simply return the message unchanged.
+ return messageParts;
+ }
}
@@ -792,5 +806,11 @@ public abstract class WsFrameBase {
return TransformationResult.OVERFLOW;
}
}
+
+ @Override
+ public List<MessagePart> sendMessagePart(List<MessagePart> messageParts) {
+ // NO-OP send so simply return the message unchanged.
+ return messageParts;
+ }
}
}
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=1606103&r1=1606102&r2=1606103&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/websocket/WsRemoteEndpointImplBase.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/websocket/WsRemoteEndpointImplBase.java Fri Jun 27 14:07:41 2014
@@ -61,6 +61,7 @@ public abstract class WsRemoteEndpointIm
private final StateMachine stateMachine = new StateMachine();
+ private Transformation transformation = null;
private boolean messagePartInProgress = false;
private final Queue<MessagePart> messagePartQueue = new ArrayDeque<>();
private final Object messagePartLock = new Object();
@@ -82,6 +83,12 @@ public abstract class WsRemoteEndpointIm
private WsSession wsSession;
private List<EncoderEntry> encoderEntries = new ArrayList<>();
+
+ protected void setTransformation(Transformation transformation) {
+ this.transformation = transformation;
+ }
+
+
public long getSendTimeout() {
return sendTimeout;
}
@@ -249,8 +256,13 @@ public abstract class WsRemoteEndpointIm
wsSession.updateLastActive();
- MessagePart mp = new MessagePart(opCode, payload, last,
- new EndMessageHandler(this, handler));
+ List<MessagePart> messageParts = new ArrayList<>();
+ messageParts.add(new MessagePart(opCode, payload, last,
+ new EndMessageHandler(this, handler)));
+
+ messageParts = transformation.sendMessagePart(messageParts);
+
+ MessagePart mp = messageParts.remove(0);
boolean doWrite = false;
synchronized (messagePartLock) {
@@ -277,6 +289,8 @@ public abstract class WsRemoteEndpointIm
messagePartInProgress = true;
doWrite = true;
}
+ // Add any remaining messages to the queue
+ messagePartQueue.addAll(messageParts);
}
if (doWrite) {
// Actual write has to be outside sync block to avoid possible
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=1606103&r1=1606102&r2=1606103&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/websocket/WsSession.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/websocket/WsSession.java Fri Jun 27 14:07:41 2014
@@ -113,8 +113,7 @@ public class WsSession implements Sessio
URI requestUri, Map<String,List<String>> requestParameterMap,
String queryString, Principal userPrincipal, String httpSessionId,
String subProtocol, Map<String,String> pathParameters,
- boolean secure, EndpointConfig endpointConfig,
- Transformation transformation) throws DeploymentException {
+ boolean secure, EndpointConfig endpointConfig) throws DeploymentException {
this.localEndpoint = localEndpoint;
this.wsRemoteEndpoint = wsRemoteEndpoint;
this.wsRemoteEndpoint.setSession(this);
Modified: tomcat/trunk/java/org/apache/tomcat/websocket/WsWebSocketContainer.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/websocket/WsWebSocketContainer.java?rev=1606103&r1=1606102&r2=1606103&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/websocket/WsWebSocketContainer.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/websocket/WsWebSocketContainer.java Fri Jun 27 14:07:41 2014
@@ -316,15 +316,15 @@ public class WsWebSocketContainer
sm.getString("wsWebSocketContainer.httpRequestFailed"), e);
}
- // Switch to WebSocket
- WsRemoteEndpointImplClient wsRemoteEndpointClient =
- new WsRemoteEndpointImplClient(channel);
+ // TODO Add extension/transformation support to the client
+ // Switch to WebSocket
+ WsRemoteEndpointImplClient wsRemoteEndpointClient = new WsRemoteEndpointImplClient(channel);
WsSession wsSession = new WsSession(endpoint, wsRemoteEndpointClient,
this, null, null, null, null, null, subProtocol,
Collections.<String, String> emptyMap(), secure,
- clientEndpointConfiguration, null);
+ clientEndpointConfiguration);
endpoint.onOpen(wsSession, clientEndpointConfiguration);
registerSession(endpoint, wsSession);
Modified: tomcat/trunk/java/org/apache/tomcat/websocket/server/WsFrameServer.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/websocket/server/WsFrameServer.java?rev=1606103&r1=1606102&r2=1606103&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/websocket/server/WsFrameServer.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/websocket/server/WsFrameServer.java Fri Jun 27 14:07:41 2014
@@ -65,4 +65,11 @@ public class WsFrameServer extends WsFra
// Data is from the client so it should be masked
return true;
}
+
+
+ @Override
+ protected Transformation getTransformation() {
+ // Overridden to make it visible to other classes in this package
+ return super.getTransformation();
+ }
}
Modified: tomcat/trunk/java/org/apache/tomcat/websocket/server/WsHttpUpgradeHandler.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/websocket/server/WsHttpUpgradeHandler.java?rev=1606103&r1=1606102&r2=1606103&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/websocket/server/WsHttpUpgradeHandler.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/websocket/server/WsHttpUpgradeHandler.java Fri Jun 27 14:07:41 2014
@@ -123,9 +123,12 @@ public class WsHttpUpgradeHandler implem
handshakeRequest.getParameterMap(),
handshakeRequest.getQueryString(),
handshakeRequest.getUserPrincipal(), httpSessionId,
- subProtocol, pathParameters, secure, endpointConfig, transformation);
+ subProtocol, pathParameters, secure, endpointConfig);
WsFrameServer wsFrame = new WsFrameServer(sis, wsSession, transformation);
sos.setWriteListener(new WsWriteListener(this, wsRemoteEndpointServer));
+ // WsFrame adds the necessary final transformations. Copy the
+ // completed transformation chain to the remote end point.
+ wsRemoteEndpointServer.setTransformation(wsFrame.getTransformation());
ep.onOpen(wsSession, endpointConfig);
webSocketContainer.registerSession(ep, wsSession);
sis.setReadListener(new WsReadListener(this, wsFrame));
Modified: tomcat/trunk/java/org/apache/tomcat/websocket/server/WsRemoteEndpointImplServer.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/websocket/server/WsRemoteEndpointImplServer.java?rev=1606103&r1=1606102&r2=1606103&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/websocket/server/WsRemoteEndpointImplServer.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/websocket/server/WsRemoteEndpointImplServer.java Fri Jun 27 14:07:41 2014
@@ -31,6 +31,7 @@ import javax.websocket.SendResult;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
import org.apache.tomcat.util.res.StringManager;
+import org.apache.tomcat.websocket.Transformation;
import org.apache.tomcat.websocket.WsRemoteEndpointImplBase;
/**
@@ -58,8 +59,7 @@ public class WsRemoteEndpointImplServer
private volatile boolean close;
- public WsRemoteEndpointImplServer(ServletOutputStream sos,
- WsServerContainer serverContainer) {
+ public WsRemoteEndpointImplServer(ServletOutputStream sos, WsServerContainer serverContainer) {
this.sos = sos;
this.wsWriteTimeout = serverContainer.getTimeout();
this.executorService = serverContainer.getExecutorService();
@@ -170,6 +170,13 @@ public class WsRemoteEndpointImplServer
}
+ @Override
+ protected void setTransformation(Transformation transformation) {
+ // Overridden purely so it is visible to other classes in this package
+ super.setTransformation(transformation);
+ }
+
+
/**
*
* @param t The throwable associated with any error that
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org