Author: markt Date: Tue Jul 2 16:13:13 2013 New Revision: 1498994 URL: http://svn.apache.org/r1498994 Log: Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=55183 Header names are case insensitive Based on a patch by Niki Dokovski.
Added: tomcat/trunk/test/org/apache/tomcat/websocket/TestWsSubprotocols.java (with props) Modified: tomcat/trunk/java/org/apache/tomcat/websocket/Constants.java tomcat/trunk/java/org/apache/tomcat/websocket/WsWebSocketContainer.java Modified: tomcat/trunk/java/org/apache/tomcat/websocket/Constants.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/websocket/Constants.java?rev=1498994&r1=1498993&r2=1498994&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/websocket/Constants.java (original) +++ tomcat/trunk/java/org/apache/tomcat/websocket/Constants.java Tue Jul 2 16:13:13 2013 @@ -16,6 +16,8 @@ */ package org.apache.tomcat.websocket; +import java.util.Locale; + /** * Internal implementation constants. */ @@ -50,6 +52,8 @@ public class Constants { public static final String WS_KEY_HEADER_NAME = "Sec-WebSocket-Key"; public static final String WS_PROTOCOL_HEADER_NAME = "Sec-WebSocket-Protocol"; + public static final String WS_PROTOCOL_HEADER_NAME_LOWER = + WS_PROTOCOL_HEADER_NAME.toLowerCase(Locale.ENGLISH); public static final String WS_EXTENSIONS_HEADER_NAME = "Sec-WebSocket-Extensions"; 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=1498994&r1=1498993&r2=1498994&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/websocket/WsWebSocketContainer.java (original) +++ tomcat/trunk/java/org/apache/tomcat/websocket/WsWebSocketContainer.java Tue Jul 2 16:13:13 2013 @@ -308,8 +308,9 @@ public class WsWebSocketContainer afterResponse(handshakeResponse); // Sub-protocol + // Header names are always stored in lower case List<String> values = handshakeResponse.getHeaders().get( - Constants.WS_PROTOCOL_HEADER_NAME); + Constants.WS_PROTOCOL_HEADER_NAME_LOWER); if (values == null || values.size() == 0) { subProtocol = null; } else if (values.size() == 1) { @@ -591,6 +592,7 @@ public class WsWebSocketContainer log.warn(sm.getString("wsWebSocketContainer.invalidHeader", line)); return; } + // Header names are case insensitive so always use lower case String headerName = line.substring(0, index).trim().toLowerCase(); // TODO handle known multi-value headers String headerValue = line.substring(index + 1).trim(); Added: tomcat/trunk/test/org/apache/tomcat/websocket/TestWsSubprotocols.java URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/tomcat/websocket/TestWsSubprotocols.java?rev=1498994&view=auto ============================================================================== --- tomcat/trunk/test/org/apache/tomcat/websocket/TestWsSubprotocols.java (added) +++ tomcat/trunk/test/org/apache/tomcat/websocket/TestWsSubprotocols.java Tue Jul 2 16:13:13 2013 @@ -0,0 +1,121 @@ +/* + * 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.tomcat.websocket; + +import java.net.URI; +import java.util.Arrays; +import java.util.List; + +import javax.servlet.ServletContextEvent; +import javax.websocket.ClientEndpointConfig; +import javax.websocket.ContainerProvider; +import javax.websocket.DeploymentException; +import javax.websocket.EndpointConfig; +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.WebSocketContainer; +import javax.websocket.server.ServerContainer; +import javax.websocket.server.ServerEndpoint; +import javax.websocket.server.ServerEndpointConfig; + +import org.junit.Assert; +import org.junit.Test; + + +import org.apache.catalina.Context; +import org.apache.catalina.deploy.ApplicationListener; +import org.apache.catalina.servlets.DefaultServlet; +import org.apache.catalina.startup.Tomcat; +import org.apache.catalina.startup.TomcatBaseTest; +import org.apache.tomcat.websocket.TesterSingleMessageClient.TesterProgrammaticEndpoint; +import org.apache.tomcat.websocket.server.Constants; +import org.apache.tomcat.websocket.server.WsListener; + +public class TestWsSubprotocols extends TomcatBaseTest { + + @Test + public void testWsSubprotocols() throws Exception { + Tomcat tomcat = getTomcatInstance(); + // Must have a real docBase - just use temp + Context ctx = tomcat.addContext("", + System.getProperty("java.io.tmpdir")); + ctx.addApplicationListener(new ApplicationListener(Config.class + .getName(), false)); + + Tomcat.addServlet(ctx, "default", new DefaultServlet()); + ctx.addServletMapping("/", "default"); + + tomcat.start(); + + WebSocketContainer wsContainer = ContainerProvider + .getWebSocketContainer(); + + tomcat.start(); + + Session wsSession = wsContainer.connectToServer( + TesterProgrammaticEndpoint.class, ClientEndpointConfig.Builder + .create().preferredSubprotocols(Arrays.asList("sp3")) + .build(), new URI("ws://localhost:" + getPort() + + SubProtocolsEndpoint.PATH_BASIC)); + + Assert.assertTrue(wsSession.isOpen()); + if (wsSession.getNegotiatedSubprotocol() != null) { + Assert.assertTrue(wsSession.getNegotiatedSubprotocol().isEmpty()); + } + wsSession.close(); + + wsSession = wsContainer.connectToServer( + TesterProgrammaticEndpoint.class, ClientEndpointConfig.Builder + .create().preferredSubprotocols(Arrays.asList("sp2")) + .build(), new URI("ws://localhost:" + getPort() + + SubProtocolsEndpoint.PATH_BASIC)); + + Assert.assertTrue(wsSession.isOpen()); + Assert.assertEquals("sp2", wsSession.getNegotiatedSubprotocol()); + Assert.assertArrayEquals(new String[]{"sp1","sp2"}, + SubProtocolsEndpoint.subprotocols.toArray(new String[2])); + wsSession.close(); + } + + @ServerEndpoint(value = "/echo", subprotocols = {"sp1","sp2"}) + public static class SubProtocolsEndpoint { + public static String PATH_BASIC = "/echo"; + public static List<String> subprotocols; + + @OnOpen + public void processOpen(@SuppressWarnings("unused") Session session, + EndpointConfig epc) { + subprotocols = ((ServerEndpointConfig)epc).getSubprotocols(); + } + + } + + public static class Config extends WsListener { + @Override + public void contextInitialized(ServletContextEvent sce) { + super.contextInitialized(sce); + ServerContainer sc = (ServerContainer) sce.getServletContext() + .getAttribute(Constants. + SERVER_CONTAINER_SERVLET_CONTEXT_ATTRIBUTE); + try { + sc.addEndpoint(SubProtocolsEndpoint.class); + } catch (DeploymentException e) { + throw new IllegalStateException(e); + } + } + } +} \ No newline at end of file Propchange: tomcat/trunk/test/org/apache/tomcat/websocket/TestWsSubprotocols.java ------------------------------------------------------------------------------ svn:eol-style = native --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org