// // ======================================================================== // Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd. // ------------------------------------------------------------------------ // All rights reserved. This program and the accompanying materials // are made available under the terms of the Eclipse Public License v1.0 // and Apache License v2.0 which accompanies this distribution. // // The Eclipse Public License is available at // http://www.eclipse.org/legal/epl-v10.html // // The Apache License v2.0 is available at // http://www.opensource.org/licenses/apache2.0.php // // You may elect to redistribute this code under either of these licenses. // ======================================================================== // package org.eclipse.jetty.websocket.client; import java.net.URI; import java.nio.ByteBuffer; import java.util.Arrays; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.WebSocketAdapter; import org.eclipse.jetty.websocket.common.test.BlockheadServer; import org.eclipse.jetty.websocket.common.test.IBlockheadServerConnection; import org.junit.Assert; import org.junit.Test; public class TomcatServerQuirksTest { public static class LatchedSocket extends WebSocketAdapter { final CountDownLatch openLatch = new CountDownLatch(1); final CountDownLatch dataLatch = new CountDownLatch(1); final CountDownLatch closeLatch = new CountDownLatch(1); @Override public void onWebSocketClose(int statusCode, String reason) { closeLatch.countDown(); } @Override public void onWebSocketConnect(Session session) { openLatch.countDown(); } @Override public void onWebSocketText(String message) { dataLatch.countDown(); } } /** * Test for when encountering a "Transfer-Encoding: chunked" on a Upgrade Response header. * <ul> * <li><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=393075">Eclipse Jetty Bug #393075</a></li> * <li><a href="https://issues.apache.org/bugzilla/show_bug.cgi?id=54067">Apache Tomcat Bug #54067</a></li> * </ul> * * @throws Exception on test failure */ @Test public void testTomcat7_0_32_WithTransferEncoding() throws Exception { BlockheadServer server = new BlockheadServer(); WebSocketClient client = new WebSocketClient(); try { final int bufferSize = 512; server.start(); // Setup Client Factory client.start(); // Create End User WebSocket Class LatchedSocket websocket = new LatchedSocket(); // Open connection URI wsURI = server.getWsUri(); client.connect(websocket,wsURI); // Accept incoming connection IBlockheadServerConnection socket = server.accept(); socket.setSoTimeout(2000); // timeout // Issue upgrade // Add the extra problematic header that triggers bug found in jetty-io socket.addResponseHeader("Transfer-Encoding","chunked"); socket.upgrade(); // Wait for proper upgrade Assert.assertTrue("Timed out waiting for Client side WebSocket open event",websocket.openLatch.await(1,TimeUnit.SECONDS)); // Have server write frame. byte payload[] = new byte[bufferSize / 2]; Arrays.fill(payload,(byte)'x'); ByteBuffer serverFrame = BufferUtil.allocate(bufferSize); BufferUtil.flipToFill(serverFrame); serverFrame.put((byte)(0x80 | 0x01)); // FIN + TEXT serverFrame.put((byte)0x7E); // No MASK and 2 bytes length serverFrame.put((byte)(payload.length >> 8)); // first length byte serverFrame.put((byte)(payload.length & 0xFF)); // second length byte serverFrame.put(payload); BufferUtil.flipToFlush(serverFrame,0); socket.write(serverFrame); socket.flush(); Assert.assertTrue(websocket.dataLatch.await(1000,TimeUnit.SECONDS)); } finally { client.stop(); server.stop(); } } }