Merge branch 'master' into javawebsocket-jsr
Conflicts: jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/TomcatServerQuirksTest.java
This commit is contained in:
commit
931cfa10ce
|
@ -48,25 +48,18 @@ import static org.junit.Assert.assertThat;
|
||||||
*/
|
*/
|
||||||
public class HostnameVerificationTest
|
public class HostnameVerificationTest
|
||||||
{
|
{
|
||||||
private SslContextFactory sslContextFactory = new SslContextFactory();
|
private SslContextFactory clientSslContextFactory = new SslContextFactory();
|
||||||
private Server server;
|
private Server server = new Server();
|
||||||
private HttpClient client;
|
private HttpClient client;
|
||||||
private NetworkConnector connector;
|
private NetworkConnector connector;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception
|
public void setUp() throws Exception
|
||||||
{
|
{
|
||||||
if (sslContextFactory != null)
|
SslContextFactory serverSslContextFactory = new SslContextFactory();
|
||||||
{
|
serverSslContextFactory.setKeyStorePath("src/test/resources/keystore.jks");
|
||||||
// keystore contains a hostname which doesn't match localhost
|
serverSslContextFactory.setKeyStorePassword("storepwd");
|
||||||
sslContextFactory.setKeyStorePath("src/test/resources/keystore.jks");
|
connector = new ServerConnector(server, serverSslContextFactory);
|
||||||
sslContextFactory.setKeyStorePassword("storepwd");
|
|
||||||
}
|
|
||||||
sslContextFactory.setEndpointIdentificationAlgorithm("HTTPS");
|
|
||||||
|
|
||||||
if (server == null)
|
|
||||||
server = new Server();
|
|
||||||
connector = new ServerConnector(server, sslContextFactory);
|
|
||||||
server.addConnector(connector);
|
server.addConnector(connector);
|
||||||
server.setHandler(new DefaultHandler()
|
server.setHandler(new DefaultHandler()
|
||||||
{
|
{
|
||||||
|
@ -79,9 +72,13 @@ public class HostnameVerificationTest
|
||||||
});
|
});
|
||||||
server.start();
|
server.start();
|
||||||
|
|
||||||
|
// keystore contains a hostname which doesn't match localhost
|
||||||
|
clientSslContextFactory.setKeyStorePath("src/test/resources/keystore.jks");
|
||||||
|
clientSslContextFactory.setKeyStorePassword("storepwd");
|
||||||
|
|
||||||
QueuedThreadPool executor = new QueuedThreadPool();
|
QueuedThreadPool executor = new QueuedThreadPool();
|
||||||
executor.setName(executor.getName() + "-client");
|
executor.setName(executor.getName() + "-client");
|
||||||
client = new HttpClient(sslContextFactory);
|
client = new HttpClient(clientSslContextFactory);
|
||||||
client.setExecutor(executor);
|
client.setExecutor(executor);
|
||||||
client.start();
|
client.start();
|
||||||
}
|
}
|
||||||
|
@ -104,6 +101,7 @@ public class HostnameVerificationTest
|
||||||
@Test
|
@Test
|
||||||
public void simpleGetWithHostnameVerificationEnabledTest() throws Exception
|
public void simpleGetWithHostnameVerificationEnabledTest() throws Exception
|
||||||
{
|
{
|
||||||
|
clientSslContextFactory.setEndpointIdentificationAlgorithm("HTTPS");
|
||||||
String uri = "https://localhost:" + connector.getLocalPort() + "/";
|
String uri = "https://localhost:" + connector.getLocalPort() + "/";
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -136,7 +134,7 @@ public class HostnameVerificationTest
|
||||||
@Test
|
@Test
|
||||||
public void simpleGetWithHostnameVerificationDisabledTest() throws Exception
|
public void simpleGetWithHostnameVerificationDisabledTest() throws Exception
|
||||||
{
|
{
|
||||||
sslContextFactory.setEndpointIdentificationAlgorithm(null);
|
clientSslContextFactory.setEndpointIdentificationAlgorithm(null);
|
||||||
String uri = "https://localhost:" + connector.getLocalPort() + "/";
|
String uri = "https://localhost:" + connector.getLocalPort() + "/";
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -157,7 +155,7 @@ public class HostnameVerificationTest
|
||||||
@Test
|
@Test
|
||||||
public void trustAllDisablesHostnameVerificationTest() throws Exception
|
public void trustAllDisablesHostnameVerificationTest() throws Exception
|
||||||
{
|
{
|
||||||
sslContextFactory.setTrustAll(true);
|
clientSslContextFactory.setTrustAll(true);
|
||||||
String uri = "https://localhost:" + connector.getLocalPort() + "/";
|
String uri = "https://localhost:" + connector.getLocalPort() + "/";
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
|
@ -37,7 +37,7 @@ import javax.servlet.ServletResponseWrapper;
|
||||||
* when it detects that the application has been deployed in a non-jetty Servlet 3
|
* when it detects that the application has been deployed in a non-jetty Servlet 3
|
||||||
* server.
|
* server.
|
||||||
*/
|
*/
|
||||||
public class Servlet3Continuation implements Continuation
|
public class Servlet3Continuation implements Continuation, AsyncListener
|
||||||
{
|
{
|
||||||
// Exception reused for all continuations
|
// Exception reused for all continuations
|
||||||
// Turn on debug in ContinuationFilter to see real stack trace.
|
// Turn on debug in ContinuationFilter to see real stack trace.
|
||||||
|
@ -46,7 +46,7 @@ public class Servlet3Continuation implements Continuation
|
||||||
private final ServletRequest _request;
|
private final ServletRequest _request;
|
||||||
private ServletResponse _response;
|
private ServletResponse _response;
|
||||||
private AsyncContext _context;
|
private AsyncContext _context;
|
||||||
private final List<AsyncListener> _listeners=new ArrayList<AsyncListener>();
|
private final List<ContinuationListener> _listeners=new ArrayList<ContinuationListener>();
|
||||||
private volatile boolean _initial=true;
|
private volatile boolean _initial=true;
|
||||||
private volatile boolean _resumed=false;
|
private volatile boolean _resumed=false;
|
||||||
private volatile boolean _expired=false;
|
private volatile boolean _expired=false;
|
||||||
|
@ -58,70 +58,13 @@ public class Servlet3Continuation implements Continuation
|
||||||
public Servlet3Continuation(ServletRequest request)
|
public Servlet3Continuation(ServletRequest request)
|
||||||
{
|
{
|
||||||
_request=request;
|
_request=request;
|
||||||
|
|
||||||
_listeners.add(new AsyncListener()
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void onComplete(AsyncEvent event) throws IOException
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onError(AsyncEvent event) throws IOException
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStartAsync(AsyncEvent event) throws IOException
|
|
||||||
{
|
|
||||||
event.getAsyncContext().addListener(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onTimeout(AsyncEvent event) throws IOException
|
|
||||||
{
|
|
||||||
_initial=false;
|
|
||||||
event.getAsyncContext().dispatch();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
@Override
|
@Override
|
||||||
public void addContinuationListener(final ContinuationListener listener)
|
public void addContinuationListener(final ContinuationListener listener)
|
||||||
{
|
{
|
||||||
AsyncListener wrapped = new AsyncListener()
|
_listeners.add(listener);
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void onComplete(final AsyncEvent event) throws IOException
|
|
||||||
{
|
|
||||||
listener.onComplete(Servlet3Continuation.this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onError(AsyncEvent event) throws IOException
|
|
||||||
{
|
|
||||||
listener.onComplete(Servlet3Continuation.this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStartAsync(AsyncEvent event) throws IOException
|
|
||||||
{
|
|
||||||
event.getAsyncContext().addListener(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onTimeout(AsyncEvent event) throws IOException
|
|
||||||
{
|
|
||||||
_expired=true;
|
|
||||||
listener.onTimeout(Servlet3Continuation.this);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (_context!=null)
|
|
||||||
_context.addListener(wrapped);
|
|
||||||
else
|
|
||||||
_listeners.add(wrapped);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
|
@ -215,10 +158,7 @@ public class Servlet3Continuation implements Continuation
|
||||||
_expired=false;
|
_expired=false;
|
||||||
_context=_request.startAsync();
|
_context=_request.startAsync();
|
||||||
_context.setTimeout(_timeoutMs);
|
_context.setTimeout(_timeoutMs);
|
||||||
|
_context.addListener(this);
|
||||||
for (AsyncListener listener:_listeners)
|
|
||||||
_context.addListener(listener);
|
|
||||||
_listeners.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
|
@ -229,10 +169,7 @@ public class Servlet3Continuation implements Continuation
|
||||||
_expired=false;
|
_expired=false;
|
||||||
_context=_request.startAsync();
|
_context=_request.startAsync();
|
||||||
_context.setTimeout(_timeoutMs);
|
_context.setTimeout(_timeoutMs);
|
||||||
|
_context.addListener(this);
|
||||||
for (AsyncListener listener:_listeners)
|
|
||||||
_context.addListener(listener);
|
|
||||||
_listeners.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
|
@ -287,4 +224,38 @@ public class Servlet3Continuation implements Continuation
|
||||||
}
|
}
|
||||||
throw new IllegalStateException("!suspended");
|
throw new IllegalStateException("!suspended");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
@Override
|
||||||
|
public void onComplete(AsyncEvent event) throws IOException
|
||||||
|
{
|
||||||
|
for (ContinuationListener listener:_listeners)
|
||||||
|
listener.onComplete(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
@Override
|
||||||
|
public void onError(AsyncEvent event) throws IOException
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
@Override
|
||||||
|
public void onStartAsync(AsyncEvent event) throws IOException
|
||||||
|
{
|
||||||
|
_initial=false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
@Override
|
||||||
|
public void onTimeout(AsyncEvent event) throws IOException
|
||||||
|
{
|
||||||
|
_initial=false;
|
||||||
|
_expired=true;
|
||||||
|
for (ContinuationListener listener:_listeners)
|
||||||
|
listener.onTimeout(this);
|
||||||
|
if (event.getSuppliedRequest().isAsyncStarted())
|
||||||
|
event.getAsyncContext().dispatch();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,8 +34,6 @@ public interface PushStrategy
|
||||||
/**
|
/**
|
||||||
* <p>Applies the SPDY push logic for the primary resource.</p>
|
* <p>Applies the SPDY push logic for the primary resource.</p>
|
||||||
*
|
*
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param stream the primary resource stream
|
* @param stream the primary resource stream
|
||||||
* @param requestHeaders the primary resource request headers
|
* @param requestHeaders the primary resource request headers
|
||||||
* @param responseHeaders the primary resource response headers
|
* @param responseHeaders the primary resource response headers
|
||||||
|
|
|
@ -38,21 +38,21 @@ import org.eclipse.jetty.util.log.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>A SPDY push strategy that auto-populates push metadata based on referrer URLs.</p> <p>A typical request for a main
|
* <p>A SPDY push strategy that auto-populates push metadata based on referrer URLs.<p>A typical request for a main
|
||||||
* resource such as <tt>index.html</tt> is immediately followed by a number of requests for associated resources.
|
* resource such as {@code index.html} is immediately followed by a number of requests for associated resources.
|
||||||
* Associated resource requests will have a <tt>Referer</tt> HTTP header that points to <tt>index.html</tt>, which is
|
* Associated resource requests will have a {@code Referer} HTTP header that points to {@code index.html}, which is
|
||||||
* used to link the associated resource to the main resource.</p> <p>However, also following a hyperlink generates a
|
* used to link the associated resource to the main resource.<p>However, also following a hyperlink generates a
|
||||||
* HTTP request with a <tt>Referer</tt> HTTP header that points to <tt>index.html</tt>; therefore a proper value for
|
* HTTP request with a {@code Referer} HTTP header that points to {@code index.html}; therefore a proper value for
|
||||||
* {@link #setReferrerPushPeriod(int)} has to be set. If the referrerPushPeriod for a main resource has elapsed,
|
* {@link #setReferrerPushPeriod(int)} has to be set. If the referrerPushPeriod for a main resource has elapsed,
|
||||||
* no more associated resources will be added for that main resource.</p> <p>This class distinguishes associated main
|
* no more associated resources will be added for that main resource.<p>This class distinguishes associated main
|
||||||
* resources by their URL path suffix and content type. CSS stylesheets, images and JavaScript files have
|
* resources by their URL path suffix and content type. CSS stylesheets, images and JavaScript files have
|
||||||
* recognizable URL path suffixes that are classified as associated resources. The suffix regexs can be configured by
|
* recognizable URL path suffixes that are classified as associated resources. The suffix regexs can be configured by
|
||||||
* constructor argument</p>
|
* constructor argument</p>
|
||||||
* <p>When CSS stylesheets refer to images, the CSS image request will have the CSS stylesheet as referrer. This
|
* <p>When CSS stylesheets refer to images, the CSS image request will have the CSS stylesheet as referrer. This
|
||||||
* implementation will push also the CSS image.</p> <p>The push metadata built by this implementation is limited by the
|
* implementation will push also the CSS image.<p>The push metadata built by this implementation is limited by the
|
||||||
* number of pages of the application itself, and by the {@link #setMaxAssociatedResources(int)} max associated resources}
|
* number of pages of the application itself, and by the {@link #setMaxAssociatedResources(int)} max associated resources}
|
||||||
* parameter. This parameter limits the number of associated resources per each main resource, so that if a main
|
* parameter. This parameter limits the number of associated resources per each main resource, so that if a main
|
||||||
* resource has hundreds of associated resources, only up to the number specified by this parameter will be pushed.</p>
|
* resource has hundreds of associated resources, only up to the number specified by this parameter will be pushed.
|
||||||
*/
|
*/
|
||||||
public class ReferrerPushStrategy implements PushStrategy
|
public class ReferrerPushStrategy implements PushStrategy
|
||||||
{
|
{
|
||||||
|
|
|
@ -1303,6 +1303,15 @@ public class SslContextFactory extends AbstractLifeCycle
|
||||||
return socket;
|
return socket;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Factory method for "scratch" {@link SSLEngine}s, usually only used for retrieving configuration
|
||||||
|
* information such as the application buffer size or the list of protocols/ciphers.
|
||||||
|
* <p />
|
||||||
|
* This method should not be used for creating {@link SSLEngine}s that are used in actual socket
|
||||||
|
* communication.
|
||||||
|
*
|
||||||
|
* @return a new, "scratch" {@link SSLEngine}
|
||||||
|
*/
|
||||||
public SSLEngine newSSLEngine()
|
public SSLEngine newSSLEngine()
|
||||||
{
|
{
|
||||||
if (!isRunning())
|
if (!isRunning())
|
||||||
|
@ -1312,6 +1321,14 @@ public class SslContextFactory extends AbstractLifeCycle
|
||||||
return sslEngine;
|
return sslEngine;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* General purpose factory method for creating {@link SSLEngine}s, although creation of
|
||||||
|
* {@link SSLEngine}s on the server-side should prefer {@link #newSSLEngine(InetSocketAddress)}.
|
||||||
|
*
|
||||||
|
* @param host the remote host
|
||||||
|
* @param port the remote port
|
||||||
|
* @return a new {@link SSLEngine}
|
||||||
|
*/
|
||||||
public SSLEngine newSSLEngine(String host, int port)
|
public SSLEngine newSSLEngine(String host, int port)
|
||||||
{
|
{
|
||||||
if (!isRunning())
|
if (!isRunning())
|
||||||
|
@ -1323,10 +1340,32 @@ public class SslContextFactory extends AbstractLifeCycle
|
||||||
return sslEngine;
|
return sslEngine;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Server-side only factory method for creating {@link SSLEngine}s.
|
||||||
|
* <p />
|
||||||
|
* If the given {@code address} is null, it is equivalent to {@link #newSSLEngine()}, otherwise
|
||||||
|
* {@link #newSSLEngine(String, int)} is called.
|
||||||
|
* <p />
|
||||||
|
* If {@link #getNeedClientAuth()} is {@code true}, then the host name is passed to
|
||||||
|
* {@link #newSSLEngine(String, int)}, possibly incurring in a reverse DNS lookup, which takes time
|
||||||
|
* and may hang the selector (since this method is usually called by the selector thread).
|
||||||
|
* <p />
|
||||||
|
* Otherwise, the host address is passed to {@link #newSSLEngine(String, int)} without DNS lookup
|
||||||
|
* penalties.
|
||||||
|
* <p />
|
||||||
|
* Clients that wish to create {@link SSLEngine} instances must use {@link #newSSLEngine(String, int)}.
|
||||||
|
*
|
||||||
|
* @param address the remote peer address
|
||||||
|
* @return a new {@link SSLEngine}
|
||||||
|
*/
|
||||||
public SSLEngine newSSLEngine(InetSocketAddress address)
|
public SSLEngine newSSLEngine(InetSocketAddress address)
|
||||||
{
|
{
|
||||||
// Must use the hostName, not the hostAddress, to allow correct host name verification
|
if (address == null)
|
||||||
return address != null ? newSSLEngine(address.getAddress().getHostName(), address.getPort()) : newSSLEngine();
|
return newSSLEngine();
|
||||||
|
|
||||||
|
boolean useHostName = getNeedClientAuth();
|
||||||
|
String hostName = useHostName ? address.getHostName() : address.getAddress().getHostAddress();
|
||||||
|
return newSSLEngine(hostName, address.getPort());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void customize(SSLEngine sslEngine)
|
public void customize(SSLEngine sslEngine)
|
||||||
|
|
|
@ -21,6 +21,7 @@ package org.eclipse.jetty.websocket.client;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
@ -76,7 +77,7 @@ public class TomcatServerQuirksTest
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
int bufferSize = 512;
|
final int bufferSize = 512;
|
||||||
|
|
||||||
server.start();
|
server.start();
|
||||||
|
|
||||||
|
@ -103,17 +104,15 @@ public class TomcatServerQuirksTest
|
||||||
Assert.assertTrue("Timed out waiting for Client side WebSocket open event",websocket.openLatch.await(1,TimeUnit.SECONDS));
|
Assert.assertTrue("Timed out waiting for Client side WebSocket open event",websocket.openLatch.await(1,TimeUnit.SECONDS));
|
||||||
|
|
||||||
// Have server write frame.
|
// Have server write frame.
|
||||||
int length = bufferSize / 2;
|
byte payload[] = new byte[bufferSize / 2];
|
||||||
ByteBuffer serverFrame = ByteBuffer.allocate(bufferSize);
|
Arrays.fill(payload,(byte)'x');
|
||||||
// BufferUtil.flipToFill(serverFrame);
|
ByteBuffer serverFrame = BufferUtil.allocate(bufferSize);
|
||||||
|
BufferUtil.flipToFill(serverFrame);
|
||||||
serverFrame.put((byte)(0x80 | 0x01)); // FIN + TEXT
|
serverFrame.put((byte)(0x80 | 0x01)); // FIN + TEXT
|
||||||
serverFrame.put((byte)0x7E); // No MASK and 2 bytes length
|
serverFrame.put((byte)0x7E); // No MASK and 2 bytes length
|
||||||
serverFrame.put((byte)(length >> 8)); // first length byte
|
serverFrame.put((byte)(payload.length >> 8)); // first length byte
|
||||||
serverFrame.put((byte)(length & 0xFF)); // second length byte
|
serverFrame.put((byte)(payload.length & 0xFF)); // second length byte
|
||||||
for (int i = 0; i < length; ++i)
|
serverFrame.put(payload);
|
||||||
{
|
|
||||||
serverFrame.put((byte)'x');
|
|
||||||
}
|
|
||||||
BufferUtil.flipToFlush(serverFrame,0);
|
BufferUtil.flipToFlush(serverFrame,0);
|
||||||
byte buf[] = BufferUtil.toArray(serverFrame);
|
byte buf[] = BufferUtil.toArray(serverFrame);
|
||||||
socket.write(buf,0,buf.length);
|
socket.write(buf,0,buf.length);
|
||||||
|
|
|
@ -158,8 +158,12 @@ public class WebSocketServerFactory extends ContainerLifeCycle implements WebSoc
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ServletUpgradeRequest sockreq = new ServletUpgradeRequest(request);
|
// TODO: use ServletUpgradeRequest in Jetty 9.1
|
||||||
ServletUpgradeResponse sockresp = new ServletUpgradeResponse(response);
|
@SuppressWarnings("deprecation")
|
||||||
|
ServletWebSocketRequest sockreq = new ServletWebSocketRequest(request);
|
||||||
|
// TODO: use ServletUpgradeResponse in Jetty 9.1
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
ServletWebSocketResponse sockresp = new ServletWebSocketResponse(response);
|
||||||
|
|
||||||
UpgradeContext context = getActiveUpgradeContext();
|
UpgradeContext context = getActiveUpgradeContext();
|
||||||
if (context == null)
|
if (context == null)
|
||||||
|
|
|
@ -68,7 +68,7 @@ public class WebSocketOverSSLTest
|
||||||
Future<Session> fut = client.connect(clientSocket,server.getServerUri());
|
Future<Session> fut = client.connect(clientSocket,server.getServerUri());
|
||||||
|
|
||||||
// wait for connect
|
// wait for connect
|
||||||
Session session = fut.get(1,TimeUnit.SECONDS);
|
Session session = fut.get(3,TimeUnit.SECONDS);
|
||||||
|
|
||||||
// Generate text frame
|
// Generate text frame
|
||||||
String msg = "this is an echo ... cho ... ho ... o";
|
String msg = "this is an echo ... cho ... ho ... o";
|
||||||
|
@ -98,13 +98,16 @@ public class WebSocketOverSSLTest
|
||||||
WebSocketClient client = new WebSocketClient(server.getSslContextFactory());
|
WebSocketClient client = new WebSocketClient(server.getSslContextFactory());
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
client.setConnectTimeout(3000);
|
||||||
client.start();
|
client.start();
|
||||||
|
|
||||||
CaptureSocket clientSocket = new CaptureSocket();
|
CaptureSocket clientSocket = new CaptureSocket();
|
||||||
Future<Session> fut = client.connect(clientSocket,server.getServerUri());
|
URI requestUri = server.getServerUri();
|
||||||
|
System.err.printf("Request URI: %s%n",requestUri.toASCIIString());
|
||||||
|
Future<Session> fut = client.connect(clientSocket,requestUri);
|
||||||
|
|
||||||
// wait for connect
|
// wait for connect
|
||||||
Session session = fut.get(3,TimeUnit.SECONDS);
|
Session session = fut.get(5,TimeUnit.SECONDS);
|
||||||
|
|
||||||
// Generate text frame
|
// Generate text frame
|
||||||
session.getRemote().sendString("session.isSecure");
|
session.getRemote().sendString("session.isSecure");
|
||||||
|
@ -133,17 +136,19 @@ public class WebSocketOverSSLTest
|
||||||
WebSocketClient client = new WebSocketClient(server.getSslContextFactory());
|
WebSocketClient client = new WebSocketClient(server.getSslContextFactory());
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
client.setConnectTimeout(3000);
|
||||||
client.start();
|
client.start();
|
||||||
|
|
||||||
CaptureSocket clientSocket = new CaptureSocket();
|
CaptureSocket clientSocket = new CaptureSocket();
|
||||||
URI requestUri = server.getServerUri().resolve("/deep?a=b");
|
URI requestUri = server.getServerUri().resolve("/deep?a=b");
|
||||||
Future<Session> fut = client.connect(clientSocket,requestUri);
|
System.err.printf("Request URI: %s%n",requestUri.toASCIIString());
|
||||||
|
client.connect(clientSocket,requestUri);
|
||||||
|
|
||||||
// wait for connect
|
// wait for connect
|
||||||
Session session = fut.get(3,TimeUnit.SECONDS);
|
clientSocket.awaitConnected(5000);
|
||||||
|
|
||||||
// Generate text frame
|
// Generate text frame
|
||||||
session.getRemote().sendString("session.upgradeRequest.requestURI");
|
clientSocket.getRemote().sendString("session.upgradeRequest.requestURI");
|
||||||
|
|
||||||
// Read frame (hopefully text frame)
|
// Read frame (hopefully text frame)
|
||||||
clientSocket.messages.awaitEventCount(1,500,TimeUnit.MILLISECONDS);
|
clientSocket.messages.awaitEventCount(1,500,TimeUnit.MILLISECONDS);
|
||||||
|
|
|
@ -27,6 +27,7 @@ import java.util.concurrent.TimeUnit;
|
||||||
import org.eclipse.jetty.toolchain.test.AdvancedRunner;
|
import org.eclipse.jetty.toolchain.test.AdvancedRunner;
|
||||||
import org.eclipse.jetty.util.Utf8Appendable.NotUtf8Exception;
|
import org.eclipse.jetty.util.Utf8Appendable.NotUtf8Exception;
|
||||||
import org.eclipse.jetty.util.Utf8StringBuilder;
|
import org.eclipse.jetty.util.Utf8StringBuilder;
|
||||||
|
import org.eclipse.jetty.util.log.StacklessLogging;
|
||||||
import org.eclipse.jetty.util.log.StdErrLog;
|
import org.eclipse.jetty.util.log.StdErrLog;
|
||||||
import org.eclipse.jetty.websocket.api.StatusCode;
|
import org.eclipse.jetty.websocket.api.StatusCode;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
||||||
|
@ -206,14 +207,17 @@ public class WebSocketServletRFCTest
|
||||||
client.sendStandardRequest();
|
client.sendStandardRequest();
|
||||||
client.expectUpgradeResponse();
|
client.expectUpgradeResponse();
|
||||||
|
|
||||||
// Generate text frame
|
try (StacklessLogging context = new StacklessLogging(EventDriver.class))
|
||||||
client.write(WebSocketFrame.text("CRASH"));
|
{
|
||||||
|
// Generate text frame
|
||||||
|
client.write(WebSocketFrame.text("CRASH"));
|
||||||
|
|
||||||
// Read frame (hopefully close frame)
|
// Read frame (hopefully close frame)
|
||||||
IncomingFramesCapture capture = client.readFrames(1,TimeUnit.MILLISECONDS,500);
|
IncomingFramesCapture capture = client.readFrames(1,TimeUnit.MILLISECONDS,500);
|
||||||
Frame cf = capture.getFrames().poll();
|
Frame cf = capture.getFrames().poll();
|
||||||
CloseInfo close = new CloseInfo(cf);
|
CloseInfo close = new CloseInfo(cf);
|
||||||
Assert.assertThat("Close Frame.status code",close.getStatusCode(),is(StatusCode.SERVER_ERROR));
|
Assert.assertThat("Close Frame.status code",close.getStatusCode(),is(StatusCode.SERVER_ERROR));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
|
|
@ -23,6 +23,7 @@ import java.nio.ByteBuffer;
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
import org.eclipse.jetty.websocket.api.Session;
|
import org.eclipse.jetty.websocket.api.Session;
|
||||||
|
import org.eclipse.jetty.websocket.api.WebSocketException;
|
||||||
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect;
|
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect;
|
||||||
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage;
|
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage;
|
||||||
import org.eclipse.jetty.websocket.api.annotations.WebSocket;
|
import org.eclipse.jetty.websocket.api.annotations.WebSocket;
|
||||||
|
@ -77,7 +78,14 @@ public class ABSocket
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// echo the message back.
|
try
|
||||||
this.session.getRemote().sendStringByFuture(message);
|
{
|
||||||
|
// echo the message back.
|
||||||
|
this.session.getRemote().sendStringByFuture(message);
|
||||||
|
}
|
||||||
|
catch (WebSocketException e)
|
||||||
|
{
|
||||||
|
LOG.warn("Unable to echo TEXT message",e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,3 +17,6 @@ org.eclipse.jetty.websocket.server.browser.LEVEL=DEBUG
|
||||||
|
|
||||||
### Disabling intentional error out of RFCSocket
|
### Disabling intentional error out of RFCSocket
|
||||||
org.eclipse.jetty.websocket.server.helper.RFCSocket.LEVEL=OFF
|
org.eclipse.jetty.websocket.server.helper.RFCSocket.LEVEL=OFF
|
||||||
|
|
||||||
|
### Hiding Stack Traces from ABSocket
|
||||||
|
org.eclipse.jetty.websocket.server.ab.ABSocket.STACKS=OFF
|
||||||
|
|
Loading…
Reference in New Issue