// // ======================================================================== // 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.common; import static org.eclipse.jetty.websocket.api.StatusCode.FAILED_TLS_HANDSHAKE; import static org.eclipse.jetty.websocket.api.StatusCode.NORMAL; import static org.eclipse.jetty.websocket.api.StatusCode.NO_CLOSE; import static org.eclipse.jetty.websocket.api.StatusCode.NO_CODE; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.nullValue; import static org.junit.Assert.assertThat; import static org.junit.Assert.fail; import java.nio.ByteBuffer; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.websocket.api.ProtocolException; import org.eclipse.jetty.websocket.common.frames.CloseFrame; import org.junit.Test; public class CloseInfoTest { /** * A test where no close is provided */ @Test public void testAnonymousClose() { CloseInfo close = new CloseInfo(); assertThat("close.code",close.getStatusCode(),is(NO_CODE)); assertThat("close.reason",close.getReason(),nullValue()); CloseFrame frame = close.asFrame(); assertThat("close frame op code",frame.getOpCode(),is(OpCode.CLOSE)); // should result in no payload assertThat("close frame has payload",frame.hasPayload(),is(false)); assertThat("close frame payload length",frame.getPayloadLength(),is(0)); } /** * A test where NO_CODE (1005) is provided */ @Test public void testNoCode() { CloseInfo close = new CloseInfo(NO_CODE); assertThat("close.code",close.getStatusCode(),is(NO_CODE)); assertThat("close.reason",close.getReason(),nullValue()); CloseFrame frame = close.asFrame(); assertThat("close frame op code",frame.getOpCode(),is(OpCode.CLOSE)); // should result in no payload assertThat("close frame has payload",frame.hasPayload(),is(false)); assertThat("close frame payload length",frame.getPayloadLength(),is(0)); } /** * A test where NO_CLOSE (1006) is provided */ @Test public void testNoClose() { CloseInfo close = new CloseInfo(NO_CLOSE); assertThat("close.code",close.getStatusCode(),is(NO_CLOSE)); assertThat("close.reason",close.getReason(),nullValue()); CloseFrame frame = close.asFrame(); assertThat("close frame op code",frame.getOpCode(),is(OpCode.CLOSE)); // should result in no payload assertThat("close frame has payload",frame.hasPayload(),is(false)); assertThat("close frame payload length",frame.getPayloadLength(),is(0)); } /** * A test of FAILED_TLS_HANDSHAKE (1007) */ @Test public void testFailedTlsHandshake() { CloseInfo close = new CloseInfo(FAILED_TLS_HANDSHAKE); assertThat("close.code",close.getStatusCode(),is(FAILED_TLS_HANDSHAKE)); assertThat("close.reason",close.getReason(),nullValue()); try { @SuppressWarnings("unused") CloseFrame frame = close.asFrame(); fail("Expected " + ProtocolException.class.getName()); } catch (ProtocolException e) { // expected path assertThat("ProtocolException message",e.getMessage(),containsString("not allowed (per RFC6455)")); } } /** * A test of NORMAL (1000) */ @Test public void testNormal() { CloseInfo close = new CloseInfo(NORMAL); assertThat("close.code",close.getStatusCode(),is(NORMAL)); assertThat("close.reason",close.getReason(),nullValue()); CloseFrame frame = close.asFrame(); assertThat("close frame op code",frame.getOpCode(),is(OpCode.CLOSE)); assertThat("close frame payload length",frame.getPayloadLength(),is(2)); } private ByteBuffer asByteBuffer(int statusCode, String reason) { int len = 2; // status code length byte utf[] = null; if (StringUtil.isNotBlank(reason)) { utf = StringUtil.getUtf8Bytes(reason); len += utf.length; } ByteBuffer buf = BufferUtil.allocate(len); BufferUtil.flipToFill(buf); buf.put((byte)((statusCode >>> 8) & 0xFF)); buf.put((byte)((statusCode >>> 0) & 0xFF)); if (utf != null) { buf.put(utf,0,utf.length); } BufferUtil.flipToFlush(buf,0); return buf; } @Test public void testFromFrame() { ByteBuffer payload = asByteBuffer(NORMAL,null); assertThat("payload length", payload.remaining(), is(2)); CloseFrame frame = new CloseFrame(); frame.setPayload(payload); // create from frame CloseInfo close = new CloseInfo(frame); assertThat("close.code",close.getStatusCode(),is(NORMAL)); assertThat("close.reason",close.getReason(),nullValue()); // and back again frame = close.asFrame(); assertThat("close frame op code",frame.getOpCode(),is(OpCode.CLOSE)); assertThat("close frame payload length",frame.getPayloadLength(),is(2)); } }