Author: markt
Date: Fri Feb 17 23:17:57 2012
New Revision: 1245803
URL: http://svn.apache.org/viewvc?rev=1245803&view=rev
Log:
Move the frame header processing into the WsInputStream since the
fragmented frame processing will required header processing at this
level.
Added:
tomcat/trunk/java/org/apache/catalina/websocket/WsFrameHeader.java
Modified:
tomcat/trunk/java/org/apache/catalina/websocket/Constants.java
tomcat/trunk/java/org/apache/catalina/websocket/StreamInbound.java
tomcat/trunk/java/org/apache/catalina/websocket/WsInputStream.java
Modified: tomcat/trunk/java/org/apache/catalina/websocket/Constants.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/websocket/Constants.java?rev=1245803&r1=1245802&r2=1245803&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/websocket/Constants.java (original)
+++ tomcat/trunk/java/org/apache/catalina/websocket/Constants.java Fri Feb 17
23:17:57 2012
@@ -21,4 +21,12 @@ package org.apache.catalina.websocket;
*/
public class Constants {
public static final String Package = "org.apache.catalina.websocket";
+
+ // OP Codes
+ public static final byte OPCODE_CONTINUATION = 0x00;
+ public static final byte OPCODE_TEXT = 0x01;
+ public static final byte OPCODE_BINARY = 0x02;
+ public static final byte OPCODE_CLOSE = 0x08;
+ public static final byte OPCODE_PING = 0x09;
+ public static final byte OPCODE_PONG = 0x0A;
}
Modified: tomcat/trunk/java/org/apache/catalina/websocket/StreamInbound.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/websocket/StreamInbound.java?rev=1245803&r1=1245802&r2=1245803&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/websocket/StreamInbound.java
(original)
+++ tomcat/trunk/java/org/apache/catalina/websocket/StreamInbound.java Fri Feb
17 23:17:57 2012
@@ -21,7 +21,6 @@ import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
-import org.apache.catalina.util.Conversions;
import org.apache.coyote.http11.upgrade.UpgradeInbound;
import org.apache.coyote.http11.upgrade.UpgradeOutbound;
import org.apache.coyote.http11.upgrade.UpgradeProcessor;
@@ -30,18 +29,6 @@ import org.apache.tomcat.util.net.Abstra
public abstract class StreamInbound implements UpgradeInbound {
- // These attributes apply to the current frame being processed
- private boolean fin = true;
- private boolean rsv1 = false;
- private boolean rsv2 = false;
- private boolean rsv3 = false;
- private int opCode = -1;
- private long payloadLength = -1;
-
- // These attributes apply to the message that may be spread over multiple
- // frames
- // TODO
-
private UpgradeProcessor<?> processor = null;
private WsOutbound outbound;
@@ -62,76 +49,30 @@ public abstract class StreamInbound impl
@Override
public SocketState onData() throws IOException {
- // Must be start the start of a frame
-
- // Read the first byte
- int i = processor.read();
-
- fin = (i & 0x80) > 0;
+ // Must be start the start of a frame or series of frames
+ WsInputStream wsIs = new WsInputStream(processor);
- rsv1 = (i & 0x40) > 0;
- rsv2 = (i & 0x20) > 0;
- rsv3 = (i & 0x10) > 0;
-
- if (rsv1 || rsv2 || rsv3) {
- // TODO: Not supported.
- }
-
- opCode = (i & 0x0F);
+ WsFrameHeader header = wsIs.getFrameHeader();
+ byte opCode = header.getOpCode();
validateOpCode(opCode);
- // Read the next byte
- i = processor.read();
-
- // Client data must be masked and this isn't
- if ((i & 0x80) == 0) {
- // TODO: Better message
- throw new IOException();
- }
-
- payloadLength = i & 0x7F;
- if (payloadLength == 126) {
- byte[] extended = new byte[2];
- processor.read(extended);
- payloadLength = Conversions.byteArrayToLong(extended);
- } else if (payloadLength == 127) {
- byte[] extended = new byte[8];
- processor.read(extended);
- payloadLength = Conversions.byteArrayToLong(extended);
+ if (opCode == Constants.OPCODE_BINARY) {
+ onBinaryData(wsIs);
+ } else if (opCode == Constants.OPCODE_TEXT) {
+ InputStreamReader r =
+ new InputStreamReader(wsIs, B2CConverter.UTF_8);
+ onTextData(r);
+ } else {
+ // TODO i18n
+ throw new IOException("OpCode " + opCode + " not supported");
}
-
- byte[] mask = new byte[4];
- processor.read(mask);
-
- if (opCode == 1 || opCode == 2) {
- WsInputStream wsIs = new WsInputStream(processor, mask,
- payloadLength);
- if (opCode == 2) {
- onBinaryData(wsIs);
- } else {
- InputStreamReader r =
- new InputStreamReader(wsIs, B2CConverter.UTF_8);
- onTextData(r);
- }
- }
-
- // TODO: Doesn't currently handle multi-frame messages. That will need
- // some refactoring.
-
- // TODO: Per frame extension handling is not currently supported.
-
- // TODO: Handle other control frames.
-
- // TODO: Handle control frames appearing in the middle of a multi-frame
- // message
-
return SocketState.UPGRADED;
}
protected abstract void onBinaryData(InputStream is) throws IOException;
protected abstract void onTextData(Reader r) throws IOException;
- private void validateOpCode(int opCode) throws IOException {
+ private void validateOpCode(byte opCode) throws IOException {
switch (opCode) {
case 0:
case 1:
Added: tomcat/trunk/java/org/apache/catalina/websocket/WsFrameHeader.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/websocket/WsFrameHeader.java?rev=1245803&view=auto
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/websocket/WsFrameHeader.java (added)
+++ tomcat/trunk/java/org/apache/catalina/websocket/WsFrameHeader.java Fri Feb
17 23:17:57 2012
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.catalina.websocket;
+
+/**
+ * This class does not represent the complete frame header, just those parts of
+ * it that need to be exposed more widely than the {@link WsInputStream}.
+ */
+public class WsFrameHeader {
+
+ private final boolean fin;
+ private final boolean rsv1;
+ private final boolean rsv2;
+ private final boolean rsv3;
+ private final byte opCode;
+
+ public WsFrameHeader(int b) {
+ fin = (b & 0x80) > 0;
+
+ rsv1 = (b & 0x40) > 0;
+ rsv2 = (b & 0x20) > 0;
+ rsv3 = (b & 0x10) > 0;
+
+ opCode = (byte) (b & 0x0F);
+ }
+
+ public boolean getFin() {
+ return fin;
+ }
+
+ public boolean getRsv1() {
+ return rsv1;
+ }
+
+ public boolean getRsv2() {
+ return rsv2;
+ }
+
+ public boolean getRsv3() {
+ return rsv3;
+ }
+
+ public byte getOpCode() {
+ return opCode;
+ }
+
+
+}
Modified: tomcat/trunk/java/org/apache/catalina/websocket/WsInputStream.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/websocket/WsInputStream.java?rev=1245803&r1=1245802&r2=1245803&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/websocket/WsInputStream.java
(original)
+++ tomcat/trunk/java/org/apache/catalina/websocket/WsInputStream.java Fri Feb
17 23:17:57 2012
@@ -18,23 +18,66 @@ package org.apache.catalina.websocket;
import java.io.IOException;
+import org.apache.catalina.util.Conversions;
import org.apache.coyote.http11.upgrade.UpgradeProcessor;
public class WsInputStream extends java.io.InputStream {
private UpgradeProcessor<?> processor;
- private byte[] mask;
+ private final WsFrameHeader wsFrameHeader;
+ private long payloadLength = -1;
+ private byte[] mask = new byte[4];
+
+
private long remaining;
private long read;
- public WsInputStream(UpgradeProcessor<?> processor, byte[] mask,
- long remaining) {
+ public WsInputStream(UpgradeProcessor<?> processor) throws IOException {
this.processor = processor;
- this.mask = mask;
- this.remaining = remaining;
- this.read = 0;
+
+ int i = processor.read();
+ this.wsFrameHeader = new WsFrameHeader(i);
+
+ // Client data must be masked
+ i = processor.read();
+ if ((i & 0x80) == 0) {
+ // TODO: StringManager / i18n
+ throw new IOException("Client frame not masked");
+ }
+
+ payloadLength = i & 0x7F;
+ if (payloadLength == 126) {
+ byte[] extended = new byte[2];
+ processor.read(extended);
+ payloadLength = Conversions.byteArrayToLong(extended);
+ } else if (payloadLength == 127) {
+ byte[] extended = new byte[8];
+ processor.read(extended);
+ payloadLength = Conversions.byteArrayToLong(extended);
+ }
+ remaining = payloadLength;
+
+ processor.read(mask);
+
+
+ // TODO: Doesn't currently handle multi-frame messages. That will need
+ // some refactoring.
+
+ // TODO: Per frame extension handling is not currently supported.
+
+ // TODO: Handle other control frames.
+
+ // TODO: Handle control frames appearing in the middle of a multi-frame
+ // message
}
+ public WsFrameHeader getFrameHeader() {
+ return wsFrameHeader;
+ }
+
+
+ // ----------------------------------------------------- InputStream
methods
+
@Override
public int read() throws IOException {
if (remaining == 0) {
@@ -47,5 +90,4 @@ public class WsInputStream extends java.
int masked = processor.read();
return masked ^ mask[(int) ((read - 1) % 4)];
}
-
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]