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