Author: markt
Date: Mon Jun 23 12:33:54 2014
New Revision: 1604781

URL: http://svn.apache.org/r1604781
Log:
Add support for parsing the extension header

Modified:
    tomcat/trunk/java/org/apache/tomcat/websocket/Util.java
    tomcat/trunk/test/org/apache/tomcat/websocket/TestUtil.java

Modified: tomcat/trunk/java/org/apache/tomcat/websocket/Util.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/websocket/Util.java?rev=1604781&r1=1604780&r2=1604781&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/websocket/Util.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/websocket/Util.java Mon Jun 23 12:33:54 
2014
@@ -43,6 +43,7 @@ import javax.websocket.Decoder.TextStrea
 import javax.websocket.DeploymentException;
 import javax.websocket.Encoder;
 import javax.websocket.EndpointConfig;
+import javax.websocket.Extension;
 import javax.websocket.MessageHandler;
 import javax.websocket.PongMessage;
 import javax.websocket.Session;
@@ -347,7 +348,6 @@ public class Util {
     }
 
 
-
     public static Set<MessageHandlerResult> getMessageHandlers(
             MessageHandler listener, EndpointConfig endpointConfig,
             Session session) {
@@ -443,6 +443,52 @@ public class Util {
     }
 
 
+    public static void parseExtensionHeader(List<Extension> extensions,
+            String header) {
+        // The relevant ABNF for the Sec-WebSocket-Extensions is as follows:
+        //      extension-list = 1#extension
+        //      extension = extension-token *( ";" extension-param )
+        //      extension-token = registered-token
+        //      registered-token = token
+        //      extension-param = token [ "=" (token | quoted-string) ]
+        //             ; When using the quoted-string syntax variant, the value
+        //             ; after quoted-string unescaping MUST conform to the
+        //             ; 'token' ABNF.
+        //
+        // The limiting of parameter values to tokens or "quoted tokens" makes
+        // the parsing of the header significantly simpler and allows a number
+        // of short-cuts to be taken.
+
+        // Step one, split the header into individual extensions using ',' as a
+        // separator
+        String unparsedExtensions[] = header.split(",");
+        for (String unparsedExtension : unparsedExtensions) {
+            // Step two, split the extension into the registered name and
+            // parameter/value pairs using ';' as a separator
+            String unparsedParameters[] = unparsedExtension.split(";");
+            WsExtension extension = new 
WsExtension(unparsedParameters[0].trim());
+
+            for (int i = 1; i < unparsedParameters.length; i++) {
+                int equalsPos = unparsedParameters[i].indexOf('=');
+                String name;
+                String value;
+                if (equalsPos == -1) {
+                    name = unparsedParameters[i].trim();
+                    value = null;
+                } else {
+                    name = unparsedParameters[i].substring(0, 
equalsPos).trim();
+                    value = unparsedParameters[i].substring(equalsPos + 
1).trim();
+                    if (value.length() > 2 && value.charAt(0) == '\"') {
+                        value = value.substring(1, value.length() - 1);
+                    }
+                }
+                extension.addParameter(new WsExtensionParameter(name, value));
+            }
+            extensions.add(extension);
+        }
+    }
+
+
     private static Method getOnMessageMethod(MessageHandler listener) {
         try {
             return listener.getClass().getMethod("onMessage", Object.class);
@@ -452,6 +498,7 @@ public class Util {
         }
     }
 
+
     public static class DecoderMatch {
 
         private final List<Class<? extends Decoder>> textDecoders =

Modified: tomcat/trunk/test/org/apache/tomcat/websocket/TestUtil.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/tomcat/websocket/TestUtil.java?rev=1604781&r1=1604780&r2=1604781&view=diff
==============================================================================
--- tomcat/trunk/test/org/apache/tomcat/websocket/TestUtil.java (original)
+++ tomcat/trunk/test/org/apache/tomcat/websocket/TestUtil.java Mon Jun 23 
12:33:54 2014
@@ -16,11 +16,14 @@
  */
 package org.apache.tomcat.websocket;
 
+import java.util.ArrayList;
 import java.util.List;
 
 import javax.websocket.EncodeException;
 import javax.websocket.Encoder;
 import javax.websocket.EndpointConfig;
+import javax.websocket.Extension;
+import javax.websocket.Extension.Parameter;
 import javax.websocket.MessageHandler;
 
 import org.junit.Assert;
@@ -370,4 +373,92 @@ public class TestUtil {
             return null;
         }
     }
+
+
+    @Test
+    public void testParseExtensionHeaderSimple01() {
+        doTestParseExtensionHeaderSimple("ext;a=1;b=2");
+    }
+
+    @Test
+    public void testParseExtensionHeaderSimple02() {
+        doTestParseExtensionHeaderSimple("ext;a=\"1\";b=2");
+    }
+
+    @Test
+    public void testParseExtensionHeaderSimple03() {
+        doTestParseExtensionHeaderSimple("ext;a=1;b=\"2\"");
+    }
+
+    @Test
+    public void testParseExtensionHeaderSimple04() {
+        doTestParseExtensionHeaderSimple(" ext ; a = 1 ; b = 2 ");
+    }
+
+    private void doTestParseExtensionHeaderSimple(String header) {
+        // Simple test
+        List<Extension> result = new ArrayList<>();
+        Util.parseExtensionHeader(result, header);
+
+        Assert.assertEquals(1, result.size());
+
+        Extension ext = result.get(0);
+        Assert.assertEquals("ext", ext.getName());
+        List<Parameter> params = ext.getParameters();
+        Assert.assertEquals(2, params.size());
+        Parameter paramA = params.get(0);
+        Assert.assertEquals("a", paramA.getName());
+        Assert.assertEquals("1", paramA.getValue());
+        Parameter paramB = params.get(1);
+        Assert.assertEquals("b", paramB.getName());
+        Assert.assertEquals("2", paramB.getValue());
+    }
+
+
+    @Test
+    public void testParseExtensionHeaderMultiple01() {
+        doTestParseExtensionHeaderMultiple("ext;a=1;b=2,ext2;c;d=xyz,ext3");
+    }
+
+    @Test
+    public void testParseExtensionHeaderMultiple02() {
+        doTestParseExtensionHeaderMultiple(
+                " ext ; a = 1 ; b = 2 , ext2 ; c ; d = xyz , ext3 ");
+    }
+
+    private void doTestParseExtensionHeaderMultiple(String header) {
+        // Simple test
+        List<Extension> result = new ArrayList<>();
+        Util.parseExtensionHeader(result, header);
+
+        Assert.assertEquals(3, result.size());
+
+        Extension ext = result.get(0);
+        Assert.assertEquals("ext", ext.getName());
+        List<Parameter> params = ext.getParameters();
+        Assert.assertEquals(2, params.size());
+        Parameter paramA = params.get(0);
+        Assert.assertEquals("a", paramA.getName());
+        Assert.assertEquals("1", paramA.getValue());
+        Parameter paramB = params.get(1);
+        Assert.assertEquals("b", paramB.getName());
+        Assert.assertEquals("2", paramB.getValue());
+
+        Extension ext2 = result.get(1);
+        Assert.assertEquals("ext2", ext2.getName());
+        List<Parameter> params2 = ext2.getParameters();
+        Assert.assertEquals(2, params2.size());
+        Parameter paramC = params2.get(0);
+        Assert.assertEquals("c", paramC.getName());
+        Assert.assertNull(paramC.getValue());
+        Parameter paramD = params2.get(1);
+        Assert.assertEquals("d", paramD.getName());
+        Assert.assertEquals("xyz", paramD.getValue());
+
+        Extension ext3 = result.get(2);
+        Assert.assertEquals("ext3", ext3.getName());
+        List<Parameter> params3 = ext3.getParameters();
+        Assert.assertEquals(0, params3.size());
+    }
+
 }



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

Reply via email to