Issue #207 - All websocket tests moved to /websocket-tests/ module
This commit is contained in:
parent
f1a89ce3b2
commit
2043a923cf
|
@ -30,19 +30,6 @@
|
|||
<version>${project.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.websocket</groupId>
|
||||
<artifactId>websocket-server</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.websocket</groupId>
|
||||
<artifactId>websocket-common</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<classifier>tests</classifier>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.toolchain</groupId>
|
||||
<artifactId>jetty-test-helper</artifactId>
|
||||
|
|
|
@ -1,60 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.jsr356;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import javax.websocket.ClientEndpoint;
|
||||
import javax.websocket.EndpointConfig;
|
||||
import javax.websocket.OnMessage;
|
||||
import javax.websocket.OnOpen;
|
||||
import javax.websocket.Session;
|
||||
|
||||
import org.eclipse.jetty.websocket.jsr356.decoders.DateDecoder;
|
||||
import org.eclipse.jetty.websocket.jsr356.encoders.TimeEncoder;
|
||||
|
||||
@ClientEndpoint(
|
||||
subprotocols = { "chat", "echo" },
|
||||
decoders = { DateDecoder.class },
|
||||
encoders = { TimeEncoder.class },
|
||||
configurator = AnnotatedEndpointConfigurator.class)
|
||||
public class AnnotatedEndpointClient
|
||||
{
|
||||
public Session session;
|
||||
public EndpointConfig config;
|
||||
|
||||
@OnOpen
|
||||
public void onOpen(Session session, EndpointConfig config)
|
||||
{
|
||||
this.session = session;
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
@OnMessage(maxMessageSize = 111222)
|
||||
public void onText(String msg)
|
||||
{
|
||||
/* do nothing */
|
||||
}
|
||||
|
||||
@OnMessage(maxMessageSize = 333444)
|
||||
public void onBinary(ByteBuffer buf)
|
||||
{
|
||||
/* do nothing */
|
||||
}
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.jsr356;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import javax.websocket.ClientEndpointConfig;
|
||||
import javax.websocket.HandshakeResponse;
|
||||
|
||||
public class AnnotatedEndpointConfigurator extends ClientEndpointConfig.Configurator
|
||||
{
|
||||
@Override
|
||||
public void afterResponse(HandshakeResponse hr)
|
||||
{
|
||||
hr.getHeaders().put("X-Test",Collections.singletonList("Extra"));
|
||||
super.afterResponse(hr);
|
||||
}
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.jsr356;
|
||||
|
||||
import javax.websocket.MessageHandler;
|
||||
|
||||
public class EchoCaptureHandler implements MessageHandler.Whole<String>
|
||||
{
|
||||
public MessageQueue messageQueue = new MessageQueue();
|
||||
|
||||
@Override
|
||||
public void onMessage(String message)
|
||||
{
|
||||
messageQueue.offer(message);
|
||||
}
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.jsr356;
|
||||
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.websocket.CloseReason;
|
||||
import javax.websocket.Endpoint;
|
||||
import javax.websocket.EndpointConfig;
|
||||
import javax.websocket.Session;
|
||||
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.junit.Assert;
|
||||
|
||||
/**
|
||||
* Basic Echo Client from extended Endpoint
|
||||
*/
|
||||
public class EndpointEchoClient extends Endpoint
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(EndpointEchoClient.class);
|
||||
private Session session = null;
|
||||
private CloseReason close = null;
|
||||
public EchoCaptureHandler textCapture = new EchoCaptureHandler();
|
||||
|
||||
public CloseReason getClose()
|
||||
{
|
||||
return close;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOpen(Session session, EndpointConfig config)
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("onOpen({}, {})",session,config);
|
||||
this.session = session;
|
||||
Assert.assertThat("Session is required",session,notNullValue());
|
||||
Assert.assertThat("EndpointConfig is required",config,notNullValue());
|
||||
this.session.addMessageHandler(textCapture);
|
||||
}
|
||||
|
||||
public void sendText(String text) throws IOException
|
||||
{
|
||||
if (session != null)
|
||||
{
|
||||
session.getBasicRemote().sendText(text);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,81 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.jsr356;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.eclipse.jetty.io.RuntimeIOException;
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.websocket.api.BatchMode;
|
||||
import org.eclipse.jetty.websocket.api.RemoteEndpoint;
|
||||
import org.eclipse.jetty.websocket.api.WebSocketAdapter;
|
||||
|
||||
/**
|
||||
* Jetty Echo Socket. using Jetty techniques.
|
||||
*/
|
||||
public class JettyEchoSocket extends WebSocketAdapter
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(JettyEchoSocket.class);
|
||||
|
||||
@Override
|
||||
public void onWebSocketBinary(byte[] payload, int offset, int len)
|
||||
{
|
||||
if (isNotConnected())
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
RemoteEndpoint remote = getRemote();
|
||||
remote.sendBytes(BufferUtil.toBuffer(payload, offset, len), null);
|
||||
if (remote.getBatchMode() == BatchMode.ON)
|
||||
remote.flush();
|
||||
}
|
||||
catch (IOException x)
|
||||
{
|
||||
throw new RuntimeIOException(x);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWebSocketError(Throwable cause)
|
||||
{
|
||||
LOG.warn(cause);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWebSocketText(String message)
|
||||
{
|
||||
if (isNotConnected())
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
RemoteEndpoint remote = getRemote();
|
||||
remote.sendString(message, null);
|
||||
if (remote.getBatchMode() == BatchMode.ON)
|
||||
remote.flush();
|
||||
}
|
||||
catch (IOException x)
|
||||
{
|
||||
throw new RuntimeIOException(x);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.jsr356;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.eclipse.jetty.util.BlockingArrayQueue;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
|
||||
public class MessageQueue extends BlockingArrayQueue<String>
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(MessageQueue.class);
|
||||
|
||||
public void awaitMessages(int expectedMessageCount, int timeoutDuration, TimeUnit timeoutUnit) throws TimeoutException
|
||||
{
|
||||
long msDur = TimeUnit.MILLISECONDS.convert(timeoutDuration,timeoutUnit);
|
||||
long now = System.currentTimeMillis();
|
||||
long expireOn = now + msDur;
|
||||
if (LOG.isDebugEnabled())
|
||||
{
|
||||
LOG.debug("Await Message.. Now: {} - expireOn: {} ({} ms)",now,expireOn,msDur);
|
||||
}
|
||||
|
||||
while (this.size() < expectedMessageCount)
|
||||
{
|
||||
try
|
||||
{
|
||||
TimeUnit.MILLISECONDS.sleep(20);
|
||||
}
|
||||
catch (InterruptedException gnore)
|
||||
{
|
||||
/* ignore */
|
||||
}
|
||||
if (!LOG.isDebugEnabled() && (System.currentTimeMillis() > expireOn))
|
||||
{
|
||||
throw new TimeoutException(String.format("Timeout reading all %d expected messages. (managed to only read %d messages)",expectedMessageCount,
|
||||
this.size()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.jsr356.annotations;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
import javax.websocket.ClientEndpoint;
|
||||
import javax.websocket.OnMessage;
|
||||
import javax.websocket.OnOpen;
|
||||
import javax.websocket.Session;
|
||||
|
||||
import org.eclipse.jetty.websocket.jsr356.decoders.DateDecoder;
|
||||
|
||||
@ClientEndpoint(decoders =
|
||||
{ DateDecoder.class })
|
||||
public class DateTextSocket
|
||||
{
|
||||
private Session session;
|
||||
|
||||
@OnMessage
|
||||
public void onMessage(Date d) throws IOException
|
||||
{
|
||||
if (d == null)
|
||||
{
|
||||
session.getAsyncRemote().sendText("Error: Date is null");
|
||||
}
|
||||
else
|
||||
{
|
||||
String msg = SimpleDateFormat.getDateInstance(SimpleDateFormat.SHORT).format(d);
|
||||
session.getAsyncRemote().sendText(msg);
|
||||
}
|
||||
}
|
||||
|
||||
@OnOpen
|
||||
public void onOpen(Session session)
|
||||
{
|
||||
this.session = session;
|
||||
}
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.jsr356.decoders;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import javax.websocket.DecodeException;
|
||||
import javax.websocket.Decoder;
|
||||
import javax.websocket.EndpointConfig;
|
||||
|
||||
/**
|
||||
* Decode Date
|
||||
*/
|
||||
public class DateDecoder implements Decoder.Text<Date>
|
||||
{
|
||||
private static final TimeZone GMT = TimeZone.getTimeZone("GMT");
|
||||
|
||||
@Override
|
||||
public Date decode(String s) throws DecodeException
|
||||
{
|
||||
try
|
||||
{
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd");
|
||||
dateFormat.setTimeZone(GMT);
|
||||
return dateFormat.parse(s);
|
||||
}
|
||||
catch (ParseException e)
|
||||
{
|
||||
throw new DecodeException(s,e.getMessage(),e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(EndpointConfig config)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean willDecode(String s)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.jsr356.decoders;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import javax.websocket.DecodeException;
|
||||
import javax.websocket.Decoder;
|
||||
import javax.websocket.EndpointConfig;
|
||||
|
||||
/**
|
||||
* Decode Date and Time
|
||||
*/
|
||||
public class DateTimeDecoder implements Decoder.Text<Date>
|
||||
{
|
||||
private static final TimeZone GMT = TimeZone.getTimeZone("GMT");
|
||||
|
||||
@Override
|
||||
public Date decode(String s) throws DecodeException
|
||||
{
|
||||
try
|
||||
{
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd G 'at' HH:mm:ss z");
|
||||
dateFormat.setTimeZone(GMT);
|
||||
return dateFormat.parse(s);
|
||||
}
|
||||
catch (ParseException e)
|
||||
{
|
||||
throw new DecodeException(s, e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(EndpointConfig config)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean willDecode(String s)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -1,68 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.jsr356.decoders;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import javax.websocket.DecodeException;
|
||||
import javax.websocket.Decoder;
|
||||
import javax.websocket.EndpointConfig;
|
||||
|
||||
/**
|
||||
* Decode Time
|
||||
*/
|
||||
public class TimeDecoder implements Decoder.Text<Date>
|
||||
{
|
||||
private static final TimeZone GMT = TimeZone.getTimeZone("GMT");
|
||||
|
||||
@Override
|
||||
public Date decode(String s) throws DecodeException
|
||||
{
|
||||
try
|
||||
{
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss z");
|
||||
dateFormat.setTimeZone(GMT);
|
||||
return dateFormat.parse(s);
|
||||
}
|
||||
catch (ParseException e)
|
||||
{
|
||||
throw new DecodeException(s, e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(EndpointConfig config)
|
||||
{
|
||||
System.out.println("#### INIT ####");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean willDecode(String s)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -1,99 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.jsr356.demo;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.websocket.ClientEndpoint;
|
||||
import javax.websocket.CloseReason;
|
||||
import javax.websocket.ContainerProvider;
|
||||
import javax.websocket.DeploymentException;
|
||||
import javax.websocket.OnClose;
|
||||
import javax.websocket.OnMessage;
|
||||
import javax.websocket.OnOpen;
|
||||
import javax.websocket.RemoteEndpoint;
|
||||
import javax.websocket.Session;
|
||||
import javax.websocket.WebSocketContainer;
|
||||
|
||||
public class ExampleClient
|
||||
{
|
||||
@ClientEndpoint
|
||||
public class ExampleSocket
|
||||
{
|
||||
public String message;
|
||||
public CountDownLatch messageLatch = new CountDownLatch(1);
|
||||
public CountDownLatch closeLatch = new CountDownLatch(1);
|
||||
|
||||
@OnOpen
|
||||
public void onOpen(Session session)
|
||||
{
|
||||
System.out.println("Opened");
|
||||
}
|
||||
|
||||
@OnMessage
|
||||
public void onMessage(String msg)
|
||||
{
|
||||
System.out.printf("Received: %s%n",Objects.toString(msg));
|
||||
this.messageLatch.countDown();
|
||||
}
|
||||
|
||||
@OnClose
|
||||
public void onClose(CloseReason close)
|
||||
{
|
||||
System.out.printf("Closed: %d, %s%n",close.getCloseCode().getCode(),Objects.toString(close.getReasonPhrase()));
|
||||
this.closeLatch.countDown();
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
try
|
||||
{
|
||||
new ExampleClient().run();
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void run() throws DeploymentException, IOException, URISyntaxException, InterruptedException
|
||||
{
|
||||
WebSocketContainer container = ContainerProvider.getWebSocketContainer();
|
||||
|
||||
System.out.printf("WebSocketContainer Impl: %s%n",container.getClass().getName());
|
||||
|
||||
ExampleSocket socket = new ExampleSocket();
|
||||
URI uri = new URI("ws://echo.websocket.org/");
|
||||
Session session = container.connectToServer(socket,uri);
|
||||
RemoteEndpoint.Basic remote = session.getBasicRemote();
|
||||
String msg = "Hello world";
|
||||
System.out.printf("Sending: %s%n",Objects.toString(msg));
|
||||
remote.sendText(msg);
|
||||
socket.messageLatch.await(1,TimeUnit.SECONDS); // give remote 1 second to respond
|
||||
session.close();
|
||||
socket.closeLatch.await(1,TimeUnit.SECONDS); // give remote 1 second to acknowledge response
|
||||
System.out.println("Socket is closed");
|
||||
}
|
||||
}
|
|
@ -1,71 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.jsr356.demo;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
import javax.websocket.ClientEndpoint;
|
||||
import javax.websocket.CloseReason;
|
||||
import javax.websocket.OnClose;
|
||||
import javax.websocket.OnMessage;
|
||||
import javax.websocket.OnOpen;
|
||||
import javax.websocket.Session;
|
||||
|
||||
@ClientEndpoint
|
||||
public class ExampleSocket
|
||||
{
|
||||
private Session session;
|
||||
public CountDownLatch messageLatch = new CountDownLatch(1);
|
||||
public CountDownLatch closeLatch = new CountDownLatch(1);
|
||||
|
||||
@OnClose
|
||||
public void onClose(CloseReason close)
|
||||
{
|
||||
System.out.printf("Closed: %d, \"%s\"%n",close.getCloseCode().getCode(),close.getReasonPhrase());
|
||||
closeLatch.countDown();
|
||||
}
|
||||
|
||||
@OnMessage
|
||||
public void onMessage(String message)
|
||||
{
|
||||
System.out.printf("Received: \"%s\"%n",message);
|
||||
messageLatch.countDown();
|
||||
}
|
||||
|
||||
@OnOpen
|
||||
public void onOpen(Session session)
|
||||
{
|
||||
System.out.printf("Opened%n");
|
||||
this.session = session;
|
||||
}
|
||||
|
||||
public void writeMessage(String message)
|
||||
{
|
||||
System.out.printf("Writing: \"%s\"%n",message);
|
||||
try
|
||||
{
|
||||
session.getBasicRemote().sendText(message);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,53 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.jsr356.encoders;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import javax.websocket.EncodeException;
|
||||
import javax.websocket.Encoder;
|
||||
import javax.websocket.EndpointConfig;
|
||||
|
||||
/**
|
||||
* Encode Date
|
||||
*/
|
||||
public class DateEncoder implements Encoder.Text<Date>
|
||||
{
|
||||
private static final TimeZone GMT = TimeZone.getTimeZone("GMT");
|
||||
|
||||
@Override
|
||||
public void destroy()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public String encode(Date object) throws EncodeException
|
||||
{
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd");
|
||||
dateFormat.setTimeZone(GMT);
|
||||
return dateFormat.format(object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(EndpointConfig config)
|
||||
{
|
||||
}
|
||||
}
|
|
@ -1,53 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.jsr356.encoders;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import javax.websocket.EncodeException;
|
||||
import javax.websocket.Encoder;
|
||||
import javax.websocket.EndpointConfig;
|
||||
|
||||
/**
|
||||
* Encode Date
|
||||
*/
|
||||
public class DateTimeEncoder implements Encoder.Text<Date>
|
||||
{
|
||||
private static final TimeZone GMT = TimeZone.getTimeZone("GMT");
|
||||
|
||||
@Override
|
||||
public void destroy()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public String encode(Date object) throws EncodeException
|
||||
{
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd G 'at' HH:mm:ss z");
|
||||
dateFormat.setTimeZone(GMT);
|
||||
return dateFormat.format(object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(EndpointConfig config)
|
||||
{
|
||||
}
|
||||
}
|
|
@ -1,53 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.jsr356.encoders;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import javax.websocket.EncodeException;
|
||||
import javax.websocket.Encoder;
|
||||
import javax.websocket.EndpointConfig;
|
||||
|
||||
/**
|
||||
* Encode Time
|
||||
*/
|
||||
public class TimeEncoder implements Encoder.Text<Date>
|
||||
{
|
||||
private static final TimeZone GMT = TimeZone.getTimeZone("GMT");
|
||||
|
||||
@Override
|
||||
public void destroy()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public String encode(Date object) throws EncodeException
|
||||
{
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss z");
|
||||
dateFormat.setTimeZone(GMT);
|
||||
return dateFormat.format(object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(EndpointConfig config)
|
||||
{
|
||||
}
|
||||
}
|
|
@ -1,128 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.jsr356.endpoints;
|
||||
|
||||
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.websocket.CloseReason;
|
||||
import javax.websocket.CloseReason.CloseCode;
|
||||
|
||||
import org.eclipse.jetty.toolchain.test.EventQueue;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.junit.Assert;
|
||||
|
||||
/**
|
||||
* Abstract base socket used for tracking state and events within the socket for testing reasons.
|
||||
*/
|
||||
public abstract class TrackingSocket
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(TrackingSocket.class);
|
||||
|
||||
public CloseReason closeReason;
|
||||
public EventQueue<String> eventQueue = new EventQueue<String>();
|
||||
public EventQueue<Throwable> errorQueue = new EventQueue<>();
|
||||
public CountDownLatch openLatch = new CountDownLatch(1);
|
||||
public CountDownLatch closeLatch = new CountDownLatch(1);
|
||||
public CountDownLatch dataLatch = new CountDownLatch(1);
|
||||
|
||||
protected void addError(Throwable t)
|
||||
{
|
||||
LOG.warn(t);
|
||||
errorQueue.add(t);
|
||||
}
|
||||
|
||||
protected void addEvent(String format, Object... args)
|
||||
{
|
||||
eventQueue.add(String.format(format,args));
|
||||
}
|
||||
|
||||
public void assertClose(CloseCode expectedCode, String expectedReason) throws InterruptedException
|
||||
{
|
||||
assertCloseCode(expectedCode);
|
||||
assertCloseReason(expectedReason);
|
||||
}
|
||||
|
||||
public void assertCloseCode(CloseCode expectedCode) throws InterruptedException
|
||||
{
|
||||
Assert.assertThat("Was Closed",closeLatch.await(50,TimeUnit.MILLISECONDS),is(true));
|
||||
Assert.assertThat("CloseReason",closeReason,notNullValue());
|
||||
Assert.assertThat("Close Code",closeReason.getCloseCode(),is(expectedCode));
|
||||
}
|
||||
|
||||
private void assertCloseReason(String expectedReason)
|
||||
{
|
||||
Assert.assertThat("Close Reason",closeReason.getReasonPhrase(),is(expectedReason));
|
||||
}
|
||||
|
||||
public void assertEvent(String expected)
|
||||
{
|
||||
String actual = eventQueue.poll();
|
||||
Assert.assertEquals("Event",expected,actual);
|
||||
}
|
||||
|
||||
public void assertIsOpen() throws InterruptedException
|
||||
{
|
||||
assertWasOpened();
|
||||
assertNotClosed();
|
||||
}
|
||||
|
||||
public void assertNotClosed()
|
||||
{
|
||||
Assert.assertThat("Closed Latch",closeLatch.getCount(),greaterThanOrEqualTo(1L));
|
||||
}
|
||||
|
||||
public void assertNotOpened()
|
||||
{
|
||||
Assert.assertThat("Open Latch",openLatch.getCount(),greaterThanOrEqualTo(1L));
|
||||
}
|
||||
|
||||
public void assertWasOpened() throws InterruptedException
|
||||
{
|
||||
Assert.assertThat("Was Opened",openLatch.await(30000,TimeUnit.MILLISECONDS),is(true));
|
||||
}
|
||||
|
||||
public void clear()
|
||||
{
|
||||
eventQueue.clear();
|
||||
errorQueue.clear();
|
||||
}
|
||||
|
||||
public void waitForClose(int timeoutDuration, TimeUnit timeoutUnit) throws InterruptedException
|
||||
{
|
||||
Assert.assertThat("Client Socket Closed",closeLatch.await(timeoutDuration,timeoutUnit),is(true));
|
||||
}
|
||||
|
||||
public void waitForConnected(int timeoutDuration, TimeUnit timeoutUnit) throws InterruptedException
|
||||
{
|
||||
Assert.assertThat("Client Socket Connected",openLatch.await(timeoutDuration,timeoutUnit),is(true));
|
||||
}
|
||||
|
||||
public void waitForData(int timeoutDuration, TimeUnit timeoutUnit) throws InterruptedException
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Waiting for message");
|
||||
Assert.assertThat("Data Received",dataLatch.await(timeoutDuration,timeoutUnit),is(true));
|
||||
}
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.jsr356.endpoints.samples;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import javax.websocket.ClientEndpoint;
|
||||
import javax.websocket.OnMessage;
|
||||
|
||||
import org.eclipse.jetty.websocket.jsr356.endpoints.TrackingSocket;
|
||||
|
||||
@ClientEndpoint
|
||||
public class BasicBinaryMessageByteBufferSocket extends TrackingSocket
|
||||
{
|
||||
@OnMessage
|
||||
public void onBinary(ByteBuffer data)
|
||||
{
|
||||
addEvent("onBinary(%s)",data);
|
||||
dataLatch.countDown();
|
||||
}
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.jsr356.endpoints.samples;
|
||||
|
||||
import javax.websocket.ClientEndpoint;
|
||||
import javax.websocket.OnError;
|
||||
import javax.websocket.Session;
|
||||
|
||||
import org.eclipse.jetty.websocket.jsr356.endpoints.TrackingSocket;
|
||||
|
||||
@ClientEndpoint
|
||||
public class BasicErrorSessionSocket extends TrackingSocket
|
||||
{
|
||||
@OnError
|
||||
public void onError(Session session)
|
||||
{
|
||||
addEvent("onError(%s)",session);
|
||||
}
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.jsr356.endpoints.samples;
|
||||
|
||||
import javax.websocket.ClientEndpoint;
|
||||
import javax.websocket.OnError;
|
||||
import javax.websocket.Session;
|
||||
|
||||
import org.eclipse.jetty.websocket.jsr356.endpoints.TrackingSocket;
|
||||
|
||||
@ClientEndpoint
|
||||
public class BasicErrorSessionThrowableSocket extends TrackingSocket
|
||||
{
|
||||
@OnError
|
||||
public void onError(Session session, Throwable t)
|
||||
{
|
||||
addEvent("onError(%s,%s)",session,t);
|
||||
addError(t);
|
||||
}
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.jsr356.endpoints.samples;
|
||||
|
||||
import javax.websocket.ClientEndpoint;
|
||||
import javax.websocket.OnError;
|
||||
|
||||
import org.eclipse.jetty.websocket.jsr356.endpoints.TrackingSocket;
|
||||
|
||||
@ClientEndpoint
|
||||
public class BasicErrorSocket extends TrackingSocket
|
||||
{
|
||||
@OnError
|
||||
public void onError()
|
||||
{
|
||||
addEvent("onError()");
|
||||
}
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.jsr356.endpoints.samples;
|
||||
|
||||
import javax.websocket.ClientEndpoint;
|
||||
import javax.websocket.OnError;
|
||||
import javax.websocket.Session;
|
||||
|
||||
import org.eclipse.jetty.websocket.jsr356.endpoints.TrackingSocket;
|
||||
|
||||
@ClientEndpoint
|
||||
public class BasicErrorThrowableSessionSocket extends TrackingSocket
|
||||
{
|
||||
@OnError
|
||||
public void onError(Throwable t, Session session)
|
||||
{
|
||||
addEvent("onError(%s,%s)",t,session);
|
||||
addError(t);
|
||||
}
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.jsr356.endpoints.samples;
|
||||
|
||||
import javax.websocket.ClientEndpoint;
|
||||
import javax.websocket.OnError;
|
||||
|
||||
import org.eclipse.jetty.websocket.jsr356.endpoints.TrackingSocket;
|
||||
|
||||
@ClientEndpoint
|
||||
public class BasicErrorThrowableSocket extends TrackingSocket
|
||||
{
|
||||
@OnError
|
||||
public void onError(Throwable t)
|
||||
{
|
||||
addEvent("onError(%s)",t);
|
||||
addError(t);
|
||||
}
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.jsr356.endpoints.samples;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import javax.websocket.ClientEndpoint;
|
||||
import javax.websocket.OnMessage;
|
||||
|
||||
import org.eclipse.jetty.util.IO;
|
||||
import org.eclipse.jetty.websocket.jsr356.endpoints.TrackingSocket;
|
||||
|
||||
@ClientEndpoint
|
||||
public class BasicInputStreamSocket extends TrackingSocket
|
||||
{
|
||||
@OnMessage
|
||||
public void onBinary(InputStream stream)
|
||||
{
|
||||
try
|
||||
{
|
||||
String msg = IO.toString(stream);
|
||||
addEvent("onBinary(%s)",msg);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
super.errorQueue.add(e);
|
||||
}
|
||||
dataLatch.countDown();
|
||||
}
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.jsr356.endpoints.samples;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import javax.websocket.ClientEndpoint;
|
||||
import javax.websocket.OnMessage;
|
||||
|
||||
import org.eclipse.jetty.util.IO;
|
||||
import org.eclipse.jetty.websocket.jsr356.endpoints.TrackingSocket;
|
||||
|
||||
@ClientEndpoint
|
||||
public class BasicInputStreamWithThrowableSocket extends TrackingSocket
|
||||
{
|
||||
@OnMessage
|
||||
public void onBinary(InputStream stream) throws IOException
|
||||
{
|
||||
String msg = IO.toString(stream);
|
||||
addEvent("onBinary(%s)",msg);
|
||||
}
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.jsr356.endpoints.samples;
|
||||
|
||||
import javax.websocket.ClientEndpoint;
|
||||
import javax.websocket.CloseReason;
|
||||
import javax.websocket.OnClose;
|
||||
import javax.websocket.OnOpen;
|
||||
|
||||
import org.eclipse.jetty.websocket.jsr356.endpoints.TrackingSocket;
|
||||
|
||||
@ClientEndpoint
|
||||
public class BasicOpenCloseSocket extends TrackingSocket
|
||||
{
|
||||
@OnOpen
|
||||
public void onOpen() {
|
||||
openLatch.countDown();
|
||||
}
|
||||
|
||||
@OnClose
|
||||
public void onClose(CloseReason close) {
|
||||
this.closeReason = close;
|
||||
closeLatch.countDown();
|
||||
}
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.jsr356.endpoints.samples;
|
||||
|
||||
import javax.websocket.ClientEndpoint;
|
||||
import javax.websocket.OnOpen;
|
||||
import javax.websocket.Session;
|
||||
|
||||
import org.eclipse.jetty.websocket.jsr356.endpoints.TrackingSocket;
|
||||
|
||||
@ClientEndpoint
|
||||
public class BasicOpenSessionSocket extends TrackingSocket
|
||||
{
|
||||
@OnOpen
|
||||
public void onOpen(Session session)
|
||||
{
|
||||
openLatch.countDown();
|
||||
}
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.jsr356.endpoints.samples;
|
||||
|
||||
import javax.websocket.ClientEndpoint;
|
||||
import javax.websocket.OnOpen;
|
||||
|
||||
import org.eclipse.jetty.websocket.jsr356.endpoints.TrackingSocket;
|
||||
|
||||
@ClientEndpoint
|
||||
public class BasicOpenSocket extends TrackingSocket
|
||||
{
|
||||
@OnOpen
|
||||
public void onOpen()
|
||||
{
|
||||
openLatch.countDown();
|
||||
}
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.jsr356.endpoints.samples;
|
||||
|
||||
import javax.websocket.ClientEndpoint;
|
||||
import javax.websocket.OnMessage;
|
||||
import javax.websocket.PongMessage;
|
||||
|
||||
import org.eclipse.jetty.websocket.jsr356.endpoints.TrackingSocket;
|
||||
|
||||
@ClientEndpoint
|
||||
public class BasicPongMessageSocket extends TrackingSocket
|
||||
{
|
||||
@OnMessage
|
||||
public void onPong(PongMessage pong)
|
||||
{
|
||||
addEvent("onPong(%s)",pong);
|
||||
dataLatch.countDown();
|
||||
}
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.jsr356.endpoints.samples;
|
||||
|
||||
import javax.websocket.ClientEndpoint;
|
||||
import javax.websocket.OnMessage;
|
||||
|
||||
import org.eclipse.jetty.websocket.jsr356.endpoints.TrackingSocket;
|
||||
|
||||
@ClientEndpoint
|
||||
public class BasicTextMessageStringSocket extends TrackingSocket
|
||||
{
|
||||
@OnMessage
|
||||
public void onText(String message)
|
||||
{
|
||||
addEvent("onText(%s)",message);
|
||||
dataLatch.countDown();
|
||||
}
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.jsr356.endpoints.samples;
|
||||
|
||||
import javax.websocket.ClientEndpoint;
|
||||
import javax.websocket.OnClose;
|
||||
|
||||
import org.eclipse.jetty.websocket.jsr356.endpoints.TrackingSocket;
|
||||
|
||||
@ClientEndpoint
|
||||
public class InvalidCloseIntSocket extends TrackingSocket
|
||||
{
|
||||
/**
|
||||
* Invalid Close Method Declaration (parameter type int)
|
||||
* @param statusCode the status code
|
||||
*/
|
||||
@OnClose
|
||||
public void onClose(int statusCode)
|
||||
{
|
||||
closeLatch.countDown();
|
||||
}
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.jsr356.endpoints.samples;
|
||||
|
||||
import javax.websocket.ClientEndpoint;
|
||||
import javax.websocket.OnError;
|
||||
|
||||
import org.eclipse.jetty.websocket.jsr356.endpoints.TrackingSocket;
|
||||
|
||||
@ClientEndpoint
|
||||
public class InvalidErrorErrorSocket extends TrackingSocket
|
||||
{
|
||||
/**
|
||||
* Invalid Error Method Declaration (parameter type Error)
|
||||
* @param error the error
|
||||
*/
|
||||
@OnError
|
||||
public void onError(Error error)
|
||||
{
|
||||
/* no impl */
|
||||
}
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.jsr356.endpoints.samples;
|
||||
|
||||
import javax.websocket.ClientEndpoint;
|
||||
import javax.websocket.OnError;
|
||||
|
||||
import org.eclipse.jetty.websocket.jsr356.endpoints.TrackingSocket;
|
||||
|
||||
@ClientEndpoint
|
||||
public class InvalidErrorExceptionSocket extends TrackingSocket
|
||||
{
|
||||
/**
|
||||
* Invalid Error Method Declaration (parameter type Exception)
|
||||
* @param e the extension
|
||||
*/
|
||||
@OnError
|
||||
public void onError(Exception e)
|
||||
{
|
||||
/* no impl */
|
||||
}
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.jsr356.endpoints.samples;
|
||||
|
||||
import javax.websocket.ClientEndpoint;
|
||||
import javax.websocket.OnError;
|
||||
|
||||
import org.eclipse.jetty.websocket.jsr356.endpoints.TrackingSocket;
|
||||
|
||||
@ClientEndpoint
|
||||
public class InvalidErrorIntSocket extends TrackingSocket
|
||||
{
|
||||
/**
|
||||
* Invalid Error Method Declaration (parameter type int)
|
||||
* @param errorCount the error count
|
||||
*/
|
||||
@OnError
|
||||
public void onError(int errorCount)
|
||||
{
|
||||
/* no impl */
|
||||
}
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.jsr356.endpoints.samples;
|
||||
|
||||
import javax.websocket.ClientEndpoint;
|
||||
import javax.websocket.CloseReason;
|
||||
import javax.websocket.OnOpen;
|
||||
|
||||
import org.eclipse.jetty.websocket.jsr356.endpoints.TrackingSocket;
|
||||
|
||||
@ClientEndpoint
|
||||
public class InvalidOpenCloseReasonSocket extends TrackingSocket
|
||||
{
|
||||
/**
|
||||
* Invalid Open Method Declaration (parameter type CloseReason)
|
||||
* @param reason the close reason
|
||||
*/
|
||||
@OnOpen
|
||||
public void onOpen(CloseReason reason)
|
||||
{
|
||||
openLatch.countDown();
|
||||
}
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.jsr356.endpoints.samples;
|
||||
|
||||
import javax.websocket.ClientEndpoint;
|
||||
import javax.websocket.OnOpen;
|
||||
|
||||
import org.eclipse.jetty.websocket.jsr356.endpoints.TrackingSocket;
|
||||
|
||||
@ClientEndpoint
|
||||
public class InvalidOpenIntSocket extends TrackingSocket
|
||||
{
|
||||
/**
|
||||
* Invalid Open Method Declaration (parameter type int)
|
||||
* @param value the open value
|
||||
*/
|
||||
@OnOpen
|
||||
public void onOpen(int value)
|
||||
{
|
||||
openLatch.countDown();
|
||||
}
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.jsr356.endpoints.samples;
|
||||
|
||||
import javax.websocket.ClientEndpoint;
|
||||
import javax.websocket.OnOpen;
|
||||
import javax.websocket.Session;
|
||||
|
||||
import org.eclipse.jetty.websocket.jsr356.endpoints.TrackingSocket;
|
||||
|
||||
@ClientEndpoint
|
||||
public class InvalidOpenSessionIntSocket extends TrackingSocket
|
||||
{
|
||||
/**
|
||||
* Invalid Open Method Declaration (parameter of type int)
|
||||
* @param session the session for the open
|
||||
* @param count the open count
|
||||
*/
|
||||
@OnOpen
|
||||
public void onOpen(Session session, int count)
|
||||
{
|
||||
openLatch.countDown();
|
||||
}
|
||||
}
|
|
@ -1,120 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.jsr356.utils;
|
||||
|
||||
import java.lang.reflect.GenericArrayType;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.lang.reflect.TypeVariable;
|
||||
import java.lang.reflect.WildcardType;
|
||||
|
||||
import org.eclipse.jetty.websocket.common.util.ReflectUtils;
|
||||
|
||||
public class TypeTree
|
||||
{
|
||||
public static void dumpTree(String indent, Type type)
|
||||
{
|
||||
if ((type == null) || (type == Object.class))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (type instanceof Class<?>)
|
||||
{
|
||||
Class<?> ctype = (Class<?>)type;
|
||||
System.out.printf("%s (Class) = %s%n",indent,ctype.getName());
|
||||
|
||||
String name = ctype.getName();
|
||||
if (name.startsWith("java.lang.") || name.startsWith("java.io."))
|
||||
{
|
||||
// filter away standard classes from tree (otherwise it will go on infinitely)
|
||||
return;
|
||||
}
|
||||
|
||||
Type superType = ctype.getGenericSuperclass();
|
||||
dumpTree(indent + ".genericSuperClass()",superType);
|
||||
|
||||
Type[] ifaces = ctype.getGenericInterfaces();
|
||||
if ((ifaces != null) && (ifaces.length > 0))
|
||||
{
|
||||
// System.out.printf("%s.genericInterfaces[].length = %d%n",indent,ifaces.length);
|
||||
for (int i = 0; i < ifaces.length; i++)
|
||||
{
|
||||
Type iface = ifaces[i];
|
||||
dumpTree(indent + ".genericInterfaces[" + i + "]",iface);
|
||||
}
|
||||
}
|
||||
|
||||
TypeVariable<?>[] typeParams = ctype.getTypeParameters();
|
||||
if ((typeParams != null) && (typeParams.length > 0))
|
||||
{
|
||||
// System.out.printf("%s.typeParameters[].length = %d%n",indent,typeParams.length);
|
||||
for (int i = 0; i < typeParams.length; i++)
|
||||
{
|
||||
TypeVariable<?> typeParam = typeParams[i];
|
||||
dumpTree(indent + ".typeParameters[" + i + "]",typeParam);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (type instanceof ParameterizedType)
|
||||
{
|
||||
ParameterizedType ptype = (ParameterizedType)type;
|
||||
System.out.printf("%s (ParameterizedType) = %s%n",indent,ReflectUtils.toShortName(ptype));
|
||||
// dumpTree(indent + ".ownerType()",ptype.getOwnerType());
|
||||
dumpTree(indent + ".rawType(" + ReflectUtils.toShortName(ptype.getRawType()) + ")",ptype.getRawType());
|
||||
Type args[] = ptype.getActualTypeArguments();
|
||||
if (args != null)
|
||||
{
|
||||
System.out.printf("%s.actualTypeArguments[].length = %d%n",indent,args.length);
|
||||
for (int i = 0; i < args.length; i++)
|
||||
{
|
||||
Type arg = args[i];
|
||||
dumpTree(indent + ".actualTypeArguments[" + i + "]",arg);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (type instanceof GenericArrayType)
|
||||
{
|
||||
GenericArrayType gtype = (GenericArrayType)type;
|
||||
System.out.printf("%s (GenericArrayType) = %s%n",indent,gtype);
|
||||
return;
|
||||
}
|
||||
|
||||
if (type instanceof TypeVariable<?>)
|
||||
{
|
||||
TypeVariable<?> tvar = (TypeVariable<?>)type;
|
||||
System.out.printf("%s (TypeVariable) = %s%n",indent,tvar);
|
||||
System.out.printf("%s.getName() = %s%n",indent,tvar.getName());
|
||||
System.out.printf("%s.getGenericDeclaration() = %s%n",indent,tvar.getGenericDeclaration());
|
||||
return;
|
||||
}
|
||||
|
||||
if (type instanceof WildcardType)
|
||||
{
|
||||
System.out.printf("%s (WildcardType) = %s%n",indent,type);
|
||||
return;
|
||||
}
|
||||
|
||||
System.out.printf("%s (?) = %s%n",indent,type);
|
||||
}
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog
|
||||
org.eclipse.jetty.LEVEL=WARN
|
||||
|
||||
# org.eclipse.jetty.websocket.LEVEL=INFO
|
||||
# org.eclipse.jetty.websocket.LEVEL=ALL
|
||||
# org.eclipse.jetty.websocket.LEVEL=DEBUG
|
||||
# org.eclipse.jetty.websocket.jsr356.LEVEL=DEBUG
|
|
@ -1,4 +0,0 @@
|
|||
a|Benjamin Franklin
|
||||
q|There never was a good war or a bad peace.
|
||||
q|We must, indeed, all hang together, or assuredly we shall all hang separately.
|
||||
q|Our new Constitution is now established, and has an appearance that promises permanency; but in this world nothing can be said to be certain, except death and taxes.
|
|
@ -1,5 +0,0 @@
|
|||
a|Mark Twain
|
||||
q|He is now fast rising from affluence to poverty.
|
||||
q|A baby is an inestimable blessing and bother.
|
||||
q|As I slowly grow wise I briskly grow cautious.
|
||||
q|A circle is a round straight line with a hole in the middle.
|
|
@ -34,13 +34,6 @@
|
|||
<groupId>javax.websocket</groupId>
|
||||
<artifactId>javax.websocket-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.websocket</groupId>
|
||||
<artifactId>websocket-common</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<classifier>tests</classifier>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.toolchain</groupId>
|
||||
<artifactId>jetty-test-helper</artifactId>
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.websocket.jsr356.server.browser;
|
||||
package examples;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
|
@ -16,7 +16,7 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.websocket.jsr356.server.browser;
|
||||
package examples;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
|
@ -16,7 +16,7 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.websocket.jsr356.server.browser;
|
||||
package examples;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
|
@ -1,133 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.jsr356.server;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.websocket.Decoder;
|
||||
import javax.websocket.Encoder;
|
||||
import javax.websocket.Extension;
|
||||
import javax.websocket.server.ServerEndpointConfig;
|
||||
|
||||
import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope;
|
||||
|
||||
public class BasicServerEndpointConfig implements ServerEndpointConfig
|
||||
{
|
||||
private final List<Class<? extends Decoder>> decoders;
|
||||
private final List<Class<? extends Encoder>> encoders;
|
||||
private final List<Extension> extensions;
|
||||
private final List<String> subprotocols;
|
||||
private final ServerEndpointConfig.Configurator configurator;
|
||||
private final Class<?> endpointClass;
|
||||
private final String path;
|
||||
private Map<String, Object> userProperties;
|
||||
|
||||
public BasicServerEndpointConfig(WebSocketContainerScope containerScope, Class<?> endpointClass, String path)
|
||||
{
|
||||
this.endpointClass = endpointClass;
|
||||
this.path = path;
|
||||
|
||||
this.decoders = new ArrayList<>();
|
||||
this.encoders = new ArrayList<>();
|
||||
this.subprotocols = new ArrayList<>();
|
||||
this.extensions = new ArrayList<>();
|
||||
this.userProperties = new HashMap<>();
|
||||
this.configurator = new ContainerDefaultConfigurator();
|
||||
}
|
||||
|
||||
public BasicServerEndpointConfig(WebSocketContainerScope containerScope, ServerEndpointConfig copy)
|
||||
{
|
||||
// immutable concepts
|
||||
this.endpointClass = copy.getEndpointClass();
|
||||
this.path = copy.getPath();
|
||||
|
||||
this.decoders = copy.getDecoders();
|
||||
this.encoders = copy.getEncoders();
|
||||
this.subprotocols = copy.getSubprotocols();
|
||||
this.extensions = copy.getExtensions();
|
||||
|
||||
ServerEndpointConfig.Configurator cfgr;
|
||||
|
||||
if (copy.getConfigurator() != null)
|
||||
{
|
||||
cfgr = copy.getConfigurator();
|
||||
}
|
||||
else
|
||||
{
|
||||
cfgr = new ContainerDefaultConfigurator();
|
||||
}
|
||||
|
||||
// Make sure all Configurators obtained are decorated
|
||||
this.configurator = containerScope.getObjectFactory().decorate(cfgr);
|
||||
|
||||
// mutable concepts
|
||||
this.userProperties = new HashMap<>(copy.getUserProperties());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Class<? extends Encoder>> getEncoders()
|
||||
{
|
||||
return encoders;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Class<? extends Decoder>> getDecoders()
|
||||
{
|
||||
return decoders;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getUserProperties()
|
||||
{
|
||||
return userProperties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getEndpointClass()
|
||||
{
|
||||
return endpointClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPath()
|
||||
{
|
||||
return path;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getSubprotocols()
|
||||
{
|
||||
return subprotocols;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Extension> getExtensions()
|
||||
{
|
||||
return extensions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServerEndpointConfig.Configurator getConfigurator()
|
||||
{
|
||||
return configurator;
|
||||
}
|
||||
}
|
|
@ -1,154 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.jsr356.server;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import javax.websocket.ClientEndpoint;
|
||||
import javax.websocket.CloseReason;
|
||||
import javax.websocket.EncodeException;
|
||||
import javax.websocket.OnClose;
|
||||
import javax.websocket.OnError;
|
||||
import javax.websocket.OnMessage;
|
||||
import javax.websocket.OnOpen;
|
||||
import javax.websocket.RemoteEndpoint.Basic;
|
||||
import javax.websocket.Session;
|
||||
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.websocket.api.CloseException;
|
||||
|
||||
@ClientEndpoint
|
||||
public class EchoClientSocket
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(EchoClientSocket.class);
|
||||
public CountDownLatch openLatch = new CountDownLatch(1);
|
||||
public CountDownLatch closeLatch = new CountDownLatch(1);
|
||||
private Session session;
|
||||
private Basic remote;
|
||||
private CompletableFuture<List<String>> expectedMessagesFuture;
|
||||
private AtomicInteger expectedMessageCount;
|
||||
private List<String> messages = new ArrayList<>();
|
||||
|
||||
public Future<List<String>> expectedMessages(int expected)
|
||||
{
|
||||
expectedMessagesFuture = new CompletableFuture<>();
|
||||
expectedMessageCount = new AtomicInteger(expected);
|
||||
return expectedMessagesFuture;
|
||||
}
|
||||
|
||||
public void close() throws IOException
|
||||
{
|
||||
if (session != null)
|
||||
{
|
||||
this.session.close(new CloseReason(CloseReason.CloseCodes.NORMAL_CLOSURE,"Test Complete"));
|
||||
}
|
||||
}
|
||||
|
||||
@OnClose
|
||||
public void onClose(CloseReason close)
|
||||
{
|
||||
this.session = null;
|
||||
remote = null;
|
||||
synchronized (expectedMessagesFuture)
|
||||
{
|
||||
if ((close.getCloseCode() != CloseReason.CloseCodes.NORMAL_CLOSURE) ||
|
||||
(close.getCloseCode() != CloseReason.CloseCodes.NO_STATUS_CODE))
|
||||
{
|
||||
expectedMessagesFuture.completeExceptionally(new CloseException(close.getCloseCode().getCode(), close.getReasonPhrase()));
|
||||
}
|
||||
}
|
||||
closeLatch.countDown();
|
||||
}
|
||||
|
||||
@OnError
|
||||
public void onError(Throwable t)
|
||||
{
|
||||
LOG.warn(t);
|
||||
synchronized (expectedMessagesFuture)
|
||||
{
|
||||
expectedMessagesFuture.completeExceptionally(t);
|
||||
}
|
||||
}
|
||||
|
||||
@OnOpen
|
||||
public void onOpen(Session session)
|
||||
{
|
||||
this.session = session;
|
||||
this.remote = session.getBasicRemote();
|
||||
openLatch.countDown();
|
||||
}
|
||||
|
||||
@OnMessage
|
||||
public void onText(String text) throws IOException, EncodeException
|
||||
{
|
||||
messages.add(text);
|
||||
synchronized (expectedMessagesFuture)
|
||||
{
|
||||
int countLeft = expectedMessageCount.decrementAndGet();
|
||||
if (countLeft <= 0)
|
||||
{
|
||||
expectedMessagesFuture.complete(messages);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void sendText(String msg) throws IOException, EncodeException
|
||||
{
|
||||
remote.sendText(msg);
|
||||
}
|
||||
|
||||
public void sendBinary(ByteBuffer msg) throws IOException, EncodeException
|
||||
{
|
||||
remote.sendBinary(msg);
|
||||
}
|
||||
|
||||
public void sendObject(Object obj) throws IOException, EncodeException
|
||||
{
|
||||
remote.sendObject(obj);
|
||||
}
|
||||
|
||||
public void sendPartialBinary(ByteBuffer part, boolean fin) throws IOException
|
||||
{
|
||||
remote.sendBinary(part,fin);
|
||||
}
|
||||
|
||||
public void sendPartialText(String part, boolean fin) throws IOException
|
||||
{
|
||||
remote.sendText(part,fin);
|
||||
}
|
||||
|
||||
public void sendPing(String message) throws IOException
|
||||
{
|
||||
remote.sendPing(BufferUtil.toBuffer(message));
|
||||
}
|
||||
|
||||
public void sendPong(String message) throws IOException
|
||||
{
|
||||
remote.sendPong(BufferUtil.toBuffer(message));
|
||||
}
|
||||
}
|
|
@ -1,113 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.jsr356.server;
|
||||
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.LinkedBlockingDeque;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.websocket.api.BatchMode;
|
||||
import org.eclipse.jetty.websocket.api.RemoteEndpoint;
|
||||
import org.eclipse.jetty.websocket.api.Session;
|
||||
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose;
|
||||
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect;
|
||||
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketError;
|
||||
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage;
|
||||
import org.eclipse.jetty.websocket.api.annotations.WebSocket;
|
||||
import org.eclipse.jetty.websocket.common.CloseInfo;
|
||||
import org.hamcrest.Matcher;
|
||||
import org.hamcrest.Matchers;
|
||||
|
||||
/**
|
||||
* This is a Jetty API version of a websocket.
|
||||
* <p>
|
||||
* This is used as a client socket during the server tests.
|
||||
*/
|
||||
@WebSocket
|
||||
public class JettyEchoSocket
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(JettyEchoSocket.class);
|
||||
private RemoteEndpoint remote;
|
||||
public CountDownLatch closeLatch = new CountDownLatch(1);
|
||||
public BlockingQueue<String> messageQueue = new LinkedBlockingDeque<>();
|
||||
public AtomicReference<CloseInfo> closeInfo = new AtomicReference<>();
|
||||
|
||||
@OnWebSocketClose
|
||||
public void onClose(int statusCode, String reason)
|
||||
{
|
||||
remote = null;
|
||||
CloseInfo close = new CloseInfo(statusCode, reason);
|
||||
boolean closeTracked = closeInfo.compareAndSet(null, close);
|
||||
this.closeLatch.countDown();
|
||||
assertTrue("Close only happened once", closeTracked);
|
||||
}
|
||||
|
||||
@OnWebSocketError
|
||||
public void onError(Throwable t)
|
||||
{
|
||||
LOG.warn(t);
|
||||
}
|
||||
|
||||
@OnWebSocketMessage
|
||||
public void onMessage(String msg) throws IOException
|
||||
{
|
||||
messageQueue.offer(msg);
|
||||
sendMessage(msg);
|
||||
}
|
||||
|
||||
@OnWebSocketConnect
|
||||
public void onOpen(Session session)
|
||||
{
|
||||
this.remote = session.getRemote();
|
||||
}
|
||||
|
||||
public void awaitCloseEvent(String prefix) throws InterruptedException
|
||||
{
|
||||
assertTrue(prefix + " onClose event", closeLatch.await(5, TimeUnit.SECONDS));
|
||||
}
|
||||
|
||||
public void assertCloseInfo(String prefix, int expectedCloseStatusCode, Matcher<? super String> reasonMatcher) throws InterruptedException
|
||||
{
|
||||
CloseInfo close = closeInfo.get();
|
||||
assertThat(prefix + " close info", close, Matchers.notNullValue());
|
||||
assertThat(prefix + " received close code", close.getStatusCode(), Matchers.is(expectedCloseStatusCode));
|
||||
assertThat(prefix + " received close reason", close.getReason(), reasonMatcher);
|
||||
}
|
||||
|
||||
public void sendMessage(String msg) throws IOException
|
||||
{
|
||||
RemoteEndpoint r = remote;
|
||||
if (r == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
r.sendStringByFuture(msg);
|
||||
if (r.getBatchMode() == BatchMode.ON)
|
||||
r.flush();
|
||||
}
|
||||
}
|
|
@ -1,143 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.jsr356.server;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Function;
|
||||
|
||||
import javax.websocket.ContainerProvider;
|
||||
import javax.websocket.WebSocketContainer;
|
||||
|
||||
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
||||
import org.eclipse.jetty.webapp.WebAppContext;
|
||||
import org.eclipse.jetty.websocket.jsr356.server.samples.pong.PongContextListener;
|
||||
import org.eclipse.jetty.websocket.jsr356.server.samples.pong.PongMessageEndpoint;
|
||||
import org.eclipse.jetty.websocket.jsr356.server.samples.pong.PongSocket;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
public class PingPongTest
|
||||
{
|
||||
private static WSServer server;
|
||||
private static URI serverUri;
|
||||
private static WebSocketContainer client;
|
||||
|
||||
@BeforeClass
|
||||
public static void startServer() throws Exception
|
||||
{
|
||||
Path testdir = MavenTestingUtils.getTargetTestingPath(PingPongTest.class.getName());
|
||||
server = new WSServer(testdir,"app");
|
||||
server.copyWebInf("pong-config-web.xml");
|
||||
|
||||
server.copyClass(PongContextListener.class);
|
||||
server.copyClass(PongMessageEndpoint.class);
|
||||
server.copyClass(PongSocket.class);
|
||||
|
||||
server.start();
|
||||
serverUri = server.getServerBaseURI();
|
||||
|
||||
WebAppContext webapp = server.createWebAppContext();
|
||||
server.deployWebapp(webapp);
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
public static void startClient() throws Exception
|
||||
{
|
||||
client = ContainerProvider.getWebSocketContainer();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void stopServer()
|
||||
{
|
||||
server.stop();
|
||||
}
|
||||
|
||||
private void assertEcho(String endpointPath, Function<EchoClientSocket,Void> sendAction, String ... expectedMsgs) throws Exception
|
||||
{
|
||||
EchoClientSocket socket = new EchoClientSocket();
|
||||
URI toUri = serverUri.resolve(endpointPath);
|
||||
|
||||
try
|
||||
{
|
||||
Future<List<String>> clientMessagesFuture = socket.expectedMessages(expectedMsgs.length);
|
||||
|
||||
// Connect
|
||||
client.connectToServer(socket,toUri);
|
||||
socket.openLatch.await(2, TimeUnit.SECONDS);
|
||||
|
||||
// Apply send action
|
||||
sendAction.apply(socket);
|
||||
|
||||
// Collect Responses
|
||||
List<String> msgs = clientMessagesFuture.get(5, TimeUnit.SECONDS);
|
||||
|
||||
// Validate Responses
|
||||
for(int i=0; i<expectedMsgs.length; i++)
|
||||
{
|
||||
assertThat("Expected message[" + i + "]",msgs.get(i),containsString(expectedMsgs[i]));
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
// Close
|
||||
socket.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test(timeout = 6000)
|
||||
public void testPongEndpoint() throws Exception
|
||||
{
|
||||
assertEcho("pong", (socket) -> {
|
||||
try
|
||||
{
|
||||
socket.sendPong("hello");
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return null;
|
||||
}, "PongMessageEndpoint.onMessage(PongMessage):[/pong]:hello");
|
||||
}
|
||||
|
||||
@Test(timeout = 6000)
|
||||
public void testPongSocket() throws Exception
|
||||
{
|
||||
assertEcho("pong-socket", (socket) -> {
|
||||
try
|
||||
{
|
||||
socket.sendPong("hello");
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return null;
|
||||
}, "PongSocket.onPong(PongMessage)[/pong-socket]:hello");
|
||||
}
|
||||
}
|
|
@ -1,55 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.jsr356.server;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.websocket.Endpoint;
|
||||
import javax.websocket.server.ServerApplicationConfig;
|
||||
import javax.websocket.server.ServerEndpointConfig;
|
||||
|
||||
public class SessionAltConfig implements ServerApplicationConfig
|
||||
{
|
||||
@Override
|
||||
public Set<ServerEndpointConfig> getEndpointConfigs(Set<Class<? extends Endpoint>> endpointClasses)
|
||||
{
|
||||
Set<ServerEndpointConfig> configs = new HashSet<>();
|
||||
Class<?> endpointClass = SessionInfoSocket.class;
|
||||
configs.add(ServerEndpointConfig.Builder.create(endpointClass,"/info/{a}/").build());
|
||||
configs.add(ServerEndpointConfig.Builder.create(endpointClass,"/info/{a}/{b}/").build());
|
||||
configs.add(ServerEndpointConfig.Builder.create(endpointClass,"/info/{a}/{b}/{c}/").build());
|
||||
configs.add(ServerEndpointConfig.Builder.create(endpointClass,"/info/{a}/{b}/{c}/{d}/").build());
|
||||
endpointClass = SessionInfoEndpoint.class;
|
||||
configs.add(ServerEndpointConfig.Builder.create(endpointClass,"/einfo/").build());
|
||||
configs.add(ServerEndpointConfig.Builder.create(endpointClass,"/einfo/{a}/").build());
|
||||
configs.add(ServerEndpointConfig.Builder.create(endpointClass,"/einfo/{a}/{b}/").build());
|
||||
configs.add(ServerEndpointConfig.Builder.create(endpointClass,"/einfo/{a}/{b}/{c}/").build());
|
||||
configs.add(ServerEndpointConfig.Builder.create(endpointClass,"/einfo/{a}/{b}/{c}/{d}/").build());
|
||||
return configs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Class<?>> getAnnotatedEndpointClasses(Set<Class<?>> scanned)
|
||||
{
|
||||
Set<Class<?>> annotated = new HashSet<>();
|
||||
annotated.add(SessionInfoSocket.class);
|
||||
return annotated;
|
||||
}
|
||||
}
|
|
@ -1,102 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.jsr356.server;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.websocket.Endpoint;
|
||||
import javax.websocket.EndpointConfig;
|
||||
import javax.websocket.MessageHandler;
|
||||
import javax.websocket.Session;
|
||||
|
||||
public class SessionInfoEndpoint extends Endpoint implements MessageHandler.Whole<String>
|
||||
{
|
||||
private Session session;
|
||||
|
||||
@Override
|
||||
public void onOpen(Session session, EndpointConfig config)
|
||||
{
|
||||
this.session = session;
|
||||
this.session.addMessageHandler(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMessage(String message)
|
||||
{
|
||||
try
|
||||
{
|
||||
if ("pathParams".equalsIgnoreCase(message))
|
||||
{
|
||||
StringBuilder ret = new StringBuilder();
|
||||
ret.append("pathParams");
|
||||
Map<String, String> pathParams = session.getPathParameters();
|
||||
if (pathParams == null)
|
||||
{
|
||||
ret.append("=<null>");
|
||||
}
|
||||
else
|
||||
{
|
||||
ret.append('[').append(pathParams.size()).append(']');
|
||||
List<String> keys = new ArrayList<>();
|
||||
for (String key : pathParams.keySet())
|
||||
{
|
||||
keys.add(key);
|
||||
}
|
||||
Collections.sort(keys);
|
||||
for (String key : keys)
|
||||
{
|
||||
String value = pathParams.get(key);
|
||||
ret.append(": '").append(key).append("'=").append(value);
|
||||
}
|
||||
}
|
||||
session.getBasicRemote().sendText(ret.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
if ("requestUri".equalsIgnoreCase(message))
|
||||
{
|
||||
StringBuilder ret = new StringBuilder();
|
||||
ret.append("requestUri=");
|
||||
URI uri = session.getRequestURI();
|
||||
if (uri == null)
|
||||
{
|
||||
ret.append("=<null>");
|
||||
}
|
||||
else
|
||||
{
|
||||
ret.append(uri.toASCIIString());
|
||||
}
|
||||
session.getBasicRemote().sendText(ret.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
// simple echo
|
||||
session.getBasicRemote().sendText("echo:'" + message + "'");
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace(System.err);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,83 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.jsr356.server;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.websocket.OnMessage;
|
||||
import javax.websocket.Session;
|
||||
import javax.websocket.server.ServerEndpoint;
|
||||
|
||||
@ServerEndpoint(value = "/info/")
|
||||
public class SessionInfoSocket
|
||||
{
|
||||
@OnMessage
|
||||
public String onMessage(Session session, String message)
|
||||
{
|
||||
if ("pathParams".equalsIgnoreCase(message))
|
||||
{
|
||||
StringBuilder ret = new StringBuilder();
|
||||
ret.append("pathParams");
|
||||
Map<String, String> pathParams = session.getPathParameters();
|
||||
if (pathParams == null)
|
||||
{
|
||||
ret.append("=<null>");
|
||||
}
|
||||
else
|
||||
{
|
||||
ret.append('[').append(pathParams.size()).append(']');
|
||||
List<String> keys = new ArrayList<>();
|
||||
for (String key : pathParams.keySet())
|
||||
{
|
||||
keys.add(key);
|
||||
}
|
||||
Collections.sort(keys);
|
||||
for (String key : keys)
|
||||
{
|
||||
String value = pathParams.get(key);
|
||||
ret.append(": '").append(key).append("'=").append(value);
|
||||
}
|
||||
}
|
||||
return ret.toString();
|
||||
}
|
||||
|
||||
if ("requestUri".equalsIgnoreCase(message))
|
||||
{
|
||||
StringBuilder ret = new StringBuilder();
|
||||
ret.append("requestUri=");
|
||||
URI uri = session.getRequestURI();
|
||||
if (uri == null)
|
||||
{
|
||||
ret.append("=<null>");
|
||||
}
|
||||
else
|
||||
{
|
||||
ret.append(uri.toASCIIString());
|
||||
}
|
||||
return ret.toString();
|
||||
}
|
||||
|
||||
// simple echo
|
||||
return "echo:'" + message + "'";
|
||||
}
|
||||
}
|
|
@ -1,128 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.jsr356.server;
|
||||
|
||||
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.websocket.CloseReason;
|
||||
import javax.websocket.CloseReason.CloseCode;
|
||||
|
||||
import org.eclipse.jetty.toolchain.test.EventQueue;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.junit.Assert;
|
||||
|
||||
/**
|
||||
* Abstract base socket used for tracking state and events within the socket for testing reasons.
|
||||
*/
|
||||
public abstract class TrackingSocket
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(TrackingSocket.class);
|
||||
|
||||
public CloseReason closeReason;
|
||||
public EventQueue<String> eventQueue = new EventQueue<String>();
|
||||
public EventQueue<Throwable> errorQueue = new EventQueue<>();
|
||||
public CountDownLatch openLatch = new CountDownLatch(1);
|
||||
public CountDownLatch closeLatch = new CountDownLatch(1);
|
||||
public CountDownLatch dataLatch = new CountDownLatch(1);
|
||||
|
||||
protected void addError(Throwable t)
|
||||
{
|
||||
LOG.warn(t);
|
||||
errorQueue.add(t);
|
||||
}
|
||||
|
||||
protected void addEvent(String format, Object... args)
|
||||
{
|
||||
eventQueue.add(String.format(format,args));
|
||||
}
|
||||
|
||||
public void assertClose(CloseCode expectedCode, String expectedReason) throws InterruptedException
|
||||
{
|
||||
assertCloseCode(expectedCode);
|
||||
assertCloseReason(expectedReason);
|
||||
}
|
||||
|
||||
public void assertCloseCode(CloseCode expectedCode) throws InterruptedException
|
||||
{
|
||||
Assert.assertThat("Was Closed",closeLatch.await(50,TimeUnit.MILLISECONDS),is(true));
|
||||
Assert.assertThat("CloseReason",closeReason,notNullValue());
|
||||
Assert.assertThat("Close Code",closeReason.getCloseCode(),is(expectedCode));
|
||||
}
|
||||
|
||||
private void assertCloseReason(String expectedReason)
|
||||
{
|
||||
Assert.assertThat("Close Reason",closeReason.getReasonPhrase(),is(expectedReason));
|
||||
}
|
||||
|
||||
public void assertEvent(String expected)
|
||||
{
|
||||
String actual = eventQueue.poll();
|
||||
Assert.assertEquals("Event",expected,actual);
|
||||
}
|
||||
|
||||
public void assertIsOpen() throws InterruptedException
|
||||
{
|
||||
assertWasOpened();
|
||||
assertNotClosed();
|
||||
}
|
||||
|
||||
public void assertNotClosed()
|
||||
{
|
||||
Assert.assertThat("Closed Latch",closeLatch.getCount(),greaterThanOrEqualTo(1L));
|
||||
}
|
||||
|
||||
public void assertNotOpened()
|
||||
{
|
||||
Assert.assertThat("Open Latch",openLatch.getCount(),greaterThanOrEqualTo(1L));
|
||||
}
|
||||
|
||||
public void assertWasOpened() throws InterruptedException
|
||||
{
|
||||
Assert.assertThat("Was Opened",openLatch.await(30000,TimeUnit.MILLISECONDS),is(true));
|
||||
}
|
||||
|
||||
public void clear()
|
||||
{
|
||||
eventQueue.clear();
|
||||
errorQueue.clear();
|
||||
}
|
||||
|
||||
public void waitForClose(int timeoutDuration, TimeUnit timeoutUnit) throws InterruptedException
|
||||
{
|
||||
Assert.assertThat("Client Socket Closed",closeLatch.await(timeoutDuration,timeoutUnit),is(true));
|
||||
}
|
||||
|
||||
public void waitForConnected(int timeoutDuration, TimeUnit timeoutUnit) throws InterruptedException
|
||||
{
|
||||
Assert.assertThat("Client Socket Connected",openLatch.await(timeoutDuration,timeoutUnit),is(true));
|
||||
}
|
||||
|
||||
public void waitForData(int timeoutDuration, TimeUnit timeoutUnit) throws InterruptedException
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Waiting for message");
|
||||
Assert.assertThat("Data Received",dataLatch.await(timeoutDuration,timeoutUnit),is(true));
|
||||
}
|
||||
}
|
|
@ -1,203 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.jsr356.server;
|
||||
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Path;
|
||||
|
||||
import org.eclipse.jetty.annotations.AnnotationConfiguration;
|
||||
import org.eclipse.jetty.plus.webapp.EnvConfiguration;
|
||||
import org.eclipse.jetty.plus.webapp.PlusConfiguration;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.ServerConnector;
|
||||
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
|
||||
import org.eclipse.jetty.server.handler.HandlerCollection;
|
||||
import org.eclipse.jetty.toolchain.test.FS;
|
||||
import org.eclipse.jetty.toolchain.test.IO;
|
||||
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
||||
import org.eclipse.jetty.toolchain.test.TestingDir;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.util.resource.PathResource;
|
||||
import org.eclipse.jetty.webapp.Configuration;
|
||||
import org.eclipse.jetty.webapp.FragmentConfiguration;
|
||||
import org.eclipse.jetty.webapp.MetaInfConfiguration;
|
||||
import org.eclipse.jetty.webapp.WebAppContext;
|
||||
import org.eclipse.jetty.webapp.WebInfConfiguration;
|
||||
import org.eclipse.jetty.webapp.WebXmlConfiguration;
|
||||
import org.junit.Assert;
|
||||
|
||||
/**
|
||||
* Utility to build out exploded directory WebApps, in the /target/tests/ directory, for testing out servers that use javax.websocket endpoints.
|
||||
* <p>
|
||||
* This is particularly useful when the WebSocket endpoints are discovered via the javax.websocket annotation scanning.
|
||||
*/
|
||||
public class WSServer
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(WSServer.class);
|
||||
private final Path contextDir;
|
||||
private final String contextPath;
|
||||
private Server server;
|
||||
private URI serverUri;
|
||||
private ContextHandlerCollection contexts;
|
||||
private Path webinf;
|
||||
private Path classesDir;
|
||||
|
||||
public WSServer(TestingDir testdir, String contextName)
|
||||
{
|
||||
this(testdir.getPath(),contextName);
|
||||
}
|
||||
|
||||
public WSServer(Path testdir, String contextName)
|
||||
{
|
||||
this.contextDir = testdir.resolve(contextName);
|
||||
this.contextPath = "/" + contextName;
|
||||
FS.ensureEmpty(contextDir);
|
||||
}
|
||||
|
||||
public void copyClass(Class<?> clazz) throws Exception
|
||||
{
|
||||
ClassLoader cl = Thread.currentThread().getContextClassLoader();
|
||||
String endpointPath = clazz.getName().replace('.','/') + ".class";
|
||||
URL classUrl = cl.getResource(endpointPath);
|
||||
Assert.assertThat("Class URL for: " + clazz,classUrl,notNullValue());
|
||||
Path destFile = classesDir.resolve(endpointPath);
|
||||
FS.ensureDirExists(destFile.getParent());
|
||||
File srcFile = new File(classUrl.toURI());
|
||||
IO.copy(srcFile,destFile.toFile());
|
||||
}
|
||||
|
||||
public void copyEndpoint(Class<?> endpointClass) throws Exception
|
||||
{
|
||||
copyClass(endpointClass);
|
||||
}
|
||||
|
||||
public void copyWebInf(String testResourceName) throws IOException
|
||||
{
|
||||
webinf = contextDir.resolve("WEB-INF");
|
||||
FS.ensureDirExists(webinf);
|
||||
classesDir = webinf.resolve("classes");
|
||||
FS.ensureDirExists(classesDir);
|
||||
Path webxml = webinf.resolve("web.xml");
|
||||
File testWebXml = MavenTestingUtils.getTestResourceFile(testResourceName);
|
||||
IO.copy(testWebXml,webxml.toFile());
|
||||
}
|
||||
|
||||
public WebAppContext createWebAppContext() throws MalformedURLException, IOException
|
||||
{
|
||||
WebAppContext context = new WebAppContext();
|
||||
context.setContextPath(this.contextPath);
|
||||
context.setBaseResource(new PathResource(this.contextDir));
|
||||
context.setAttribute("org.eclipse.jetty.websocket.jsr356",Boolean.TRUE);
|
||||
|
||||
context.setConfigurations(new Configuration[] {
|
||||
new AnnotationConfiguration(),
|
||||
new WebXmlConfiguration(),
|
||||
new WebInfConfiguration(),
|
||||
new PlusConfiguration(),
|
||||
new MetaInfConfiguration(),
|
||||
new FragmentConfiguration(),
|
||||
new EnvConfiguration()});
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
public void createWebInf() throws IOException
|
||||
{
|
||||
copyWebInf("empty-web.xml");
|
||||
}
|
||||
|
||||
public void deployWebapp(WebAppContext webapp) throws Exception
|
||||
{
|
||||
contexts.addHandler(webapp);
|
||||
contexts.manage(webapp);
|
||||
webapp.setThrowUnavailableOnStartupException(true);
|
||||
webapp.start();
|
||||
if (LOG.isDebugEnabled())
|
||||
{
|
||||
webapp.dump(System.err);
|
||||
}
|
||||
}
|
||||
|
||||
public void dump()
|
||||
{
|
||||
server.dumpStdErr();
|
||||
}
|
||||
|
||||
public URI getServerBaseURI()
|
||||
{
|
||||
return serverUri;
|
||||
}
|
||||
|
||||
public Server getServer()
|
||||
{
|
||||
return server;
|
||||
}
|
||||
|
||||
public Path getWebAppDir()
|
||||
{
|
||||
return this.contextDir;
|
||||
}
|
||||
|
||||
public void start() throws Exception
|
||||
{
|
||||
server = new Server();
|
||||
ServerConnector connector = new ServerConnector(server);
|
||||
connector.setPort(0);
|
||||
server.addConnector(connector);
|
||||
|
||||
HandlerCollection handlers = new HandlerCollection();
|
||||
contexts = new ContextHandlerCollection();
|
||||
handlers.addHandler(contexts);
|
||||
server.setHandler(handlers);
|
||||
|
||||
server.start();
|
||||
|
||||
String host = connector.getHost();
|
||||
if (host == null)
|
||||
{
|
||||
host = "localhost";
|
||||
}
|
||||
int port = connector.getLocalPort();
|
||||
serverUri = new URI(String.format("ws://%s:%d%s/",host,port,contextPath));
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Server started on {}",serverUri);
|
||||
}
|
||||
|
||||
public void stop()
|
||||
{
|
||||
if (server != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
server.stop();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace(System.err);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<web-app
|
||||
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
|
||||
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
|
||||
version="3.1">
|
||||
|
||||
<context-param>
|
||||
<param-name>org.eclipse.jetty.websocket.jsr356.addDynamicFilter</param-name>
|
||||
<param-value>false</param-value>
|
||||
</context-param>
|
||||
|
||||
<filter>
|
||||
<filter-name>wsuf-test</filter-name>
|
||||
<filter-class>org.eclipse.jetty.websocket.server.WebSocketUpgradeFilter</filter-class>
|
||||
</filter>
|
||||
|
||||
<filter-mapping>
|
||||
<filter-name>wsuf-test</filter-name>
|
||||
<url-pattern>/echo/*</url-pattern>
|
||||
</filter-mapping>
|
||||
</web-app>
|
Binary file not shown.
Before Width: | Height: | Size: 132 KiB |
|
@ -1 +0,0 @@
|
|||
acaa0165afd6912984d96472fef9db9b72b45cd3 larger.png
|
Binary file not shown.
Before Width: | Height: | Size: 4.2 MiB |
|
@ -1 +0,0 @@
|
|||
96fadcd98ea76c0f7928dccd37f35c9a3518cde8 largest.jpg
|
Binary file not shown.
Before Width: | Height: | Size: 44 KiB |
|
@ -1 +0,0 @@
|
|||
c99b6ea3b589be24c91fc3d09e1d384d190892ae medium.png
|
Binary file not shown.
Before Width: | Height: | Size: 3.1 KiB |
|
@ -1 +0,0 @@
|
|||
7a1a94aff526a8271b67871c2a6461b8609ce5ae small.png
|
|
@ -1,8 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<web-app
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://java.sun.com/xml/ns/javaee"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
|
||||
metadata-complete="false"
|
||||
version="3.0">
|
||||
</web-app>
|
|
@ -1,12 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<web-app
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://java.sun.com/xml/ns/javaee"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
|
||||
metadata-complete="false"
|
||||
version="3.0">
|
||||
|
||||
<listener>
|
||||
<listener-class>org.eclipse.jetty.websocket.jsr356.server.samples.idletimeout.IdleTimeoutContextListener</listener-class>
|
||||
</listener>
|
||||
</web-app>
|
|
@ -35,13 +35,6 @@
|
|||
<artifactId>websocket-common</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.websocket</groupId>
|
||||
<artifactId>websocket-common</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<classifier>tests</classifier>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.toolchain</groupId>
|
||||
<artifactId>jetty-test-helper</artifactId>
|
||||
|
|
|
@ -29,12 +29,13 @@ import java.util.concurrent.TimeUnit;
|
|||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import org.eclipse.jetty.io.ByteBufferPool;
|
||||
import org.eclipse.jetty.io.MappedByteBufferPool;
|
||||
import org.eclipse.jetty.websocket.api.Session;
|
||||
import org.eclipse.jetty.websocket.api.WebSocketAdapter;
|
||||
import org.eclipse.jetty.websocket.client.ClientUpgradeRequest;
|
||||
import org.eclipse.jetty.websocket.client.WebSocketClient;
|
||||
import org.eclipse.jetty.websocket.common.OpCode;
|
||||
import org.eclipse.jetty.websocket.common.test.LeakTrackingBufferPoolRule;
|
||||
|
||||
/**
|
||||
* This is not a general purpose websocket client.
|
||||
|
@ -99,7 +100,7 @@ public class ClientDemo
|
|||
|
||||
private static final Random __random = new Random();
|
||||
|
||||
private static LeakTrackingBufferPoolRule bufferPool = new LeakTrackingBufferPoolRule("ClientDemo");
|
||||
private static ByteBufferPool bufferPool = new MappedByteBufferPool();
|
||||
|
||||
private final String _host;
|
||||
private final int _port;
|
||||
|
@ -256,7 +257,6 @@ public class ClientDemo
|
|||
|
||||
wsclient.stop();
|
||||
}
|
||||
bufferPool.assertNoLeaks();
|
||||
}
|
||||
|
||||
private static void usage(String[] args)
|
||||
|
|
|
@ -64,18 +64,6 @@
|
|||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>artifact-jars</id>
|
||||
<goals>
|
||||
<goal>test-jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.websocket.common.test;
|
||||
package org.eclipse.jetty.websocket.common;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.concurrent.Executor;
|
|
@ -1,32 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.io.http;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public interface HttpResponseHeaderParseListener
|
||||
{
|
||||
void addHeader(String name, String value);
|
||||
|
||||
void setRemainingBuffer(ByteBuffer copy);
|
||||
|
||||
void setStatusCode(int statusCode);
|
||||
|
||||
void setStatusReason(String statusReason);
|
||||
}
|
|
@ -1,145 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.io.http;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.Utf8LineParser;
|
||||
|
||||
/**
|
||||
* Responsible for reading UTF8 Response Header lines and parsing them into a provided UpgradeResponse object.
|
||||
*/
|
||||
public class HttpResponseHeaderParser
|
||||
{
|
||||
@SuppressWarnings("serial")
|
||||
public static class ParseException extends RuntimeException
|
||||
{
|
||||
public ParseException(String message)
|
||||
{
|
||||
super(message);
|
||||
}
|
||||
|
||||
public ParseException(String message, Throwable cause)
|
||||
{
|
||||
super(message,cause);
|
||||
}
|
||||
}
|
||||
|
||||
private enum State
|
||||
{
|
||||
STATUS_LINE,
|
||||
HEADER,
|
||||
END
|
||||
}
|
||||
|
||||
private static final Pattern PAT_HEADER = Pattern.compile("([^:]+):\\s*(.*)");
|
||||
private static final Pattern PAT_STATUS_LINE = Pattern.compile("^HTTP/1.[01]\\s+(\\d+)\\s+(.*)",Pattern.CASE_INSENSITIVE);
|
||||
|
||||
private final HttpResponseHeaderParseListener listener;
|
||||
private final Utf8LineParser lineParser;
|
||||
private State state;
|
||||
|
||||
public HttpResponseHeaderParser(HttpResponseHeaderParseListener listener)
|
||||
{
|
||||
this.listener = listener;
|
||||
this.lineParser = new Utf8LineParser();
|
||||
this.state = State.STATUS_LINE;
|
||||
}
|
||||
|
||||
public boolean isDone()
|
||||
{
|
||||
return (state == State.END);
|
||||
}
|
||||
|
||||
public HttpResponseHeaderParseListener parse(ByteBuffer buf) throws ParseException
|
||||
{
|
||||
while (!isDone() && (buf.remaining() > 0))
|
||||
{
|
||||
String line = lineParser.parse(buf);
|
||||
if (line != null)
|
||||
{
|
||||
if (parseHeader(line))
|
||||
{
|
||||
// Now finished with parsing the entire response header
|
||||
// Save the remaining bytes for WebSocket to process.
|
||||
|
||||
ByteBuffer copy = ByteBuffer.allocate(buf.remaining());
|
||||
BufferUtil.put(buf,copy);
|
||||
BufferUtil.flipToFlush(copy,0);
|
||||
this.listener.setRemainingBuffer(copy);
|
||||
return listener;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean parseHeader(String line) throws ParseException
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case STATUS_LINE:
|
||||
{
|
||||
Matcher mat = PAT_STATUS_LINE.matcher(line);
|
||||
if (!mat.matches())
|
||||
{
|
||||
throw new ParseException("Unexpected HTTP response status line [" + line + "]");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
listener.setStatusCode(Integer.parseInt(mat.group(1)));
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
throw new ParseException("Unexpected HTTP response status code",e);
|
||||
}
|
||||
listener.setStatusReason(mat.group(2));
|
||||
state = State.HEADER;
|
||||
break;
|
||||
}
|
||||
case HEADER:
|
||||
{
|
||||
if (StringUtil.isBlank(line))
|
||||
{
|
||||
state = State.END;
|
||||
return parseHeader(line);
|
||||
}
|
||||
|
||||
Matcher header = PAT_HEADER.matcher(line);
|
||||
if (header.matches())
|
||||
{
|
||||
String headerName = header.group(1);
|
||||
String headerValue = header.group(2);
|
||||
// do need to split header/value if comma delimited?
|
||||
listener.addHeader(headerName,headerValue);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case END:
|
||||
state = State.STATUS_LINE;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -273,6 +273,10 @@ public class UnorderedSignature
|
|||
}
|
||||
try
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
{
|
||||
LOG.debug("Invoking {}", method);
|
||||
}
|
||||
return method.invoke(obj, args);
|
||||
}
|
||||
catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e)
|
||||
|
|
|
@ -23,6 +23,24 @@ package org.eclipse.jetty.websocket.common.util;
|
|||
*/
|
||||
public final class TextUtil
|
||||
{
|
||||
/**
|
||||
* Create a hint of what the text is like.
|
||||
* <p>
|
||||
* Used by logging and error messages to get a hint of what the text is like.
|
||||
*
|
||||
* @param text
|
||||
* the text to abbreviate, quote, and generally give you a hint of what the value is.
|
||||
* @return the abbreviated text
|
||||
*/
|
||||
public static String quote(String text)
|
||||
{
|
||||
if (text == null)
|
||||
{
|
||||
return "<null>";
|
||||
}
|
||||
return '"' + text + '"';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a hint of what the text is like.
|
||||
* <p>
|
||||
|
|
|
@ -1,40 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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 examples;
|
||||
|
||||
import org.eclipse.jetty.websocket.api.Session;
|
||||
import org.eclipse.jetty.websocket.api.WebSocketAdapter;
|
||||
import org.eclipse.jetty.websocket.common.test.EventCapture;
|
||||
|
||||
public class AdapterConnectCloseSocket extends WebSocketAdapter
|
||||
{
|
||||
public EventCapture capture = new EventCapture();
|
||||
|
||||
@Override
|
||||
public void onWebSocketClose(int statusCode, String reason)
|
||||
{
|
||||
capture.add("onWebSocketClose(%d, %s)",statusCode,capture.q(reason));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWebSocketConnect(Session sess)
|
||||
{
|
||||
capture.add("onWebSocketConnect(%s)",sess);
|
||||
}
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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 examples;
|
||||
|
||||
import org.eclipse.jetty.websocket.api.Session;
|
||||
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose;
|
||||
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect;
|
||||
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketFrame;
|
||||
import org.eclipse.jetty.websocket.api.annotations.WebSocket;
|
||||
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
||||
import org.eclipse.jetty.websocket.common.test.EventCapture;
|
||||
|
||||
@WebSocket
|
||||
public class AnnotatedFramesSocket
|
||||
{
|
||||
public EventCapture capture = new EventCapture();
|
||||
|
||||
@OnWebSocketClose
|
||||
public void onClose(int statusCode, String reason)
|
||||
{
|
||||
capture.add("onClose(%d, %s)",statusCode,capture.q(reason));
|
||||
}
|
||||
|
||||
@OnWebSocketConnect
|
||||
public void onConnect(Session sess)
|
||||
{
|
||||
capture.add("onConnect(%s)",sess);
|
||||
}
|
||||
|
||||
@OnWebSocketFrame
|
||||
public void onFrame(Frame frame)
|
||||
{
|
||||
capture.add("onFrame(%s)",frame);
|
||||
}
|
||||
}
|
|
@ -1,79 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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 examples;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.Reader;
|
||||
|
||||
import org.eclipse.jetty.websocket.api.Session;
|
||||
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose;
|
||||
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect;
|
||||
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketFrame;
|
||||
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage;
|
||||
import org.eclipse.jetty.websocket.api.annotations.WebSocket;
|
||||
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
||||
import org.eclipse.jetty.websocket.common.test.EventCapture;
|
||||
|
||||
@WebSocket
|
||||
public class AnnotatedStreamingSocket
|
||||
{
|
||||
public EventCapture capture = new EventCapture();
|
||||
|
||||
@OnWebSocketClose
|
||||
public void onClose(int statusCode, String reason)
|
||||
{
|
||||
capture.add("onClose(%d, %s)",statusCode,capture.q(reason));
|
||||
}
|
||||
|
||||
@OnWebSocketConnect
|
||||
public void onConnect(Session sess)
|
||||
{
|
||||
capture.add("onConnect(%s)",sess);
|
||||
}
|
||||
|
||||
@OnWebSocketFrame
|
||||
public void onFrame(Frame frame)
|
||||
{
|
||||
}
|
||||
|
||||
// Binary
|
||||
@OnWebSocketMessage
|
||||
public void onMessage(byte buf[], int offset, int length)
|
||||
{
|
||||
}
|
||||
|
||||
// Binary
|
||||
@OnWebSocketMessage
|
||||
public void onMessage(InputStream stream)
|
||||
{
|
||||
}
|
||||
|
||||
// Text
|
||||
@OnWebSocketMessage
|
||||
public void onMessage(Reader stream)
|
||||
{
|
||||
}
|
||||
|
||||
// Text
|
||||
@OnWebSocketMessage
|
||||
public void onMessage(String message)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
|
@ -1,196 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.io.http;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
import static org.hamcrest.Matchers.nullValue;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jetty.toolchain.test.TestTracker;
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
|
||||
public class HttpResponseHeaderParserTest
|
||||
{
|
||||
@Rule
|
||||
public TestTracker tt = new TestTracker();
|
||||
|
||||
private void appendUtf8(ByteBuffer buf, String line)
|
||||
{
|
||||
buf.put(ByteBuffer.wrap(StringUtil.getUtf8Bytes(line)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseNotFound()
|
||||
{
|
||||
StringBuilder resp = new StringBuilder();
|
||||
resp.append("HTTP/1.1 404 Not Found\r\n");
|
||||
resp.append("Date: Fri, 26 Apr 2013 21:43:08 GMT\r\n");
|
||||
resp.append("Content-Type: text/html; charset=ISO-8859-1\r\n");
|
||||
resp.append("Cache-Control: must-revalidate,no-cache,no-store\r\n");
|
||||
resp.append("Content-Length: 38\r\n");
|
||||
resp.append("Server: Jetty(9.0.0.v20130308)\r\n");
|
||||
resp.append("\r\n");
|
||||
// and some body content
|
||||
resp.append("What you are looking for is not here\r\n");
|
||||
|
||||
ByteBuffer buf = BufferUtil.toBuffer(resp.toString(),StandardCharsets.UTF_8);
|
||||
|
||||
HttpResponseParseCapture capture = new HttpResponseParseCapture();
|
||||
HttpResponseHeaderParser parser = new HttpResponseHeaderParser(capture);
|
||||
assertThat("Parser.parse",parser.parse(buf),notNullValue());
|
||||
assertThat("Response.statusCode",capture.getStatusCode(),is(404));
|
||||
assertThat("Response.statusReason",capture.getStatusReason(),is("Not Found"));
|
||||
assertThat("Response.headers[Content-Length]",capture.getHeader("Content-Length"),is("38"));
|
||||
|
||||
assertThat("Response.remainingBuffer",capture.getRemainingBuffer().remaining(),is(38));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseRealWorldResponse()
|
||||
{
|
||||
// Arbitrary Http Response Headers seen in the wild.
|
||||
// Request URI -> https://ssl.google-analytics.com/__utm.gif
|
||||
List<String> expected = new ArrayList<>();
|
||||
expected.add("HTTP/1.0 200 OK");
|
||||
expected.add("Date: Thu, 09 Aug 2012 16:16:39 GMT");
|
||||
expected.add("Content-Length: 35");
|
||||
expected.add("X-Content-Type-Options: nosniff");
|
||||
expected.add("Pragma: no-cache");
|
||||
expected.add("Expires: Wed, 19 Apr 2000 11:43:00 GMT");
|
||||
expected.add("Last-Modified: Wed, 21 Jan 2004 19:51:30 GMT");
|
||||
expected.add("Content-Type: image/gif");
|
||||
expected.add("Cache-Control: private, no-cache, no-cache=Set-Cookie, proxy-revalidate");
|
||||
expected.add("Age: 518097");
|
||||
expected.add("Server: GFE/2.0");
|
||||
expected.add("Connection: Keep-Alive");
|
||||
expected.add("");
|
||||
|
||||
// Prepare Buffer
|
||||
ByteBuffer buf = ByteBuffer.allocate(512);
|
||||
for (String line : expected)
|
||||
{
|
||||
appendUtf8(buf,line + "\r\n");
|
||||
}
|
||||
|
||||
BufferUtil.flipToFlush(buf,0);
|
||||
|
||||
// Parse Buffer
|
||||
HttpResponseParseCapture capture = new HttpResponseParseCapture();
|
||||
HttpResponseHeaderParser parser = new HttpResponseHeaderParser(capture);
|
||||
assertThat("Parser.parse",parser.parse(buf),notNullValue());
|
||||
|
||||
Assert.assertThat("Response.statusCode",capture.getStatusCode(),is(200));
|
||||
Assert.assertThat("Response.statusReason",capture.getStatusReason(),is("OK"));
|
||||
|
||||
Assert.assertThat("Response.header[age]",capture.getHeader("age"),is("518097"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseRealWorldResponse_SmallBuffers()
|
||||
{
|
||||
// Arbitrary Http Response Headers seen in the wild.
|
||||
// Request URI -> https://ssl.google-analytics.com/__utm.gif
|
||||
List<String> expected = new ArrayList<>();
|
||||
expected.add("HTTP/1.0 200 OK");
|
||||
expected.add("Date: Thu, 09 Aug 2012 16:16:39 GMT");
|
||||
expected.add("Content-Length: 35");
|
||||
expected.add("X-Content-Type-Options: nosniff");
|
||||
expected.add("Pragma: no-cache");
|
||||
expected.add("Expires: Wed, 19 Apr 2000 11:43:00 GMT");
|
||||
expected.add("Last-Modified: Wed, 21 Jan 2004 19:51:30 GMT");
|
||||
expected.add("Content-Type: image/gif");
|
||||
expected.add("Cache-Control: private, no-cache, no-cache=Set-Cookie, proxy-revalidate");
|
||||
expected.add("Age: 518097");
|
||||
expected.add("Server: GFE/2.0");
|
||||
expected.add("Connection: Keep-Alive");
|
||||
expected.add("");
|
||||
|
||||
// Prepare Buffer
|
||||
ByteBuffer buf = ByteBuffer.allocate(512);
|
||||
for (String line : expected)
|
||||
{
|
||||
appendUtf8(buf,line + "\r\n");
|
||||
}
|
||||
BufferUtil.flipToFlush(buf,0);
|
||||
|
||||
// Prepare small buffers to simulate a slow read/fill/parse from the network
|
||||
ByteBuffer small1 = buf.slice();
|
||||
ByteBuffer small2 = buf.slice();
|
||||
ByteBuffer small3 = buf.slice();
|
||||
|
||||
small1.limit(50);
|
||||
small2.position(50);
|
||||
small2.limit(70);
|
||||
small3.position(70);
|
||||
|
||||
// Parse Buffer
|
||||
HttpResponseParseCapture capture = new HttpResponseParseCapture();
|
||||
HttpResponseHeaderParser parser = new HttpResponseHeaderParser(capture);
|
||||
assertThat("Parser.parse",parser.parse(buf),notNullValue());
|
||||
|
||||
// Parse small 1
|
||||
Assert.assertThat("Small 1",parser.parse(small1),nullValue());
|
||||
|
||||
// Parse small 2
|
||||
Assert.assertThat("Small 2",parser.parse(small2),nullValue());
|
||||
|
||||
// Parse small 3
|
||||
Assert.assertThat("Small 3",parser.parse(small3),notNullValue());
|
||||
|
||||
Assert.assertThat("Response.statusCode",capture.getStatusCode(),is(200));
|
||||
Assert.assertThat("Response.statusReason",capture.getStatusReason(),is("OK"));
|
||||
|
||||
Assert.assertThat("Response.header[age]",capture.getHeader("age"),is("518097"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseUpgrade()
|
||||
{
|
||||
// Example from RFC6455 - Section 1.2 (Protocol Overview)
|
||||
StringBuilder resp = new StringBuilder();
|
||||
resp.append("HTTP/1.1 101 Switching Protocols\r\n");
|
||||
resp.append("Upgrade: websocket\r\n");
|
||||
resp.append("Connection: Upgrade\r\n");
|
||||
resp.append("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n");
|
||||
resp.append("Sec-WebSocket-Protocol: chat\r\n");
|
||||
resp.append("\r\n");
|
||||
|
||||
ByteBuffer buf = BufferUtil.toBuffer(resp.toString(),StandardCharsets.UTF_8);
|
||||
|
||||
HttpResponseParseCapture capture = new HttpResponseParseCapture();
|
||||
HttpResponseHeaderParser parser = new HttpResponseHeaderParser(capture);
|
||||
assertThat("Parser.parse",parser.parse(buf),notNullValue());
|
||||
assertThat("Response.statusCode",capture.getStatusCode(),is(101));
|
||||
assertThat("Response.statusReason",capture.getStatusReason(),is("Switching Protocols"));
|
||||
assertThat("Response.headers[Upgrade]",capture.getHeader("Upgrade"),is("websocket"));
|
||||
assertThat("Response.headers[Connection]",capture.getHeader("Connection"),is("Upgrade"));
|
||||
|
||||
assertThat("Buffer.remaining",buf.remaining(),is(0));
|
||||
}
|
||||
}
|
|
@ -1,75 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.io.http;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
public class HttpResponseParseCapture implements HttpResponseHeaderParseListener
|
||||
{
|
||||
private int statusCode;
|
||||
private String statusReason;
|
||||
private Map<String, String> headers = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
|
||||
private ByteBuffer remainingBuffer;
|
||||
|
||||
@Override
|
||||
public void addHeader(String name, String value)
|
||||
{
|
||||
headers.put(name,value);
|
||||
}
|
||||
|
||||
public String getHeader(String name)
|
||||
{
|
||||
return headers.get(name);
|
||||
}
|
||||
|
||||
public ByteBuffer getRemainingBuffer()
|
||||
{
|
||||
return remainingBuffer;
|
||||
}
|
||||
|
||||
public int getStatusCode()
|
||||
{
|
||||
return statusCode;
|
||||
}
|
||||
|
||||
public String getStatusReason()
|
||||
{
|
||||
return statusReason;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRemainingBuffer(ByteBuffer copy)
|
||||
{
|
||||
this.remainingBuffer = copy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStatusCode(int code)
|
||||
{
|
||||
this.statusCode = code;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStatusReason(String reason)
|
||||
{
|
||||
this.statusReason = reason;
|
||||
}
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.message;
|
||||
|
||||
import org.eclipse.jetty.websocket.api.WebSocketAdapter;
|
||||
|
||||
/**
|
||||
* Do nothing Dummy Socket, used in testing.
|
||||
*/
|
||||
public class DummySocket extends WebSocketAdapter
|
||||
{
|
||||
/* intentionally empty */
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.message;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public class MessageDebug
|
||||
{
|
||||
public static String toDetailHint(byte[] data, int offset, int len)
|
||||
{
|
||||
StringBuilder buf = new StringBuilder();
|
||||
ByteBuffer buffer = ByteBuffer.wrap(data,offset,len);
|
||||
|
||||
buf.append("byte[").append(data.length);
|
||||
buf.append("](o=").append(offset);
|
||||
buf.append(",len=").append(len);
|
||||
|
||||
buf.append(")<<<");
|
||||
for (int i = buffer.position(); i < buffer.limit(); i++)
|
||||
{
|
||||
char c = (char)buffer.get(i);
|
||||
if ((c >= ' ') && (c <= 127))
|
||||
{
|
||||
buf.append(c);
|
||||
}
|
||||
else if ((c == '\r') || (c == '\n'))
|
||||
{
|
||||
buf.append('|');
|
||||
}
|
||||
else
|
||||
{
|
||||
buf.append('\ufffd');
|
||||
}
|
||||
if ((i == (buffer.position() + 16)) && (buffer.limit() > (buffer.position() + 32)))
|
||||
{
|
||||
buf.append("...");
|
||||
i = buffer.limit() - 16;
|
||||
}
|
||||
}
|
||||
buf.append(">>>");
|
||||
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
|
@ -1,112 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.message;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.jetty.toolchain.test.EventQueue;
|
||||
import org.eclipse.jetty.util.IO;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose;
|
||||
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketError;
|
||||
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage;
|
||||
import org.eclipse.jetty.websocket.api.annotations.WebSocket;
|
||||
import org.junit.Assert;
|
||||
|
||||
@WebSocket
|
||||
public class TrackingInputStreamSocket
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(TrackingInputStreamSocket.class);
|
||||
private final String id;
|
||||
public int closeCode = -1;
|
||||
public StringBuilder closeMessage = new StringBuilder();
|
||||
public CountDownLatch closeLatch = new CountDownLatch(1);
|
||||
public EventQueue<String> messageQueue = new EventQueue<>();
|
||||
public EventQueue<Throwable> errorQueue = new EventQueue<>();
|
||||
|
||||
public TrackingInputStreamSocket()
|
||||
{
|
||||
this("socket");
|
||||
}
|
||||
|
||||
public TrackingInputStreamSocket(String id)
|
||||
{
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public void assertClose(int expectedStatusCode, String expectedReason) throws InterruptedException
|
||||
{
|
||||
assertCloseCode(expectedStatusCode);
|
||||
assertCloseReason(expectedReason);
|
||||
}
|
||||
|
||||
public void assertCloseCode(int expectedCode) throws InterruptedException
|
||||
{
|
||||
Assert.assertThat("Was Closed",closeLatch.await(50,TimeUnit.MILLISECONDS),is(true));
|
||||
Assert.assertThat("Close Code",closeCode,is(expectedCode));
|
||||
}
|
||||
|
||||
private void assertCloseReason(String expectedReason)
|
||||
{
|
||||
Assert.assertThat("Close Reason",closeMessage.toString(),is(expectedReason));
|
||||
}
|
||||
|
||||
@OnWebSocketClose
|
||||
public void onClose(int statusCode, String reason)
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("{} onClose({},{})",id,statusCode,reason);
|
||||
closeCode = statusCode;
|
||||
closeMessage.append(reason);
|
||||
closeLatch.countDown();
|
||||
}
|
||||
|
||||
@OnWebSocketError
|
||||
public void onError(Throwable cause)
|
||||
{
|
||||
errorQueue.add(cause);
|
||||
}
|
||||
|
||||
@OnWebSocketMessage
|
||||
public void onInputStream(InputStream stream)
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("{} onInputStream({})",id,stream);
|
||||
try
|
||||
{
|
||||
String msg = IO.toString(stream);
|
||||
messageQueue.add(msg);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
errorQueue.add(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void waitForClose(int timeoutDuration, TimeUnit timeoutUnit) throws InterruptedException
|
||||
{
|
||||
Assert.assertThat("Client Socket Closed",closeLatch.await(timeoutDuration,timeoutUnit),is(true));
|
||||
}
|
||||
}
|
|
@ -1,183 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.message;
|
||||
|
||||
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.eclipse.jetty.toolchain.test.EventQueue;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.websocket.api.Session;
|
||||
import org.eclipse.jetty.websocket.api.WebSocketAdapter;
|
||||
import org.eclipse.jetty.websocket.common.test.EventCapture;
|
||||
import org.junit.Assert;
|
||||
|
||||
/**
|
||||
* Testing Socket used on client side WebSocket testing.
|
||||
*/
|
||||
public class TrackingSocket extends WebSocketAdapter
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(TrackingSocket.class);
|
||||
|
||||
private final String id;
|
||||
public int closeCode = -1;
|
||||
public StringBuilder closeMessage = new StringBuilder();
|
||||
public CountDownLatch openLatch = new CountDownLatch(1);
|
||||
public CountDownLatch closeLatch = new CountDownLatch(1);
|
||||
public CountDownLatch dataLatch = new CountDownLatch(1);
|
||||
public EventQueue<String> messageQueue = new EventQueue<>();
|
||||
public EventQueue<Throwable> errorQueue = new EventQueue<>();
|
||||
public EventCapture events = new EventCapture();
|
||||
|
||||
public TrackingSocket()
|
||||
{
|
||||
this("socket");
|
||||
}
|
||||
|
||||
public TrackingSocket(String id)
|
||||
{
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public void assertClose(int expectedStatusCode, String expectedReason) throws InterruptedException
|
||||
{
|
||||
assertCloseCode(expectedStatusCode);
|
||||
assertCloseReason(expectedReason);
|
||||
}
|
||||
|
||||
public void assertCloseCode(int expectedCode) throws InterruptedException
|
||||
{
|
||||
Assert.assertThat("Was Closed",closeLatch.await(50,TimeUnit.MILLISECONDS),is(true));
|
||||
Assert.assertThat("Close Code",closeCode,is(expectedCode));
|
||||
}
|
||||
|
||||
private void assertCloseReason(String expectedReason)
|
||||
{
|
||||
Assert.assertThat("Close Reason",closeMessage.toString(),is(expectedReason));
|
||||
}
|
||||
|
||||
public void assertIsOpen() throws InterruptedException
|
||||
{
|
||||
assertWasOpened();
|
||||
assertNotClosed();
|
||||
}
|
||||
|
||||
public void assertMessage(String expected)
|
||||
{
|
||||
String actual = messageQueue.poll();
|
||||
Assert.assertEquals("Message",expected,actual);
|
||||
}
|
||||
|
||||
public void assertNotClosed()
|
||||
{
|
||||
Assert.assertThat("Closed Latch",closeLatch.getCount(),greaterThanOrEqualTo(1L));
|
||||
}
|
||||
|
||||
public void assertNotOpened()
|
||||
{
|
||||
Assert.assertThat("Open Latch",openLatch.getCount(),greaterThanOrEqualTo(1L));
|
||||
}
|
||||
|
||||
public void assertWasOpened() throws InterruptedException
|
||||
{
|
||||
Assert.assertThat("Was Opened",openLatch.await(30,TimeUnit.SECONDS),is(true));
|
||||
}
|
||||
|
||||
public void awaitMessage(int expectedMessageCount, TimeUnit timeoutUnit, int timeoutDuration) throws TimeoutException, InterruptedException
|
||||
{
|
||||
messageQueue.awaitEventCount(expectedMessageCount,timeoutDuration,timeoutUnit);
|
||||
}
|
||||
|
||||
public void clear()
|
||||
{
|
||||
messageQueue.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWebSocketBinary(byte[] payload, int offset, int len)
|
||||
{
|
||||
LOG.debug("{} onWebSocketBinary(byte[{}],{},{})",id,payload.length,offset,len);
|
||||
events.add("onWebSocketBinary(byte[{}],{},{})",payload.length,offset,len);
|
||||
messageQueue.offer(MessageDebug.toDetailHint(payload,offset,len));
|
||||
dataLatch.countDown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWebSocketClose(int statusCode, String reason)
|
||||
{
|
||||
LOG.debug("{} onWebSocketClose({},{})",id,statusCode,reason);
|
||||
events.add("onWebSocketClose({},{})",statusCode,reason);
|
||||
super.onWebSocketClose(statusCode,reason);
|
||||
closeCode = statusCode;
|
||||
closeMessage.append(reason);
|
||||
closeLatch.countDown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWebSocketConnect(Session session)
|
||||
{
|
||||
events.add("onWebSocketConnect({})",session);
|
||||
super.onWebSocketConnect(session);
|
||||
openLatch.countDown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWebSocketError(Throwable cause)
|
||||
{
|
||||
LOG.debug("{} onWebSocketError",id,cause);
|
||||
events.add("onWebSocketError({})",cause);
|
||||
Assert.assertThat("Error capture",errorQueue.offer(cause),is(true));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWebSocketText(String message)
|
||||
{
|
||||
LOG.debug("{} onWebSocketText({})",id,message);
|
||||
events.add("onWebSocketText({})",message);
|
||||
messageQueue.offer(message);
|
||||
dataLatch.countDown();
|
||||
}
|
||||
|
||||
public void waitForClose(int timeoutDuration, TimeUnit timeoutUnit) throws InterruptedException
|
||||
{
|
||||
Assert.assertThat("Client Socket Closed",closeLatch.await(timeoutDuration,timeoutUnit),is(true));
|
||||
}
|
||||
|
||||
public void waitForConnected(int timeoutDuration, TimeUnit timeoutUnit) throws InterruptedException
|
||||
{
|
||||
Assert.assertThat("Client Socket Connected",openLatch.await(timeoutDuration,timeoutUnit),is(true));
|
||||
}
|
||||
|
||||
public void waitForMessage(int timeoutDuration, TimeUnit timeoutUnit) throws InterruptedException
|
||||
{
|
||||
LOG.debug("{} Waiting for message",id);
|
||||
Assert.assertThat("Message Received",dataLatch.await(timeoutDuration,timeoutUnit),is(true));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return String.format("TrackingSocket[%s]", id);
|
||||
}
|
||||
}
|
|
@ -1,110 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.test;
|
||||
|
||||
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.LinkedBlockingDeque;
|
||||
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
||||
import org.eclipse.jetty.websocket.common.OpCode;
|
||||
import org.eclipse.jetty.websocket.common.WebSocketFrame;
|
||||
import org.junit.Assert;
|
||||
|
||||
public abstract class AbstractFrameCapture
|
||||
{
|
||||
public BlockingQueue<WebSocketFrame> frames = new LinkedBlockingDeque<>();
|
||||
|
||||
public void assertFrameCount(int expectedCount)
|
||||
{
|
||||
if (frames.size() != expectedCount)
|
||||
{
|
||||
// dump details
|
||||
System.err.printf("Expected %d frame(s)%n",expectedCount);
|
||||
System.err.printf("But actually captured %d frame(s)%n",frames.size());
|
||||
int i = 0;
|
||||
for (Frame frame : frames)
|
||||
{
|
||||
System.err.printf(" [%d] Frame[%s] - %s%n", i++,
|
||||
OpCode.name(frame.getOpCode()),
|
||||
BufferUtil.toDetailString(frame.getPayload()));
|
||||
}
|
||||
}
|
||||
Assert.assertThat("Captured frame count",frames.size(),is(expectedCount));
|
||||
}
|
||||
|
||||
public void assertHasFrame(byte op)
|
||||
{
|
||||
Assert.assertThat(OpCode.name(op),getFrameCount(op),greaterThanOrEqualTo(1));
|
||||
}
|
||||
|
||||
public void assertHasFrame(byte op, int expectedCount)
|
||||
{
|
||||
String msg = String.format("%s frame count",OpCode.name(op));
|
||||
Assert.assertThat(msg,getFrameCount(op),is(expectedCount));
|
||||
}
|
||||
|
||||
public void assertHasNoFrames()
|
||||
{
|
||||
Assert.assertThat("Frame count",frames.size(),is(0));
|
||||
}
|
||||
|
||||
public void clear()
|
||||
{
|
||||
frames.clear();
|
||||
}
|
||||
|
||||
public void dump()
|
||||
{
|
||||
System.err.printf("Captured %d incoming frames%n",frames.size());
|
||||
int i = 0;
|
||||
for (Frame frame : frames)
|
||||
{
|
||||
System.err.printf("[%3d] %s%n",i++,frame);
|
||||
System.err.printf(" payload: %s%n",BufferUtil.toDetailString(frame.getPayload()));
|
||||
}
|
||||
}
|
||||
|
||||
public int getFrameCount(byte op)
|
||||
{
|
||||
int count = 0;
|
||||
for (WebSocketFrame frame : frames)
|
||||
{
|
||||
if (frame.getOpCode() == op)
|
||||
{
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
public Queue<WebSocketFrame> getFrames()
|
||||
{
|
||||
return frames;
|
||||
}
|
||||
|
||||
public int size()
|
||||
{
|
||||
return frames.size();
|
||||
}
|
||||
}
|
|
@ -1,69 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.test;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.nullValue;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
|
||||
public class ByteBufferAssert
|
||||
{
|
||||
public static void assertEquals(String message, byte[] expected, byte[] actual)
|
||||
{
|
||||
assertThat(message + " byte[].length",actual.length,is(expected.length));
|
||||
int len = expected.length;
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
assertThat(message + " byte[" + i + "]",actual[i],is(expected[i]));
|
||||
}
|
||||
}
|
||||
|
||||
public static void assertEquals(String message, ByteBuffer expectedBuffer, ByteBuffer actualBuffer)
|
||||
{
|
||||
if (expectedBuffer == null)
|
||||
{
|
||||
assertThat(message,actualBuffer,nullValue());
|
||||
}
|
||||
else
|
||||
{
|
||||
byte expectedBytes[] = BufferUtil.toArray(expectedBuffer);
|
||||
byte actualBytes[] = BufferUtil.toArray(actualBuffer);
|
||||
assertEquals(message,expectedBytes,actualBytes);
|
||||
}
|
||||
}
|
||||
|
||||
public static void assertEquals(String message, String expectedString, ByteBuffer actualBuffer)
|
||||
{
|
||||
String actualString = BufferUtil.toString(actualBuffer);
|
||||
assertThat(message,actualString,is(expectedString));
|
||||
}
|
||||
|
||||
public static void assertSize(String message, int expectedSize, ByteBuffer buffer)
|
||||
{
|
||||
if ((expectedSize == 0) && (buffer == null))
|
||||
{
|
||||
return;
|
||||
}
|
||||
assertThat(message + " buffer.remaining",buffer.remaining(),is(expectedSize));
|
||||
}
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.test;
|
||||
|
||||
import org.eclipse.jetty.websocket.api.annotations.WebSocket;
|
||||
|
||||
@WebSocket
|
||||
public class DummySocket
|
||||
{
|
||||
/* does nothing */
|
||||
}
|
|
@ -1,93 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.test;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.startsWith;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.eclipse.jetty.toolchain.test.EventQueue;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.junit.Assert;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class EventCapture extends EventQueue<String>
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(EventCapture.class);
|
||||
|
||||
public static class Assertable
|
||||
{
|
||||
private final String event;
|
||||
|
||||
public Assertable(String event)
|
||||
{
|
||||
this.event = event;
|
||||
}
|
||||
|
||||
public void assertEventContains(String expected)
|
||||
{
|
||||
Assert.assertThat("Event",event,containsString(expected));
|
||||
}
|
||||
|
||||
public void assertEventRegex(String regex)
|
||||
{
|
||||
Assert.assertTrue("Event: regex:[" + regex + "] in [" + event + "]",Pattern.matches(regex,event));
|
||||
}
|
||||
|
||||
public void assertEventStartsWith(String expected)
|
||||
{
|
||||
Assert.assertThat("Event",event,startsWith(expected));
|
||||
}
|
||||
|
||||
public void assertEvent(String expected)
|
||||
{
|
||||
Assert.assertThat("Event",event,is(expected));
|
||||
}
|
||||
}
|
||||
|
||||
public void add(String format, Object... args)
|
||||
{
|
||||
String msg = String.format(format,args);
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("EVENT: {}",msg);
|
||||
super.offer(msg);
|
||||
}
|
||||
|
||||
public Assertable pop()
|
||||
{
|
||||
return new Assertable(super.poll());
|
||||
}
|
||||
|
||||
public void assertEventCount(int expectedCount)
|
||||
{
|
||||
Assert.assertThat("Event Count",size(),is(expectedCount));
|
||||
}
|
||||
|
||||
public String q(String str)
|
||||
{
|
||||
if (str == null)
|
||||
{
|
||||
return "<null>";
|
||||
}
|
||||
return '"' + str + '"';
|
||||
}
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.test;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import org.eclipse.jetty.websocket.common.Generator;
|
||||
|
||||
public interface Fuzzed
|
||||
{
|
||||
URI getServerURI();
|
||||
|
||||
Generator getLaxGenerator();
|
||||
|
||||
String getTestMethodName();
|
||||
}
|
|
@ -1,94 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.test;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import org.eclipse.jetty.websocket.common.io.http.HttpResponseHeaderParseListener;
|
||||
|
||||
public class HttpResponse implements HttpResponseHeaderParseListener
|
||||
{
|
||||
private int statusCode;
|
||||
private String statusReason;
|
||||
private Map<String, String> headers = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
|
||||
private ByteBuffer remainingBuffer;
|
||||
|
||||
@Override
|
||||
public void addHeader(String name, String value)
|
||||
{
|
||||
headers.put(name,value);
|
||||
}
|
||||
|
||||
public String getExtensionsHeader()
|
||||
{
|
||||
return getHeader("Sec-WebSocket-Extensions");
|
||||
}
|
||||
|
||||
public String getHeader(String name)
|
||||
{
|
||||
return headers.get(name);
|
||||
}
|
||||
|
||||
public ByteBuffer getRemainingBuffer()
|
||||
{
|
||||
return remainingBuffer;
|
||||
}
|
||||
|
||||
public int getStatusCode()
|
||||
{
|
||||
return statusCode;
|
||||
}
|
||||
|
||||
public String getStatusReason()
|
||||
{
|
||||
return statusReason;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRemainingBuffer(ByteBuffer copy)
|
||||
{
|
||||
this.remainingBuffer = copy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStatusCode(int code)
|
||||
{
|
||||
this.statusCode = code;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStatusReason(String reason)
|
||||
{
|
||||
this.statusReason = reason;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
StringBuilder str = new StringBuilder();
|
||||
str.append("HTTP/1.1 ").append(statusCode).append(' ').append(statusReason);
|
||||
for (Map.Entry<String, String> entry : headers.entrySet())
|
||||
{
|
||||
str.append('\n').append(entry.getKey()).append(": ").append(entry.getValue());
|
||||
}
|
||||
return str.toString();
|
||||
}
|
||||
}
|
|
@ -1,61 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.test;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import org.eclipse.jetty.io.LeakTrackingByteBufferPool;
|
||||
import org.eclipse.jetty.io.MappedByteBufferPool;
|
||||
import org.junit.rules.TestRule;
|
||||
import org.junit.runner.Description;
|
||||
import org.junit.runners.model.Statement;
|
||||
|
||||
public class LeakTrackingBufferPoolRule extends LeakTrackingByteBufferPool implements TestRule
|
||||
{
|
||||
private final String id;
|
||||
|
||||
public LeakTrackingBufferPoolRule(String id)
|
||||
{
|
||||
super(new MappedByteBufferPool.Tagged());
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public void assertNoLeaks()
|
||||
{
|
||||
assertThat("Leaked Acquires Count for [" + id + "]",getLeakedAcquires(),is(0L));
|
||||
assertThat("Leaked Releases Count for [" + id + "]",getLeakedReleases(),is(0L));
|
||||
assertThat("Leaked Resource Count for [" + id + "]", getLeakedResources(),is(0L));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Statement apply(final Statement statement, Description description)
|
||||
{
|
||||
return new Statement()
|
||||
{
|
||||
@Override
|
||||
public void evaluate() throws Throwable
|
||||
{
|
||||
clearTracking();
|
||||
statement.evaluate();
|
||||
assertNoLeaks();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.test;
|
||||
|
||||
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
||||
import org.eclipse.jetty.websocket.common.Parser;
|
||||
import org.eclipse.jetty.websocket.common.WebSocketFrame;
|
||||
|
||||
public class ParserCapture extends AbstractFrameCapture implements Parser.Handler
|
||||
{
|
||||
@Override
|
||||
public boolean onFrame(Frame frame)
|
||||
{
|
||||
WebSocketFrame copy = WebSocketFrame.copy(frame);
|
||||
frames.add(copy);
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -1,110 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.test;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.junit.Assert;
|
||||
|
||||
public class RawFrameBuilder
|
||||
{
|
||||
public static void putOpFin(ByteBuffer buf, byte opcode, boolean fin)
|
||||
{
|
||||
byte b = 0x00;
|
||||
if (fin)
|
||||
{
|
||||
b |= 0x80;
|
||||
}
|
||||
b |= opcode & 0x0F;
|
||||
buf.put(b);
|
||||
}
|
||||
|
||||
public static void putLengthAndMask(ByteBuffer buf, int length, byte mask[])
|
||||
{
|
||||
if (mask != null)
|
||||
{
|
||||
Assert.assertThat("Mask.length",mask.length,is(4));
|
||||
putLength(buf,length,(mask != null));
|
||||
buf.put(mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
putLength(buf,length,false);
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] mask(final byte[] data, final byte mask[])
|
||||
{
|
||||
Assert.assertThat("Mask.length",mask.length,is(4));
|
||||
int len = data.length;
|
||||
byte ret[] = new byte[len];
|
||||
System.arraycopy(data,0,ret,0,len);
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
ret[i] ^= mask[i % 4];
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static void putLength(ByteBuffer buf, int length, boolean masked)
|
||||
{
|
||||
if (length < 0)
|
||||
{
|
||||
throw new IllegalArgumentException("Length cannot be negative");
|
||||
}
|
||||
byte b = (masked?(byte)0x80:0x00);
|
||||
|
||||
// write the uncompressed length
|
||||
if (length > 0xFF_FF)
|
||||
{
|
||||
buf.put((byte)(b | 0x7F));
|
||||
buf.put((byte)0x00);
|
||||
buf.put((byte)0x00);
|
||||
buf.put((byte)0x00);
|
||||
buf.put((byte)0x00);
|
||||
buf.put((byte)((length >> 24) & 0xFF));
|
||||
buf.put((byte)((length >> 16) & 0xFF));
|
||||
buf.put((byte)((length >> 8) & 0xFF));
|
||||
buf.put((byte)(length & 0xFF));
|
||||
}
|
||||
else if (length >= 0x7E)
|
||||
{
|
||||
buf.put((byte)(b | 0x7E));
|
||||
buf.put((byte)(length >> 8));
|
||||
buf.put((byte)(length & 0xFF));
|
||||
}
|
||||
else
|
||||
{
|
||||
buf.put((byte)(b | length));
|
||||
}
|
||||
}
|
||||
|
||||
public static void putMask(ByteBuffer buf, byte mask[])
|
||||
{
|
||||
Assert.assertThat("Mask.length",mask.length,is(4));
|
||||
buf.put(mask);
|
||||
}
|
||||
|
||||
public static void putPayloadLength(ByteBuffer buf, int length)
|
||||
{
|
||||
putLength(buf,length,true);
|
||||
}
|
||||
}
|
|
@ -1,136 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.test;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jetty.io.ByteBufferPool;
|
||||
import org.eclipse.jetty.io.LeakTrackingByteBufferPool;
|
||||
import org.eclipse.jetty.io.MappedByteBufferPool;
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
||||
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
||||
import org.eclipse.jetty.websocket.common.Generator;
|
||||
import org.eclipse.jetty.websocket.common.WebSocketFrame;
|
||||
|
||||
/**
|
||||
* Convenience Generator.
|
||||
*/
|
||||
public class UnitGenerator extends Generator
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(UnitGenerator.class);
|
||||
|
||||
public static ByteBuffer generate(Frame frame)
|
||||
{
|
||||
return generate(new Frame[]
|
||||
{ frame });
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate All Frames into a single ByteBuffer.
|
||||
* <p>
|
||||
* This is highly inefficient and is not used in production! (This exists to make testing of the Generator easier)
|
||||
*
|
||||
* @param frames
|
||||
* the frames to generate from
|
||||
* @return the ByteBuffer representing all of the generated frames provided.
|
||||
*/
|
||||
public static ByteBuffer generate(Frame[] frames)
|
||||
{
|
||||
Generator generator = new UnitGenerator();
|
||||
|
||||
// Generate into single bytebuffer
|
||||
int buflen = 0;
|
||||
for (Frame f : frames)
|
||||
{
|
||||
buflen += f.getPayloadLength() + Generator.MAX_HEADER_LENGTH;
|
||||
}
|
||||
ByteBuffer completeBuf = ByteBuffer.allocate(buflen);
|
||||
BufferUtil.clearToFill(completeBuf);
|
||||
|
||||
// Generate frames
|
||||
for (Frame f : frames)
|
||||
{
|
||||
generator.generateWholeFrame(f,completeBuf);
|
||||
}
|
||||
|
||||
BufferUtil.flipToFlush(completeBuf,0);
|
||||
if (LOG.isDebugEnabled())
|
||||
{
|
||||
LOG.debug("generate({} frames) - {}",frames.length,BufferUtil.toDetailString(completeBuf));
|
||||
}
|
||||
return completeBuf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a single giant buffer of all provided frames Not appropriate for production code, but useful for testing.
|
||||
* @param frames the list of frames to generate from
|
||||
* @return the bytebuffer representing all of the generated frames
|
||||
*/
|
||||
public static ByteBuffer generate(List<WebSocketFrame> frames)
|
||||
{
|
||||
// Create non-symmetrical mask (helps show mask bytes order issues)
|
||||
byte[] MASK =
|
||||
{ 0x11, 0x22, 0x33, 0x44 };
|
||||
|
||||
// the generator
|
||||
Generator generator = new UnitGenerator();
|
||||
|
||||
// Generate into single bytebuffer
|
||||
int buflen = 0;
|
||||
for (Frame f : frames)
|
||||
{
|
||||
buflen += f.getPayloadLength() + Generator.MAX_HEADER_LENGTH;
|
||||
}
|
||||
ByteBuffer completeBuf = ByteBuffer.allocate(buflen);
|
||||
BufferUtil.clearToFill(completeBuf);
|
||||
|
||||
// Generate frames
|
||||
for (WebSocketFrame f : frames)
|
||||
{
|
||||
f.setMask(MASK); // make sure we have the test mask set
|
||||
BufferUtil.put(generator.generateHeaderBytes(f),completeBuf);
|
||||
ByteBuffer window = f.getPayload();
|
||||
if (BufferUtil.hasContent(window))
|
||||
{
|
||||
BufferUtil.put(window,completeBuf);
|
||||
}
|
||||
}
|
||||
|
||||
BufferUtil.flipToFlush(completeBuf,0);
|
||||
if (LOG.isDebugEnabled())
|
||||
{
|
||||
LOG.debug("generate({} frames) - {}",frames.size(),BufferUtil.toDetailString(completeBuf));
|
||||
}
|
||||
return completeBuf;
|
||||
}
|
||||
|
||||
public UnitGenerator()
|
||||
{
|
||||
super(WebSocketPolicy.newServerPolicy(),new LeakTrackingByteBufferPool(new MappedByteBufferPool.Tagged()));
|
||||
}
|
||||
|
||||
public UnitGenerator(ByteBufferPool bufferPool)
|
||||
{
|
||||
super(WebSocketPolicy.newServerPolicy(),bufferPool);
|
||||
}
|
||||
}
|
|
@ -1,70 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.test;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.eclipse.jetty.io.LeakTrackingByteBufferPool;
|
||||
import org.eclipse.jetty.io.MappedByteBufferPool;
|
||||
import org.eclipse.jetty.util.log.StacklessLogging;
|
||||
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
||||
import org.eclipse.jetty.websocket.common.Parser;
|
||||
|
||||
public class UnitParser extends Parser
|
||||
{
|
||||
public UnitParser(WebSocketPolicy policy, Parser.Handler handler)
|
||||
{
|
||||
super(policy,new LeakTrackingByteBufferPool(new MappedByteBufferPool.Tagged()),handler);
|
||||
}
|
||||
|
||||
private void parsePartial(ByteBuffer buf, int numBytes)
|
||||
{
|
||||
int len = Math.min(numBytes,buf.remaining());
|
||||
byte arr[] = new byte[len];
|
||||
buf.get(arr,0,len);
|
||||
this.parse(ByteBuffer.wrap(arr));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a buffer, but do so in a quiet fashion, squelching stacktraces if encountered.
|
||||
* <p>
|
||||
* Use if you know the parse will cause an exception and just don't wnat to make the test console all noisy.
|
||||
* @param buf the buffer to parse
|
||||
*/
|
||||
@Deprecated
|
||||
public void parseQuietly(ByteBuffer buf)
|
||||
{
|
||||
try (StacklessLogging ignored = new StacklessLogging(Parser.class))
|
||||
{
|
||||
parse(buf);
|
||||
}
|
||||
catch (Exception ignore)
|
||||
{
|
||||
/* ignore */
|
||||
}
|
||||
}
|
||||
|
||||
public void parseSlowly(ByteBuffer buf, int segmentSize)
|
||||
{
|
||||
while (buf.remaining() > 0)
|
||||
{
|
||||
parsePartial(buf,segmentSize);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,111 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.util;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.security.DigestOutputStream;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.eclipse.jetty.toolchain.test.Hex;
|
||||
import org.eclipse.jetty.toolchain.test.IO;
|
||||
import org.junit.Assert;
|
||||
|
||||
/**
|
||||
* Calculate the sha1sum for various content
|
||||
*/
|
||||
public class Sha1Sum
|
||||
{
|
||||
private static class NoOpOutputStream extends OutputStream
|
||||
{
|
||||
@Override
|
||||
public void write(byte[] b) throws IOException
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(byte[] b, int off, int len) throws IOException
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() throws IOException
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(int b) throws IOException
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public static String calculate(File file) throws NoSuchAlgorithmException, IOException
|
||||
{
|
||||
return calculate(file.toPath());
|
||||
}
|
||||
|
||||
public static String calculate(Path path) throws NoSuchAlgorithmException, IOException
|
||||
{
|
||||
MessageDigest digest = MessageDigest.getInstance("SHA1");
|
||||
try (InputStream in = Files.newInputStream(path,StandardOpenOption.READ);
|
||||
NoOpOutputStream noop = new NoOpOutputStream();
|
||||
DigestOutputStream digester = new DigestOutputStream(noop,digest))
|
||||
{
|
||||
IO.copy(in,digester);
|
||||
return Hex.asHex(digest.digest());
|
||||
}
|
||||
}
|
||||
|
||||
public static String calculate(byte[] buf) throws NoSuchAlgorithmException
|
||||
{
|
||||
MessageDigest digest = MessageDigest.getInstance("SHA1");
|
||||
digest.update(buf);
|
||||
return Hex.asHex(digest.digest());
|
||||
}
|
||||
|
||||
public static String calculate(byte[] buf, int offset, int len) throws NoSuchAlgorithmException
|
||||
{
|
||||
MessageDigest digest = MessageDigest.getInstance("SHA1");
|
||||
digest.update(buf,offset,len);
|
||||
return Hex.asHex(digest.digest());
|
||||
}
|
||||
|
||||
public static String loadSha1(File sha1File) throws IOException
|
||||
{
|
||||
String contents = IO.readToString(sha1File);
|
||||
Pattern pat = Pattern.compile("^[0-9A-Fa-f]*");
|
||||
Matcher mat = pat.matcher(contents);
|
||||
Assert.assertTrue("Should have found HEX code in SHA1 file: " + sha1File,mat.find());
|
||||
return mat.group();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog
|
||||
org.eclipse.jetty.LEVEL=WARN
|
||||
# org.eclipse.jetty.websocket.LEVEL=DEBUG
|
||||
# org.eclipse.jetty.websocket.protocol.Parser.LEVEL=DEBUG
|
||||
# org.eclipse.jetty.websocket.protocol.LEVEL=DEBUG
|
||||
# org.eclipse.jetty.websocket.io.payload.LEVEL=DEBUG
|
||||
# org.eclipse.jetty.websocket.common.extensions.LEVEL=DEBUG
|
||||
# org.eclipse.jetty.websocket.common.message.LEVEL=DEBUG
|
||||
# org.eclipse.jetty.websocket.common.WebSocketSession.LEVEL=DEBUG
|
||||
# org.eclipse.jetty.websocket.common.function.LEVEL=DEBUG
|
|
@ -14,23 +14,6 @@
|
|||
<bundle-symbolic-name>${project.groupId}.server</bundle-symbolic-name>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>test-jar</id>
|
||||
<goals>
|
||||
<goal>test-jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.websocket</groupId>
|
||||
|
@ -80,13 +63,6 @@
|
|||
<version>${project.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.websocket</groupId>
|
||||
<artifactId>websocket-common</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<classifier>tests</classifier>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.toolchain</groupId>
|
||||
<artifactId>jetty-test-helper</artifactId>
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.websocket.server.browser;
|
||||
package examples;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
|
@ -16,7 +16,7 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.websocket.server.browser;
|
||||
package examples;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
|
@ -1,51 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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.server;
|
||||
|
||||
import javax.servlet.ServletContextEvent;
|
||||
import javax.servlet.ServletContextListener;
|
||||
|
||||
import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest;
|
||||
import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse;
|
||||
import org.eclipse.jetty.websocket.servlet.WebSocketCreator;
|
||||
|
||||
public class InfoContextAltAttributeListener implements WebSocketCreator, ServletContextListener
|
||||
{
|
||||
private static final String ATTR = "alt.config";
|
||||
|
||||
@Override
|
||||
public void contextInitialized(ServletContextEvent sce)
|
||||
{
|
||||
NativeWebSocketConfiguration configuration = new NativeWebSocketConfiguration(sce.getServletContext());
|
||||
configuration.getFactory().getPolicy().setMaxTextMessageSize(10 * 1024 * 1024);
|
||||
configuration.addMapping("/info/*", this);
|
||||
sce.getServletContext().setAttribute(ATTR, configuration);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contextDestroyed(ServletContextEvent sce)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createWebSocket(ServletUpgradeRequest req, ServletUpgradeResponse resp)
|
||||
{
|
||||
return new InfoSocket();
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue