Merged branch 'master' into '431642'.
diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationParser.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationParser.java
index 5587c2f..41b1627 100644
--- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationParser.java
+++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationParser.java
@@ -69,6 +69,8 @@
private static final Logger LOG = Log.getLogger(AnnotationParser.class);
protected Set<String> _parsedClassNames = new ConcurrentHashSet<String>();
+
+ protected static int ASM_OPCODE_VERSION = Opcodes.ASM5; //compatibility of api
/**
@@ -373,7 +375,7 @@
final String signature,
final String[] exceptions)
{
- super(Opcodes.ASM4);
+ super(ASM_OPCODE_VERSION);
_handlers = handlers;
_mi = new MethodInfo(classInfo, name, access, methodDesc,signature, exceptions);
}
@@ -417,7 +419,7 @@
final String signature,
final Object value)
{
- super(Opcodes.ASM4);
+ super(ASM_OPCODE_VERSION);
_handlers = handlers;
_fieldInfo = new FieldInfo(classInfo, fieldName, access, fieldType, signature, value);
}
@@ -456,7 +458,7 @@
public MyClassVisitor(Set<? extends Handler> handlers, Resource containingResource)
{
- super(Opcodes.ASM4);
+ super(ASM_OPCODE_VERSION);
_handlers = handlers;
_containingResource = containingResource;
}
@@ -702,6 +704,7 @@
}
catch (Exception ex)
{
+ if (LOG.isDebugEnabled()) LOG.debug("Error scanning file "+files[f], ex);
me.add(new RuntimeException("Error scanning file "+files[f],ex));
}
}
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java
index 15cd719..5649b29 100644
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java
+++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java
@@ -228,7 +228,6 @@
protected void doStop() throws Exception
{
cookieStore.removeAll();
- cookieStore = null;
decoderFactories.clear();
handlers.clear();
diff --git a/jetty-distribution/pom.xml b/jetty-distribution/pom.xml
index 5003e02..d81eb57 100644
--- a/jetty-distribution/pom.xml
+++ b/jetty-distribution/pom.xml
@@ -570,7 +570,7 @@
<argument>jetty.home=${assembly-directory}</argument>
<argument>jetty.base=${assembly-directory}/demo-base</argument>
<argument>--add-to-start=server,continuation,deploy,websocket,ext,resources,client,annotations,jndi,servlets</argument>
- <argument>--add-to-startd-ini=jsp,jstl,http,https</argument>
+ <argument>--add-to-startd=jsp,jstl,http,https</argument>
</arguments>
</configuration>
<goals>
diff --git a/jetty-distribution/src/main/resources/bin/jetty.sh b/jetty-distribution/src/main/resources/bin/jetty.sh
index ce489db..3190332 100644
--- a/jetty-distribution/src/main/resources/bin/jetty.sh
+++ b/jetty-distribution/src/main/resources/bin/jetty.sh
@@ -105,8 +105,14 @@
running()
{
- local PID=$(cat "$1" 2>/dev/null) || return 1
- kill -0 "$PID" 2>/dev/null
+ if [ -f "$1" ]
+ then
+ local PID=$(cat "$1" 2>/dev/null) || return 1
+ kill -0 "$PID" 2>/dev/null
+ return
+ fi
+ rm -f "$1"
+ return 1
}
started()
@@ -408,16 +414,10 @@
else
- if [ -f "$JETTY_PID" ]
+ if running $JETTY_PID
then
- if running $JETTY_PID
- then
- echo "Already Running!"
- exit 1
- else
- # dead pid file - remove
- rm -f "$JETTY_PID"
- fi
+ echo "Already Running $(cat $JETTY_PID)!"
+ exit 1
fi
if [ "$JETTY_USER" ]
@@ -519,16 +519,10 @@
run|demo)
echo "Running Jetty: "
- if [ -f "$JETTY_PID" ]
+ if running "$JETTY_PID"
then
- if running "$JETTY_PID"
- then
- echo "Already Running!"
- exit 1
- else
- # dead pid file - remove
- rm -f "$JETTY_PID"
- fi
+ echo Already Running $(cat "$JETTY_PID")!
+ exit 1
fi
exec "${RUN_CMD[@]}"
@@ -550,7 +544,7 @@
echo "RUN_CMD = ${RUN_CMD[*]}"
echo
- if [ -f "$JETTY_PID" ]
+ if running "$JETTY_PID"
then
echo "Jetty running pid=$(< "$JETTY_PID")"
exit 0
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractEndPoint.java b/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractEndPoint.java
index bfcb1aa..8fa2cc8 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractEndPoint.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractEndPoint.java
@@ -44,6 +44,7 @@
return AbstractEndPoint.this.needsFill();
}
};
+
private final WriteFlusher _writeFlusher = new WriteFlusher(this)
{
@Override
@@ -142,9 +143,22 @@
@Override
protected void onIdleExpired(TimeoutException timeout)
{
- // Note: Rely on fillInterest to notify onReadTimeout to close connection.
- _fillInterest.onFail(timeout);
- _writeFlusher.onFail(timeout);
+ boolean output_shutdown=isOutputShutdown();
+ boolean input_shutdown=isInputShutdown();
+ boolean fillFailed = _fillInterest.onFail(timeout);
+ boolean writeFailed = _writeFlusher.onFail(timeout);
+
+ // If the endpoint is half closed and there was no onFail handling, the close here
+ // This handles the situation where the connection has completed its close handling
+ // and the endpoint is half closed, but the other party does not complete the close.
+ // This perhaps should not check for half closed, however the servlet spec case allows
+ // for a dispatched servlet or suspended request to extend beyond the connections idle
+ // time. So if this test would always close an idle endpoint that is not handled, then
+ // we would need a mode to ignore timeouts for some HTTP states
+ if (isOpen() && (output_shutdown || input_shutdown) && !(fillFailed || writeFailed))
+ close();
+ else
+ LOG.debug("Ignored idle endpoint {}",this);
}
@Override
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/FillInterest.java b/jetty-io/src/main/java/org/eclipse/jetty/io/FillInterest.java
index 0f3c2e5..b2c3f68 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/FillInterest.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/FillInterest.java
@@ -93,12 +93,17 @@
/* ------------------------------------------------------------ */
/** Call to signal a failure to a registered interest
+ * @return true if the cause was passed to a {@link Callback} instance
*/
- public void onFail(Throwable cause)
+ public boolean onFail(Throwable cause)
{
Callback callback=_interested.get();
if (callback!=null && _interested.compareAndSet(callback,null))
+ {
callback.failed(cause);
+ return true;
+ }
+ return false;
}
/* ------------------------------------------------------------ */
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/WriteFlusher.java b/jetty-io/src/main/java/org/eclipse/jetty/io/WriteFlusher.java
index 326ef3f..dd44e53 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/WriteFlusher.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/WriteFlusher.java
@@ -253,10 +253,14 @@
return _buffers;
}
- protected void fail(Throwable cause)
+ protected boolean fail(Throwable cause)
{
if (_callback!=null)
+ {
_callback.failed(cause);
+ return true;
+ }
+ return false;
}
protected void complete()
@@ -430,7 +434,12 @@
}
}
- public void onFail(Throwable cause)
+ /* ------------------------------------------------------------ */
+ /** Notify the flusher of a failure
+ * @param cause The cause of the failure
+ * @return true if the flusher passed the failure to a {@link Callback} instance
+ */
+ public boolean onFail(Throwable cause)
{
// Keep trying to handle the failure until we get to IDLE or FAILED state
while(true)
@@ -442,7 +451,7 @@
case FAILED:
if (DEBUG)
LOG.debug("ignored: {} {}", this, cause);
- return;
+ return false;
case PENDING:
if (DEBUG)
@@ -450,10 +459,7 @@
PendingState pending = (PendingState)current;
if (updateState(pending,__IDLE))
- {
- pending.fail(cause);
- return;
- }
+ return pending.fail(cause);
break;
default:
@@ -461,7 +467,7 @@
LOG.debug("failed: {} {}", this, cause);
if (updateState(current,new FailedState(cause)))
- return;
+ return false;
break;
}
}
diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/ByteArrayEndPointTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/ByteArrayEndPointTest.java
index d23be98..f6cefa1 100644
--- a/jetty-io/src/test/java/org/eclipse/jetty/io/ByteArrayEndPointTest.java
+++ b/jetty-io/src/test/java/org/eclipse/jetty/io/ByteArrayEndPointTest.java
@@ -19,8 +19,6 @@
package org.eclipse.jetty.io;
import static org.hamcrest.Matchers.*;
-import static org.hamcrest.Matchers.containsString;
-import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.instanceOf;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -37,8 +35,6 @@
import org.eclipse.jetty.toolchain.test.annotation.Slow;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.FutureCallback;
-import org.eclipse.jetty.util.log.Log;
-import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.thread.Scheduler;
import org.eclipse.jetty.util.thread.TimerScheduler;
import org.junit.After;
@@ -132,6 +128,7 @@
assertEquals(true,endp.flush(BufferUtil.EMPTY_BUFFER,BufferUtil.toBuffer(" and"),BufferUtil.toBuffer(" more")));
assertEquals("some output some more and more",endp.getOutputString());
+ endp.close();
}
@Test
@@ -150,6 +147,7 @@
assertEquals(true,endp.flush(data));
assertEquals("data.",BufferUtil.toString(endp.takeOutput()));
+ endp.close();
}
@@ -237,6 +235,7 @@
assertTrue(fcb.isDone());
assertEquals(null, fcb.get());
assertEquals(" more.", endp.getOutputString());
+ endp.close();
}
/**
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/annotations/AnnotationParser.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/annotations/AnnotationParser.java
index b1ccba2..8887036 100644
--- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/annotations/AnnotationParser.java
+++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/annotations/AnnotationParser.java
@@ -35,6 +35,7 @@
import org.eclipse.jetty.osgi.boot.utils.BundleFileLocatorHelper;
import org.eclipse.jetty.util.ConcurrentHashSet;
import org.eclipse.jetty.util.resource.Resource;
+import org.objectweb.asm.Opcodes;
import org.osgi.framework.Bundle;
import org.osgi.framework.Constants;
@@ -50,6 +51,14 @@
private ConcurrentHashMap<Resource, Bundle> _resourceToBundle = new ConcurrentHashMap<Resource, Bundle>();
private ConcurrentHashMap<Bundle,URI> _bundleToUri = new ConcurrentHashMap<Bundle, URI>();
+ static
+ {
+ //As of jetty 9.2.0, the impl of asm visitor classes is compatible with both asm4 and asm5.
+ //We need to use asm4 with osgi, because we need to use aries spifly to support annotations,
+ //and currently this only supports asm4. Therefore, we set the asm api version to be 4 for osgi.
+ ASM_OPCODE_VERSION = Opcodes.ASM4;
+ }
+
/**
* Keep track of a jetty URI Resource and its associated OSGi bundle.
* @param uri
diff --git a/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/ProxyServlet.java b/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/ProxyServlet.java
index 3323f1c..8d7c543 100644
--- a/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/ProxyServlet.java
+++ b/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/ProxyServlet.java
@@ -48,7 +48,6 @@
import org.eclipse.jetty.client.util.InputStreamContentProvider;
import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpHeader;
-import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.HttpCookieStore;
@@ -392,7 +391,7 @@
}
final Request proxyRequest = _client.newRequest(rewrittenURI)
- .method(HttpMethod.fromString(request.getMethod()))
+ .method(request.getMethod())
.version(HttpVersion.fromString(request.getProtocol()));
// Copy headers
@@ -434,10 +433,10 @@
asyncContext.setTimeout(0);
request.setAttribute(ASYNC_CONTEXT, asyncContext);
- customizeProxyRequest(proxyRequest, request);
-
if (hasContent)
- proxyRequest.content(proxyRequestContent(asyncContext, requestId));
+ proxyRequest.content(proxyRequestContent(proxyRequest, request));
+
+ customizeProxyRequest(proxyRequest, request);
if (_log.isDebugEnabled())
{
@@ -476,9 +475,8 @@
proxyRequest.send(new ProxyResponseListener(request, response));
}
- protected ContentProvider proxyRequestContent(final AsyncContext asyncContext, final int requestId) throws IOException
+ protected ContentProvider proxyRequestContent(Request proxyRequest, final HttpServletRequest request) throws IOException
{
- final HttpServletRequest request = (HttpServletRequest)asyncContext.getRequest();
return new InputStreamContentProvider(request.getInputStream())
{
@Override
@@ -490,7 +488,7 @@
@Override
protected ByteBuffer onRead(byte[] buffer, int offset, int length)
{
- _log.debug("{} proxying content to upstream: {} bytes", requestId, length);
+ _log.debug("{} proxying content to upstream: {} bytes", getRequestId(request), length);
return super.onRead(buffer, offset, length);
}
};
@@ -609,7 +607,8 @@
* <li>proxyTo - a mandatory URI like http://host:80/context to which the request is proxied.</li>
* <li>prefix - an optional URI prefix that is stripped from the start of the forwarded URI.</li>
* </ul>
- * For example, if a request is received at /foo/bar and the 'proxyTo' parameter is "http://host:80/context"
+ * <p/>
+ * For example, if a request is received at "/foo/bar", the 'proxyTo' parameter is "http://host:80/context"
* and the 'prefix' parameter is "/foo", then the request would be proxied to "http://host:80/context/bar".
*/
public static class Transparent extends ProxyServlet
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintSecurityHandler.java b/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintSecurityHandler.java
index d8ad639..201618d 100644
--- a/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintSecurityHandler.java
+++ b/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintSecurityHandler.java
@@ -45,6 +45,7 @@
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.server.UserIdentity;
+import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.security.Constraint;
@@ -820,7 +821,9 @@
if (paths != null && !paths.isEmpty())
{
for (String p:paths)
- LOG.warn("Path with uncovered http methods: {}",p);
+ LOG.warn("{} has uncovered http methods for path: {}",ContextHandler.getCurrentContext(), p);
+ if (LOG.isDebugEnabled())
+ LOG.debug(new Throwable());
return true;
}
return false;
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/HashLoginService.java b/jetty-security/src/main/java/org/eclipse/jetty/security/HashLoginService.java
index 55f7ed2..335aabd 100644
--- a/jetty-security/src/main/java/org/eclipse/jetty/security/HashLoginService.java
+++ b/jetty-security/src/main/java/org/eclipse/jetty/security/HashLoginService.java
@@ -133,6 +133,7 @@
/**
* @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart()
*/
+ @Override
protected void doStart() throws Exception
{
super.doStart();
@@ -154,6 +155,7 @@
/**
* @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStop()
*/
+ @Override
protected void doStop() throws Exception
{
super.doStop();
@@ -163,6 +165,7 @@
}
/* ------------------------------------------------------------ */
+ @Override
public void update(String userName, Credential credential, String[] roleArray)
{
if (LOG.isDebugEnabled())
@@ -171,6 +174,7 @@
}
/* ------------------------------------------------------------ */
+ @Override
public void remove(String userName)
{
if (LOG.isDebugEnabled())
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java b/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java
index 90c0d1b..a6e108e 100644
--- a/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java
+++ b/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java
@@ -43,6 +43,7 @@
import org.eclipse.jetty.server.handler.ContextHandler.Context;
import org.eclipse.jetty.server.handler.HandlerWrapper;
import org.eclipse.jetty.server.session.AbstractSession;
+import org.eclipse.jetty.util.component.LifeCycle;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
@@ -74,8 +75,6 @@
private LoginService _loginService;
private IdentityService _identityService;
private boolean _renewSession=true;
- private boolean _discoveredIdentityService = false;
- private boolean _discoveredLoginService = false;
/* ------------------------------------------------------------ */
protected SecurityHandler()
@@ -266,20 +265,24 @@
}
/* ------------------------------------------------------------ */
- protected LoginService findLoginService()
+ protected LoginService findLoginService() throws Exception
{
Collection<LoginService> list = getServer().getBeans(LoginService.class);
-
+ LoginService service = null;
String realm=getRealmName();
if (realm!=null)
{
- for (LoginService service : list)
- if (service.getName()!=null && service.getName().equals(realm))
- return service;
+ for (LoginService s : list)
+ if (s.getName()!=null && s.getName().equals(realm))
+ {
+ service=s;
+ break;
+ }
}
else if (list.size()==1)
- return list.iterator().next();
- return null;
+ service = list.iterator().next();
+
+ return service;
}
/* ------------------------------------------------------------ */
@@ -342,9 +345,10 @@
if (_loginService==null)
{
setLoginService(findLoginService());
- _discoveredLoginService = true;
+ if (_loginService!=null)
+ unmanage(_loginService);
}
-
+
if (_identityService==null)
{
if (_loginService!=null)
@@ -353,10 +357,16 @@
if (_identityService==null)
setIdentityService(findIdentityService());
- if (_identityService==null && _realmName!=null)
- setIdentityService(new DefaultIdentityService());
-
- _discoveredIdentityService = true;
+ if (_identityService==null)
+ {
+ if (_realmName!=null)
+ {
+ setIdentityService(new DefaultIdentityService());
+ manage(_identityService);
+ }
+ }
+ else
+ unmanage(_identityService);
}
if (_loginService!=null)
@@ -387,17 +397,16 @@
protected void doStop() throws Exception
{
//if we discovered the services (rather than had them explicitly configured), remove them.
- if (_discoveredIdentityService)
+ if (!isManaged(_identityService))
{
removeBean(_identityService);
- _identityService = null;
-
+ _identityService = null;
}
- if (_discoveredLoginService)
+ if (!isManaged(_loginService))
{
removeBean(_loginService);
- _loginService = null;
+ _loginService=null;
}
super.doStop();
@@ -427,6 +436,7 @@
/**
* @see org.eclipse.jetty.security.Authenticator.AuthConfiguration#isSessionRenewedOnAuthentication()
*/
+ @Override
public boolean isSessionRenewedOnAuthentication()
{
return _renewSession;
@@ -473,7 +483,7 @@
{
if (!baseRequest.isHandled())
{
- response.sendError(Response.SC_FORBIDDEN);
+ response.sendError(HttpServletResponse.SC_FORBIDDEN);
baseRequest.setHandled(true);
}
return;
@@ -488,7 +498,7 @@
LOG.warn("No authenticator for: "+roleInfo);
if (!baseRequest.isHandled())
{
- response.sendError(Response.SC_FORBIDDEN);
+ response.sendError(HttpServletResponse.SC_FORBIDDEN);
baseRequest.setHandled(true);
}
return;
@@ -524,7 +534,7 @@
boolean authorized=checkWebResourcePermissions(pathInContext, baseRequest, base_response, roleInfo, userAuth.getUserIdentity());
if (!authorized)
{
- response.sendError(Response.SC_FORBIDDEN, "!role");
+ response.sendError(HttpServletResponse.SC_FORBIDDEN, "!role");
baseRequest.setHandled(true);
return;
}
@@ -574,7 +584,7 @@
{
// jaspi 3.8.3 send HTTP 500 internal server error, with message
// from AuthException
- response.sendError(Response.SC_INTERNAL_SERVER_ERROR, e.getMessage());
+ response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
}
finally
{
@@ -634,6 +644,7 @@
/* ------------------------------------------------------------ */
public class NotChecked implements Principal
{
+ @Override
public String getName()
{
return null;
@@ -656,6 +667,7 @@
/* ------------------------------------------------------------ */
public static final Principal __NO_USER = new Principal()
{
+ @Override
public String getName()
{
return null;
@@ -680,6 +692,7 @@
*/
public static final Principal __NOBODY = new Principal()
{
+ @Override
public String getName()
{
return "Nobody";
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConfiguration.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConfiguration.java
index 87f62c2..352af25 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConfiguration.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConfiguration.java
@@ -52,7 +52,7 @@
private String _secureScheme = HttpScheme.HTTPS.asString();
private boolean _sendServerVersion = true; //send Server: header
private boolean _sendXPoweredBy = false; //send X-Powered-By: header
- private boolean _sendDateHeader = false; //send Date: header
+ private boolean _sendDateHeader = true; //send Date: header
public interface Customizer
{
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpInput.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpInput.java
index a1f9a8b..e5d31f0 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpInput.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpInput.java
@@ -288,6 +288,14 @@
}
}
+ public boolean isAsync()
+ {
+ synchronized (lock())
+ {
+ return _contentState==ASYNC;
+ }
+ }
+
/**
* @return whether an EOF has been detected, even though there may be content to consume.
*/
@@ -436,6 +444,7 @@
input.blockForContent();
}
+ @Override
public String toString()
{
return "STREAM";
@@ -471,6 +480,7 @@
return true;
}
+ @Override
public String toString()
{
return "EARLY_EOF";
@@ -485,6 +495,7 @@
return true;
}
+ @Override
public String toString()
{
return "EOF";
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpOutput.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpOutput.java
index 610db58..7c0fd89 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpOutput.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpOutput.java
@@ -74,7 +74,7 @@
write completed - - - ASYNC READY->owp -
*/
- enum OutputState { OPEN, ASYNC, READY, PENDING, UNREADY, CLOSED }
+ enum OutputState { OPEN, ASYNC, READY, PENDING, UNREADY, ERROR, CLOSED }
private final AtomicReference<OutputState> _state=new AtomicReference<>(OutputState.OPEN);
public HttpOutput(HttpChannel<?> channel)
@@ -146,7 +146,9 @@
break loop;
case UNREADY:
- throw new WritePendingException(); // TODO ?
+ if (_state.compareAndSet(state,OutputState.ERROR))
+ _writeListener.onError(_onError==null?new EofException("Async close"):_onError);
+ continue;
default:
if (_state.compareAndSet(state,OutputState.CLOSED))
@@ -179,7 +181,9 @@
break loop;
case UNREADY:
- throw new WritePendingException(); // TODO ?
+ if (_state.compareAndSet(state,OutputState.ERROR))
+ _writeListener.onError(_onError==null?new EofException("Async closed"):_onError);
+ continue;
default:
if (_state.compareAndSet(state,OutputState.CLOSED))
@@ -238,6 +242,9 @@
case UNREADY:
throw new WritePendingException();
+ case ERROR:
+ throw new EofException(_onError);
+
case CLOSED:
return;
}
@@ -298,6 +305,9 @@
case UNREADY:
throw new WritePendingException();
+ case ERROR:
+ throw new EofException(_onError);
+
case CLOSED:
throw new EofException("Closed");
}
@@ -396,6 +406,9 @@
case UNREADY:
throw new WritePendingException();
+ case ERROR:
+ throw new EofException(_onError);
+
case CLOSED:
throw new EofException("Closed");
}
@@ -476,6 +489,9 @@
case UNREADY:
throw new WritePendingException();
+ case ERROR:
+ throw new EofException(_onError);
+
case CLOSED:
throw new EofException("Closed");
}
@@ -615,6 +631,8 @@
if (!_state.compareAndSet(OutputState.OPEN, OutputState.PENDING))
continue;
break;
+ case ERROR:
+ throw new EofException(_onError);
case CLOSED:
throw new EofException("Closed");
default:
@@ -706,6 +724,9 @@
return false;
case UNREADY:
return false;
+
+ case ERROR:
+ return true;
case CLOSED:
return true;
@@ -716,45 +737,55 @@
@Override
public void run()
{
- if(_onError!=null)
+ loop: while (true)
{
- Throwable th=_onError;
- _onError=null;
- _writeListener.onError(new IOException(th));
- close();
- }
-
- switch(_state.get())
- {
- case READY:
- try
+ OutputState state = _state.get();
+
+ if(_onError!=null)
+ {
+ switch(state)
{
- _writeListener.onWritePossible();
+ case CLOSED:
+ case ERROR:
+ _onError=null;
+ break loop;
+
+ default:
+ if (_state.compareAndSet(state, OutputState.ERROR))
+ {
+ Throwable th=_onError;
+ _onError=null;
+ LOG.debug("onError",th);
+ _writeListener.onError(th);
+ close();
+
+ break loop;
+ }
+
}
- catch (Throwable e)
- {
- _writeListener.onError(e);
- close();
- }
- break;
-
- case CLOSED:
- try
- {
- new Throwable().printStackTrace();
+ continue loop;
+ }
+
+ switch(_state.get())
+ {
+ case READY:
+ case CLOSED:
// even though a write is not possible, because a close has
// occurred, we need to call onWritePossible to tell async
// producer that the last write completed.
- _writeListener.onWritePossible();
- }
- catch (Throwable e)
- {
- _writeListener.onError(e);
- }
- break;
-
- default:
-
+ try
+ {
+ _writeListener.onWritePossible();
+ break loop;
+ }
+ catch (Throwable e)
+ {
+ _onError=e;
+ }
+ break;
+ default:
+
+ }
}
}
@@ -769,37 +800,29 @@
@Override
protected void completed()
{
- try
+ while(true)
{
- while(true)
+ OutputState last=_state.get();
+ switch(last)
{
- HttpOutput.OutputState last=_state.get();
- switch(last)
- {
- case PENDING:
- if (!_state.compareAndSet(HttpOutput.OutputState.PENDING, HttpOutput.OutputState.ASYNC))
- continue;
- break;
+ case PENDING:
+ if (!_state.compareAndSet(OutputState.PENDING, OutputState.ASYNC))
+ continue;
+ break;
- case UNREADY:
- if (!_state.compareAndSet(HttpOutput.OutputState.UNREADY, HttpOutput.OutputState.READY))
- continue;
- _channel.getState().onWritePossible();
- break;
+ case UNREADY:
+ if (!_state.compareAndSet(OutputState.UNREADY, OutputState.READY))
+ continue;
+ _channel.getState().onWritePossible();
+ break;
- case CLOSED:
- break;
+ case CLOSED:
+ break;
- default:
- throw new IllegalStateException();
- }
- break;
+ default:
+ throw new IllegalStateException();
}
- }
- catch (Exception e)
- {
- _onError=e;
- _channel.getState().onWritePossible();
+ break;
}
}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java
index df679b4..adf325e 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java
@@ -339,6 +339,8 @@
throw new IllegalStateException("Form too large " + content_length + ">" + maxFormContentSize);
}
InputStream in = getInputStream();
+ if (_input.isAsync())
+ throw new IllegalStateException("Cannot extract parameters with async IO");
// Add form params to query params
UrlEncoded.decodeTo(in,_baseParameters,encoding,content_length < 0?maxFormContentSize:-1,maxFormKeys);
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java
index b6b3331..333aecd 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java
@@ -1384,8 +1384,9 @@
/* ------------------------------------------------------------ */
/**
- * @param base
- * The resourceBase to set.
+ * Set the base resource for this context.
+ * @param base The resource used as the base for all static content of this context.
+ * @see #setResourceBase(String)
*/
public void setBaseResource(Resource base)
{
@@ -1393,9 +1394,11 @@
}
/* ------------------------------------------------------------ */
- /**
- * @param resourceBase
- * The base resource as a string.
+ /**
+ * Set the base resource for this context.
+ * @param resourceBase A string representing the base resource for the context. Any string accepted
+ * by {@link Resource#newResource(String)} may be passed and the call is equivalent to
+ * <code>setBaseResource(newResource(resourceBase));</code>
*/
public void setResourceBase(String resourceBase)
{
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionManager.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionManager.java
index f76df68..1f966c5 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionManager.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionManager.java
@@ -26,7 +26,6 @@
import java.util.EventListener;
import java.util.HashSet;
import java.util.List;
-import java.util.Map;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
@@ -49,7 +48,7 @@
import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject;
import org.eclipse.jetty.util.annotation.ManagedOperation;
-import org.eclipse.jetty.util.component.AbstractLifeCycle;
+import org.eclipse.jetty.util.component.ContainerLifeCycle;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.statistic.CounterStatistic;
import org.eclipse.jetty.util.statistic.SampleStatistic;
@@ -66,7 +65,7 @@
*/
@SuppressWarnings("deprecation")
@ManagedObject("Abstract Session Manager")
-public abstract class AbstractSessionManager extends AbstractLifeCycle implements SessionManager
+public abstract class AbstractSessionManager extends ContainerLifeCycle implements SessionManager
{
final static Logger __log = SessionHandler.LOG;
@@ -82,11 +81,13 @@
static final HttpSessionContext __nullSessionContext=new HttpSessionContext()
{
+ @Override
public HttpSession getSession(String sessionId)
{
return null;
}
+ @Override
@SuppressWarnings({ "rawtypes", "unchecked" })
public Enumeration getIds()
{
@@ -162,6 +163,7 @@
}
/* ------------------------------------------------------------ */
+ @Override
public HttpCookie access(HttpSession session,boolean secure)
{
long now=System.currentTimeMillis();
@@ -187,6 +189,7 @@
}
/* ------------------------------------------------------------ */
+ @Override
public void addEventListener(EventListener listener)
{
if (listener instanceof HttpSessionAttributeListener)
@@ -195,17 +198,22 @@
_sessionListeners.add((HttpSessionListener)listener);
if (listener instanceof HttpSessionIdListener)
_sessionIdListeners.add((HttpSessionIdListener)listener);
+ addBean(listener,false);
}
/* ------------------------------------------------------------ */
+ @Override
public void clearEventListeners()
{
+ for (EventListener e :getBeans(EventListener.class))
+ removeBean(e);
_sessionAttributeListeners.clear();
_sessionListeners.clear();
_sessionIdListeners.clear();
}
/* ------------------------------------------------------------ */
+ @Override
public void complete(HttpSession session)
{
AbstractSession s = ((SessionIf)session).getSession();
@@ -237,17 +245,20 @@
Thread.currentThread().setContextClassLoader(serverLoader);
_sessionIdManager=new HashSessionIdManager();
server.setSessionIdManager(_sessionIdManager);
+ server.manage(_sessionIdManager);
+ _sessionIdManager.start();
}
finally
{
Thread.currentThread().setContextClassLoader(_loader);
}
}
+
+ // server session id is never managed by this manager
+ addBean(_sessionIdManager,false);
}
}
- if (!_sessionIdManager.isStarted())
- _sessionIdManager.start();
// Look for a session cookie name
if (_context!=null)
@@ -299,6 +310,7 @@
/**
* @return Returns the httpOnly.
*/
+ @Override
@ManagedAttribute("true if cookies use the http only flag")
public boolean getHttpOnly()
{
@@ -306,6 +318,7 @@
}
/* ------------------------------------------------------------ */
+ @Override
public HttpSession getHttpSession(String nodeId)
{
String cluster_id = getSessionIdManager().getClusterId(nodeId);
@@ -318,18 +331,9 @@
/* ------------------------------------------------------------ */
/**
- * @return Returns the metaManager used for cross context session management
- * @deprecated Use {@link #getSessionIdManager()}
- */
- public SessionIdManager getIdManager()
- {
- return getSessionIdManager();
- }
-
- /* ------------------------------------------------------------ */
- /**
* @return Returns the SessionIdManager used for cross context session management
*/
+ @Override
@ManagedAttribute("Session ID Manager")
public SessionIdManager getSessionIdManager()
{
@@ -350,16 +354,6 @@
/* ------------------------------------------------------------ */
/**
- * @see #getSessionsMax()
- */
- @Deprecated
- public int getMaxSessions()
- {
- return getSessionsMax();
- }
-
- /* ------------------------------------------------------------ */
- /**
* @return maximum number of sessions
*/
@ManagedAttribute("maximum number of simultaneous sessions")
@@ -379,33 +373,12 @@
}
/* ------------------------------------------------------------ */
- /**
- * @deprecated use {@link #getSessionIdManager()}
- */
- @Deprecated
- public SessionIdManager getMetaManager()
- {
- return getSessionIdManager();
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @deprecated always returns 0. no replacement available.
- */
- @Deprecated
- public int getMinSessions()
- {
- return 0;
- }
-
- /* ------------------------------------------------------------ */
@ManagedAttribute("time before a session cookie is re-set (in s)")
public int getRefreshCookieAge()
{
return _refreshCookieAge;
}
-
/* ------------------------------------------------------------ */
/**
* @return same as SessionCookieConfig.getSecure(). If true, session
@@ -438,8 +411,6 @@
_secureRequestOnly = secureRequestOnly;
}
-
-
/* ------------------------------------------------------------ */
@ManagedAttribute("the set session cookie")
public String getSessionCookie()
@@ -473,6 +444,7 @@
*
* @see org.eclipse.jetty.server.SessionManager#getSessionCookie(javax.servlet.http.HttpSession, java.lang.String, boolean)
*/
+ @Override
public HttpCookie getSessionCookie(HttpSession session, String contextPath, boolean requestIsSecure)
{
if (isUsingCookies())
@@ -527,18 +499,6 @@
}
/* ------------------------------------------------------------ */
- /**
- * @deprecated Need to review if it is needed.
- */
- @SuppressWarnings("rawtypes")
- public Map getSessionMap()
- {
- throw new UnsupportedOperationException();
- }
-
-
-
- /* ------------------------------------------------------------ */
@ManagedAttribute("number of currently active sessions")
public int getSessions()
{
@@ -546,6 +506,7 @@
}
/* ------------------------------------------------------------ */
+ @Override
@ManagedAttribute("name of use for URL session tracking")
public String getSessionIdPathParameterName()
{
@@ -553,6 +514,7 @@
}
/* ------------------------------------------------------------ */
+ @Override
public String getSessionIdPathParameterNamePrefix()
{
return _sessionIdPathParameterNamePrefix;
@@ -562,12 +524,14 @@
/**
* @return Returns the usingCookies.
*/
+ @Override
public boolean isUsingCookies()
{
return _usingCookies;
}
/* ------------------------------------------------------------ */
+ @Override
public boolean isValid(HttpSession session)
{
AbstractSession s = ((SessionIf)session).getSession();
@@ -575,6 +539,7 @@
}
/* ------------------------------------------------------------ */
+ @Override
public String getClusterId(HttpSession session)
{
AbstractSession s = ((SessionIf)session).getSession();
@@ -582,6 +547,7 @@
}
/* ------------------------------------------------------------ */
+ @Override
public String getNodeId(HttpSession session)
{
AbstractSession s = ((SessionIf)session).getSession();
@@ -592,6 +558,7 @@
/**
* Create a new HttpSession for a request
*/
+ @Override
public HttpSession newHttpSession(HttpServletRequest request)
{
AbstractSession session=newSession(request);
@@ -601,6 +568,7 @@
}
/* ------------------------------------------------------------ */
+ @Override
public void removeEventListener(EventListener listener)
{
if (listener instanceof HttpSessionAttributeListener)
@@ -608,17 +576,7 @@
if (listener instanceof HttpSessionListener)
_sessionListeners.remove(listener);
}
-
- /* ------------------------------------------------------------ */
- /**
- * @see #statsReset()
- */
- @Deprecated
- public void resetStats()
- {
- statsReset();
- }
-
+
/* ------------------------------------------------------------ */
/**
* Reset statistics values
@@ -643,54 +601,42 @@
/* ------------------------------------------------------------ */
/**
* @param metaManager The metaManager used for cross context session management.
- * @deprecated use {@link #setSessionIdManager(SessionIdManager)}
*/
- public void setIdManager(SessionIdManager metaManager)
- {
- setSessionIdManager(metaManager);
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @param metaManager The metaManager used for cross context session management.
- */
+ @Override
public void setSessionIdManager(SessionIdManager metaManager)
{
+ updateBean(_sessionIdManager, metaManager);
_sessionIdManager=metaManager;
}
-
-
/* ------------------------------------------------------------ */
/**
* @param seconds
*/
+ @Override
public void setMaxInactiveInterval(int seconds)
{
_dftMaxIdleSecs=seconds;
}
-
/* ------------------------------------------------------------ */
public void setRefreshCookieAge(int ageInSeconds)
{
_refreshCookieAge=ageInSeconds;
}
-
-
+ /* ------------------------------------------------------------ */
public void setSessionCookie(String cookieName)
{
_sessionCookie=cookieName;
}
-
-
/* ------------------------------------------------------------ */
/**
* @param sessionHandler
* The sessionHandler to set.
*/
+ @Override
public void setSessionHandler(SessionHandler sessionHandler)
{
_sessionHandler=sessionHandler;
@@ -698,6 +644,7 @@
/* ------------------------------------------------------------ */
+ @Override
public void setSessionIdPathParameterName(String param)
{
_sessionIdPathParameterName =(param==null||"none".equals(param))?null:param;
@@ -844,12 +791,14 @@
}
/* ------------------------------------------------------------ */
+ @Override
public Set<SessionTrackingMode> getDefaultSessionTrackingModes()
{
return __defaultSessionTrackingModes;
}
/* ------------------------------------------------------------ */
+ @Override
public Set<SessionTrackingMode> getEffectiveSessionTrackingModes()
{
return Collections.unmodifiableSet(_sessionTrackingModes);
@@ -871,8 +820,8 @@
return _usingURLs;
}
-
/* ------------------------------------------------------------ */
+ @Override
public SessionCookieConfig getSessionCookieConfig()
{
return _cookieConfig;
@@ -917,6 +866,7 @@
/**
* @see org.eclipse.jetty.server.SessionManager#isCheckingRemoteSessionIdEncoding()
*/
+ @Override
@ManagedAttribute("check remote session id encoding")
public boolean isCheckingRemoteSessionIdEncoding()
{
@@ -927,6 +877,7 @@
/**
* @see org.eclipse.jetty.server.SessionManager#setCheckingRemoteSessionIdEncoding(boolean)
*/
+ @Override
public void setCheckingRemoteSessionIdEncoding(boolean remote)
{
_checkingRemoteSessionIdEncoding=remote;
@@ -1091,4 +1042,11 @@
}
}
}
+
+ @Override
+ @Deprecated
+ public SessionIdManager getMetaManager()
+ {
+ throw new UnsupportedOperationException();
+ }
}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/HashSessionManager.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/HashSessionManager.java
index beda6ce..1effd32 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/HashSessionManager.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/HashSessionManager.java
@@ -34,6 +34,7 @@
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
+import org.eclipse.jetty.server.SessionIdManager;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.util.ClassLoadingObjectInputStream;
import org.eclipse.jetty.util.IO;
@@ -60,9 +61,7 @@
final static Logger LOG = SessionHandler.LOG;
protected final ConcurrentMap<String,HashedSession> _sessions=new ConcurrentHashMap<String,HashedSession>();
- private static int __id;
private Scheduler _timer;
- private boolean _timerStop=false;
private Scheduler.Task _task;
long _scavengePeriodMs=30000;
long _savePeriodMs=0; //don't do period saves by default
@@ -134,14 +133,11 @@
@Override
public void doStart() throws Exception
{
- super.doStart();
-
- _timerStop=false;
//try shared scheduler from Server first
_timer = getSessionHandler().getServer().getBean(Scheduler.class);
if (_timer == null)
{
- //try one passwed into the context
+ //try one passed into the context
ServletContext context = ContextHandler.getCurrentContext();
if (context!=null)
_timer = (Scheduler)context.getAttribute("org.eclipse.jetty.server.session.timer");
@@ -149,12 +145,14 @@
if (_timer == null)
{
- //make a scheduler if none useable
- _timerStop=true;
- _timer=new ScheduledExecutorScheduler();
- _timer.start();
+ //make a scheduler if none useable
+ _timer=new ScheduledExecutorScheduler(toString()+"Timer",true);
+ addBean(_timer,true);
}
-
+ else
+ addBean(_timer,false);
+
+ super.doStart();
setScavengePeriod(getScavengePeriod());
@@ -186,8 +184,6 @@
if (_task!=null)
_task.cancel();
_task=null;
- if (_timer!=null && _timerStop)
- _timer.stop();
_timer=null;
}
@@ -427,7 +423,7 @@
/* ------------------------------------------------------------ */
@Override
protected void shutdownSessions() throws Exception
- {
+ {
// Invalidate all sessions to cause unbind events
ArrayList<HashedSession> sessions=new ArrayList<HashedSession>(_sessions.values());
int loop=100;
@@ -672,7 +668,6 @@
if (size>0)
{
ClassLoadingObjectInputStream ois = new ClassLoadingObjectInputStream(is);
-
for (int i=0; i<size;i++)
{
String key = ois.readUTF();
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/AsyncRequestReadTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/AsyncRequestReadTest.java
index c8a4321..2c9fd57 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/AsyncRequestReadTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/AsyncRequestReadTest.java
@@ -59,6 +59,7 @@
server = new Server();
connector = new ServerConnector(server);
connector.setIdleTimeout(10000);
+ connector.getConnectionFactory(HttpConnectionFactory.class).getHttpConfiguration().setSendDateHeader(false);
server.addConnector(connector);
}
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/HttpServerTestFixture.java b/jetty-server/src/test/java/org/eclipse/jetty/server/HttpServerTestFixture.java
index 1636cd4..abce05f 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/HttpServerTestFixture.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/HttpServerTestFixture.java
@@ -68,6 +68,7 @@
protected void startServer(ServerConnector connector) throws Exception
{
_connector = connector;
+ _connector.getConnectionFactory(HttpConnectionFactory.class).getHttpConfiguration().setSendDateHeader(false);
_server.addConnector(_connector);
_server.setHandler(new HandlerWrapper());
_server.start();
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/session/HashSessionManagerTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/session/HashSessionManagerTest.java
index 451cb00..ebd686d 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/session/HashSessionManagerTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/session/HashSessionManagerTest.java
@@ -23,6 +23,7 @@
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
+import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.StdErrLog;
import org.junit.After;
@@ -94,6 +95,7 @@
public void testHashSession() throws Exception
{
File testDir = MavenTestingUtils.getTargetTestingDir("saved");
+ IO.delete(testDir);
testDir.mkdirs();
Server server = new Server();
@@ -109,10 +111,12 @@
AbstractSessionIdManager idManager = new HashSessionIdManager();
idManager.setWorkerName("foo");
manager.setSessionIdManager(idManager);
+ server.setSessionIdManager(idManager);
- idManager.start();
+ server.start();
manager.start();
+
HashedSession session = (HashedSession)manager.newHttpSession(new Request(null, null));
String sessionId = session.getId();
@@ -120,14 +124,12 @@
session.setAttribute("two", new Integer(2));
//stop will persist sessions
- idManager.stop();
manager.setMaxInactiveInterval(30); //change max inactive interval for *new* sessions
manager.stop();
Assert.assertTrue("File should exist!", new File(testDir, session.getId()).exists());
//start will restore sessions
- idManager.start();
manager.start();
HashedSession restoredSession = (HashedSession)manager.getSession(sessionId);
@@ -138,5 +140,7 @@
Assert.assertEquals(1, ((Integer)o).intValue());
Assert.assertEquals(5, restoredSession.getMaxInactiveInterval());
+
+ server.stop();
}
}
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SSLEngineTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SSLEngineTest.java
index 29db142..564e9c1 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SSLEngineTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SSLEngineTest.java
@@ -109,6 +109,7 @@
http.getHttpConfiguration().setRequestHeaderSize(512);
connector=new ServerConnector(server, sslContextFactory, http);
connector.setPort(0);
+ connector.getConnectionFactory(HttpConnectionFactory.class).getHttpConfiguration().setSendDateHeader(false);
server.addConnector(connector);
}
diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java
index 09e57cb..6f0e5b1 100644
--- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java
+++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java
@@ -89,6 +89,10 @@
* Unless run as part of a {@link ServletContextHandler} or derivative, the {@link #initialize()}
* method must be called manually after start().
*/
+
+/* ------------------------------------------------------------ */
+/**
+ */
@ManagedObject("Servlet Handler")
public class ServletHandler extends ScopedHandler
{
@@ -107,6 +111,7 @@
private boolean _filterChainsCached=true;
private int _maxFilterChainsCacheSize=512;
private boolean _startWithUnavailable=false;
+ private boolean _ensureDefaultServlet=true;
private IdentityService _identityService;
private ServletHolder[] _servlets=new ServletHolder[0];
@@ -153,7 +158,7 @@
updateNameMappings();
updateMappings();
- if (getServletMapping("/")==null)
+ if (getServletMapping("/")==null && _ensureDefaultServlet)
{
LOG.debug("Adding Default404Servlet to {}",this);
addServletWithMapping(Default404Servlet.class,"/");
@@ -183,6 +188,26 @@
}
+ /* ------------------------------------------------------------ */
+ /**
+ * @return true if ServletHandler always has a default servlet, using {@link Default404Servlet} if no other
+ * default servlet is configured.
+ */
+ public boolean isEnsureDefaultServlet()
+ {
+ return _ensureDefaultServlet;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @param ensureDefaultServlet true if ServletHandler always has a default servlet, using {@link Default404Servlet} if no other
+ * default servlet is configured.
+ */
+ public void setEnsureDefaultServlet(boolean ensureDefaultServlet)
+ {
+ _ensureDefaultServlet=ensureDefaultServlet;
+ }
+
/* ----------------------------------------------------------------- */
@Override
protected void start(LifeCycle l) throws Exception
@@ -379,8 +404,6 @@
{
return _servletMappings;
}
-
-
/* ------------------------------------------------------------ */
/**
@@ -397,9 +420,6 @@
return _servletPathMappings.get(pathSpec);
}
-
-
-
/* ------------------------------------------------------------ */
/** Get Servlets.
* @return Array of defined servlets
@@ -528,12 +548,7 @@
try
{
if (servlet_holder==null)
- {
- if (getHandler()==null)
- notFound(request, response);
- else
- nextHandle(target,baseRequest,request,response);
- }
+ notFound(baseRequest,request, response);
else
{
// unwrap any tunnelling of base Servlet request/responses
@@ -1511,11 +1526,11 @@
}
/* ------------------------------------------------------------ */
- protected void notFound(HttpServletRequest request, HttpServletResponse response) throws IOException
+ protected void notFound(Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
- if(LOG.isDebugEnabled())
- LOG.debug("Not Found "+request.getRequestURI());
- //Override to send an error back, eg with: response.sendError(HttpServletResponse.SC_NOT_FOUND);
+ LOG.debug("Not Found {}",request.getRequestURI());
+ if (getHandler()!=null)
+ nextHandle(URIUtil.addPaths(request.getServletPath(),request.getPathInfo()),baseRequest,request,response);
}
/* ------------------------------------------------------------ */
@@ -1615,8 +1630,7 @@
// pass to next filter
if (_filterHolder!=null)
{
- if (LOG.isDebugEnabled())
- LOG.debug("call filter " + _filterHolder);
+ LOG.debug("call filter {}", _filterHolder);
Filter filter= _filterHolder.getFilter();
if (_filterHolder.isAsyncSupported())
filter.doFilter(request, response, _next);
@@ -1642,20 +1656,15 @@
}
// Call servlet
-
HttpServletRequest srequest = (HttpServletRequest)request;
- if (_servletHolder != null)
+ if (_servletHolder == null)
+ notFound(baseRequest, srequest, (HttpServletResponse)response);
+ else
{
if (LOG.isDebugEnabled())
LOG.debug("call servlet " + _servletHolder);
_servletHolder.handle(baseRequest,request, response);
}
- else if (getHandler()==null)
- notFound(srequest, (HttpServletResponse)response);
- else
- nextHandle(URIUtil.addPaths(srequest.getServletPath(),srequest.getPathInfo()),
- baseRequest,srequest,(HttpServletResponse)response);
-
}
@Override
@@ -1724,20 +1733,13 @@
// Call servlet
HttpServletRequest srequest = (HttpServletRequest)request;
- if (_servletHolder != null)
- {
- if (LOG.isDebugEnabled())
- LOG.debug("call servlet " + _servletHolder);
- _servletHolder.handle(_baseRequest,request, response);
- }
- else if (getHandler()==null)
- notFound(srequest, (HttpServletResponse)response);
+ if (_servletHolder == null)
+ notFound((request instanceof Request)?((Request)request):HttpChannel.getCurrentHttpChannel().getRequest(), srequest, (HttpServletResponse)response);
else
{
- Request baseRequest=(request instanceof Request)?((Request)request):HttpChannel.getCurrentHttpChannel().getRequest();
- nextHandle(URIUtil.addPaths(srequest.getServletPath(),srequest.getPathInfo()),
- baseRequest,srequest,(HttpServletResponse)response);
- }
+ LOG.debug("call servlet {}", _servletHolder);
+ _servletHolder.handle(_baseRequest,request, response);
+ }
}
/* ------------------------------------------------------------ */
@@ -1795,6 +1797,7 @@
/* ------------------------------------------------------------ */
public static class Default404Servlet extends HttpServlet
{
+ @Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/AsyncContextTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/AsyncContextTest.java
index bbcb708..abfe555 100644
--- a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/AsyncContextTest.java
+++ b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/AsyncContextTest.java
@@ -40,6 +40,7 @@
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.LocalConnector;
import org.eclipse.jetty.server.QuietServletException;
import org.eclipse.jetty.server.Request;
@@ -70,6 +71,7 @@
_contextHandler = new ServletContextHandler(ServletContextHandler.NO_SESSIONS);
_connector = new LocalConnector(_server);
_connector.setIdleTimeout(5000);
+ _connector.getConnectionFactory(HttpConnectionFactory.class).getHttpConfiguration().setSendDateHeader(false);
_server.setConnectors(new Connector[]
{ _connector });
diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/AsyncIOServletTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/AsyncIOServletTest.java
index 563b895..b37f94c 100644
--- a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/AsyncIOServletTest.java
+++ b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/AsyncIOServletTest.java
@@ -18,11 +18,17 @@
package org.eclipse.jetty.servlet;
+import static org.hamcrest.Matchers.*;
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.not;
+import static org.junit.Assert.assertThat;
+
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
+import java.nio.charset.StandardCharsets;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
@@ -30,6 +36,7 @@
import javax.servlet.AsyncContext;
import javax.servlet.ReadListener;
import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
import javax.servlet.WriteListener;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
@@ -39,6 +46,7 @@
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.toolchain.test.http.SimpleHttpParser;
import org.eclipse.jetty.toolchain.test.http.SimpleHttpResponse;
+import org.hamcrest.Matchers;
import org.junit.After;
import org.junit.Assert;
import org.junit.Test;
@@ -56,7 +64,7 @@
connector = new ServerConnector(server);
server.addConnector(connector);
- context = new ServletContextHandler(server, "", false, false);
+ context = new ServletContextHandler(server, "/", false, false);
ServletHolder holder = new ServletHolder(servlet);
holder.setAsyncSupported(true);
context.addServlet(holder, path);
@@ -111,7 +119,8 @@
@Override
public void onError(Throwable t)
{
- Assert.assertSame(throwable, t);
+ Assert.assertThat("onError type",t,instanceOf(throwable.getClass()));
+ Assert.assertThat("onError message",t.getMessage(),is(throwable.getMessage()));
latch.countDown();
response.setStatus(500);
asyncContext.complete();
@@ -231,10 +240,10 @@
@Override
public void onError(Throwable t)
{
- Assert.assertSame(throwable, t);
latch.countDown();
response.setStatus(500);
asyncContext.complete();
+ Assert.assertSame(throwable, t);
}
});
}
@@ -257,4 +266,81 @@
Assert.assertEquals("500", response.getCode());
}
}
+
+
+ @Test
+ public void testAsyncWriteClosed() throws Exception
+ {
+ final CountDownLatch latch = new CountDownLatch(1);
+ String text = "Now is the winter of our discontent. How Now Brown Cow. The quick brown fox jumped over the lazy dog.\n";
+ for (int i=0;i<10;i++)
+ text=text+text;
+ final byte[] data = text.getBytes(StandardCharsets.ISO_8859_1);
+
+ startServer(new HttpServlet()
+ {
+ @Override
+ protected void service(HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException
+ {
+ response.flushBuffer();
+
+ final AsyncContext async = request.startAsync();
+ final ServletOutputStream out = response.getOutputStream();
+ out.setWriteListener(new WriteListener()
+ {
+ @Override
+ public void onWritePossible() throws IOException
+ {
+ while (out.isReady())
+ {
+ try
+ {
+ Thread.sleep(100);
+ out.write(data);
+ }
+ catch(IOException e)
+ {
+ throw e;
+ }
+ catch(Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ @Override
+ public void onError(Throwable t)
+ {
+ async.complete();
+ latch.countDown();
+ }
+ });
+ }
+ });
+
+ String request = "GET " + path + " HTTP/1.1\r\n" +
+ "Host: localhost:" + connector.getLocalPort() + "\r\n" +
+ "\r\n";
+
+ try (Socket client = new Socket("localhost", connector.getLocalPort()))
+ {
+ OutputStream output = client.getOutputStream();
+ output.write(request.getBytes("UTF-8"));
+ output.flush();
+
+ BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
+ String line=in.readLine();
+ assertThat(line, containsString("200 OK"));
+ while (line.length()>0)
+ line=in.readLine();
+ line=in.readLine();
+ assertThat(line, not(containsString(" ")));
+ line=in.readLine();
+ assertThat(line, containsString("discontent. How Now Brown Cow. The "));
+ }
+
+ if (!latch.await(5, TimeUnit.SECONDS))
+ Assert.fail();
+ }
}
diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DispatcherTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DispatcherTest.java
index 6bc920f..8ed551d 100644
--- a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DispatcherTest.java
+++ b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DispatcherTest.java
@@ -78,6 +78,7 @@
_server = new Server();
_connector = new LocalConnector(_server);
_connector.getConnectionFactory(HttpConfiguration.ConnectionFactory.class).getHttpConfiguration().setSendServerVersion(false);
+ _connector.getConnectionFactory(HttpConfiguration.ConnectionFactory.class).getHttpConfiguration().setSendDateHeader(false);
_contextCollection = new ContextHandlerCollection();
_contextHandler = new ServletContextHandler();
diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/InvokerTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/InvokerTest.java
index 13dface..d94f6cd 100644
--- a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/InvokerTest.java
+++ b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/InvokerTest.java
@@ -49,6 +49,7 @@
_server = new Server();
_connector = new LocalConnector(_server);
_connector.getConnectionFactory(HttpConfiguration.ConnectionFactory.class).getHttpConfiguration().setSendServerVersion(false);
+ _connector.getConnectionFactory(HttpConfiguration.ConnectionFactory.class).getHttpConfiguration().setSendDateHeader(false);
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
_server.addConnector(_connector);
diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/ServletContextHandlerTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/ServletContextHandlerTest.java
index c4b4699..7ebbe2b 100644
--- a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/ServletContextHandlerTest.java
+++ b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/ServletContextHandlerTest.java
@@ -40,13 +40,18 @@
import org.eclipse.jetty.security.ConstraintSecurityHandler;
import org.eclipse.jetty.security.SecurityHandler;
+import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.LocalConnector;
+import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.server.handler.AbstractHandlerContainer;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
+import org.eclipse.jetty.server.handler.HandlerList;
import org.eclipse.jetty.server.handler.ResourceHandler;
import org.eclipse.jetty.server.session.SessionHandler;
+import org.eclipse.jetty.util.component.LifeCycle.Listener;
import org.hamcrest.Matchers;
import org.junit.After;
import org.junit.Assert;
@@ -276,7 +281,37 @@
assertTrue(contextDestroy.get());
}
-
+
+ @Test
+ public void testFallThrough() throws Exception
+ {
+ HandlerList list = new HandlerList();
+ _server.setHandler(list);
+
+ ServletContextHandler root = new ServletContextHandler(list,"/",ServletContextHandler.SESSIONS);
+
+ ServletHandler servlet = root.getServletHandler();
+ servlet.setEnsureDefaultServlet(false);
+ servlet.addServletWithMapping(HelloServlet.class, "/hello/*");
+
+ list.addHandler(new AbstractHandler()
+ {
+ @Override
+ public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ {
+ response.sendError(404, "Fell Through");
+ }
+ });
+
+ _server.start();
+
+ String response= _connector.getResponses("GET /hello HTTP/1.0\r\n\r\n");
+ Assert.assertThat(response, Matchers.containsString("200 OK"));
+
+ response= _connector.getResponses("GET /other HTTP/1.0\r\n\r\n");
+ Assert.assertThat(response, Matchers.containsString("404 Fell Through"));
+
+ }
private int assertResponseContains(String expected, String response)
{
diff --git a/jetty-start/src/main/java/org/eclipse/jetty/start/PathMatchers.java b/jetty-start/src/main/java/org/eclipse/jetty/start/PathMatchers.java
index 609c8b2..58ce0ca 100644
--- a/jetty-start/src/main/java/org/eclipse/jetty/start/PathMatchers.java
+++ b/jetty-start/src/main/java/org/eclipse/jetty/start/PathMatchers.java
@@ -47,7 +47,7 @@
}
}
}
-
+
private static final char GLOB_CHARS[] = "*?".toCharArray();
private static final char SYNTAXED_GLOB_CHARS[] = "{}[]|:".toCharArray();
private static final Path EMPTY_PATH = new File(".").toPath();
@@ -167,7 +167,12 @@
*/
public static boolean isAbsolute(final String pattern)
{
- return asPath(pattern).isAbsolute();
+ Path searchRoot = getSearchRoot(pattern);
+ if (searchRoot == EMPTY_PATH)
+ {
+ return false;
+ }
+ return searchRoot.isAbsolute();
}
/**
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/log/Log.java b/jetty-util/src/main/java/org/eclipse/jetty/util/log/Log.java
index 7d998b3..57838f2 100644
--- a/jetty-util/src/main/java/org/eclipse/jetty/util/log/Log.java
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/log/Log.java
@@ -151,33 +151,32 @@
public static void initialized()
{
-
synchronized (Log.class)
{
if (__initialized)
return;
__initialized = true;
- }
-
- final long uptime=ManagementFactory.getRuntimeMXBean().getUptime();
- try
- {
- Class<?> log_class = Loader.loadClass(Log.class, __logClass);
- if (LOG == null || !LOG.getClass().equals(log_class))
+ final long uptime=ManagementFactory.getRuntimeMXBean().getUptime();
+
+ try
{
- LOG = (Logger)log_class.newInstance();
- LOG.debug("Logging to {} via {}", LOG, log_class.getName());
+ Class<?> log_class = Loader.loadClass(Log.class, __logClass);
+ if (LOG == null || !LOG.getClass().equals(log_class))
+ {
+ LOG = (Logger)log_class.newInstance();
+ LOG.debug("Logging to {} via {}", LOG, log_class.getName());
+ }
}
+ catch(Throwable e)
+ {
+ // Unable to load specified Logger implementation, default to standard logging.
+ initStandardLogging(e);
+ }
+
+ if (LOG!=null)
+ LOG.info(String.format("Logging initialized @%dms",uptime));
}
- catch(Throwable e)
- {
- // Unable to load specified Logger implementation, default to standard logging.
- initStandardLogging(e);
- }
-
- if (LOG!=null)
- LOG.info(String.format("Logging initialized @%dms",uptime));
}
private static void initStandardLogging(Throwable e)
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/resource/Resource.java b/jetty-util/src/main/java/org/eclipse/jetty/util/resource/Resource.java
index 401e75a..623731a 100644
--- a/jetty-util/src/main/java/org/eclipse/jetty/util/resource/Resource.java
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/resource/Resource.java
@@ -46,6 +46,10 @@
/* ------------------------------------------------------------ */
/**
* Abstract resource class.
+ * <p>
+ * This class provides a resource abstraction, where a resource may be
+ * a file, a URL or an entry in a jar file.
+ * </p>
*/
public abstract class Resource implements ResourceFactory, Closeable
{
diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/StandardDescriptorProcessor.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/StandardDescriptorProcessor.java
index 06cd46f..ad7bbd7 100644
--- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/StandardDescriptorProcessor.java
+++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/StandardDescriptorProcessor.java
@@ -1417,12 +1417,13 @@
{
jsp_pg_servlet=new ServletHolder(JspPropertyGroupServlet.NAME,new JspPropertyGroupServlet(context,handler));
_servletHolderMap.put(JspPropertyGroupServlet.NAME,jsp_pg_servlet);
+ _servletHolders.add(jsp_pg_servlet);
}
ServletMapping mapping = new ServletMapping();
mapping.setServletName(JspPropertyGroupServlet.NAME);
mapping.setPathSpecs(paths.toArray(new String[paths.size()]));
- context.getServletHandler().addServletMapping(mapping);
+ _servletMappings.add(mapping);
}
}
diff --git a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/endpoints/AbstractJsrEventDriver.java b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/endpoints/AbstractJsrEventDriver.java
index 3b91b38..d7b9ced 100644
--- a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/endpoints/AbstractJsrEventDriver.java
+++ b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/endpoints/AbstractJsrEventDriver.java
@@ -31,11 +31,10 @@
import org.eclipse.jetty.websocket.common.CloseInfo;
import org.eclipse.jetty.websocket.common.WebSocketSession;
import org.eclipse.jetty.websocket.common.events.AbstractEventDriver;
-import org.eclipse.jetty.websocket.common.events.EventDriver;
import org.eclipse.jetty.websocket.jsr356.JsrSession;
import org.eclipse.jetty.websocket.jsr356.metadata.EndpointMetadata;
-public abstract class AbstractJsrEventDriver extends AbstractEventDriver implements EventDriver
+public abstract class AbstractJsrEventDriver extends AbstractEventDriver
{
protected final EndpointMetadata metadata;
protected final EndpointConfig config;
diff --git a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/endpoints/JsrAnnotatedEventDriver.java b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/endpoints/JsrAnnotatedEventDriver.java
index a550c20..0cf9df7 100644
--- a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/endpoints/JsrAnnotatedEventDriver.java
+++ b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/endpoints/JsrAnnotatedEventDriver.java
@@ -23,6 +23,7 @@
import java.io.Reader;
import java.nio.ByteBuffer;
import java.util.Map;
+
import javax.websocket.CloseReason;
import javax.websocket.DecodeException;
@@ -31,7 +32,6 @@
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.events.EventDriver;
import org.eclipse.jetty.websocket.common.message.MessageInputStream;
import org.eclipse.jetty.websocket.common.message.MessageReader;
import org.eclipse.jetty.websocket.common.message.SimpleBinaryMessage;
@@ -44,7 +44,7 @@
/**
* Base implementation for JSR-356 Annotated event drivers.
*/
-public class JsrAnnotatedEventDriver extends AbstractJsrEventDriver implements EventDriver
+public class JsrAnnotatedEventDriver extends AbstractJsrEventDriver
{
private static final Logger LOG = Log.getLogger(JsrAnnotatedEventDriver.class);
private final JsrEvents<?, ?> events;
diff --git a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/endpoints/JsrEndpointEventDriver.java b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/endpoints/JsrEndpointEventDriver.java
index b977147..9ac4906 100644
--- a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/endpoints/JsrEndpointEventDriver.java
+++ b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/endpoints/JsrEndpointEventDriver.java
@@ -23,6 +23,7 @@
import java.io.Reader;
import java.nio.ByteBuffer;
import java.util.Map;
+
import javax.websocket.CloseReason;
import javax.websocket.Endpoint;
import javax.websocket.MessageHandler;
@@ -34,7 +35,6 @@
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.events.EventDriver;
import org.eclipse.jetty.websocket.common.message.MessageInputStream;
import org.eclipse.jetty.websocket.common.message.MessageReader;
import org.eclipse.jetty.websocket.jsr356.JsrPongMessage;
@@ -49,7 +49,7 @@
/**
* EventDriver for websocket that extend from {@link javax.websocket.Endpoint}
*/
-public class JsrEndpointEventDriver extends AbstractJsrEventDriver implements EventDriver
+public class JsrEndpointEventDriver extends AbstractJsrEventDriver
{
private static final Logger LOG = Log.getLogger(JsrEndpointEventDriver.class);
diff --git a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/ConfiguratorTest.java b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/ConfiguratorTest.java
index 045118a..f6cdb3b 100644
--- a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/ConfiguratorTest.java
+++ b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/ConfiguratorTest.java
@@ -37,6 +37,7 @@
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.servlet.ServletContextHandler;
+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.util.QuoteUtil;
@@ -44,7 +45,6 @@
import org.eclipse.jetty.websocket.common.frames.TextFrame;
import org.eclipse.jetty.websocket.common.test.BlockheadClient;
import org.eclipse.jetty.websocket.common.test.HttpResponse;
-import org.eclipse.jetty.websocket.common.test.IncomingFramesCapture;
import org.eclipse.jetty.websocket.jsr356.server.deploy.WebSocketServerContainerInitializer;
import org.junit.AfterClass;
import org.junit.Assert;
@@ -210,8 +210,8 @@
client.expectUpgradeResponse();
client.write(new TextFrame().setPayload("X-Dummy"));
- IncomingFramesCapture capture = client.readFrames(1,TimeUnit.SECONDS,1);
- WebSocketFrame frame = capture.getFrames().poll();
+ EventQueue<WebSocketFrame> frames = client.readFrames(1,1,TimeUnit.SECONDS);
+ WebSocketFrame frame = frames.poll();
Assert.assertThat("Frame Response", frame.getPayloadAsUTF8(), is("Request Header [X-Dummy]: \"Bogus\""));
}
}
diff --git a/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/io/ConnectionManager.java b/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/io/ConnectionManager.java
index da112f9..ab20d77 100644
--- a/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/io/ConnectionManager.java
+++ b/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/io/ConnectionManager.java
@@ -32,6 +32,7 @@
import org.eclipse.jetty.util.component.ContainerLifeCycle;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.websocket.api.StatusCode;
import org.eclipse.jetty.websocket.api.WebSocketException;
import org.eclipse.jetty.websocket.client.ClientUpgradeRequest;
import org.eclipse.jetty.websocket.client.WebSocketClient;
@@ -158,7 +159,7 @@
sessions.add(session);
}
- private void closeAllConnections()
+ private void shutdownAllConnections()
{
for (WebSocketSession session : sessions)
{
@@ -166,11 +167,13 @@
{
try
{
- session.getConnection().close();
+ session.getConnection().close(
+ StatusCode.SHUTDOWN,
+ "Shutdown");
}
catch (Throwable t)
{
- LOG.debug("During Close All Connections",t);
+ LOG.debug("During Shutdown All Connections",t);
}
}
}
@@ -203,7 +206,7 @@
@Override
protected void doStop() throws Exception
{
- closeAllConnections();
+ shutdownAllConnections();
sessions.clear();
super.doStop();
removeBean(selector);
diff --git a/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/io/WebSocketClientSelectorManager.java b/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/io/WebSocketClientSelectorManager.java
index 928e911..6616f54 100644
--- a/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/io/WebSocketClientSelectorManager.java
+++ b/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/io/WebSocketClientSelectorManager.java
@@ -98,7 +98,7 @@
else
{
// Standard "ws://"
- endPoint.setIdleTimeout(connectPromise.getClient().getMaxIdleTimeout());
+ endPoint.setIdleTimeout(connectPromise.getDriver().getPolicy().getIdleTimeout());
return newUpgradeConnection(channel,endPoint,connectPromise);
}
}
@@ -139,4 +139,9 @@
{
this.sslContextFactory = sslContextFactory;
}
+
+ public WebSocketPolicy getPolicy()
+ {
+ return policy;
+ }
}
diff --git a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/ClientCloseTest.java b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/ClientCloseTest.java
new file mode 100644
index 0000000..2b1f824
--- /dev/null
+++ b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/ClientCloseTest.java
@@ -0,0 +1,624 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.opensource.org/licenses/apache2.0.php
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+//
+
+package org.eclipse.jetty.websocket.client;
+
+import static org.hamcrest.Matchers.*;
+
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.nio.ByteBuffer;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.SocketChannel;
+import java.util.Arrays;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.io.EofException;
+import org.eclipse.jetty.io.SelectChannelEndPoint;
+import org.eclipse.jetty.io.SelectorManager.ManagedSelector;
+import org.eclipse.jetty.toolchain.test.EventQueue;
+import org.eclipse.jetty.toolchain.test.TestTracker;
+import org.eclipse.jetty.util.BufferUtil;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.thread.Scheduler;
+import org.eclipse.jetty.websocket.api.ProtocolException;
+import org.eclipse.jetty.websocket.api.Session;
+import org.eclipse.jetty.websocket.api.StatusCode;
+import org.eclipse.jetty.websocket.api.WebSocketAdapter;
+import org.eclipse.jetty.websocket.client.io.ConnectionManager;
+import org.eclipse.jetty.websocket.client.io.WebSocketClientSelectorManager;
+import org.eclipse.jetty.websocket.common.CloseInfo;
+import org.eclipse.jetty.websocket.common.OpCode;
+import org.eclipse.jetty.websocket.common.WebSocketFrame;
+import org.eclipse.jetty.websocket.common.WebSocketSession;
+import org.eclipse.jetty.websocket.common.frames.TextFrame;
+import org.eclipse.jetty.websocket.common.io.AbstractWebSocketConnection;
+import org.eclipse.jetty.websocket.common.test.BlockheadServer;
+import org.eclipse.jetty.websocket.common.test.BlockheadServer.ServerConnection;
+import org.eclipse.jetty.websocket.common.test.IncomingFramesCapture;
+import org.eclipse.jetty.websocket.common.test.RawFrameBuilder;
+import org.hamcrest.Matcher;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+public class ClientCloseTest
+{
+ private static final Logger LOG = Log.getLogger(ClientCloseTest.class);
+
+ private static class CloseTrackingSocket extends WebSocketAdapter
+ {
+ private static final Logger LOG = Log.getLogger(ClientCloseTest.CloseTrackingSocket.class);
+
+ public int closeCode = -1;
+ public String closeReason = null;
+ public CountDownLatch closeLatch = new CountDownLatch(1);
+ public CountDownLatch openLatch = new CountDownLatch(1);
+
+ public EventQueue<String> messageQueue = new EventQueue<>();
+ public EventQueue<Throwable> errorQueue = new EventQueue<>();
+
+ public void assertNoCloseEvent()
+ {
+ Assert.assertThat("Client Close Event",closeLatch.getCount(),is(1L));
+ Assert.assertThat("Client Close Event Status Code ",closeCode,is(-1));
+ }
+
+ public void assertReceivedCloseEvent(int clientTimeoutMs, Matcher<Integer> statusCodeMatcher, Matcher<String> reasonMatcher)
+ throws InterruptedException
+ {
+ long maxTimeout = clientTimeoutMs * 2;
+
+ Assert.assertThat("Client Close Event Occurred",closeLatch.await(maxTimeout,TimeUnit.MILLISECONDS),is(true));
+ Assert.assertThat("Client Close Event Status Code",closeCode,statusCodeMatcher);
+ if (reasonMatcher == null)
+ {
+ Assert.assertThat("Client Close Event Reason",closeReason,nullValue());
+ }
+ else
+ {
+ Assert.assertThat("Client Close Event Reason",closeReason,reasonMatcher);
+ }
+ }
+
+ public void assertReceivedError(Class<? extends Throwable> expectedThrownClass, Matcher<String> messageMatcher) throws TimeoutException,
+ InterruptedException
+ {
+ errorQueue.awaitEventCount(1,500,TimeUnit.MILLISECONDS);
+ Throwable actual = errorQueue.poll();
+ Assert.assertThat("Client Error Event",actual,instanceOf(expectedThrownClass));
+ if (messageMatcher == null)
+ {
+ Assert.assertThat("Client Error Event Message",actual.getMessage(),nullValue());
+ }
+ else
+ {
+ Assert.assertThat("Client Error Event Message",actual.getMessage(),messageMatcher);
+ }
+ }
+
+ public void clearQueues()
+ {
+ messageQueue.clear();
+ errorQueue.clear();
+ }
+
+ @Override
+ public void onWebSocketClose(int statusCode, String reason)
+ {
+ LOG.debug("onWebSocketClose({},{})",statusCode,reason);
+ super.onWebSocketClose(statusCode,reason);
+ closeCode = statusCode;
+ closeReason = reason;
+ closeLatch.countDown();
+ }
+
+ @Override
+ public void onWebSocketConnect(Session session)
+ {
+ super.onWebSocketConnect(session);
+ openLatch.countDown();
+ }
+
+ @Override
+ public void onWebSocketError(Throwable cause)
+ {
+ LOG.debug("onWebSocketError",cause);
+ Assert.assertThat("Error capture",errorQueue.offer(cause),is(true));
+ }
+
+ @Override
+ public void onWebSocketText(String message)
+ {
+ LOG.debug("onWebSocketText({})",message);
+ messageQueue.offer(message);
+ }
+
+ public EndPoint getEndPoint() throws Exception
+ {
+ Session session = getSession();
+ Assert.assertThat("Session type",session,instanceOf(WebSocketSession.class));
+
+ WebSocketSession wssession = (WebSocketSession)session;
+ Field fld = wssession.getClass().getDeclaredField("connection");
+ fld.setAccessible(true);
+ Assert.assertThat("Field: connection",fld,notNullValue());
+
+ Object val = fld.get(wssession);
+ Assert.assertThat("Connection type",val,instanceOf(AbstractWebSocketConnection.class));
+ @SuppressWarnings("resource")
+ AbstractWebSocketConnection wsconn = (AbstractWebSocketConnection)val;
+ return wsconn.getEndPoint();
+ }
+ }
+
+ @Rule
+ public TestTracker tt = new TestTracker();
+
+ private BlockheadServer server;
+ private WebSocketClient client;
+
+ private void confirmConnection(CloseTrackingSocket clientSocket, Future<Session> clientFuture, ServerConnection serverConn) throws Exception
+ {
+ // Wait for client connect on via future
+ clientFuture.get(500,TimeUnit.MILLISECONDS);
+
+ // Wait for client connect via client websocket
+ Assert.assertThat("Client WebSocket is Open",clientSocket.openLatch.await(500,TimeUnit.MILLISECONDS),is(true));
+
+ try
+ {
+ // Send message from client to server
+ final String echoMsg = "echo-test";
+ Future<Void> testFut = clientSocket.getRemote().sendStringByFuture(echoMsg);
+
+ // Wait for send future
+ testFut.get(500,TimeUnit.MILLISECONDS);
+
+ // Read Frame on server side
+ IncomingFramesCapture serverCapture = serverConn.readFrames(1,500,TimeUnit.MILLISECONDS);
+ serverCapture.assertNoErrors();
+ serverCapture.assertFrameCount(1);
+ WebSocketFrame frame = serverCapture.getFrames().poll();
+ Assert.assertThat("Server received frame",frame.getOpCode(),is(OpCode.TEXT));
+ Assert.assertThat("Server received frame payload",frame.getPayloadAsUTF8(),is(echoMsg));
+
+ // Server send echo reply
+ serverConn.write(new TextFrame().setPayload(echoMsg));
+
+ // Wait for received echo
+ clientSocket.messageQueue.awaitEventCount(1,1,TimeUnit.SECONDS);
+
+ // Verify received message
+ String recvMsg = clientSocket.messageQueue.poll();
+ Assert.assertThat("Received message",recvMsg,is(echoMsg));
+
+ // Verify that there are no errors
+ Assert.assertThat("Error events",clientSocket.errorQueue,empty());
+ }
+ finally
+ {
+ clientSocket.clearQueues();
+ }
+ }
+
+ private void confirmServerReceivedCloseFrame(ServerConnection serverConn, int expectedCloseCode, Matcher<String> closeReasonMatcher) throws IOException,
+ TimeoutException
+ {
+ IncomingFramesCapture serverCapture = serverConn.readFrames(1,500,TimeUnit.MILLISECONDS);
+ serverCapture.assertNoErrors();
+ serverCapture.assertFrameCount(1);
+ serverCapture.assertHasFrame(OpCode.CLOSE,1);
+ WebSocketFrame frame = serverCapture.getFrames().poll();
+ Assert.assertThat("Server received close frame",frame.getOpCode(),is(OpCode.CLOSE));
+ CloseInfo closeInfo = new CloseInfo(frame);
+ Assert.assertThat("Server received close code",closeInfo.getStatusCode(),is(expectedCloseCode));
+ if (closeReasonMatcher == null)
+ {
+ Assert.assertThat("Server received close reason",closeInfo.getReason(),nullValue());
+ }
+ else
+ {
+ Assert.assertThat("Server received close reason",closeInfo.getReason(),closeReasonMatcher);
+ }
+ }
+
+ public static class TestWebSocketClient extends WebSocketClient
+ {
+ @Override
+ protected ConnectionManager newConnectionManager()
+ {
+ return new TestConnectionManager(this);
+ }
+ }
+
+ public static class TestConnectionManager extends ConnectionManager
+ {
+ public TestConnectionManager(WebSocketClient client)
+ {
+ super(client);
+ }
+
+ @Override
+ protected WebSocketClientSelectorManager newWebSocketClientSelectorManager(WebSocketClient client)
+ {
+ return new TestSelectorManager(client);
+ }
+ }
+
+ public static class TestSelectorManager extends WebSocketClientSelectorManager
+ {
+ public TestSelectorManager(WebSocketClient client)
+ {
+ super(client);
+ }
+
+ @Override
+ protected EndPoint newEndPoint(SocketChannel channel, ManagedSelector selectSet, SelectionKey selectionKey) throws IOException
+ {
+ return new TestEndPoint(channel,selectSet,selectionKey,getScheduler(),getPolicy().getIdleTimeout());
+ }
+ }
+
+ public static class TestEndPoint extends SelectChannelEndPoint
+ {
+ public AtomicBoolean congestedFlush = new AtomicBoolean(false);
+
+ public TestEndPoint(SocketChannel channel, ManagedSelector selector, SelectionKey key, Scheduler scheduler, long idleTimeout)
+ {
+ super(channel,selector,key,scheduler,idleTimeout);
+ }
+
+ @Override
+ public boolean flush(ByteBuffer... buffers) throws IOException
+ {
+ boolean flushed = super.flush(buffers);
+ congestedFlush.set(!flushed);
+ return flushed;
+ }
+ }
+
+ @Before
+ public void startClient() throws Exception
+ {
+ client = new TestWebSocketClient();
+ client.start();
+ }
+
+ @Before
+ public void startServer() throws Exception
+ {
+ server = new BlockheadServer();
+ server.start();
+ }
+
+ @After
+ public void stopClient() throws Exception
+ {
+ if (client.isRunning())
+ {
+ client.stop();
+ }
+ }
+
+ @After
+ public void stopServer() throws Exception
+ {
+ server.stop();
+ }
+
+ @Test
+ public void testHalfClose() throws Exception
+ {
+ // Set client timeout
+ final int timeout = 1000;
+ client.setMaxIdleTimeout(timeout);
+
+ // Client connects
+ CloseTrackingSocket clientSocket = new CloseTrackingSocket();
+ Future<Session> clientConnectFuture = client.connect(clientSocket,server.getWsUri());
+
+ // Server accepts connect
+ ServerConnection serverConn = server.accept();
+ serverConn.upgrade();
+
+ // client confirms connection via echo
+ confirmConnection(clientSocket,clientConnectFuture,serverConn);
+
+ // client sends close frame (code 1000, normal)
+ final String origCloseReason = "Normal Close";
+ clientSocket.getSession().close(StatusCode.NORMAL,origCloseReason);
+
+ // server receives close frame
+ confirmServerReceivedCloseFrame(serverConn,StatusCode.NORMAL,is(origCloseReason));
+
+ // server sends 2 messages
+ serverConn.write(new TextFrame().setPayload("Hello"));
+ serverConn.write(new TextFrame().setPayload("World"));
+
+ // server sends close frame (code 1000, no reason)
+ CloseInfo sclose = new CloseInfo(StatusCode.NORMAL,"From Server");
+ serverConn.write(sclose.asFrame());
+
+ // client receives 2 messages
+ clientSocket.messageQueue.awaitEventCount(2,1,TimeUnit.SECONDS);
+
+ // Verify received messages
+ String recvMsg = clientSocket.messageQueue.poll();
+ Assert.assertThat("Received message 1",recvMsg,is("Hello"));
+ recvMsg = clientSocket.messageQueue.poll();
+ Assert.assertThat("Received message 2",recvMsg,is("World"));
+
+ // Verify that there are no errors
+ Assert.assertThat("Error events",clientSocket.errorQueue,empty());
+
+ // client close event on ws-endpoint
+ clientSocket.assertReceivedCloseEvent(timeout,is(StatusCode.NORMAL),containsString("From Server"));
+ }
+
+ @Test
+ public void testNetworkCongestion() throws Exception
+ {
+ // Set client timeout
+ final int timeout = 1000;
+ client.setMaxIdleTimeout(timeout);
+
+ // Client connects
+ CloseTrackingSocket clientSocket = new CloseTrackingSocket();
+ Future<Session> clientConnectFuture = client.connect(clientSocket,server.getWsUri());
+
+ // Server accepts connect
+ ServerConnection serverConn = server.accept();
+ serverConn.upgrade();
+
+ // client confirms connection via echo
+ confirmConnection(clientSocket,clientConnectFuture,serverConn);
+
+ // client sends BIG frames (until it cannot write anymore)
+ // server must not read (for test purpose, in order to congest connection)
+ // when write is congested, client enqueue close frame
+ // client initiate write, but write never completes
+ EndPoint endp = clientSocket.getEndPoint();
+ Assert.assertThat("EndPoint is testable",endp,instanceOf(TestEndPoint.class));
+ TestEndPoint testendp = (TestEndPoint)endp;
+
+ char msg[] = new char[10240];
+ int writeCount = 0;
+ long writeSize = 0;
+ int i = 0;
+ while (!testendp.congestedFlush.get())
+ {
+ int z = i - ((i / 26) * 26);
+ char c = (char)('a' + z);
+ Arrays.fill(msg,c);
+ clientSocket.getRemote().sendStringByFuture(String.valueOf(msg));
+ writeCount++;
+ writeSize += msg.length;
+ }
+ LOG.debug("Wrote {} frames totalling {} bytes of payload before congestion kicked in",writeCount,writeSize);
+
+ // Verify that there are no errors
+ Assert.assertThat("Error events",clientSocket.errorQueue,empty());
+
+ // client idle timeout triggers close event on client ws-endpoint
+ // client close event on ws-endpoint
+ clientSocket.assertReceivedCloseEvent(timeout,is(StatusCode.SHUTDOWN),containsString("Timeout"));
+ }
+
+ @Test
+ public void testProtocolException() throws Exception
+ {
+ // Set client timeout
+ final int timeout = 1000;
+ client.setMaxIdleTimeout(timeout);
+
+ // Client connects
+ CloseTrackingSocket clientSocket = new CloseTrackingSocket();
+ Future<Session> clientConnectFuture = client.connect(clientSocket,server.getWsUri());
+
+ // Server accepts connect
+ ServerConnection serverConn = server.accept();
+ serverConn.upgrade();
+
+ // client confirms connection via echo
+ confirmConnection(clientSocket,clientConnectFuture,serverConn);
+
+ // client should not have received close message (yet)
+ clientSocket.assertNoCloseEvent();
+
+ // server sends bad close frame (too big of a reason message)
+ byte msg[] = new byte[400];
+ Arrays.fill(msg,(byte)'x');
+ ByteBuffer bad = ByteBuffer.allocate(500);
+ RawFrameBuilder.putOpFin(bad,OpCode.CLOSE,true);
+ RawFrameBuilder.putLength(bad,msg.length + 2,false);
+ bad.putShort((short)StatusCode.NORMAL);
+ bad.put(msg);
+ BufferUtil.flipToFlush(bad,0);
+ serverConn.write(bad);
+
+ // client should have noticed the error
+ clientSocket.assertReceivedError(ProtocolException.class,containsString("Invalid control frame"));
+
+ // client parse invalid frame, notifies server of close (protocol error)
+ confirmServerReceivedCloseFrame(serverConn,StatusCode.PROTOCOL,allOf(containsString("Invalid control frame"),containsString("length")));
+
+ // server disconnects
+ serverConn.disconnect();
+
+ // client triggers close event on client ws-endpoint
+ clientSocket.assertReceivedCloseEvent(timeout,is(StatusCode.PROTOCOL),allOf(containsString("Invalid control frame"),containsString("length")));
+ }
+
+ @Test
+ public void testReadEOF() throws Exception
+ {
+ // Set client timeout
+ final int timeout = 1000;
+ client.setMaxIdleTimeout(timeout);
+
+ // Client connects
+ CloseTrackingSocket clientSocket = new CloseTrackingSocket();
+ Future<Session> clientConnectFuture = client.connect(clientSocket,server.getWsUri());
+
+ // Server accepts connect
+ ServerConnection serverConn = server.accept();
+ serverConn.upgrade();
+
+ // client confirms connection via echo
+ confirmConnection(clientSocket,clientConnectFuture,serverConn);
+
+ // client sends close frame
+ final String origCloseReason = "Normal Close";
+ clientSocket.getSession().close(StatusCode.NORMAL,origCloseReason);
+
+ // server receives close frame
+ confirmServerReceivedCloseFrame(serverConn,StatusCode.NORMAL,is(origCloseReason));
+
+ // client should not have received close message (yet)
+ clientSocket.assertNoCloseEvent();
+
+ // server shuts down connection (no frame reply)
+ serverConn.disconnect();
+
+ // client reads -1 (EOF)
+ // client triggers close event on client ws-endpoint
+ clientSocket.assertReceivedCloseEvent(timeout,is(StatusCode.ABNORMAL),containsString("EOF"));
+ }
+
+ @Test
+ public void testServerNoCloseHandshake() throws Exception
+ {
+ // Set client timeout
+ final int timeout = 1000;
+ client.setMaxIdleTimeout(timeout);
+
+ // Client connects
+ CloseTrackingSocket clientSocket = new CloseTrackingSocket();
+ Future<Session> clientConnectFuture = client.connect(clientSocket,server.getWsUri());
+
+ // Server accepts connect
+ ServerConnection serverConn = server.accept();
+ serverConn.upgrade();
+
+ // client confirms connection via echo
+ confirmConnection(clientSocket,clientConnectFuture,serverConn);
+
+ // client sends close frame
+ final String origCloseReason = "Normal Close";
+ clientSocket.getSession().close(StatusCode.NORMAL,origCloseReason);
+
+ // server receives close frame
+ confirmServerReceivedCloseFrame(serverConn,StatusCode.NORMAL,is(origCloseReason));
+
+ // client should not have received close message (yet)
+ clientSocket.assertNoCloseEvent();
+
+ // server never sends close frame handshake
+ // server sits idle
+
+ // client idle timeout triggers close event on client ws-endpoint
+ clientSocket.assertReceivedCloseEvent(timeout,is(StatusCode.SHUTDOWN),containsString("Timeout"));
+ }
+
+ @Test
+ public void testStopLifecycle() throws Exception
+ {
+ // Set client timeout
+ final int timeout = 1000;
+ client.setMaxIdleTimeout(timeout);
+
+ int clientCount = 3;
+ CloseTrackingSocket clientSockets[] = new CloseTrackingSocket[clientCount];
+ ServerConnection serverConns[] = new ServerConnection[clientCount];
+
+ // Connect Multiple Clients
+ for (int i = 0; i < clientCount; i++)
+ {
+ // Client Request Upgrade
+ clientSockets[i] = new CloseTrackingSocket();
+ Future<Session> clientConnectFuture = client.connect(clientSockets[i],server.getWsUri());
+
+ // Server accepts connection
+ serverConns[i] = server.accept();
+ serverConns[i].upgrade();
+
+ // client confirms connection via echo
+ confirmConnection(clientSockets[i],clientConnectFuture,serverConns[i]);
+ }
+
+ // client lifecycle stop
+ client.stop();
+
+ // clients send close frames (code 1001, shutdown)
+ for (int i = 0; i < clientCount; i++)
+ {
+ // server receives close frame
+ confirmServerReceivedCloseFrame(serverConns[i],StatusCode.SHUTDOWN,containsString("Shutdown"));
+ }
+
+ // clients disconnect
+ for (int i = 0; i < clientCount; i++)
+ {
+ clientSockets[i].assertReceivedCloseEvent(timeout,is(StatusCode.SHUTDOWN),containsString("Shutdown"));
+ }
+ }
+
+ @Test
+ public void testWriteException() throws Exception
+ {
+ // Set client timeout
+ final int timeout = 1000;
+ client.setMaxIdleTimeout(timeout);
+
+ // Client connects
+ CloseTrackingSocket clientSocket = new CloseTrackingSocket();
+ Future<Session> clientConnectFuture = client.connect(clientSocket,server.getWsUri());
+
+ // Server accepts connect
+ ServerConnection serverConn = server.accept();
+ serverConn.upgrade();
+
+ // client confirms connection via echo
+ confirmConnection(clientSocket,clientConnectFuture,serverConn);
+
+ // setup client endpoint for write failure (test only)
+ EndPoint endp = clientSocket.getEndPoint();
+ endp.shutdownOutput();
+
+ // client enqueue close frame
+ // client write failure
+ final String origCloseReason = "Normal Close";
+ clientSocket.getSession().close(StatusCode.NORMAL,origCloseReason);
+
+ clientSocket.assertReceivedError(EofException.class,null);
+
+ // client triggers close event on client ws-endpoint
+ // assert - close code==1006 (abnormal)
+ // assert - close reason message contains (write failure)
+ clientSocket.assertReceivedCloseEvent(timeout,is(StatusCode.ABNORMAL),containsString("EOF"));
+ }
+}
diff --git a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/ServerWriteThread.java b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/ServerWriteThread.java
index e06e883..2cea2fd 100644
--- a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/ServerWriteThread.java
+++ b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/ServerWriteThread.java
@@ -19,7 +19,6 @@
package org.eclipse.jetty.websocket.client;
import java.io.IOException;
-import java.util.concurrent.Exchanger;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
@@ -32,7 +31,6 @@
{
private static final Logger LOG = Log.getLogger(ServerWriteThread.class);
private final ServerConnection conn;
- private Exchanger<String> exchanger;
private int slowness = -1;
private int messageCount = 100;
private String message = "Hello";
@@ -42,11 +40,6 @@
this.conn = conn;
}
- public Exchanger<String> getExchanger()
- {
- return exchanger;
- }
-
public String getMessage()
{
return message;
@@ -73,12 +66,6 @@
{
conn.write(new TextFrame().setPayload(message));
- if (exchanger != null)
- {
- // synchronized on exchange
- exchanger.exchange(message);
- }
-
m.incrementAndGet();
if (slowness > 0)
@@ -93,11 +80,6 @@
}
}
- public void setExchanger(Exchanger<String> exchanger)
- {
- this.exchanger = exchanger;
- }
-
public void setMessage(String message)
{
this.message = message;
diff --git a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/SlowServerTest.java b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/SlowServerTest.java
index 80720f3..4f56ec6 100644
--- a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/SlowServerTest.java
+++ b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/SlowServerTest.java
@@ -49,7 +49,7 @@
public void startClient() throws Exception
{
client = new WebSocketClient();
- client.getPolicy().setIdleTimeout(60000);
+ client.setMaxIdleTimeout(60000);
client.start();
}
@@ -78,7 +78,7 @@
{
JettyTrackingSocket tsocket = new JettyTrackingSocket();
client.setMasker(new ZeroMasker());
- client.getPolicy().setIdleTimeout(60000);
+ client.setMaxIdleTimeout(60000);
URI wsUri = server.getWsUri();
Future<Session> future = client.connect(tsocket,wsUri);
@@ -123,41 +123,38 @@
@Slow
public void testServerSlowToSend() throws Exception
{
- // final Exchanger<String> exchanger = new Exchanger<String>();
- JettyTrackingSocket tsocket = new JettyTrackingSocket();
- // tsocket.messageExchanger = exchanger;
+ JettyTrackingSocket clientSocket = new JettyTrackingSocket();
client.setMasker(new ZeroMasker());
- client.getPolicy().setIdleTimeout(60000);
+ client.setMaxIdleTimeout(60000);
URI wsUri = server.getWsUri();
- Future<Session> future = client.connect(tsocket,wsUri);
+ Future<Session> clientConnectFuture = client.connect(clientSocket,wsUri);
- ServerConnection sconnection = server.accept();
- sconnection.setSoTimeout(60000);
- sconnection.upgrade();
+ ServerConnection serverConn = server.accept();
+ serverConn.setSoTimeout(60000);
+ serverConn.upgrade();
// Confirm connected
- future.get(500,TimeUnit.MILLISECONDS);
- tsocket.waitForConnected(500,TimeUnit.MILLISECONDS);
+ clientConnectFuture.get(500,TimeUnit.MILLISECONDS);
+ clientSocket.waitForConnected(500,TimeUnit.MILLISECONDS);
// Have server write slowly.
int messageCount = 1000;
- ServerWriteThread writer = new ServerWriteThread(sconnection);
+ ServerWriteThread writer = new ServerWriteThread(serverConn);
writer.setMessageCount(messageCount);
writer.setMessage("Hello");
- // writer.setExchanger(exchanger);
writer.setSlowness(10);
writer.start();
writer.join();
// Verify receive
- Assert.assertThat("Message Receive Count",tsocket.messageQueue.size(),is(messageCount));
+ Assert.assertThat("Message Receive Count",clientSocket.messageQueue.size(),is(messageCount));
// Close
- sconnection.close(StatusCode.NORMAL);
+ serverConn.close(StatusCode.NORMAL);
- Assert.assertTrue("Client Socket Closed",tsocket.closeLatch.await(10,TimeUnit.SECONDS));
- tsocket.assertCloseCode(StatusCode.NORMAL);
+ Assert.assertTrue("Client Socket Closed",clientSocket.closeLatch.await(10,TimeUnit.SECONDS));
+ clientSocket.assertCloseCode(StatusCode.NORMAL);
}
}
diff --git a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/TimeoutTest.java b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/TimeoutTest.java
deleted file mode 100644
index 72c1fc1..0000000
--- a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/TimeoutTest.java
+++ /dev/null
@@ -1,115 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-package org.eclipse.jetty.websocket.client;
-
-import static org.hamcrest.Matchers.lessThanOrEqualTo;
-
-import java.net.URI;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-
-import org.eclipse.jetty.toolchain.test.TestTracker;
-import org.eclipse.jetty.websocket.api.Session;
-import org.eclipse.jetty.websocket.api.StatusCode;
-import org.eclipse.jetty.websocket.common.test.BlockheadServer;
-import org.eclipse.jetty.websocket.common.test.BlockheadServer.ServerConnection;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-
-/**
- * Various tests for Timeout handling
- */
-public class TimeoutTest
-{
- @Rule
- public TestTracker tt = new TestTracker();
-
- private BlockheadServer server;
- private WebSocketClient client;
-
- @Before
- public void startClient() throws Exception
- {
- client = new WebSocketClient();
- client.getPolicy().setIdleTimeout(250); // idle timeout (for all tests here)
- client.start();
- }
-
- @Before
- public void startServer() throws Exception
- {
- server = new BlockheadServer();
- server.start();
- }
-
- @After
- public void stopClient() throws Exception
- {
- client.stop();
- }
-
- @After
- public void stopServer() throws Exception
- {
- server.stop();
- }
-
- /**
- * In a situation where the upgrade/connection is successful, and there is no activity for a while, the idle timeout triggers on the client side and
- * automatically initiates a close handshake.
- */
- @Test
- public void testIdleDetectedByClient() throws Exception
- {
- JettyTrackingSocket wsocket = new JettyTrackingSocket();
-
- URI wsUri = server.getWsUri();
- client.setMaxIdleTimeout(1000);
- Future<Session> future = client.connect(wsocket,wsUri);
-
- ServerConnection ssocket = server.accept();
- ssocket.upgrade();
-
- try
- {
- ssocket.startEcho();
- // Validate that connect occurred
- future.get(500,TimeUnit.MILLISECONDS);
- wsocket.waitForConnected(500,TimeUnit.MILLISECONDS);
-
- // Wait for inactivity idle timeout.
- long start = System.currentTimeMillis();
- wsocket.waitForClose(2,TimeUnit.SECONDS);
- long end = System.currentTimeMillis();
- long dur = (end - start);
- // Make sure idle timeout takes less than 5 total seconds
- Assert.assertThat("Idle Timeout",dur,lessThanOrEqualTo(3000L));
-
- // Client should see a close event, with abnormal status NO_CLOSE
- wsocket.assertCloseCode(StatusCode.ABNORMAL);
- }
- finally
- {
- ssocket.stopEcho();
- }
- }
-}
diff --git a/jetty-websocket/websocket-client/src/test/resources/jetty-logging.properties b/jetty-websocket/websocket-client/src/test/resources/jetty-logging.properties
index 7c9bd36..9668b13 100644
--- a/jetty-websocket/websocket-client/src/test/resources/jetty-logging.properties
+++ b/jetty-websocket/websocket-client/src/test/resources/jetty-logging.properties
@@ -1,12 +1,17 @@
org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog
org.eclipse.jetty.LEVEL=WARN
# org.eclipse.jetty.LEVEL=DEBUG
-# org.eclipse.jetty.io.ChannelEndPoint.LEVEL=INFO
+# org.eclipse.jetty.io.ChannelEndPoint.LEVEL=DEBUG
+# org.eclipse.jetty.io.SelectChannelEndPoint.LEVEL=DEBUG
+# org.eclipse.jetty.io.IdleTimeout.LEVEL=DEBUG
+# org.eclipse.jetty.io.FillInterest.LEVEL=DEBUG
+# org.eclipse.jetty.io.AbstractConnection.LEVEL=DEBUG
# org.eclipse.jetty.websocket.LEVEL=WARN
# org.eclipse.jetty.websocket.LEVEL=DEBUG
# org.eclipse.jetty.websocket.client.LEVEL=DEBUG
# org.eclipse.jetty.websocket.common.io.AbstractWebSocketConnection.LEVEL=DEBUG
-# org.eclipse.jetty.websocket.common.io.WriteBytesProvider.LEVEL=DEBUG
+# org.eclipse.jetty.websocket.common.io.IOState.LEVEL=DEBUG
+
# org.eclipse.jetty.websocket.common.Generator.LEVEL=DEBUG
# org.eclipse.jetty.websocket.common.Parser.LEVEL=DEBUG
# org.eclipse.jetty.websocket.client.TrackingSocket.LEVEL=DEBUG
diff --git a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/CloseInfo.java b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/CloseInfo.java
index 03a737c..f14c252 100644
--- a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/CloseInfo.java
+++ b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/CloseInfo.java
@@ -20,6 +20,7 @@
import java.nio.ByteBuffer;
+import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.Utf8Appendable.NotUtf8Exception;
import org.eclipse.jetty.util.Utf8StringBuilder;
@@ -65,7 +66,8 @@
statusCode |= (data.get() & 0xFF) << 8;
statusCode |= (data.get() & 0xFF);
- if(validate) {
+ if (validate)
+ {
if ((statusCode < StatusCode.NORMAL) || (statusCode == StatusCode.UNDEFINED) || (statusCode == StatusCode.NO_CLOSE)
|| (statusCode == StatusCode.NO_CODE) || ((statusCode > 1011) && (statusCode <= 2999)) || (statusCode >= 5000))
{
@@ -120,7 +122,7 @@
public CloseInfo(int statusCode)
{
- this(statusCode, null);
+ this(statusCode,null);
}
public CloseInfo(int statusCode, String reason)
@@ -144,8 +146,9 @@
utf = StringUtil.getUtf8Bytes(reason);
len += utf.length;
}
-
- ByteBuffer buf = ByteBuffer.allocate(len);
+
+ ByteBuffer buf = BufferUtil.allocate(len);
+ BufferUtil.flipToFill(buf);
buf.put((byte)((statusCode >>> 8) & 0xFF));
buf.put((byte)((statusCode >>> 0) & 0xFF));
@@ -153,7 +156,7 @@
{
buf.put(utf,0,utf.length);
}
- buf.flip();
+ BufferUtil.flipToFlush(buf,0);
return buf;
}
@@ -162,7 +165,14 @@
{
CloseFrame frame = new CloseFrame();
frame.setFin(true);
- frame.setPayload(asByteBuffer());
+ if ((statusCode >= 1000) && (statusCode != StatusCode.NO_CLOSE) && (statusCode != StatusCode.NO_CODE))
+ {
+ if (statusCode == StatusCode.FAILED_TLS_HANDSHAKE)
+ {
+ throw new ProtocolException("Close Frame with status code " + statusCode + " not allowed (per RFC6455)");
+ }
+ frame.setPayload(asByteBuffer());
+ }
return frame;
}
@@ -180,10 +190,10 @@
{
return !((statusCode == StatusCode.NORMAL) || (statusCode == StatusCode.NO_CODE));
}
-
+
public boolean isAbnormal()
{
- return (statusCode == StatusCode.ABNORMAL);
+ return (statusCode != StatusCode.NORMAL);
}
@Override
diff --git a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/Parser.java b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/Parser.java
index 0cf7e5f..86195a0 100644
--- a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/Parser.java
+++ b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/Parser.java
@@ -96,8 +96,9 @@
private void assertSanePayloadLength(long len)
{
- if (LOG.isDebugEnabled())
- LOG.debug("Payload Length: {} - {}",len,this);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("{} Payload Length: {} - {}",policy.getBehavior(),len,this);
+ }
// Since we use ByteBuffer so often, having lengths over Integer.MAX_VALUE is really impossible.
if (len > Integer.MAX_VALUE)
@@ -239,7 +240,7 @@
incomingFramesHandler.incomingError(e);
}
- public void parse(ByteBuffer buffer)
+ public void parse(ByteBuffer buffer) throws WebSocketException
{
if (buffer.remaining() <= 0)
{
@@ -266,13 +267,20 @@
{
buffer.position(buffer.limit()); // consume remaining
reset();
+ // let session know
notifyWebSocketException(e);
+ // need to throw for proper close behavior in connection
+ throw e;
}
catch (Throwable t)
{
buffer.position(buffer.limit()); // consume remaining
reset();
- notifyWebSocketException(new WebSocketException(t));
+ // let session know
+ WebSocketException e = new WebSocketException(t);
+ notifyWebSocketException(e);
+ // need to throw for proper close behavior in connection
+ throw e;
}
}
@@ -299,7 +307,9 @@
private boolean parseFrame(ByteBuffer buffer)
{
if (LOG.isDebugEnabled())
+ {
LOG.debug("{} Parsing {} bytes",policy.getBehavior(),buffer.remaining());
+ }
while (buffer.hasRemaining())
{
switch (state)
@@ -318,7 +328,8 @@
}
if (LOG.isDebugEnabled())
- LOG.debug("OpCode {}, fin={} rsv={}{}{}",
+ LOG.debug("{} OpCode {}, fin={} rsv={}{}{}",
+ policy.getBehavior(),
OpCode.name(opcode),
fin,
(isRsv1InUse()?'1':'.'),
@@ -412,11 +423,6 @@
throw new ProtocolException("RSV3 not allowed to be set");
}
}
- else
- {
- if (LOG.isDebugEnabled())
- LOG.debug("OpCode {}, fin={} rsv=000",OpCode.name(opcode),fin);
- }
state = State.PAYLOAD_LEN;
break;
@@ -591,8 +597,9 @@
buffer.limit(limit);
buffer.position(buffer.position() + window.remaining());
- if (LOG.isDebugEnabled())
- LOG.debug("Window: {}",BufferUtil.toDetailString(window));
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("{} Window: {}",policy.getBehavior(),BufferUtil.toDetailString(window));
+ }
maskProcessor.process(window);
diff --git a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/WebSocketSession.java b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/WebSocketSession.java
index 460d1d7..04637e3 100644
--- a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/WebSocketSession.java
+++ b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/WebSocketSession.java
@@ -41,6 +41,7 @@
import org.eclipse.jetty.websocket.api.SuspendToken;
import org.eclipse.jetty.websocket.api.UpgradeRequest;
import org.eclipse.jetty.websocket.api.UpgradeResponse;
+import org.eclipse.jetty.websocket.api.WebSocketBehavior;
import org.eclipse.jetty.websocket.api.WebSocketException;
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
import org.eclipse.jetty.websocket.api.extensions.ExtensionFactory;
@@ -90,20 +91,19 @@
@Override
public void close()
{
- this.close(StatusCode.NORMAL, null);
+ this.close(StatusCode.NORMAL,null);
}
@Override
public void close(CloseStatus closeStatus)
{
- this.close(closeStatus.getCode(), closeStatus.getPhrase());
+ this.close(closeStatus.getCode(),closeStatus.getPhrase());
}
@Override
public void close(int statusCode, String reason)
{
- connection.close(statusCode, reason);
- notifyClose(statusCode, reason);
+ connection.close(statusCode,reason);
}
/**
@@ -115,7 +115,7 @@
connection.disconnect();
// notify of harsh disconnect
- notifyClose(StatusCode.NO_CLOSE, "Harsh disconnect");
+ notifyClose(StatusCode.NO_CLOSE,"Harsh disconnect");
}
public void dispatch(Runnable runnable)
@@ -130,7 +130,7 @@
out.append(indent).append(" +- incomingHandler : ");
if (incomingHandler instanceof Dumpable)
{
- ((Dumpable)incomingHandler).dump(out, indent + " ");
+ ((Dumpable)incomingHandler).dump(out,indent + " ");
}
else
{
@@ -140,7 +140,7 @@
out.append(indent).append(" +- outgoingHandler : ");
if (outgoingHandler instanceof Dumpable)
{
- ((Dumpable)outgoingHandler).dump(out, indent + " ");
+ ((Dumpable)outgoingHandler).dump(out,indent + " ");
}
else
{
@@ -273,7 +273,7 @@
{
final int prime = 31;
int result = 1;
- result = (prime * result) + ((connection == null) ? 0 : connection.hashCode());
+ result = (prime * result) + ((connection == null)?0:connection.hashCode());
return result;
}
@@ -328,7 +328,11 @@
public void notifyClose(int statusCode, String reason)
{
- websocket.onClose(new CloseInfo(statusCode, reason));
+ if (LOG.isDebugEnabled())
+ {
+ LOG.debug("notifyClose({},{})",statusCode,reason);
+ }
+ websocket.onClose(new CloseInfo(statusCode,reason));
}
public void notifyError(Throwable cause)
@@ -342,12 +346,13 @@
{
switch (state)
{
- case CLOSING:
+ case CLOSED:
// notify session listeners
for (SessionListener listener : sessionListeners)
{
try
{
+ LOG.debug("{}.onSessionClosed()",listener.getClass().getSimpleName());
listener.onSessionClosed(this);
}
catch (Throwable t)
@@ -355,12 +360,10 @@
LOG.ignore(t);
}
}
- break;
- case CLOSED:
IOState ioState = this.connection.getIOState();
CloseInfo close = ioState.getCloseInfo();
// confirmed close of local endpoint
- notifyClose(close.getStatusCode(), close.getReason());
+ notifyClose(close.getStatusCode(),close.getReason());
break;
case OPEN:
// notify session listeners
@@ -394,17 +397,32 @@
connection.getIOState().onConnected();
// Connect remote
- remote = new WebSocketRemoteEndpoint(connection, outgoingHandler, getBatchMode());
+ remote = new WebSocketRemoteEndpoint(connection,outgoingHandler,getBatchMode());
- // Open WebSocket
- websocket.openSession(this);
-
- // Open connection
- connection.getIOState().onOpened();
-
- if (LOG.isDebugEnabled())
+ try
{
- LOG.debug("open -> {}", dump());
+ // Open WebSocket
+ websocket.openSession(this);
+
+ // Open connection
+ connection.getIOState().onOpened();
+
+ if (LOG.isDebugEnabled())
+ {
+ LOG.debug("open -> {}",dump());
+ }
+ }
+ catch (Throwable t)
+ {
+ // Exception on end-user WS-Endpoint.
+ // Fast-fail & close connection with reason.
+ int statusCode = StatusCode.SERVER_ERROR;
+ if(policy.getBehavior() == WebSocketBehavior.CLIENT)
+ {
+ statusCode = StatusCode.POLICY_VIOLATION;
+ }
+
+ close(statusCode,t.getMessage());
}
}
@@ -444,11 +462,11 @@
List<String> values = entry.getValue();
if (values != null)
{
- this.parameterMap.put(entry.getKey(), values.toArray(new String[values.size()]));
+ this.parameterMap.put(entry.getKey(),values.toArray(new String[values.size()]));
}
else
{
- this.parameterMap.put(entry.getKey(), new String[0]);
+ this.parameterMap.put(entry.getKey(),new String[0]);
}
}
}
diff --git a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/events/AbstractEventDriver.java b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/events/AbstractEventDriver.java
index 8cc60f0..7a55b2d 100644
--- a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/events/AbstractEventDriver.java
+++ b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/events/AbstractEventDriver.java
@@ -88,13 +88,7 @@
{
if (LOG.isDebugEnabled())
{
- LOG.debug("incoming(WebSocketException)",e);
- }
-
- if (e instanceof CloseException)
- {
- CloseException close = (CloseException)e;
- terminateConnection(close.getStatusCode(),close.getMessage());
+ LOG.debug("incomingError(" + e.getClass().getName() + ")",e);
}
onError(e);
@@ -105,7 +99,7 @@
{
if (LOG.isDebugEnabled())
{
- LOG.debug("{}.onFrame({})",websocket.getClass().getSimpleName(),frame);
+ LOG.debug("incomingFrame({})",frame);
}
try
@@ -226,6 +220,7 @@
catch (Throwable t)
{
unhandled(t);
+ throw t;
}
}
diff --git a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/ExtensionStack.java b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/ExtensionStack.java
index 18e4a9d..a249c0e 100644
--- a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/ExtensionStack.java
+++ b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/ExtensionStack.java
@@ -370,10 +370,13 @@
protected Action process() throws Exception
{
current = entries.poll();
- LOG.debug("Processing {}", current);
if (current == null)
+ {
+ LOG.debug("Entering IDLE");
return Action.IDLE;
- nextOutgoing.outgoingFrame(current.frame, this, current.batchMode);
+ }
+ LOG.debug("Processing {}",current);
+ nextOutgoing.outgoingFrame(current.frame,this,current.batchMode);
return Action.SCHEDULED;
}
diff --git a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/io/AbstractWebSocketConnection.java b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/io/AbstractWebSocketConnection.java
index c9f98bb..7494aba 100644
--- a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/io/AbstractWebSocketConnection.java
+++ b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/io/AbstractWebSocketConnection.java
@@ -32,7 +32,6 @@
import org.eclipse.jetty.io.AbstractConnection;
import org.eclipse.jetty.io.ByteBufferPool;
-import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.StringUtil;
@@ -59,8 +58,7 @@
import org.eclipse.jetty.websocket.common.io.IOState.ConnectionStateListener;
/**
- * Provides the implementation of {@link LogicalConnection} within the
- * framework of the new {@link Connection} framework of {@code jetty-io}.
+ * Provides the implementation of {@link LogicalConnection} within the framework of the new {@link Connection} framework of {@code jetty-io}.
*/
public abstract class AbstractWebSocketConnection extends AbstractConnection implements LogicalConnection, ConnectionStateListener, Dumpable
{
@@ -68,7 +66,7 @@
{
private Flusher(ByteBufferPool bufferPool, Generator generator, EndPoint endpoint)
{
- super(bufferPool, generator, endpoint, getPolicy().getMaxBinaryMessageBufferSize(), 8);
+ super(bufferPool,generator,endpoint,getPolicy().getMaxBinaryMessageBufferSize(),8);
}
@Override
@@ -106,7 +104,7 @@
// Abnormal Close
reason = CloseStatus.trimMaxReasonLength(reason);
session.notifyError(x);
- session.notifyClose(StatusCode.NO_CLOSE,reason);
+ session.notifyClose(StatusCode.ABNORMAL,reason);
disconnect(); // disconnect endpoint & connection
}
@@ -116,10 +114,11 @@
{
private final boolean outputOnly;
- public OnDisconnectCallback(boolean outputOnly) {
+ public OnDisconnectCallback(boolean outputOnly)
+ {
this.outputOnly = outputOnly;
}
-
+
@Override
public void writeFailed(Throwable x)
{
@@ -133,6 +132,68 @@
}
}
+ public class OnCloseLocalCallback implements WriteCallback
+ {
+ private final WriteCallback callback;
+ private final CloseInfo close;
+
+ public OnCloseLocalCallback(WriteCallback callback, CloseInfo close)
+ {
+ this.callback = callback;
+ this.close = close;
+ }
+
+ public OnCloseLocalCallback(CloseInfo close)
+ {
+ this(null,close);
+ }
+
+ @Override
+ public void writeFailed(Throwable x)
+ {
+ try
+ {
+ if (callback != null)
+ {
+ callback.writeFailed(x);
+ }
+ }
+ finally
+ {
+ onLocalClose();
+ }
+ }
+
+ @Override
+ public void writeSuccess()
+ {
+ try
+ {
+ if (callback != null)
+ {
+ callback.writeSuccess();
+ }
+ }
+ finally
+ {
+ onLocalClose();
+ }
+ }
+
+ private void onLocalClose()
+ {
+ LOG.debug("Local Close Confirmed {}",close);
+ if (close.isAbnormal())
+ {
+ ioState.onAbnormalClose(close);
+ }
+ else
+ {
+ ioState.onCloseLocal(close);
+ }
+ }
+ }
+
public static class Stats
{
private AtomicLong countFillInterestedEvents = new AtomicLong(0);
@@ -218,29 +279,22 @@
@Override
public void close(int statusCode, String reason)
{
+ LOG.debug("close({},{})",statusCode,reason);
CloseInfo close = new CloseInfo(statusCode,reason);
- if (statusCode == StatusCode.ABNORMAL)
- {
- flusher.close(); // TODO this makes the IdleTimeoutTest pass, but I'm dubious it is the correct way
- ioState.onAbnormalClose(close);
- }
- else
- {
- ioState.onCloseLocal(close);
- }
+ this.outgoingFrame(close.asFrame(),new OnCloseLocalCallback(close),BatchMode.OFF);
}
-
@Override
public void disconnect()
{
- LOG.debug("{} disconnect()",policy.getBehavior());
- flusher.close();
disconnect(false);
}
private void disconnect(boolean onlyOutput)
{
+ LOG.debug("{} disconnect({})",policy.getBehavior(),onlyOutput?"outputOnly":"both");
+ // close FrameFlusher, we cannot write anymore at this point.
+ flusher.close();
EndPoint endPoint = getEndPoint();
// We need to gently close first, to allow
// SSL close alerts to be sent by Jetty
@@ -366,7 +420,9 @@
@Override
public void onClose()
{
+ LOG.debug("{} onClose()",policy.getBehavior());
super.onClose();
+ // ioState.onDisconnected();
flusher.close();
}
@@ -385,7 +441,7 @@
{
// Fire out a close frame, indicating abnormal shutdown, then disconnect
CloseInfo abnormal = new CloseInfo(StatusCode.SHUTDOWN,"Abnormal Close - " + ioState.getCloseInfo().getReason());
- outgoingFrame(abnormal.asFrame(),new OnDisconnectCallback(false), BatchMode.OFF);
+ outgoingFrame(abnormal.asFrame(),new OnDisconnectCallback(false),BatchMode.OFF);
}
else
{
@@ -394,9 +450,13 @@
}
break;
case CLOSING:
- CloseInfo close = ioState.getCloseInfo();
- // reply to close handshake from remote
- outgoingFrame(close.asFrame(),new OnDisconnectCallback(true), BatchMode.OFF);
+ // First occurrence of .onCloseLocal or .onCloseRemote use
+ if (ioState.wasRemoteCloseInitiated())
+ {
+ CloseInfo close = ioState.getCloseInfo();
+ // reply to close handshake from remote
+ outgoingFrame(close.asFrame(),new OnCloseLocalCallback(new OnDisconnectCallback(true),close),BatchMode.OFF);
+ }
default:
break;
}
@@ -447,20 +507,26 @@
@Override
protected boolean onReadTimeout()
{
- LOG.debug("{} Read Timeout",policy.getBehavior());
-
IOState state = getIOState();
- if ((state.getConnectionState() == ConnectionState.CLOSING) || (state.getConnectionState() == ConnectionState.CLOSED))
+ ConnectionState cstate = state.getConnectionState();
+ LOG.debug("{} Read Timeout - {}",policy.getBehavior(),cstate);
+
+ if (cstate == ConnectionState.CLOSED)
{
- // close already initiated, extra timeouts not relevant
+ // close already completed, extra timeouts not relevant
// allow underlying connection and endpoint to disconnect on its own
return true;
}
- // Initiate close - politely send close frame.
- session.notifyError(new SocketTimeoutException("Timeout on Read"));
- // This is an Abnormal Close condition
- close(StatusCode.ABNORMAL,"Idle Timeout");
+ try
+ {
+ session.notifyError(new SocketTimeoutException("Timeout on Read"));
+ }
+ finally
+ {
+ // This is an Abnormal Close condition
+ close(StatusCode.SHUTDOWN,"Idle Timeout");
+ }
return false;
}
@@ -476,7 +542,7 @@
LOG.debug("outgoingFrame({}, {})",frame,callback);
}
- flusher.enqueue(frame,callback, batchMode);
+ flusher.enqueue(frame,callback,batchMode);
}
private int read(ByteBuffer buffer)
@@ -504,7 +570,6 @@
LOG.debug("Filled {} bytes - {}",filled,BufferUtil.toDetailString(buffer));
}
parser.parse(buffer);
- // TODO: has the end user application already consumed what it was given?
}
}
}
@@ -520,6 +585,12 @@
close(e.getStatusCode(),e.getMessage());
return -1;
}
+ catch (Throwable t)
+ {
+ LOG.warn(t);
+ close(StatusCode.ABNORMAL,t.getMessage());
+ return -1;
+ }
}
@Override
diff --git a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/io/FrameFlusher.java b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/io/FrameFlusher.java
index a7bb3cb..6e995e5 100644
--- a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/io/FrameFlusher.java
+++ b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/io/FrameFlusher.java
@@ -29,7 +29,6 @@
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.util.ArrayQueue;
import org.eclipse.jetty.util.BufferUtil;
-import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.IteratingCallback;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
@@ -45,246 +44,22 @@
*/
public class FrameFlusher
{
- public static final BinaryFrame FLUSH_FRAME = new BinaryFrame();
- private static final Logger LOG = Log.getLogger(FrameFlusher.class);
-
- private final ByteBufferPool bufferPool;
- private final EndPoint endpoint;
- private final int bufferSize;
- private final Generator generator;
- private final int maxGather;
- private final Object lock = new Object();
- private final ArrayQueue<FrameEntry> queue = new ArrayQueue<>(16, 16, lock);
- private final Flusher flusher = new Flusher();
- private final AtomicBoolean closed = new AtomicBoolean();
- private volatile Throwable failure;
-
- public FrameFlusher(ByteBufferPool bufferPool, Generator generator, EndPoint endpoint, int bufferSize, int maxGather)
- {
- this.bufferPool = bufferPool;
- this.endpoint = endpoint;
- this.bufferSize = bufferSize;
- this.generator = Objects.requireNonNull(generator);
- this.maxGather = maxGather;
- }
-
- public void enqueue(Frame frame, WriteCallback callback, BatchMode batchMode)
- {
- if (closed.get())
- {
- notifyCallbackFailure(callback, new EOFException("Connection has been closed locally"));
- return;
- }
- if (flusher.isFailed())
- {
- notifyCallbackFailure(callback, failure);
- return;
- }
-
- FrameEntry entry = new FrameEntry(frame, callback, batchMode);
-
- synchronized (lock)
- {
- switch (frame.getOpCode())
- {
- case OpCode.PING:
- {
- // Prepend PINGs so they are processed first.
- queue.add(0, entry);
- break;
- }
- case OpCode.CLOSE:
- {
- // There may be a chance that other frames are
- // added after this close frame, but we will
- // fail them later to keep it simple here.
- closed.set(true);
- queue.add(entry);
- break;
- }
- default:
- {
- queue.add(entry);
- break;
- }
- }
- }
-
- if (LOG.isDebugEnabled())
- LOG.debug("{} queued {}", this, entry);
-
- flusher.iterate();
- }
-
- public void close()
- {
- if (closed.compareAndSet(false, true))
- {
- LOG.debug("{} closing {}", this);
- EOFException eof = new EOFException("Connection has been closed locally");
- flusher.failed(eof);
-
- // Fail also queued entries.
- List<FrameEntry> entries = new ArrayList<>();
- synchronized (lock)
- {
- entries.addAll(queue);
- queue.clear();
- }
- // Notify outside sync block.
- for (FrameEntry entry : entries)
- notifyCallbackFailure(entry.callback, eof);
- }
- }
-
- protected void onFailure(Throwable x)
- {
- LOG.warn(x);
- }
-
- protected void notifyCallbackSuccess(WriteCallback callback)
- {
- try
- {
- if (callback != null)
- callback.writeSuccess();
- }
- catch (Throwable x)
- {
- LOG.debug("Exception while notifying success of callback " + callback, x);
- }
- }
-
- protected void notifyCallbackFailure(WriteCallback callback, Throwable failure)
- {
- try
- {
- if (callback != null)
- callback.writeFailed(failure);
- }
- catch (Throwable x)
- {
- LOG.debug("Exception while notifying failure of callback " + callback, x);
- }
- }
-
- @Override
- public String toString()
- {
- ByteBuffer aggregate = flusher.aggregate;
- return String.format("%s[queueSize=%d,aggregateSize=%d,failure=%s]",
- getClass().getSimpleName(),
- queue.size(),
- aggregate == null ? 0 : aggregate.position(),
- failure);
- }
-
private class Flusher extends IteratingCallback
{
private final List<FrameEntry> entries = new ArrayList<>(maxGather);
- private final List<ByteBuffer> buffers = new ArrayList<>(maxGather * 2 + 1);
+ private final List<ByteBuffer> buffers = new ArrayList<>((maxGather * 2) + 1);
private ByteBuffer aggregate;
private BatchMode batchMode;
- @Override
- protected Action process() throws Exception
- {
- int space = aggregate == null ? bufferSize : BufferUtil.space(aggregate);
- BatchMode currentBatchMode = BatchMode.AUTO;
- synchronized (lock)
- {
- while (entries.size() <= maxGather && !queue.isEmpty())
- {
- FrameEntry entry = queue.remove(0);
- currentBatchMode = BatchMode.max(currentBatchMode, entry.batchMode);
-
- // Force flush if we need to.
- if (entry.frame == FLUSH_FRAME)
- currentBatchMode = BatchMode.OFF;
-
- int payloadLength = BufferUtil.length(entry.frame.getPayload());
- int approxFrameLength = Generator.MAX_HEADER_LENGTH + payloadLength;
-
- // If it is a "big" frame, avoid copying into the aggregate buffer.
- if (approxFrameLength > (bufferSize >> 2))
- currentBatchMode = BatchMode.OFF;
-
- // If the aggregate buffer overflows, do not batch.
- space -= approxFrameLength;
- if (space <= 0)
- currentBatchMode = BatchMode.OFF;
-
- entries.add(entry);
- }
- }
-
- if (LOG.isDebugEnabled())
- LOG.debug("{} processing {} entries: {}", FrameFlusher.this, entries.size(), entries);
-
- if (entries.isEmpty())
- {
- if (batchMode != BatchMode.AUTO)
- {
- // Nothing more to do, release the aggregate buffer if we need to.
- // Releasing it here rather than in succeeded() allows for its reuse.
- releaseAggregate();
- return Action.IDLE;
- }
-
- LOG.debug("{} auto flushing", FrameFlusher.this);
- return flush();
- }
-
- batchMode = currentBatchMode;
-
- return currentBatchMode == BatchMode.OFF ? flush() : batch();
- }
-
- private Action flush()
- {
- if (!BufferUtil.isEmpty(aggregate))
- {
- buffers.add(aggregate);
- if (LOG.isDebugEnabled())
- LOG.debug("{} flushing aggregate {}", FrameFlusher.this, aggregate);
- }
-
- // Do not allocate the iterator here.
- for (int i = 0; i < entries.size(); ++i)
- {
- FrameEntry entry = entries.get(i);
- // Skip the "synthetic" frame used for flushing.
- if (entry.frame == FLUSH_FRAME)
- continue;
- buffers.add(entry.generateHeaderBytes());
- ByteBuffer payload = entry.frame.getPayload();
- if (BufferUtil.hasContent(payload))
- buffers.add(payload);
- }
-
- if (LOG.isDebugEnabled())
- LOG.debug("{} flushing {} frames: {}", FrameFlusher.this, entries.size(), entries);
-
- if (buffers.isEmpty())
- {
- releaseAggregate();
- // We may have the FLUSH_FRAME to notify.
- succeedEntries();
- return Action.IDLE;
- }
-
- endpoint.write(this, buffers.toArray(new ByteBuffer[buffers.size()]));
- buffers.clear();
- return Action.SCHEDULED;
- }
-
private Action batch()
{
if (aggregate == null)
{
- aggregate = bufferPool.acquire(bufferSize, true);
+ aggregate = bufferPool.acquire(bufferSize,true);
if (LOG.isDebugEnabled())
- LOG.debug("{} acquired aggregate buffer {}", FrameFlusher.this, aggregate);
+ {
+ LOG.debug("{} acquired aggregate buffer {}",FrameFlusher.this,aggregate);
+ }
}
// Do not allocate the iterator here.
@@ -296,17 +71,149 @@
ByteBuffer payload = entry.frame.getPayload();
if (BufferUtil.hasContent(payload))
- BufferUtil.append(aggregate, payload);
+ {
+ BufferUtil.append(aggregate,payload);
+ }
}
if (LOG.isDebugEnabled())
- LOG.debug("{} aggregated {} frames: {}", FrameFlusher.this, entries.size(), entries);
+ {
+ LOG.debug("{} aggregated {} frames: {}",FrameFlusher.this,entries.size(),entries);
+ }
succeeded();
return Action.SCHEDULED;
}
+ @Override
+ protected void completed()
+ {
+ // This IteratingCallback never completes.
+ }
+
+ @Override
+ public void failed(Throwable x)
+ {
+ for (FrameEntry entry : entries)
+ {
+ notifyCallbackFailure(entry.callback,x);
+ entry.release();
+ }
+ entries.clear();
+ super.failed(x);
+ failure = x;
+ onFailure(x);
+ }
+
+ private Action flush()
+ {
+ if (!BufferUtil.isEmpty(aggregate))
+ {
+ buffers.add(aggregate);
+ if (LOG.isDebugEnabled())
+ {
+ LOG.debug("{} flushing aggregate {}",FrameFlusher.this,aggregate);
+ }
+ }
+
+ // Do not allocate the iterator here.
+ for (int i = 0; i < entries.size(); ++i)
+ {
+ FrameEntry entry = entries.get(i);
+ // Skip the "synthetic" frame used for flushing.
+ if (entry.frame == FLUSH_FRAME)
+ {
+ continue;
+ }
+ buffers.add(entry.generateHeaderBytes());
+ ByteBuffer payload = entry.frame.getPayload();
+ if (BufferUtil.hasContent(payload))
+ {
+ buffers.add(payload);
+ }
+ }
+
+ if (LOG.isDebugEnabled())
+ {
+ LOG.debug("{} flushing {} frames: {}",FrameFlusher.this,entries.size(),entries);
+ }
+
+ if (buffers.isEmpty())
+ {
+ releaseAggregate();
+ // We may have the FLUSH_FRAME to notify.
+ succeedEntries();
+ return Action.IDLE;
+ }
+
+ endpoint.write(this,buffers.toArray(new ByteBuffer[buffers.size()]));
+ buffers.clear();
+ return Action.SCHEDULED;
+ }
+
+ @Override
+ protected Action process() throws Exception
+ {
+ int space = aggregate == null?bufferSize:BufferUtil.space(aggregate);
+ BatchMode currentBatchMode = BatchMode.AUTO;
+ synchronized (lock)
+ {
+ while ((entries.size() <= maxGather) && !queue.isEmpty())
+ {
+ FrameEntry entry = queue.remove(0);
+ currentBatchMode = BatchMode.max(currentBatchMode,entry.batchMode);
+
+ // Force flush if we need to.
+ if (entry.frame == FLUSH_FRAME)
+ {
+ currentBatchMode = BatchMode.OFF;
+ }
+
+ int payloadLength = BufferUtil.length(entry.frame.getPayload());
+ int approxFrameLength = Generator.MAX_HEADER_LENGTH + payloadLength;
+
+ // If it is a "big" frame, avoid copying into the aggregate buffer.
+ if (approxFrameLength > (bufferSize >> 2))
+ {
+ currentBatchMode = BatchMode.OFF;
+ }
+
+ // If the aggregate buffer overflows, do not batch.
+ space -= approxFrameLength;
+ if (space <= 0)
+ {
+ currentBatchMode = BatchMode.OFF;
+ }
+
+ entries.add(entry);
+ }
+ }
+
+ if (LOG.isDebugEnabled())
+ {
+ LOG.debug("{} processing {} entries: {}",FrameFlusher.this,entries.size(),entries);
+ }
+
+ if (entries.isEmpty())
+ {
+ if (batchMode != BatchMode.AUTO)
+ {
+ // Nothing more to do, release the aggregate buffer if we need to.
+ // Releasing it here rather than in succeeded() allows for its reuse.
+ releaseAggregate();
+ return Action.IDLE;
+ }
+
+ LOG.debug("{} auto flushing",FrameFlusher.this);
+ return flush();
+ }
+
+ batchMode = currentBatchMode;
+
+ return currentBatchMode == BatchMode.OFF?flush():batch();
+ }
+
private void releaseAggregate()
{
- if (aggregate != null && BufferUtil.isEmpty(aggregate))
+ if ((aggregate != null) && BufferUtil.isEmpty(aggregate))
{
bufferPool.release(aggregate);
aggregate = null;
@@ -331,26 +238,6 @@
}
entries.clear();
}
-
- @Override
- protected void completed()
- {
- // This IteratingCallback never completes.
- }
-
- @Override
- public void failed(Throwable x)
- {
- for (FrameEntry entry : entries)
- {
- notifyCallbackFailure(entry.callback, x);
- entry.release();
- }
- entries.clear();
- super.failed(x);
- failure = x;
- onFailure(x);
- }
}
private class FrameEntry
@@ -374,7 +261,7 @@
private void generateHeaderBytes(ByteBuffer buffer)
{
- generator.generateHeaderBytes(frame, buffer);
+ generator.generateHeaderBytes(frame,buffer);
}
private void release()
@@ -389,7 +276,145 @@
@Override
public String toString()
{
- return String.format("%s[%s,%s,%s,%s]", getClass().getSimpleName(), frame, callback, batchMode, failure);
+ return String.format("%s[%s,%s,%s,%s]",getClass().getSimpleName(),frame,callback,batchMode,failure);
}
}
+
+ public static final BinaryFrame FLUSH_FRAME = new BinaryFrame();
+ private static final Logger LOG = Log.getLogger(FrameFlusher.class);
+ private final ByteBufferPool bufferPool;
+ private final EndPoint endpoint;
+ private final int bufferSize;
+ private final Generator generator;
+ private final int maxGather;
+ private final Object lock = new Object();
+ private final ArrayQueue<FrameEntry> queue = new ArrayQueue<>(16,16,lock);
+ private final Flusher flusher = new Flusher();
+ private final AtomicBoolean closed = new AtomicBoolean();
+ private volatile Throwable failure;
+
+ public FrameFlusher(ByteBufferPool bufferPool, Generator generator, EndPoint endpoint, int bufferSize, int maxGather)
+ {
+ this.bufferPool = bufferPool;
+ this.endpoint = endpoint;
+ this.bufferSize = bufferSize;
+ this.generator = Objects.requireNonNull(generator);
+ this.maxGather = maxGather;
+ }
+
+ public void close()
+ {
+ if (closed.compareAndSet(false,true))
+ {
+ LOG.debug("{} closing {}",this);
+ EOFException eof = new EOFException("Connection has been closed locally");
+ flusher.failed(eof);
+
+ // Fail also queued entries.
+ List<FrameEntry> entries = new ArrayList<>();
+ synchronized (lock)
+ {
+ entries.addAll(queue);
+ queue.clear();
+ }
+ // Notify outside sync block.
+ for (FrameEntry entry : entries)
+ {
+ notifyCallbackFailure(entry.callback,eof);
+ }
+ }
+ }
+
+ public void enqueue(Frame frame, WriteCallback callback, BatchMode batchMode)
+ {
+ if (closed.get())
+ {
+ notifyCallbackFailure(callback,new EOFException("Connection has been closed locally"));
+ return;
+ }
+ if (flusher.isFailed())
+ {
+ notifyCallbackFailure(callback,failure);
+ return;
+ }
+
+ FrameEntry entry = new FrameEntry(frame,callback,batchMode);
+
+ synchronized (lock)
+ {
+ switch (frame.getOpCode())
+ {
+ case OpCode.PING:
+ {
+ // Prepend PINGs so they are processed first.
+ queue.add(0,entry);
+ break;
+ }
+ case OpCode.CLOSE:
+ {
+ // There may be a chance that other frames are
+ // added after this close frame, but we will
+ // fail them later to keep it simple here.
+ closed.set(true);
+ queue.add(entry);
+ break;
+ }
+ default:
+ {
+ queue.add(entry);
+ break;
+ }
+ }
+ }
+
+ if (LOG.isDebugEnabled())
+ {
+ LOG.debug("{} queued {}",this,entry);
+ }
+
+ flusher.iterate();
+ }
+
+ protected void notifyCallbackFailure(WriteCallback callback, Throwable failure)
+ {
+ try
+ {
+ if (callback != null)
+ {
+ callback.writeFailed(failure);
+ }
+ }
+ catch (Throwable x)
+ {
+ LOG.debug("Exception while notifying failure of callback " + callback,x);
+ }
+ }
+
+ protected void notifyCallbackSuccess(WriteCallback callback)
+ {
+ try
+ {
+ if (callback != null)
+ {
+ callback.writeSuccess();
+ }
+ }
+ catch (Throwable x)
+ {
+ LOG.debug("Exception while notifying success of callback " + callback,x);
+ }
+ }
+
+ protected void onFailure(Throwable x)
+ {
+ LOG.warn(x);
+ }
+
+ @Override
+ public String toString()
+ {
+ ByteBuffer aggregate = flusher.aggregate;
+ return String.format("%s[queueSize=%d,aggregateSize=%d,failure=%s]",getClass().getSimpleName(),queue.size(),aggregate == null?0:aggregate.position(),
+ failure);
+ }
}
diff --git a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/io/IOState.java b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/io/IOState.java
index 6d4dbc4..815d2d3 100644
--- a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/io/IOState.java
+++ b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/io/IOState.java
@@ -139,6 +139,10 @@
{
for (ConnectionStateListener listener : listeners)
{
+ if (LOG.isDebugEnabled())
+ {
+ LOG.debug("{}.onConnectionStateChange({})",listener.getClass().getSimpleName(),state.name());
+ }
listener.onConnectionStateChange(state);
}
}
@@ -166,8 +170,7 @@
}
this.state = ConnectionState.CLOSED;
- if (closeInfo == null)
- this.closeInfo = close;
+ this.closeInfo = close;
this.inputAvailable = false;
this.outputAvailable = false;
this.closeHandshakeSource = CloseHandshakeSource.ABNORMAL;
@@ -193,16 +196,16 @@
if (initialState == ConnectionState.CONNECTED)
{
- // fast close. a local close request from end-user onConnected() method
+ // fast close. a local close request from end-user onConnect/onOpen method
LOG.debug("FastClose in CONNECTED detected");
// Force the state open (to allow read/write to endpoint)
onOpened();
+ LOG.debug("FastClose continuing with Closure");
}
synchronized (this)
{
- if (closeInfo == null)
- closeInfo = close;
+ closeInfo = close;
boolean in = inputAvailable;
boolean out = outputAvailable;
@@ -236,7 +239,6 @@
LOG.debug("notifying state listeners: {}",event);
notifyStateListeners(event);
- /*
// if abnormal, we don't expect an answer.
if (close.isAbnormal())
{
@@ -253,7 +255,6 @@
notifyStateListeners(event);
return;
}
- */
}
}
@@ -272,8 +273,7 @@
return;
}
- if (closeInfo == null)
- closeInfo = close;
+ closeInfo = close;
boolean in = inputAvailable;
boolean out = outputAvailable;
@@ -360,7 +360,7 @@
// already opened
return;
}
-
+
if (this.state != ConnectionState.CONNECTED)
{
LOG.debug("Unable to open, not in CONNECTED state: {}",this.state);
@@ -394,12 +394,11 @@
return;
}
- CloseInfo close = new CloseInfo(StatusCode.NO_CLOSE,"Read EOF");
+ CloseInfo close = new CloseInfo(StatusCode.ABNORMAL,"Read EOF");
this.cleanClose = false;
this.state = ConnectionState.CLOSED;
- if (closeInfo == null)
- this.closeInfo = close;
+ this.closeInfo = close;
this.inputAvailable = false;
this.outputAvailable = false;
this.closeHandshakeSource = CloseHandshakeSource.ABNORMAL;
@@ -408,6 +407,58 @@
notifyStateListeners(event);
}
+ public void onDisconnected()
+ {
+ ConnectionState event = null;
+ synchronized (this)
+ {
+ if (this.state == ConnectionState.CLOSED)
+ {
+ // already closed
+ return;
+ }
+
+ CloseInfo close = new CloseInfo(StatusCode.ABNORMAL,"Disconnected");
+
+ this.cleanClose = false;
+ this.state = ConnectionState.CLOSED;
+ this.closeInfo = close;
+ this.inputAvailable = false;
+ this.outputAvailable = false;
+ this.closeHandshakeSource = CloseHandshakeSource.ABNORMAL;
+ event = this.state;
+ }
+ notifyStateListeners(event);
+ }
+
+ @Override
+ public String toString()
+ {
+ StringBuilder str = new StringBuilder();
+ str.append(this.getClass().getSimpleName());
+ str.append("@").append(Integer.toHexString(hashCode()));
+ str.append("[").append(state);
+ str.append(',');
+ if (!inputAvailable)
+ {
+ str.append('!');
+ }
+ str.append("in,");
+ if (!outputAvailable)
+ {
+ str.append('!');
+ }
+ str.append("out");
+ if ((state == ConnectionState.CLOSED) || (state == ConnectionState.CLOSING))
+ {
+ str.append(",close=").append(closeInfo);
+ str.append(",clean=").append(cleanClose);
+ str.append(",closeSource=").append(closeHandshakeSource);
+ }
+ str.append(']');
+ return str.toString();
+ }
+
public boolean wasAbnormalClose()
{
return closeHandshakeSource == CloseHandshakeSource.ABNORMAL;
@@ -427,4 +478,5 @@
{
return closeHandshakeSource == CloseHandshakeSource.REMOTE;
}
+
}
diff --git a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/util/ReflectUtils.java b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/util/ReflectUtils.java
index 32b9c1b..2194ec5 100644
--- a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/util/ReflectUtils.java
+++ b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/util/ReflectUtils.java
@@ -392,4 +392,4 @@
}
return name;
}
-}
+}
\ No newline at end of file
diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/CloseInfoTest.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/CloseInfoTest.java
new file mode 100644
index 0000000..a40e306
--- /dev/null
+++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/CloseInfoTest.java
@@ -0,0 +1,166 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.opensource.org/licenses/apache2.0.php
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+//
+
+package org.eclipse.jetty.websocket.common;
+
+import static org.eclipse.jetty.websocket.api.StatusCode.*;
+import static org.hamcrest.Matchers.*;
+import static org.junit.Assert.*;
+
+import java.nio.ByteBuffer;
+
+import org.eclipse.jetty.util.BufferUtil;
+import org.eclipse.jetty.util.StringUtil;
+import org.eclipse.jetty.websocket.api.ProtocolException;
+import org.eclipse.jetty.websocket.common.frames.CloseFrame;
+import org.junit.Test;
+
+public class CloseInfoTest
+{
+ /**
+ * A test where no close is provided
+ */
+ @Test
+ public void testAnonymousClose()
+ {
+ CloseInfo close = new CloseInfo();
+ assertThat("close.code",close.getStatusCode(),is(NO_CODE));
+ assertThat("close.reason",close.getReason(),nullValue());
+
+ CloseFrame frame = close.asFrame();
+ assertThat("close frame op code",frame.getOpCode(),is(OpCode.CLOSE));
+ // should result in no payload
+ assertThat("close frame has payload",frame.hasPayload(),is(false));
+ assertThat("close frame payload length",frame.getPayloadLength(),is(0));
+ }
+
+ /**
+ * A test where NO_CODE (1005) is provided
+ */
+ @Test
+ public void testNoCode()
+ {
+ CloseInfo close = new CloseInfo(NO_CODE);
+ assertThat("close.code",close.getStatusCode(),is(NO_CODE));
+ assertThat("close.reason",close.getReason(),nullValue());
+
+ CloseFrame frame = close.asFrame();
+ assertThat("close frame op code",frame.getOpCode(),is(OpCode.CLOSE));
+ // should result in no payload
+ assertThat("close frame has payload",frame.hasPayload(),is(false));
+ assertThat("close frame payload length",frame.getPayloadLength(),is(0));
+ }
+
+ /**
+ * A test where NO_CLOSE (1006) is provided
+ */
+ @Test
+ public void testNoClose()
+ {
+ CloseInfo close = new CloseInfo(NO_CLOSE);
+ assertThat("close.code",close.getStatusCode(),is(NO_CLOSE));
+ assertThat("close.reason",close.getReason(),nullValue());
+
+ CloseFrame frame = close.asFrame();
+ assertThat("close frame op code",frame.getOpCode(),is(OpCode.CLOSE));
+ // should result in no payload
+ assertThat("close frame has payload",frame.hasPayload(),is(false));
+ assertThat("close frame payload length",frame.getPayloadLength(),is(0));
+ }
+
+ /**
+ * A test of FAILED_TLS_HANDSHAKE (1007)
+ */
+ @Test
+ public void testFailedTlsHandshake()
+ {
+ CloseInfo close = new CloseInfo(FAILED_TLS_HANDSHAKE);
+ assertThat("close.code",close.getStatusCode(),is(FAILED_TLS_HANDSHAKE));
+ assertThat("close.reason",close.getReason(),nullValue());
+
+ try
+ {
+ @SuppressWarnings("unused")
+ CloseFrame frame = close.asFrame();
+ fail("Expected " + ProtocolException.class.getName());
+ }
+ catch (ProtocolException e)
+ {
+ // expected path
+ assertThat("ProtocolException message",e.getMessage(),containsString("not allowed (per RFC6455)"));
+ }
+ }
+
+ /**
+ * A test of NORMAL (1000)
+ */
+ @Test
+ public void testNormal()
+ {
+ CloseInfo close = new CloseInfo(NORMAL);
+ assertThat("close.code",close.getStatusCode(),is(NORMAL));
+ assertThat("close.reason",close.getReason(),nullValue());
+
+ CloseFrame frame = close.asFrame();
+ assertThat("close frame op code",frame.getOpCode(),is(OpCode.CLOSE));
+ assertThat("close frame payload length",frame.getPayloadLength(),is(2));
+ }
+
+ private ByteBuffer asByteBuffer(int statusCode, String reason)
+ {
+ int len = 2; // status code length
+ byte utf[] = null;
+ if (StringUtil.isNotBlank(reason))
+ {
+ utf = StringUtil.getUtf8Bytes(reason);
+ len += utf.length;
+ }
+
+ ByteBuffer buf = BufferUtil.allocate(len);
+ BufferUtil.flipToFill(buf);
+ buf.put((byte)((statusCode >>> 8) & 0xFF));
+ buf.put((byte)((statusCode >>> 0) & 0xFF));
+
+ if (utf != null)
+ {
+ buf.put(utf,0,utf.length);
+ }
+ BufferUtil.flipToFlush(buf,0);
+
+ return buf;
+ }
+
+ @Test
+ public void testFromFrame()
+ {
+ ByteBuffer payload = asByteBuffer(NORMAL,null);
+ assertThat("payload length", payload.remaining(), is(2));
+ CloseFrame frame = new CloseFrame();
+ frame.setPayload(payload);
+
+ // create from frame
+ CloseInfo close = new CloseInfo(frame);
+ assertThat("close.code",close.getStatusCode(),is(NORMAL));
+ assertThat("close.reason",close.getReason(),nullValue());
+
+ // and back again
+ frame = close.asFrame();
+ assertThat("close frame op code",frame.getOpCode(),is(OpCode.CLOSE));
+ assertThat("close frame payload length",frame.getPayloadLength(),is(2));
+ }
+}
diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/ab/TestABCase4.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/ab/TestABCase4.java
index fe6011d..6b0f018 100644
--- a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/ab/TestABCase4.java
+++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/ab/TestABCase4.java
@@ -21,6 +21,7 @@
import java.nio.ByteBuffer;
import org.eclipse.jetty.util.log.StacklessLogging;
+import org.eclipse.jetty.websocket.api.ProtocolException;
import org.eclipse.jetty.websocket.api.WebSocketBehavior;
import org.eclipse.jetty.websocket.api.WebSocketException;
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
@@ -39,8 +40,7 @@
{
ByteBuffer expected = ByteBuffer.allocate(32);
- expected.put(new byte[]
- { (byte)0x8b, 0x00 });
+ expected.put(new byte[] { (byte)0x8b, 0x00 });
expected.flip();
@@ -50,10 +50,17 @@
{
Parser parser = new UnitParser(policy);
parser.setIncomingFramesHandler(capture);
- parser.parse(expected);
+ try
+ {
+ parser.parse(expected);
+ }
+ catch (ProtocolException ignore)
+ {
+ // ignore
+ }
}
- Assert.assertEquals( "error on undefined opcode", 1, capture.getErrorCount(WebSocketException.class)) ;
+ Assert.assertEquals("error on undefined opcode",1,capture.getErrorCount(WebSocketException.class));
Throwable known = capture.getErrors().poll();
@@ -65,8 +72,7 @@
{
ByteBuffer expected = ByteBuffer.allocate(32);
- expected.put(new byte[]
- { (byte)0x8c, 0x01, 0x00 });
+ expected.put(new byte[] { (byte)0x8c, 0x01, 0x00 });
expected.flip();
@@ -76,24 +82,29 @@
{
Parser parser = new UnitParser(policy);
parser.setIncomingFramesHandler(capture);
- parser.parse(expected);
+ try
+ {
+ parser.parse(expected);
+ }
+ catch (ProtocolException ignore)
+ {
+ // ignore
+ }
}
- Assert.assertEquals( "error on undefined opcode", 1, capture.getErrorCount(WebSocketException.class)) ;
+ Assert.assertEquals("error on undefined opcode",1,capture.getErrorCount(WebSocketException.class));
Throwable known = capture.getErrors().poll();
Assert.assertTrue("undefined option should be in message",known.getMessage().contains("Unknown opcode: 12"));
}
-
@Test
public void testParserNonControlOpCode3Case4_1_1() throws Exception
{
ByteBuffer expected = ByteBuffer.allocate(32);
- expected.put(new byte[]
- { (byte)0x83, 0x00 });
+ expected.put(new byte[] { (byte)0x83, 0x00 });
expected.flip();
@@ -103,10 +114,17 @@
{
Parser parser = new UnitParser(policy);
parser.setIncomingFramesHandler(capture);
- parser.parse(expected);
+ try
+ {
+ parser.parse(expected);
+ }
+ catch (ProtocolException ignore)
+ {
+ // ignore
+ }
}
- Assert.assertEquals( "error on undefined opcode", 1, capture.getErrorCount(WebSocketException.class)) ;
+ Assert.assertEquals("error on undefined opcode",1,capture.getErrorCount(WebSocketException.class));
Throwable known = capture.getErrors().poll();
@@ -118,8 +136,7 @@
{
ByteBuffer expected = ByteBuffer.allocate(32);
- expected.put(new byte[]
- { (byte)0x84, 0x01, 0x00 });
+ expected.put(new byte[] { (byte)0x84, 0x01, 0x00 });
expected.flip();
@@ -129,10 +146,17 @@
{
Parser parser = new UnitParser(policy);
parser.setIncomingFramesHandler(capture);
- parser.parse(expected);
+ try
+ {
+ parser.parse(expected);
+ }
+ catch (ProtocolException ignore)
+ {
+ // ignore
+ }
}
- Assert.assertEquals( "error on undefined opcode", 1, capture.getErrorCount(WebSocketException.class)) ;
+ Assert.assertEquals("error on undefined opcode",1,capture.getErrorCount(WebSocketException.class));
Throwable known = capture.getErrors().poll();
diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadClient.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadClient.java
index bd02460..9f5f17e 100644
--- a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadClient.java
+++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadClient.java
@@ -18,7 +18,8 @@
package org.eclipse.jetty.websocket.common.test;
-import java.io.Closeable;
+import static org.hamcrest.Matchers.*;
+
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
@@ -35,12 +36,13 @@
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-import java.util.concurrent.atomic.AtomicInteger;
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.MappedByteBufferPool;
+import org.eclipse.jetty.toolchain.test.EventQueue;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.StringUtil;
@@ -68,10 +70,6 @@
import org.eclipse.jetty.websocket.common.io.http.HttpResponseHeaderParser;
import org.junit.Assert;
-import static org.hamcrest.Matchers.anyOf;
-import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.notNullValue;
-
/**
* A simple websocket client for performing unit tests with.
* <p>
@@ -84,21 +82,110 @@
* with regards to basic IO behavior, a write should work as expected, a read should work as expected, but <u>what</u> byte it sends or reads is not within its
* scope.
*/
-public class BlockheadClient implements IncomingFrames, OutgoingFrames, ConnectionStateListener, Closeable
+public class BlockheadClient implements OutgoingFrames, ConnectionStateListener, AutoCloseable
{
+ private class FrameReadingThread extends Thread implements Runnable, IncomingFrames
+ {
+ public long totalBytes = 0;
+ public long totalReadOps = 0;
+ public long totalParseOps = 0;
+
+ public EventQueue<WebSocketFrame> frames = new EventQueue<>();
+ public EventQueue<Throwable> errors = new EventQueue<>();
+
+ @Override
+ public void run()
+ {
+ LOG.debug("Reading frames from server");
+
+ byte buf[] = new byte[BUFFER_SIZE];
+ try
+ {
+ if ((remainingBuffer != null) && (remainingBuffer.remaining() > 0))
+ {
+ LOG.debug("Reading bytes received during response header parse: {}",BufferUtil.toDetailString(remainingBuffer));
+ totalBytes += remainingBuffer.remaining();
+ totalReadOps++;
+ parser.parse(remainingBuffer);
+ }
+
+ int len = 0;
+ int available = 0;
+ while (!eof)
+ {
+ available = in.available();
+ len = in.read(buf,0,Math.min(available,buf.length));
+ totalReadOps++;
+ if (len < 0)
+ {
+ eof = true;
+ break;
+ }
+ else if (len > 0)
+ {
+ totalBytes += len;
+ ByteBuffer bbuf = ByteBuffer.wrap(buf,0,len);
+ if (LOG.isDebugEnabled())
+ {
+ LOG.debug("Read {} bytes: {}",len,BufferUtil.toDetailString(bbuf));
+ }
+ totalParseOps++;
+ parser.parse(bbuf);
+ }
+ }
+ }
+ catch (IOException e)
+ {
+ LOG.debug(e);
+ }
+ }
+
+ @Override
+ public String toString()
+ {
+ StringBuilder str = new StringBuilder();
+ str.append("FrameReadingThread[");
+ str.append(",frames=" + frames.size());
+ str.append(",errors=" + errors.size());
+ str.append(String.format(",totalBytes=%,d",totalBytes));
+ str.append(String.format(",totalReadOps=%,d",totalReadOps));
+ str.append(String.format(",totalParseOps=%,d",totalParseOps));
+ str.append("]");
+ return str.toString();
+ }
+
+ @Override
+ public synchronized void incomingError(Throwable t)
+ {
+ this.errors.add(t);
+ }
+
+ @Override
+ public synchronized void incomingFrame(Frame frame)
+ {
+ this.frames.add(WebSocketFrame.copy(frame));
+ }
+
+ public synchronized void clear()
+ {
+ this.frames.clear();
+ this.errors.clear();
+ }
+ }
+
private static final String REQUEST_HASH_KEY = "dGhlIHNhbXBsZSBub25jZQ==";
- private static final int BUFFER_SIZE = 8192;
+ private static final int BUFFER_SIZE = 64 * 1024;
private static final Logger LOG = Log.getLogger(BlockheadClient.class);
- /** Set to true to disable timeouts (for debugging reasons) */
- private boolean debug = false;
private final URI destHttpURI;
private final URI destWebsocketURI;
private final ByteBufferPool bufferPool;
private final Generator generator;
private final Parser parser;
- private final IncomingFramesCapture incomingFrames;
- private final WebSocketExtensionFactory extensionFactory;
+ private final WebSocketExtensionFactory extensionFactory;
+ private FrameReadingThread frameReader;
+
+ private ExecutorService executor;
private Socket socket;
private OutputStream out;
private InputStream in;
@@ -106,16 +193,15 @@
private String protocols;
private List<String> extensions = new ArrayList<>();
private List<String> headers = new ArrayList<>();
- private byte[] clientmask = new byte[]
- { (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF };
+ private byte[] clientmask = new byte[] { (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF };
private int timeout = 1000;
- private AtomicInteger parseCount;
private OutgoingFrames outgoing = this;
private boolean eof = false;
private ExtensionStack extensionStack;
private IOState ioState;
private CountDownLatch disconnectedLatch = new CountDownLatch(1);
private ByteBuffer remainingBuffer;
+
private String connectionValue = "Upgrade";
public BlockheadClient(URI destWebsocketURI) throws URISyntaxException
@@ -140,9 +226,6 @@
this.bufferPool = new MappedByteBufferPool(8192);
this.generator = new Generator(policy,bufferPool);
this.parser = new Parser(policy,bufferPool);
- this.parseCount = new AtomicInteger(0);
-
- this.incomingFrames = new IncomingFramesCapture();
this.extensionFactory = new WebSocketExtensionFactory(policy,bufferPool);
this.ioState = new IOState();
@@ -166,7 +249,7 @@
public void clearCaptured()
{
- this.incomingFrames.clear();
+ frameReader.clear();
}
public void clearExtensions()
@@ -174,6 +257,7 @@
extensions.clear();
}
+ @Override
public void close()
{
LOG.debug("close()");
@@ -182,22 +266,16 @@
public void close(int statusCode, String message)
{
+ LOG.debug("close({},{})",statusCode,message);
CloseInfo close = new CloseInfo(statusCode,message);
- ioState.onCloseLocal(close);
-
if (!ioState.isClosed())
{
- WebSocketFrame frame = close.asFrame();
- LOG.debug("Issuing: {}",frame);
- try
- {
- write(frame);
- }
- catch (IOException e)
- {
- LOG.debug(e);
- }
+ ioState.onCloseLocal(close);
+ }
+ else
+ {
+ LOG.debug("Not issuing close. ioState = {}",ioState);
}
}
@@ -222,6 +300,10 @@
IO.close(in);
IO.close(out);
disconnectedLatch.countDown();
+ if (frameReader != null)
+ {
+ frameReader.interrupt();
+ }
if (socket != null)
{
try
@@ -293,8 +375,12 @@
extensionStack = new ExtensionStack(this.extensionFactory);
extensionStack.negotiate(configs);
+ // Setup Frame Reader
+ this.frameReader = new FrameReadingThread();
+ this.frameReader.start();
+
// Start with default routing
- extensionStack.setNextIncoming(this); // the websocket layer
+ extensionStack.setNextIncoming(frameReader); // the websocket layer
extensionStack.setNextOutgoing(outgoing); // the network layer
// Configure Parser / Generator
@@ -331,6 +417,15 @@
return connectionValue;
}
+ public ExecutorService getExecutor()
+ {
+ if (executor == null)
+ {
+ executor = Executors.newCachedThreadPool();
+ }
+ return executor;
+ }
+
private List<ExtensionConfig> getExtensionConfigs(HttpResponse response)
{
List<ExtensionConfig> configs = new ArrayList<>();
@@ -408,38 +503,6 @@
return destWebsocketURI;
}
- /**
- * Errors received (after extensions)
- */
- @Override
- public void incomingError(Throwable e)
- {
- incomingFrames.incomingError(e);
- }
-
- /**
- * Frames received (after extensions)
- */
- @Override
- public void incomingFrame(Frame frame)
- {
- LOG.debug("incoming({})",frame);
- int count = parseCount.incrementAndGet();
- if ((count % 10) == 0)
- {
- LOG.info("Client parsed {} frames",count);
- }
-
- if (frame.getOpCode() == OpCode.CLOSE)
- {
- CloseInfo close = new CloseInfo(frame);
- ioState.onCloseRemote(close);
- }
-
- WebSocketFrame copy = WebSocketFrame.copy(frame);
- incomingFrames.incomingFrame(copy);
- }
-
public boolean isConnected()
{
return (socket != null) && (socket.isConnected());
@@ -448,6 +511,7 @@
@Override
public void onConnectionStateChange(ConnectionState state)
{
+ LOG.debug("CLIENT onConnectionStateChange() - {}",state);
switch (state)
{
case CLOSED:
@@ -455,10 +519,17 @@
// this.disconnect();
break;
case CLOSING:
- if (ioState.wasRemoteCloseInitiated())
+ CloseInfo close = ioState.getCloseInfo();
+
+ WebSocketFrame frame = close.asFrame();
+ LOG.debug("Issuing: {}",frame);
+ try
{
- CloseInfo close = ioState.getCloseInfo();
- close(close.getStatusCode(),close.getReason());
+ write(frame);
+ }
+ catch (IOException e)
+ {
+ LOG.debug(e);
}
break;
default:
@@ -503,107 +574,41 @@
}
}
- public int read(ByteBuffer buf) throws IOException
+ public EventQueue<WebSocketFrame> readFrames(int expectedFrameCount, int timeoutDuration, TimeUnit timeoutUnit) throws Exception
{
- if (eof)
- {
- throw new EOFException("Hit EOF");
- }
-
- if ((remainingBuffer != null) && (remainingBuffer.remaining() > 0))
- {
- return BufferUtil.put(remainingBuffer,buf);
- }
-
- int len = -1;
- int b;
- while ((in.available() > 0) && (buf.remaining() > 0))
- {
- b = in.read();
- if (b == (-1))
- {
- eof = true;
- break;
- }
- buf.put((byte)b);
- len++;
- }
-
- return len;
- }
-
- public IncomingFramesCapture readFrames(int expectedCount, TimeUnit timeoutUnit, int timeoutDuration) throws IOException, TimeoutException
- {
- LOG.debug("Read: waiting for {} frame(s) from server",expectedCount);
-
- ByteBuffer buf = bufferPool.acquire(BUFFER_SIZE,false);
- BufferUtil.clearToFill(buf);
- try
- {
- long msDur = TimeUnit.MILLISECONDS.convert(timeoutDuration,timeoutUnit);
- long now = System.currentTimeMillis();
- long expireOn = now + msDur;
- LOG.debug("Now: {} - expireOn: {} ({} ms)",now,expireOn,msDur);
-
- long iter = 0;
-
- int len = 0;
- while (incomingFrames.size() < expectedCount)
- {
- BufferUtil.clearToFill(buf);
- len = read(buf);
- if (len > 0)
- {
- BufferUtil.flipToFlush(buf,0);
- if (LOG.isDebugEnabled())
- {
- LOG.debug("Read {} bytes: {}",len,BufferUtil.toDetailString(buf));
- }
- parser.parse(buf);
- }
- else
- {
- if (LOG.isDebugEnabled())
- {
- iter++;
- if ((iter % 10000000) == 0)
- {
- LOG.debug("10,000,000 reads of zero length");
- iter = 0;
- }
- }
- }
-
- if (!debug && (System.currentTimeMillis() > expireOn))
- {
- incomingFrames.dump();
- throw new TimeoutException(String.format("Timeout reading all %d expected frames. (managed to only read %d frame(s))",expectedCount,
- incomingFrames.size()));
- }
- }
- }
- finally
- {
- bufferPool.release(buf);
- }
-
- return incomingFrames;
+ frameReader.frames.awaitEventCount(expectedFrameCount,timeoutDuration,timeoutUnit);
+ return frameReader.frames;
}
public HttpResponse readResponseHeader() throws IOException
{
HttpResponse response = new HttpResponse();
- HttpResponseHeaderParser parser = new HttpResponseHeaderParser(response);
+ HttpResponseHeaderParser respParser = new HttpResponseHeaderParser(response);
- ByteBuffer buf = BufferUtil.allocate(512);
+ byte buf[] = new byte[512];
- do
+ while (!eof)
{
- BufferUtil.flipToFill(buf);
- read(buf);
- BufferUtil.flipToFlush(buf,0);
+ int available = in.available();
+ int len = in.read(buf,0,Math.min(available,buf.length));
+ if (len < 0)
+ {
+ eof = true;
+ break;
+ }
+ else if (len > 0)
+ {
+ ByteBuffer bbuf = ByteBuffer.wrap(buf,0,len);
+ if (LOG.isDebugEnabled())
+ {
+ LOG.debug("Read {} bytes: {}",len,BufferUtil.toDetailString(bbuf));
+ }
+ if (respParser.parse(bbuf) != null)
+ {
+ break;
+ }
+ }
}
- while (parser.parse(buf) == null);
remainingBuffer = response.getRemainingBuffer();
@@ -643,9 +648,9 @@
this.connectionValue = connectionValue;
}
- public void setDebug(boolean flag)
+ public void setExecutor(ExecutorService executor)
{
- this.debug = flag;
+ this.executor = executor;
}
public void setProtocols(String protocols)
@@ -653,7 +658,7 @@
this.protocols = protocols;
}
- public void setTimeout(TimeUnit unit, int duration)
+ public void setTimeout(int duration, TimeUnit unit)
{
this.timeout = (int)TimeUnit.MILLISECONDS.convert(duration,unit);
}
@@ -701,19 +706,19 @@
{
if (!ioState.isOpen())
{
+ LOG.debug("IO Not Open / Not Writing: {}",frame);
return;
}
LOG.debug("write(Frame->{}) to {}",frame,outgoing);
if (LOG.isDebugEnabled())
{
- frame.setMask(new byte[]
- { 0x00, 0x00, 0x00, 0x00 });
+ frame.setMask(new byte[] { 0x00, 0x00, 0x00, 0x00 });
}
else
{
frame.setMask(clientmask);
}
- extensionStack.outgoingFrame(frame,null, BatchMode.OFF);
+ extensionStack.outgoingFrame(frame,null,BatchMode.OFF);
}
public void writeRaw(ByteBuffer buf) throws IOException
diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadServer.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadServer.java
index c3cd1ad..1b665bd 100644
--- a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadServer.java
+++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadServer.java
@@ -54,6 +54,7 @@
import org.eclipse.jetty.websocket.api.extensions.Frame;
import org.eclipse.jetty.websocket.api.extensions.IncomingFrames;
import org.eclipse.jetty.websocket.api.extensions.OutgoingFrames;
+import org.eclipse.jetty.websocket.api.extensions.Frame.Type;
import org.eclipse.jetty.websocket.common.AcceptHash;
import org.eclipse.jetty.websocket.common.CloseInfo;
import org.eclipse.jetty.websocket.common.Generator;
@@ -124,7 +125,6 @@
{
write(new CloseFrame());
flush();
- disconnect();
}
public void close(int statusCode) throws IOException
@@ -132,7 +132,6 @@
CloseInfo close = new CloseInfo(statusCode);
write(close.asFrame());
flush();
- disconnect();
}
public void disconnect()
@@ -229,6 +228,19 @@
CloseInfo close = new CloseInfo(frame);
LOG.debug("Close frame: {}",close);
}
+
+ Type type = frame.getType();
+ if (echoing.get() && (type.isData() || type.isContinuation()))
+ {
+ try
+ {
+ write(WebSocketFrame.copy(frame));
+ }
+ catch (IOException e)
+ {
+ LOG.warn(e);
+ }
+ }
}
@Override
@@ -317,9 +329,18 @@
return len;
}
+ /**
+ * @deprecated use {@link #readFrames(int, int, TimeUnit)} for correct parameter order
+ */
+ @Deprecated
public IncomingFramesCapture readFrames(int expectedCount, TimeUnit timeoutUnit, int timeoutDuration) throws IOException, TimeoutException
{
- LOG.debug("Read: waiting for {} frame(s) from server",expectedCount);
+ return readFrames(expectedCount,timeoutDuration,timeoutUnit);
+ }
+
+ public IncomingFramesCapture readFrames(int expectedCount, int timeoutDuration, TimeUnit timeoutUnit) throws IOException, TimeoutException
+ {
+ LOG.debug("Read: waiting for {} frame(s) from client",expectedCount);
int startCount = incomingFrames.size();
ByteBuffer buf = bufferPool.acquire(BUFFER_SIZE,false);
@@ -562,13 +583,22 @@
public void write(Frame frame) throws IOException
{
LOG.debug("write(Frame->{}) to {}",frame,outgoing);
- outgoing.outgoingFrame(frame,null, BatchMode.OFF);
+ outgoing.outgoingFrame(frame,null,BatchMode.OFF);
}
public void write(int b) throws IOException
{
getOutputStream().write(b);
}
+
+ public void write(ByteBuffer buf) throws IOException
+ {
+ byte arr[] = BufferUtil.toArray(buf);
+ if ((arr != null) && (arr.length > 0))
+ {
+ getOutputStream().write(arr);
+ }
+ }
}
private static final Logger LOG = Log.getLogger(BlockheadServer.class);
diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/Fuzzer.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/Fuzzer.java
index 3d6c641..1a72c89 100644
--- a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/Fuzzer.java
+++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/Fuzzer.java
@@ -18,6 +18,8 @@
package org.eclipse.jetty.websocket.common.test;
+import static org.hamcrest.Matchers.*;
+
import java.io.IOException;
import java.net.SocketException;
import java.nio.ByteBuffer;
@@ -25,8 +27,8 @@
import java.util.List;
import java.util.Locale;
import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
+import org.eclipse.jetty.toolchain.test.EventQueue;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
@@ -39,13 +41,10 @@
import org.eclipse.jetty.websocket.common.io.IOState;
import org.junit.Assert;
-import static org.hamcrest.Matchers.containsString;
-import static org.hamcrest.Matchers.is;
-
/**
* Fuzzing utility for the AB tests.
*/
-public class Fuzzer
+public class Fuzzer implements AutoCloseable
{
public static enum CloseState
{
@@ -95,6 +94,7 @@
policy.setIdleTimeout(5000);
this.client = new BlockheadClient(policy,testcase.getServerURI());
+ this.client.setTimeout(2,TimeUnit.SECONDS);
this.generator = testcase.getLaxGenerator();
this.testname = testcase.getTestMethodName();
}
@@ -117,8 +117,14 @@
buf.flip();
return buf;
}
+
+ @Override
+ public void close() throws Exception
+ {
+ this.client.disconnect();
+ }
- public void close()
+ public void disconnect()
{
this.client.disconnect();
}
@@ -134,28 +140,24 @@
}
}
- public void expect(List<WebSocketFrame> expect) throws IOException, TimeoutException
+ public void expect(List<WebSocketFrame> expect) throws Exception
{
- expect(expect,TimeUnit.SECONDS,10);
+ expect(expect,10,TimeUnit.SECONDS);
}
- public void expect(List<WebSocketFrame> expect, TimeUnit unit, int duration) throws IOException, TimeoutException
+ public void expect(List<WebSocketFrame> expect, int duration, TimeUnit unit) throws Exception
{
int expectedCount = expect.size();
LOG.debug("expect() {} frame(s)",expect.size());
// Read frames
- IncomingFramesCapture capture = client.readFrames(expect.size(),unit,duration);
- if (LOG.isDebugEnabled())
- {
- capture.dump();
- }
-
+ EventQueue<WebSocketFrame> frames = client.readFrames(expect.size(),duration,unit);
+
String prefix = "";
for (int i = 0; i < expectedCount; i++)
{
WebSocketFrame expected = expect.get(i);
- WebSocketFrame actual = capture.getFrames().poll();
+ WebSocketFrame actual = frames.poll();
prefix = "Frame[" + i + "]";
@@ -177,7 +179,7 @@
}
}
- public void expect(WebSocketFrame expect) throws IOException, TimeoutException
+ public void expect(WebSocketFrame expect) throws Exception
{
expect(Collections.singletonList(expect));
}
@@ -187,23 +189,6 @@
// TODO Should test for no more frames. success if connection closed.
}
- public void expectServerDisconnect(DisconnectMode mode)
- {
- client.expectServerDisconnect();
- IOState ios = client.getIOState();
-
- switch (mode)
- {
- case CLEAN:
- Assert.assertTrue(ios.wasRemoteCloseInitiated());
- Assert.assertTrue(ios.wasCleanClose());
- break;
- case UNCLEAN:
- Assert.assertTrue(ios.wasRemoteCloseInitiated());
- break;
- }
- }
-
public CloseState getCloseState()
{
IOState ios = client.getIOState();
diff --git a/jetty-websocket/websocket-server/src/main/java/org/eclipse/jetty/websocket/server/WebSocketServerFactory.java b/jetty-websocket/websocket-server/src/main/java/org/eclipse/jetty/websocket/server/WebSocketServerFactory.java
index bebe7c0..f6a2f2c 100644
--- a/jetty-websocket/websocket-server/src/main/java/org/eclipse/jetty/websocket/server/WebSocketServerFactory.java
+++ b/jetty-websocket/websocket-server/src/main/java/org/eclipse/jetty/websocket/server/WebSocketServerFactory.java
@@ -44,6 +44,7 @@
import org.eclipse.jetty.util.thread.ScheduledExecutorScheduler;
import org.eclipse.jetty.util.thread.Scheduler;
import org.eclipse.jetty.websocket.api.InvalidWebSocketException;
+import org.eclipse.jetty.websocket.api.StatusCode;
import org.eclipse.jetty.websocket.api.WebSocketException;
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
import org.eclipse.jetty.websocket.api.extensions.ExtensionFactory;
@@ -199,11 +200,23 @@
}
}
- protected void closeAllConnections()
+ protected void shutdownAllConnections()
{
for (WebSocketSession session : openSessions)
{
- session.close();
+ if (session.getConnection() != null)
+ {
+ try
+ {
+ session.getConnection().close(
+ StatusCode.SHUTDOWN,
+ "Shutdown");
+ }
+ catch (Throwable t)
+ {
+ LOG.debug("During Shutdown All Connections",t);
+ }
+ }
}
openSessions.clear();
}
@@ -269,7 +282,7 @@
@Override
protected void doStop() throws Exception
{
- closeAllConnections();
+ shutdownAllConnections();
super.doStop();
}
diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/AnnotatedMaxMessageSizeTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/AnnotatedMaxMessageSizeTest.java
index b07597e..e6ca4dc 100644
--- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/AnnotatedMaxMessageSizeTest.java
+++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/AnnotatedMaxMessageSizeTest.java
@@ -28,6 +28,7 @@
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
+import org.eclipse.jetty.toolchain.test.EventQueue;
import org.eclipse.jetty.util.log.StacklessLogging;
import org.eclipse.jetty.websocket.api.StatusCode;
import org.eclipse.jetty.websocket.common.CloseInfo;
@@ -36,7 +37,6 @@
import org.eclipse.jetty.websocket.common.WebSocketFrame;
import org.eclipse.jetty.websocket.common.frames.TextFrame;
import org.eclipse.jetty.websocket.common.test.BlockheadClient;
-import org.eclipse.jetty.websocket.common.test.IncomingFramesCapture;
import org.eclipse.jetty.websocket.server.examples.echo.BigEchoSocket;
import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory;
import org.junit.AfterClass;
@@ -100,8 +100,8 @@
client.write(new TextFrame().setPayload(msg));
// Read frame (hopefully text frame)
- IncomingFramesCapture capture = client.readFrames(1,TimeUnit.MILLISECONDS,500);
- WebSocketFrame tf = capture.getFrames().poll();
+ EventQueue<WebSocketFrame> frames = client.readFrames(1,500,TimeUnit.MILLISECONDS);
+ WebSocketFrame tf = frames.poll();
Assert.assertThat("Text Frame.status code",tf.getPayloadAsUTF8(),is(msg));
}
finally
@@ -127,8 +127,8 @@
client.write(new TextFrame().setPayload(ByteBuffer.wrap(buf)));
// Read frame (hopefully close frame saying its too large)
- IncomingFramesCapture capture = client.readFrames(1,TimeUnit.MILLISECONDS,500);
- WebSocketFrame tf = capture.getFrames().poll();
+ EventQueue<WebSocketFrame> frames = client.readFrames(1,500,TimeUnit.MILLISECONDS);
+ WebSocketFrame tf = frames.poll();
Assert.assertThat("Frame is close", tf.getOpCode(), is(OpCode.CLOSE));
CloseInfo close = new CloseInfo(tf);
Assert.assertThat("Close Code", close.getStatusCode(), is(StatusCode.MESSAGE_TOO_LARGE));
diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ChromeTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ChromeTest.java
index 1abe09b..38ab890 100644
--- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ChromeTest.java
+++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ChromeTest.java
@@ -22,19 +22,17 @@
import java.util.concurrent.TimeUnit;
+import org.eclipse.jetty.toolchain.test.EventQueue;
import org.eclipse.jetty.websocket.common.WebSocketFrame;
import org.eclipse.jetty.websocket.common.frames.TextFrame;
import org.eclipse.jetty.websocket.common.test.BlockheadClient;
import org.eclipse.jetty.websocket.common.test.HttpResponse;
-import org.eclipse.jetty.websocket.common.test.IncomingFramesCapture;
import org.eclipse.jetty.websocket.server.examples.MyEchoServlet;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
-import org.junit.Ignore;
import org.junit.Test;
-@Ignore("Bug 395444")
public class ChromeTest
{
private static SimpleServletServer server;
@@ -70,8 +68,8 @@
client.write(new TextFrame().setPayload(msg));
// Read frame (hopefully text frame)
- IncomingFramesCapture capture = client.readFrames(1,TimeUnit.MILLISECONDS,500);
- WebSocketFrame tf = capture.getFrames().poll();
+ EventQueue<WebSocketFrame> frames = client.readFrames(1,500,TimeUnit.MILLISECONDS);
+ WebSocketFrame tf = frames.poll();
Assert.assertThat("Text Frame.status code",tf.getPayloadAsUTF8(),is(msg));
}
finally
diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/FirefoxTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/FirefoxTest.java
index 46dbdd9..771cdd4 100644
--- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/FirefoxTest.java
+++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/FirefoxTest.java
@@ -18,20 +18,20 @@
package org.eclipse.jetty.websocket.server;
+import static org.hamcrest.Matchers.*;
+
import java.util.concurrent.TimeUnit;
+import org.eclipse.jetty.toolchain.test.EventQueue;
import org.eclipse.jetty.websocket.common.WebSocketFrame;
import org.eclipse.jetty.websocket.common.frames.TextFrame;
import org.eclipse.jetty.websocket.common.test.BlockheadClient;
-import org.eclipse.jetty.websocket.common.test.IncomingFramesCapture;
import org.eclipse.jetty.websocket.server.examples.MyEchoServlet;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
-import static org.hamcrest.Matchers.is;
-
public class FirefoxTest
{
private static SimpleServletServer server;
@@ -65,8 +65,8 @@
client.write(new TextFrame().setPayload(msg));
// Read frame (hopefully text frame)
- IncomingFramesCapture capture = client.readFrames(1, TimeUnit.MILLISECONDS, 500);
- WebSocketFrame tf = capture.getFrames().poll();
+ EventQueue<WebSocketFrame> frames = client.readFrames(1, 500, TimeUnit.MILLISECONDS);
+ WebSocketFrame tf = frames.poll();
Assert.assertThat("Text Frame.status code", tf.getPayloadAsUTF8(), is(msg));
}
}
diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/FragmentExtensionTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/FragmentExtensionTest.java
index 045b96c..be15bac 100644
--- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/FragmentExtensionTest.java
+++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/FragmentExtensionTest.java
@@ -22,11 +22,11 @@
import java.util.concurrent.TimeUnit;
+import org.eclipse.jetty.toolchain.test.EventQueue;
import org.eclipse.jetty.websocket.common.WebSocketFrame;
import org.eclipse.jetty.websocket.common.frames.TextFrame;
import org.eclipse.jetty.websocket.common.test.BlockheadClient;
import org.eclipse.jetty.websocket.common.test.HttpResponse;
-import org.eclipse.jetty.websocket.common.test.IncomingFramesCapture;
import org.eclipse.jetty.websocket.server.helper.EchoServlet;
import org.junit.AfterClass;
import org.junit.Assert;
@@ -79,7 +79,7 @@
try
{
// Make sure the read times out if there are problems with the implementation
- client.setTimeout(TimeUnit.SECONDS,1);
+ client.setTimeout(1,TimeUnit.SECONDS);
client.connect();
client.sendStandardRequest();
HttpResponse resp = client.expectUpgradeResponse();
@@ -90,10 +90,10 @@
client.write(new TextFrame().setPayload(msg));
String parts[] = split(msg,fragSize);
- IncomingFramesCapture capture = client.readFrames(parts.length,TimeUnit.MILLISECONDS,1000);
+ EventQueue<WebSocketFrame> frames = client.readFrames(parts.length,1000,TimeUnit.MILLISECONDS);
for (int i = 0; i < parts.length; i++)
{
- WebSocketFrame frame = capture.getFrames().poll();
+ WebSocketFrame frame = frames.poll();
Assert.assertThat("text[" + i + "].payload",frame.getPayloadAsUTF8(),is(parts[i]));
}
}
diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/FrameCompressionExtensionTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/FrameCompressionExtensionTest.java
index 607ba24..8811cc6 100644
--- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/FrameCompressionExtensionTest.java
+++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/FrameCompressionExtensionTest.java
@@ -22,11 +22,11 @@
import java.util.concurrent.TimeUnit;
+import org.eclipse.jetty.toolchain.test.EventQueue;
import org.eclipse.jetty.websocket.common.WebSocketFrame;
import org.eclipse.jetty.websocket.common.frames.TextFrame;
import org.eclipse.jetty.websocket.common.test.BlockheadClient;
import org.eclipse.jetty.websocket.common.test.HttpResponse;
-import org.eclipse.jetty.websocket.common.test.IncomingFramesCapture;
import org.eclipse.jetty.websocket.server.helper.EchoServlet;
import org.junit.AfterClass;
import org.junit.Assert;
@@ -61,7 +61,7 @@
try
{
// Make sure the read times out if there are problems with the implementation
- client.setTimeout(TimeUnit.SECONDS,1);
+ client.setTimeout(1,TimeUnit.SECONDS);
client.connect();
client.sendStandardRequest();
HttpResponse resp = client.expectUpgradeResponse();
@@ -73,8 +73,8 @@
// Client sends first message
client.write(new TextFrame().setPayload(msg));
- IncomingFramesCapture capture = client.readFrames(1,TimeUnit.MILLISECONDS,1000);
- WebSocketFrame frame = capture.getFrames().poll();
+ EventQueue<WebSocketFrame> frames = client.readFrames(1,1000,TimeUnit.MILLISECONDS);
+ WebSocketFrame frame = frames.poll();
Assert.assertThat("TEXT.payload",frame.getPayloadAsUTF8(),is(msg.toString()));
// Client sends second message
@@ -82,8 +82,8 @@
msg = "There";
client.write(new TextFrame().setPayload(msg));
- capture = client.readFrames(1,TimeUnit.SECONDS,1);
- frame = capture.getFrames().poll();
+ frames = client.readFrames(1,1,TimeUnit.SECONDS);
+ frame = frames.poll();
Assert.assertThat("TEXT.payload",frame.getPayloadAsUTF8(),is(msg.toString()));
}
finally
diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/IdentityExtensionTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/IdentityExtensionTest.java
index c0ca20f..5c12713 100644
--- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/IdentityExtensionTest.java
+++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/IdentityExtensionTest.java
@@ -22,11 +22,11 @@
import java.util.concurrent.TimeUnit;
+import org.eclipse.jetty.toolchain.test.EventQueue;
import org.eclipse.jetty.websocket.common.WebSocketFrame;
import org.eclipse.jetty.websocket.common.frames.TextFrame;
import org.eclipse.jetty.websocket.common.test.BlockheadClient;
import org.eclipse.jetty.websocket.common.test.HttpResponse;
-import org.eclipse.jetty.websocket.common.test.IncomingFramesCapture;
import org.eclipse.jetty.websocket.server.helper.EchoServlet;
import org.junit.AfterClass;
import org.junit.Assert;
@@ -64,7 +64,7 @@
try
{
// Make sure the read times out if there are problems with the implementation
- client.setTimeout(TimeUnit.SECONDS,1);
+ client.setTimeout(1,TimeUnit.SECONDS);
client.connect();
client.sendStandardRequest();
HttpResponse resp = client.expectUpgradeResponse();
@@ -73,8 +73,8 @@
client.write(new TextFrame().setPayload("Hello"));
- IncomingFramesCapture capture = client.readFrames(1,TimeUnit.MILLISECONDS,1000);
- WebSocketFrame frame = capture.getFrames().poll();
+ EventQueue<WebSocketFrame> frames = client.readFrames(1,1000,TimeUnit.MILLISECONDS);
+ WebSocketFrame frame = frames.poll();
Assert.assertThat("TEXT.payload",frame.getPayloadAsUTF8(),is("Hello"));
}
finally
diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/IdleTimeoutTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/IdleTimeoutTest.java
index 7a6998b..4b36004 100644
--- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/IdleTimeoutTest.java
+++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/IdleTimeoutTest.java
@@ -18,14 +18,22 @@
package org.eclipse.jetty.websocket.server;
+import static org.hamcrest.Matchers.*;
+
import java.util.concurrent.TimeUnit;
+import org.eclipse.jetty.toolchain.test.EventQueue;
+import org.eclipse.jetty.websocket.api.StatusCode;
+import org.eclipse.jetty.websocket.common.CloseInfo;
+import org.eclipse.jetty.websocket.common.OpCode;
+import org.eclipse.jetty.websocket.common.WebSocketFrame;
import org.eclipse.jetty.websocket.common.frames.TextFrame;
import org.eclipse.jetty.websocket.common.test.BlockheadClient;
import org.eclipse.jetty.websocket.server.helper.RFCSocket;
import org.eclipse.jetty.websocket.servlet.WebSocketServlet;
import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory;
import org.junit.AfterClass;
+import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
@@ -65,7 +73,7 @@
{
BlockheadClient client = new BlockheadClient(server.getServerUri());
client.setProtocols("onConnect");
- client.setTimeout(TimeUnit.MILLISECONDS,2500);
+ client.setTimeout(2500,TimeUnit.MILLISECONDS);
try
{
client.connect();
@@ -83,8 +91,13 @@
// The server could not read this frame, if it is in this half closed state
client.write(new TextFrame().setPayload("Hello"));
- // Expect server to be disconnected at this point
- client.expectServerDisconnect();
+ // Expect server to have closed due to its own timeout
+ EventQueue<WebSocketFrame> frames = client.readFrames(1,500,TimeUnit.MILLISECONDS);
+ WebSocketFrame frame = frames.poll();
+ Assert.assertThat("frame opcode",frame.getOpCode(),is(OpCode.CLOSE));
+ CloseInfo close = new CloseInfo(frame);
+ Assert.assertThat("close code",close.getStatusCode(),is(StatusCode.SHUTDOWN));
+ Assert.assertThat("close reason",close.getReason(),containsString("Timeout"));
}
finally
{
diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/PerMessageDeflateExtensionTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/PerMessageDeflateExtensionTest.java
index 4747e8a..d06dd75 100644
--- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/PerMessageDeflateExtensionTest.java
+++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/PerMessageDeflateExtensionTest.java
@@ -18,22 +18,21 @@
package org.eclipse.jetty.websocket.server;
+import static org.hamcrest.Matchers.*;
+
import java.util.concurrent.TimeUnit;
+import org.eclipse.jetty.toolchain.test.EventQueue;
import org.eclipse.jetty.websocket.common.WebSocketFrame;
import org.eclipse.jetty.websocket.common.frames.TextFrame;
import org.eclipse.jetty.websocket.common.test.BlockheadClient;
import org.eclipse.jetty.websocket.common.test.HttpResponse;
-import org.eclipse.jetty.websocket.common.test.IncomingFramesCapture;
import org.eclipse.jetty.websocket.server.helper.EchoServlet;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
-import static org.hamcrest.Matchers.containsString;
-import static org.hamcrest.Matchers.is;
-
public class PerMessageDeflateExtensionTest
{
private static SimpleServletServer server;
@@ -65,7 +64,7 @@
try
{
// Make sure the read times out if there are problems with the implementation
- client.setTimeout(TimeUnit.SECONDS,1);
+ client.setTimeout(1,TimeUnit.SECONDS);
client.connect();
client.sendStandardRequest();
HttpResponse resp = client.expectUpgradeResponse();
@@ -77,8 +76,8 @@
// Client sends first message
client.write(new TextFrame().setPayload(msg));
- IncomingFramesCapture capture = client.readFrames(1,TimeUnit.MILLISECONDS,1000);
- WebSocketFrame frame = capture.getFrames().poll();
+ EventQueue<WebSocketFrame> frames = client.readFrames(1,1000,TimeUnit.MILLISECONDS);
+ WebSocketFrame frame = frames.poll();
Assert.assertThat("TEXT.payload",frame.getPayloadAsUTF8(),is(msg.toString()));
// Client sends second message
@@ -86,8 +85,8 @@
msg = "There";
client.write(new TextFrame().setPayload(msg));
- capture = client.readFrames(1,TimeUnit.SECONDS,1);
- frame = capture.getFrames().poll();
+ frames = client.readFrames(1,1,TimeUnit.SECONDS);
+ frame = frames.poll();
Assert.assertThat("TEXT.payload",frame.getPayloadAsUTF8(),is(msg.toString()));
}
finally
diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/RequestHeadersTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/RequestHeadersTest.java
index 6cc9950..4726858 100644
--- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/RequestHeadersTest.java
+++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/RequestHeadersTest.java
@@ -107,7 +107,7 @@
public void testAccessRequestCookies() throws Exception
{
BlockheadClient client = new BlockheadClient(server.getServerUri());
- client.setTimeout(TimeUnit.SECONDS,1);
+ client.setTimeout(1,TimeUnit.SECONDS);
try
{
diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketCloseTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketCloseTest.java
index 0c2ddb3..0ec98a3 100644
--- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketCloseTest.java
+++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketCloseTest.java
@@ -25,6 +25,7 @@
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
+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.util.log.StacklessLogging;
@@ -36,7 +37,6 @@
import org.eclipse.jetty.websocket.common.WebSocketFrame;
import org.eclipse.jetty.websocket.common.events.AbstractEventDriver;
import org.eclipse.jetty.websocket.common.test.BlockheadClient;
-import org.eclipse.jetty.websocket.common.test.IncomingFramesCapture;
import org.eclipse.jetty.websocket.server.helper.RFCSocket;
import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest;
import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse;
@@ -114,7 +114,7 @@
public void onWebSocketConnect(Session sess)
{
LOG.debug("onWebSocketConnect({})",sess);
- sess.close();
+ sess.close(StatusCode.NORMAL,"FastCloseServer");
}
}
@@ -129,14 +129,10 @@
public void onWebSocketConnect(Session sess)
{
LOG.debug("onWebSocketConnect({})",sess);
+ // Test failure due to unhandled exception
+ // this should trigger a fast-fail closure during open/connect
throw new RuntimeException("Intentional FastFail");
}
-
- @Override
- public void onWebSocketError(Throwable cause)
- {
- errors.add(cause);
- }
}
private static final Logger LOG = Log.getLogger(WebSocketCloseTest.class);
@@ -163,30 +159,28 @@
@Test
public void testFastClose() throws Exception
{
- BlockheadClient client = new BlockheadClient(server.getServerUri());
- client.setProtocols("fastclose");
- client.setTimeout(TimeUnit.SECONDS,1);
- try
+ try (BlockheadClient client = new BlockheadClient(server.getServerUri()))
{
+ client.setProtocols("fastclose");
+ client.setTimeout(1,TimeUnit.SECONDS);
client.connect();
client.sendStandardRequest();
client.expectUpgradeResponse();
- IncomingFramesCapture capture = client.readFrames(1,TimeUnit.SECONDS,1);
- WebSocketFrame frame = capture.getFrames().poll();
+ // Verify that client got close frame
+ EventQueue<WebSocketFrame> frames = client.readFrames(1,1,TimeUnit.SECONDS);
+ WebSocketFrame frame = frames.poll();
Assert.assertThat("frames[0].opcode",frame.getOpCode(),is(OpCode.CLOSE));
CloseInfo close = new CloseInfo(frame);
Assert.assertThat("Close Status Code",close.getStatusCode(),is(StatusCode.NORMAL));
-
+
+ // Notify server of close handshake
client.write(close.asFrame()); // respond with close
-
+
+ // ensure server socket got close event
Assert.assertThat("Fast Close Latch",closeSocket.closeLatch.await(1,TimeUnit.SECONDS),is(true));
Assert.assertThat("Fast Close.statusCode",closeSocket.closeStatusCode,is(StatusCode.NORMAL));
}
- finally
- {
- client.close();
- }
}
/**
@@ -195,33 +189,29 @@
@Test
public void testFastFail() throws Exception
{
- BlockheadClient client = new BlockheadClient(server.getServerUri());
- client.setProtocols("fastfail");
- client.setTimeout(TimeUnit.SECONDS,1);
- try
+ try (BlockheadClient client = new BlockheadClient(server.getServerUri()))
{
+ client.setProtocols("fastfail");
+ client.setTimeout(1,TimeUnit.SECONDS);
try (StacklessLogging scope = new StacklessLogging(AbstractEventDriver.class))
{
client.connect();
client.sendStandardRequest();
client.expectUpgradeResponse();
- IncomingFramesCapture capture = client.readFrames(1,TimeUnit.SECONDS,1);
- WebSocketFrame frame = capture.getFrames().poll();
+ EventQueue<WebSocketFrame> frames = client.readFrames(1,1,TimeUnit.SECONDS);
+ WebSocketFrame frame = frames.poll();
Assert.assertThat("frames[0].opcode",frame.getOpCode(),is(OpCode.CLOSE));
CloseInfo close = new CloseInfo(frame);
Assert.assertThat("Close Status Code",close.getStatusCode(),is(StatusCode.SERVER_ERROR));
client.write(close.asFrame()); // respond with close
+ // ensure server socket got close event
Assert.assertThat("Fast Fail Latch",closeSocket.closeLatch.await(1,TimeUnit.SECONDS),is(true));
Assert.assertThat("Fast Fail.statusCode",closeSocket.closeStatusCode,is(StatusCode.SERVER_ERROR));
Assert.assertThat("Fast Fail.errors",closeSocket.errors.size(),is(1));
}
}
- finally
- {
- client.close();
- }
}
}
diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketServerSessionTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketServerSessionTest.java
index 8b3732b..4d3568b 100644
--- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketServerSessionTest.java
+++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketServerSessionTest.java
@@ -18,15 +18,16 @@
package org.eclipse.jetty.websocket.server;
+import static org.hamcrest.Matchers.*;
+
import java.net.URI;
-import java.util.Queue;
import java.util.concurrent.TimeUnit;
import org.eclipse.jetty.toolchain.test.AdvancedRunner;
+import org.eclipse.jetty.toolchain.test.EventQueue;
import org.eclipse.jetty.websocket.common.WebSocketFrame;
import org.eclipse.jetty.websocket.common.frames.TextFrame;
import org.eclipse.jetty.websocket.common.test.BlockheadClient;
-import org.eclipse.jetty.websocket.common.test.IncomingFramesCapture;
import org.eclipse.jetty.websocket.server.helper.SessionServlet;
import org.junit.AfterClass;
import org.junit.Assert;
@@ -34,8 +35,6 @@
import org.junit.Test;
import org.junit.runner.RunWith;
-import static org.hamcrest.Matchers.is;
-
/**
* Testing various aspects of the server side support for WebSocket {@link Session}
*/
@@ -90,8 +89,7 @@
client.write(new TextFrame().setPayload("getParameterMap|cost")); // intentionally invalid
// Read frame (hopefully text frame)
- IncomingFramesCapture capture = client.readFrames(4, TimeUnit.SECONDS, 5);
- Queue<WebSocketFrame> frames = capture.getFrames();
+ EventQueue<WebSocketFrame> frames = client.readFrames(4,5,TimeUnit.SECONDS);
WebSocketFrame tf = frames.poll();
Assert.assertThat("Parameter Map[snack]", tf.getPayloadAsUTF8(), is("[cashews]"));
tf = frames.poll();
diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketServletRFCTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketServletRFCTest.java
index fe27a9d..7071838 100644
--- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketServletRFCTest.java
+++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketServletRFCTest.java
@@ -25,6 +25,7 @@
import java.util.concurrent.TimeUnit;
import org.eclipse.jetty.toolchain.test.AdvancedRunner;
+import org.eclipse.jetty.toolchain.test.EventQueue;
import org.eclipse.jetty.util.Utf8Appendable.NotUtf8Exception;
import org.eclipse.jetty.util.Utf8StringBuilder;
import org.eclipse.jetty.util.log.StacklessLogging;
@@ -41,7 +42,6 @@
import org.eclipse.jetty.websocket.common.frames.ContinuationFrame;
import org.eclipse.jetty.websocket.common.frames.TextFrame;
import org.eclipse.jetty.websocket.common.test.BlockheadClient;
-import org.eclipse.jetty.websocket.common.test.IncomingFramesCapture;
import org.eclipse.jetty.websocket.common.test.UnitGenerator;
import org.eclipse.jetty.websocket.common.util.Hex;
import org.eclipse.jetty.websocket.server.helper.RFCServlet;
@@ -116,8 +116,8 @@
client.write(bin); // write buf3 (fin=true)
// Read frame echo'd back (hopefully a single binary frame)
- IncomingFramesCapture capture = client.readFrames(1,TimeUnit.MILLISECONDS,1000);
- Frame binmsg = capture.getFrames().poll();
+ EventQueue<WebSocketFrame> frames = client.readFrames(1,1000,TimeUnit.MILLISECONDS);
+ Frame binmsg = frames.poll();
int expectedSize = buf1.length + buf2.length + buf3.length;
Assert.assertThat("BinaryFrame.payloadLength",binmsg.getPayloadLength(),is(expectedSize));
@@ -182,8 +182,8 @@
client.write(new TextFrame().setPayload(msg));
// Read frame (hopefully text frame)
- IncomingFramesCapture capture = client.readFrames(1,TimeUnit.MILLISECONDS,500);
- WebSocketFrame tf = capture.getFrames().poll();
+ EventQueue<WebSocketFrame> frames = client.readFrames(1,500,TimeUnit.MILLISECONDS);
+ WebSocketFrame tf = frames.poll();
Assert.assertThat("Text Frame.status code",tf.getPayloadAsUTF8(),is(msg));
}
finally
@@ -215,8 +215,8 @@
client.write(new TextFrame().setPayload("CRASH"));
// Read frame (hopefully close frame)
- IncomingFramesCapture capture = client.readFrames(1,TimeUnit.MILLISECONDS,500);
- Frame cf = capture.getFrames().poll();
+ EventQueue<WebSocketFrame> frames = client.readFrames(1,500,TimeUnit.MILLISECONDS);
+ Frame cf = frames.poll();
CloseInfo close = new CloseInfo(cf);
Assert.assertThat("Close Frame.status code",close.getStatusCode(),is(StatusCode.SERVER_ERROR));
}
@@ -261,8 +261,8 @@
client.write(new TextFrame().setPayload(msg));
// Read frame (hopefully text frame)
- IncomingFramesCapture capture = client.readFrames(1,TimeUnit.MILLISECONDS,500);
- WebSocketFrame tf = capture.getFrames().poll();
+ EventQueue<WebSocketFrame> frames = client.readFrames(1,500,TimeUnit.MILLISECONDS);
+ WebSocketFrame tf = frames.poll();
Assert.assertThat("Text Frame.status code",tf.getPayloadAsUTF8(),is(msg));
}
finally
@@ -294,8 +294,8 @@
client.writeRaw(bbHeader);
client.writeRaw(txt.getPayload());
- IncomingFramesCapture capture = client.readFrames(1,TimeUnit.SECONDS,1);
- WebSocketFrame frame = capture.getFrames().poll();
+ EventQueue<WebSocketFrame> frames = client.readFrames(1,1,TimeUnit.SECONDS);
+ WebSocketFrame frame = frames.poll();
Assert.assertThat("frames[0].opcode",frame.getOpCode(),is(OpCode.CLOSE));
CloseInfo close = new CloseInfo(frame);
Assert.assertThat("Close Status Code",close.getStatusCode(),is(StatusCode.BAD_PAYLOAD));
@@ -340,8 +340,8 @@
client.write(new TextFrame().setPayload(msg));
// Read frame (hopefully text frame)
- IncomingFramesCapture capture = client.readFrames(1,TimeUnit.MILLISECONDS,500);
- WebSocketFrame tf = capture.getFrames().poll();
+ EventQueue<WebSocketFrame> frames = client.readFrames(1,500,TimeUnit.MILLISECONDS);
+ WebSocketFrame tf = frames.poll();
Assert.assertThat("Text Frame.status code",tf.getPayloadAsUTF8(),is(msg));
}
finally
diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase1.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase1.java
index 20ff642..502fb80 100644
--- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase1.java
+++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase1.java
@@ -48,18 +48,12 @@
expect.add(new TextFrame());
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try
+ try (Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
fuzzer.setSendMode(SendMode.BULK);
fuzzer.send(send);
fuzzer.expect(expect);
- fuzzer.expectServerDisconnect(Fuzzer.DisconnectMode.CLEAN);
- }
- finally
- {
- fuzzer.close();
}
}
@@ -81,18 +75,12 @@
expect.add(new TextFrame().setPayload(clone(buf)));
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try
+ try (Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
fuzzer.setSendMode(SendMode.BULK);
fuzzer.send(send);
fuzzer.expect(expect);
- fuzzer.expectServerDisconnect(Fuzzer.DisconnectMode.CLEAN);
- }
- finally
- {
- fuzzer.close();
}
}
@@ -114,18 +102,12 @@
expect.add(new TextFrame().setPayload(clone(buf)));
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try
+ try (Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
fuzzer.setSendMode(SendMode.BULK);
fuzzer.send(send);
fuzzer.expect(expect);
- fuzzer.expectServerDisconnect(Fuzzer.DisconnectMode.CLEAN);
- }
- finally
- {
- fuzzer.close();
}
}
@@ -147,18 +129,12 @@
expect.add(new TextFrame().setPayload(clone(buf)));
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try
+ try (Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
fuzzer.setSendMode(SendMode.BULK);
fuzzer.send(send);
fuzzer.expect(expect);
- fuzzer.expectServerDisconnect(Fuzzer.DisconnectMode.CLEAN);
- }
- finally
- {
- fuzzer.close();
}
}
@@ -180,18 +156,12 @@
expect.add(new TextFrame().setPayload(clone(buf)));
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try
+ try (Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
fuzzer.setSendMode(SendMode.BULK);
fuzzer.send(send);
fuzzer.expect(expect);
- fuzzer.expectServerDisconnect(Fuzzer.DisconnectMode.CLEAN);
- }
- finally
- {
- fuzzer.close();
}
}
@@ -213,18 +183,12 @@
expect.add(new TextFrame().setPayload(clone(buf)));
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try
+ try (Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
fuzzer.setSendMode(SendMode.BULK);
fuzzer.send(send);
fuzzer.expect(expect);
- fuzzer.expectServerDisconnect(Fuzzer.DisconnectMode.CLEAN);
- }
- finally
- {
- fuzzer.close();
}
}
@@ -246,18 +210,12 @@
expect.add(new TextFrame().setPayload(clone(buf)));
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try
+ try (Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
fuzzer.setSendMode(SendMode.BULK);
fuzzer.send(send);
fuzzer.expect(expect);
- fuzzer.expectServerDisconnect(Fuzzer.DisconnectMode.CLEAN);
- }
- finally
- {
- fuzzer.close();
}
}
@@ -284,19 +242,13 @@
expect.add(new TextFrame().setPayload(clone(buf)));
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try
+ try (Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
fuzzer.setSendMode(SendMode.SLOW);
fuzzer.setSlowSendSegmentSize(segmentSize);
fuzzer.send(send);
fuzzer.expect(expect);
- fuzzer.expectServerDisconnect(Fuzzer.DisconnectMode.CLEAN);
- }
- finally
- {
- fuzzer.close();
}
}
@@ -314,18 +266,12 @@
expect.add(new BinaryFrame());
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try
+ try (Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
fuzzer.setSendMode(SendMode.BULK);
fuzzer.send(send);
fuzzer.expect(expect);
- fuzzer.expectServerDisconnect(Fuzzer.DisconnectMode.CLEAN);
- }
- finally
- {
- fuzzer.close();
}
}
@@ -347,18 +293,12 @@
expect.add(new BinaryFrame().setPayload(clone(buf)));
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try
+ try (Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
fuzzer.setSendMode(SendMode.BULK);
fuzzer.send(send);
fuzzer.expect(expect);
- fuzzer.expectServerDisconnect(Fuzzer.DisconnectMode.CLEAN);
- }
- finally
- {
- fuzzer.close();
}
}
@@ -380,18 +320,12 @@
expect.add(new BinaryFrame().setPayload(clone(buf)));
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try
+ try (Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
fuzzer.setSendMode(SendMode.BULK);
fuzzer.send(send);
fuzzer.expect(expect);
- fuzzer.expectServerDisconnect(Fuzzer.DisconnectMode.CLEAN);
- }
- finally
- {
- fuzzer.close();
}
}
@@ -413,18 +347,12 @@
expect.add(new BinaryFrame().setPayload(clone(buf)));
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try
+ try (Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
fuzzer.setSendMode(SendMode.BULK);
fuzzer.send(send);
fuzzer.expect(expect);
- fuzzer.expectServerDisconnect(Fuzzer.DisconnectMode.CLEAN);
- }
- finally
- {
- fuzzer.close();
}
}
@@ -446,18 +374,12 @@
expect.add(new BinaryFrame().setPayload(clone(buf)));
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try
+ try (Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
fuzzer.setSendMode(SendMode.BULK);
fuzzer.send(send);
fuzzer.expect(expect);
- fuzzer.expectServerDisconnect(Fuzzer.DisconnectMode.CLEAN);
- }
- finally
- {
- fuzzer.close();
}
}
@@ -479,18 +401,12 @@
expect.add(new BinaryFrame().setPayload(clone(buf)));
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try
+ try (Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
fuzzer.setSendMode(SendMode.BULK);
fuzzer.send(send);
fuzzer.expect(expect);
- fuzzer.expectServerDisconnect(Fuzzer.DisconnectMode.CLEAN);
- }
- finally
- {
- fuzzer.close();
}
}
@@ -512,18 +428,12 @@
expect.add(new BinaryFrame().setPayload(clone(buf)));
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try
+ try (Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
fuzzer.setSendMode(SendMode.BULK);
fuzzer.send(send);
fuzzer.expect(expect);
- fuzzer.expectServerDisconnect(Fuzzer.DisconnectMode.CLEAN);
- }
- finally
- {
- fuzzer.close();
}
}
@@ -550,19 +460,13 @@
expect.add(new BinaryFrame().setPayload(clone(buf)));
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try
+ try (Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
fuzzer.setSendMode(SendMode.SLOW);
fuzzer.setSlowSendSegmentSize(segmentSize);
fuzzer.send(send);
fuzzer.expect(expect);
- fuzzer.expectServerDisconnect(Fuzzer.DisconnectMode.CLEAN);
- }
- finally
- {
- fuzzer.close();
}
}
}
diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase2.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase2.java
index 0e43806..4a1a1c1 100644
--- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase2.java
+++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase2.java
@@ -50,18 +50,13 @@
WebSocketFrame expect = new PongFrame();
- Fuzzer fuzzer = new Fuzzer(this);
- try
+ try (Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
fuzzer.send(send);
fuzzer.expect(expect);
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -89,18 +84,13 @@
send.add(new CloseInfo(StatusCode.NORMAL).asFrame());
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try
+ try (Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
fuzzer.send(send);
fuzzer.expect(expect);
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -128,8 +118,7 @@
send.add(new CloseInfo(StatusCode.NORMAL).asFrame());
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try
+ try (Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.SLOW);
@@ -137,10 +126,6 @@
fuzzer.send(send);
fuzzer.expect(expect);
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -159,18 +144,13 @@
expect.add(new PongFrame().setPayload(copyOf(payload)));
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try
+ try (Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
fuzzer.send(send);
fuzzer.expect(expect);
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -179,8 +159,7 @@
@Test
public void testCase2_3() throws Exception
{
- byte payload[] = new byte[]
- { 0x00, (byte)0xFF, (byte)0xFE, (byte)0xFD, (byte)0xFC, (byte)0xFB, 0x00, (byte)0xFF };
+ byte payload[] = new byte[] { 0x00, (byte)0xFF, (byte)0xFE, (byte)0xFD, (byte)0xFC, (byte)0xFB, 0x00, (byte)0xFF };
List<WebSocketFrame> send = new ArrayList<>();
send.add(new PingFrame().setPayload(payload));
@@ -190,18 +169,13 @@
expect.add(new PongFrame().setPayload(copyOf(payload)));
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try
+ try (Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
fuzzer.send(send);
fuzzer.expect(expect);
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -221,18 +195,13 @@
expect.add(new PongFrame().setPayload(copyOf(payload)));
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try
+ try (Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
fuzzer.send(send);
fuzzer.expect(expect);
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -241,32 +210,26 @@
@Test
public void testCase2_5() throws Exception
{
- try(StacklessLogging scope = new StacklessLogging(Parser.class))
+ try (StacklessLogging scope = new StacklessLogging(Parser.class))
{
byte payload[] = new byte[126]; // intentionally too big
Arrays.fill(payload,(byte)'5');
ByteBuffer buf = ByteBuffer.wrap(payload);
-
+
List<WebSocketFrame> send = new ArrayList<>();
// trick websocket frame into making extra large payload for ping
send.add(new BadFrame(OpCode.PING).setPayload(buf));
send.add(new CloseInfo(StatusCode.NORMAL,"Test 2.5").asFrame());
-
+
List<WebSocketFrame> expect = new ArrayList<>();
expect.add(new CloseInfo(StatusCode.PROTOCOL).asFrame());
-
- Fuzzer fuzzer = new Fuzzer(this);
- try
+
+ try (Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
fuzzer.send(send);
fuzzer.expect(expect);
- fuzzer.expectServerDisconnect(Fuzzer.DisconnectMode.CLEAN);
- }
- finally
- {
- fuzzer.close();
}
}
}
@@ -288,8 +251,7 @@
expect.add(new PongFrame().setPayload(copyOf(payload)));
expect.add(new CloseInfo(StatusCode.NORMAL,"Test 2.6").asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try
+ try (Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.SLOW);
@@ -297,10 +259,6 @@
fuzzer.send(send);
fuzzer.expect(expect);
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -316,18 +274,13 @@
List<WebSocketFrame> expect = new ArrayList<>();
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try
+ try (Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
fuzzer.send(send);
fuzzer.expect(expect);
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -343,18 +296,13 @@
List<WebSocketFrame> expect = new ArrayList<>();
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try
+ try (Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
fuzzer.send(send);
fuzzer.expect(expect);
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -372,17 +320,12 @@
expect.add(new PongFrame().setPayload("our ping")); // our pong
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try
+ try (Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
fuzzer.send(send);
fuzzer.expect(expect);
}
- finally
- {
- fuzzer.close();
- }
}
}
diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase3.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase3.java
index 4b5373b..de9ec69 100644
--- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase3.java
+++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase3.java
@@ -51,18 +51,13 @@
WebSocketFrame expect = new CloseInfo(StatusCode.PROTOCOL).asFrame();
- Fuzzer fuzzer = new Fuzzer(this);
- try(StacklessLogging logging = new StacklessLogging(Parser.class))
+ try (Fuzzer fuzzer = new Fuzzer(this); StacklessLogging logging = new StacklessLogging(Parser.class))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
fuzzer.send(send);
fuzzer.expect(expect);
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -80,18 +75,13 @@
expect.add(new TextFrame().setPayload("small")); // echo on good frame
expect.add(new CloseInfo(StatusCode.PROTOCOL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try(StacklessLogging logging = new StacklessLogging(Parser.class))
+ try (Fuzzer fuzzer = new Fuzzer(this); StacklessLogging logging = new StacklessLogging(Parser.class))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
fuzzer.send(send);
fuzzer.expect(expect);
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -109,18 +99,13 @@
expect.add(new TextFrame().setPayload("small")); // echo on good frame
expect.add(new CloseInfo(StatusCode.PROTOCOL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try(StacklessLogging logging = new StacklessLogging(Parser.class))
+ try (Fuzzer fuzzer = new Fuzzer(this); StacklessLogging logging = new StacklessLogging(Parser.class))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.PER_FRAME);
fuzzer.send(send);
fuzzer.expect(expect);
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -138,8 +123,7 @@
expect.add(new TextFrame().setPayload("small")); // echo on good frame
expect.add(new CloseInfo(StatusCode.PROTOCOL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try(StacklessLogging logging = new StacklessLogging(Parser.class))
+ try (Fuzzer fuzzer = new Fuzzer(this); StacklessLogging logging = new StacklessLogging(Parser.class))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.SLOW);
@@ -147,10 +131,6 @@
fuzzer.send(send);
fuzzer.expect(expect);
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -168,18 +148,13 @@
List<WebSocketFrame> expect = new ArrayList<>();
expect.add(new CloseInfo(StatusCode.PROTOCOL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try(StacklessLogging logging = new StacklessLogging(Parser.class))
+ try (Fuzzer fuzzer = new Fuzzer(this); StacklessLogging logging = new StacklessLogging(Parser.class))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
fuzzer.send(send);
fuzzer.expect(expect);
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -197,18 +172,13 @@
List<WebSocketFrame> expect = new ArrayList<>();
expect.add(new CloseInfo(StatusCode.PROTOCOL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try(StacklessLogging logging = new StacklessLogging(Parser.class))
+ try (Fuzzer fuzzer = new Fuzzer(this); StacklessLogging logging = new StacklessLogging(Parser.class))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
fuzzer.send(send);
fuzzer.expect(expect);
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -230,17 +200,12 @@
List<WebSocketFrame> expect = new ArrayList<>();
expect.add(new CloseInfo(StatusCode.PROTOCOL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try(StacklessLogging logging = new StacklessLogging(Parser.class))
+ try (Fuzzer fuzzer = new Fuzzer(this); StacklessLogging logging = new StacklessLogging(Parser.class))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
fuzzer.send(send);
fuzzer.expect(expect);
}
- finally
- {
- fuzzer.close();
- }
}
}
diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase4.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase4.java
index ffb6961..61f59ad 100644
--- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase4.java
+++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase4.java
@@ -53,18 +53,13 @@
List<WebSocketFrame> expect = new ArrayList<>();
expect.add(new CloseInfo(StatusCode.PROTOCOL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try(StacklessLogging logging = new StacklessLogging(Parser.class))
+ try (Fuzzer fuzzer = new Fuzzer(this); StacklessLogging logging = new StacklessLogging(Parser.class))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
fuzzer.send(send);
fuzzer.expect(expect);
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -82,18 +77,13 @@
List<WebSocketFrame> expect = new ArrayList<>();
expect.add(new CloseInfo(StatusCode.PROTOCOL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try(StacklessLogging logging = new StacklessLogging(Parser.class))
+ try (Fuzzer fuzzer = new Fuzzer(this); StacklessLogging logging = new StacklessLogging(Parser.class))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
fuzzer.send(send);
fuzzer.expect(expect);
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -111,18 +101,13 @@
expect.add(new TextFrame().setPayload("hello")); // echo
expect.add(new CloseInfo(StatusCode.PROTOCOL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try(StacklessLogging logging = new StacklessLogging(Parser.class))
+ try (Fuzzer fuzzer = new Fuzzer(this); StacklessLogging logging = new StacklessLogging(Parser.class))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
fuzzer.send(send);
fuzzer.expect(expect);
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -132,7 +117,7 @@
public void testCase4_1_4() throws Exception
{
ByteBuffer buf = ByteBuffer.wrap(StringUtil.getUtf8Bytes("bad"));
-
+
List<WebSocketFrame> send = new ArrayList<>();
send.add(new TextFrame().setPayload("hello"));
send.add(new BadFrame((byte)6).setPayload(buf)); // intentionally bad
@@ -142,18 +127,13 @@
expect.add(new TextFrame().setPayload("hello")); // echo
expect.add(new CloseInfo(StatusCode.PROTOCOL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try(StacklessLogging logging = new StacklessLogging(Parser.class))
+ try (Fuzzer fuzzer = new Fuzzer(this); StacklessLogging logging = new StacklessLogging(Parser.class))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
fuzzer.send(send);
fuzzer.expect(expect);
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -163,7 +143,7 @@
public void testCase4_1_5() throws Exception
{
ByteBuffer buf = ByteBuffer.wrap(StringUtil.getUtf8Bytes("bad"));
-
+
List<WebSocketFrame> send = new ArrayList<>();
send.add(new TextFrame().setPayload("hello"));
send.add(new BadFrame((byte)7).setPayload(buf)); // intentionally bad
@@ -173,18 +153,13 @@
expect.add(new TextFrame().setPayload("hello")); // echo
expect.add(new CloseInfo(StatusCode.PROTOCOL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try(StacklessLogging logging = new StacklessLogging(Parser.class))
+ try (Fuzzer fuzzer = new Fuzzer(this); StacklessLogging logging = new StacklessLogging(Parser.class))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
fuzzer.send(send);
fuzzer.expect(expect);
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -199,18 +174,13 @@
List<WebSocketFrame> expect = new ArrayList<>();
expect.add(new CloseInfo(StatusCode.PROTOCOL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try(StacklessLogging logging = new StacklessLogging(Parser.class))
+ try (Fuzzer fuzzer = new Fuzzer(this); StacklessLogging logging = new StacklessLogging(Parser.class))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
fuzzer.send(send);
fuzzer.expect(expect);
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -220,25 +190,20 @@
public void testCase4_2_2() throws Exception
{
ByteBuffer buf = ByteBuffer.wrap(StringUtil.getUtf8Bytes("bad"));
-
+
List<WebSocketFrame> send = new ArrayList<>();
send.add(new BadFrame((byte)12).setPayload(buf)); // intentionally bad
List<WebSocketFrame> expect = new ArrayList<>();
expect.add(new CloseInfo(StatusCode.PROTOCOL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try(StacklessLogging logging = new StacklessLogging(Parser.class))
+ try (Fuzzer fuzzer = new Fuzzer(this); StacklessLogging logging = new StacklessLogging(Parser.class))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
fuzzer.send(send);
fuzzer.expect(expect);
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -256,18 +221,13 @@
expect.add(new TextFrame().setPayload("hello")); // echo
expect.add(new CloseInfo(StatusCode.PROTOCOL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try(StacklessLogging logging = new StacklessLogging(Parser.class))
+ try (Fuzzer fuzzer = new Fuzzer(this); StacklessLogging logging = new StacklessLogging(Parser.class))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
fuzzer.send(send);
fuzzer.expect(expect);
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -277,7 +237,7 @@
public void testCase4_2_4() throws Exception
{
ByteBuffer buf = ByteBuffer.wrap(StringUtil.getUtf8Bytes("bad"));
-
+
List<WebSocketFrame> send = new ArrayList<>();
send.add(new TextFrame().setPayload("hello"));
send.add(new BadFrame((byte)14).setPayload(buf)); // intentionally bad
@@ -287,18 +247,13 @@
expect.add(new TextFrame().setPayload("hello")); // echo
expect.add(new CloseInfo(StatusCode.PROTOCOL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try(StacklessLogging logging = new StacklessLogging(Parser.class))
+ try (Fuzzer fuzzer = new Fuzzer(this); StacklessLogging logging = new StacklessLogging(Parser.class))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
fuzzer.send(send);
fuzzer.expect(expect);
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -308,7 +263,7 @@
public void testCase4_2_5() throws Exception
{
ByteBuffer buf = ByteBuffer.wrap(StringUtil.getUtf8Bytes("bad"));
-
+
List<WebSocketFrame> send = new ArrayList<>();
send.add(new TextFrame().setPayload("hello"));
send.add(new BadFrame((byte)15).setPayload(buf)); // intentionally bad
@@ -318,17 +273,12 @@
expect.add(new TextFrame().setPayload("hello")); // echo
expect.add(new CloseInfo(StatusCode.PROTOCOL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try(StacklessLogging logging = new StacklessLogging(Parser.class))
+ try (Fuzzer fuzzer = new Fuzzer(this); StacklessLogging logging = new StacklessLogging(Parser.class))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
fuzzer.send(send);
fuzzer.expect(expect);
}
- finally
- {
- fuzzer.close();
- }
}
}
diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase5.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase5.java
index c957fc9..c6349a3 100644
--- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase5.java
+++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase5.java
@@ -57,19 +57,14 @@
List<WebSocketFrame> expect = new ArrayList<>();
expect.add(new CloseInfo(StatusCode.PROTOCOL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try(StacklessLogging supress = new StacklessLogging(Parser.class))
+ try(Fuzzer fuzzer = new Fuzzer(this);StacklessLogging supress = new StacklessLogging(Parser.class))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
fuzzer.send(send);
fuzzer.expect(expect);
}
- finally
- {
- fuzzer.close();
- }
- }
+ }
/**
* Send continuation+fin, then text+fin (framewise)
@@ -85,18 +80,13 @@
List<WebSocketFrame> expect = new ArrayList<>();
expect.add(new CloseInfo(StatusCode.PROTOCOL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try(StacklessLogging supress = new StacklessLogging(Parser.class))
+ try(Fuzzer fuzzer = new Fuzzer(this);StacklessLogging supress = new StacklessLogging(Parser.class))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.PER_FRAME);
fuzzer.sendAndIgnoreBrokenPipe(send);
fuzzer.expect(expect);
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -113,8 +103,7 @@
List<WebSocketFrame> expect = new ArrayList<>();
expect.add(new CloseInfo(StatusCode.PROTOCOL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try(StacklessLogging supress = new StacklessLogging(Parser.class))
+ try(Fuzzer fuzzer = new Fuzzer(this);StacklessLogging supress = new StacklessLogging(Parser.class))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.SLOW);
@@ -122,10 +111,6 @@
fuzzer.sendAndIgnoreBrokenPipe(send);
fuzzer.expect(expect);
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -142,18 +127,13 @@
List<WebSocketFrame> expect = new ArrayList<>();
expect.add(new CloseInfo(StatusCode.PROTOCOL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try(StacklessLogging supress = new StacklessLogging(Parser.class))
+ try(Fuzzer fuzzer = new Fuzzer(this);StacklessLogging supress = new StacklessLogging(Parser.class))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
fuzzer.sendAndIgnoreBrokenPipe(send);
fuzzer.expect(expect);
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -170,18 +150,13 @@
List<WebSocketFrame> expect = new ArrayList<>();
expect.add(new CloseInfo(StatusCode.PROTOCOL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try(StacklessLogging supress = new StacklessLogging(Parser.class))
+ try(Fuzzer fuzzer = new Fuzzer(this);StacklessLogging supress = new StacklessLogging(Parser.class))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.PER_FRAME);
fuzzer.sendAndIgnoreBrokenPipe(send);
fuzzer.expect(expect);
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -198,8 +173,7 @@
List<WebSocketFrame> expect = new ArrayList<>();
expect.add(new CloseInfo(StatusCode.PROTOCOL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try(StacklessLogging supress = new StacklessLogging(Parser.class))
+ try(Fuzzer fuzzer = new Fuzzer(this);StacklessLogging supress = new StacklessLogging(Parser.class))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.SLOW);
@@ -207,10 +181,6 @@
fuzzer.sendAndIgnoreBrokenPipe(send);
fuzzer.expect(expect);
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -230,18 +200,13 @@
expect.add(new TextFrame().setPayload("fragment1fragment2"));
expect.add(new CloseInfo(StatusCode.PROTOCOL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try(StacklessLogging supress = new StacklessLogging(Parser.class))
+ try(Fuzzer fuzzer = new Fuzzer(this);StacklessLogging supress = new StacklessLogging(Parser.class))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
fuzzer.send(send);
fuzzer.expect(expect);
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -262,18 +227,13 @@
List<WebSocketFrame> expect = new ArrayList<>();
expect.add(new CloseInfo(StatusCode.PROTOCOL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try(StacklessLogging supress = new StacklessLogging(Parser.class))
+ try(Fuzzer fuzzer = new Fuzzer(this);StacklessLogging supress = new StacklessLogging(Parser.class))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
fuzzer.sendAndIgnoreBrokenPipe(send);
fuzzer.expect(expect);
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -294,18 +254,13 @@
List<WebSocketFrame> expect = new ArrayList<>();
expect.add(new CloseInfo(StatusCode.PROTOCOL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try(StacklessLogging supress = new StacklessLogging(Parser.class))
+ try(Fuzzer fuzzer = new Fuzzer(this);StacklessLogging supress = new StacklessLogging(Parser.class))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
fuzzer.send(send);
fuzzer.expect(expect);
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -322,18 +277,13 @@
List<WebSocketFrame> expect = new ArrayList<>();
expect.add(new CloseInfo(StatusCode.PROTOCOL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try(StacklessLogging supress = new StacklessLogging(Parser.class))
+ try(Fuzzer fuzzer = new Fuzzer(this);StacklessLogging supress = new StacklessLogging(Parser.class))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
fuzzer.send(send);
fuzzer.expect(expect);
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -365,8 +315,7 @@
expect2.add(new TextFrame().setPayload("f1,f2,f3,f4,f5"));
expect2.add(new CloseInfo(StatusCode.NORMAL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try(StacklessLogging supress = new StacklessLogging(Parser.class))
+ try(Fuzzer fuzzer = new Fuzzer(this);StacklessLogging supress = new StacklessLogging(Parser.class))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
@@ -382,10 +331,6 @@
fuzzer.send(send2);
fuzzer.expect(expect2);
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -402,18 +347,13 @@
List<WebSocketFrame> expect = new ArrayList<>();
expect.add(new CloseInfo(StatusCode.PROTOCOL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try(StacklessLogging supress = new StacklessLogging(Parser.class))
+ try(Fuzzer fuzzer = new Fuzzer(this);StacklessLogging supress = new StacklessLogging(Parser.class))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
fuzzer.send(send);
fuzzer.expect(expect);
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -442,8 +382,7 @@
expect2.add(new TextFrame().setPayload("f1,f2,f3,f4,f5"));
expect2.add(new CloseInfo(StatusCode.NORMAL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try(StacklessLogging supress = new StacklessLogging(Parser.class))
+ try(Fuzzer fuzzer = new Fuzzer(this);StacklessLogging supress = new StacklessLogging(Parser.class))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.PER_FRAME);
@@ -456,10 +395,6 @@
fuzzer.send(send2);
fuzzer.expect(expect2);
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -488,8 +423,7 @@
expect2.add(new TextFrame().setPayload("f1,f2,f3,f4,f5"));
expect2.add(new CloseInfo(StatusCode.NORMAL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try(StacklessLogging supress = new StacklessLogging(Parser.class))
+ try(Fuzzer fuzzer = new Fuzzer(this);StacklessLogging supress = new StacklessLogging(Parser.class))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.SLOW);
@@ -503,10 +437,6 @@
fuzzer.send(send2);
fuzzer.expect(expect2);
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -524,18 +454,13 @@
expect.add(new TextFrame().setPayload("hello, world"));
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try(StacklessLogging supress = new StacklessLogging(Parser.class))
+ try(Fuzzer fuzzer = new Fuzzer(this);StacklessLogging supress = new StacklessLogging(Parser.class))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
fuzzer.send(send);
fuzzer.expect(expect);
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -553,18 +478,13 @@
expect.add(new TextFrame().setPayload("hello, world"));
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try(StacklessLogging supress = new StacklessLogging(Parser.class))
+ try(Fuzzer fuzzer = new Fuzzer(this);StacklessLogging supress = new StacklessLogging(Parser.class))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.PER_FRAME);
fuzzer.send(send);
fuzzer.expect(expect);
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -582,8 +502,7 @@
expect.add(new TextFrame().setPayload("hello, world"));
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try(StacklessLogging supress = new StacklessLogging(Parser.class))
+ try(Fuzzer fuzzer = new Fuzzer(this);StacklessLogging supress = new StacklessLogging(Parser.class))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.SLOW);
@@ -591,10 +510,6 @@
fuzzer.send(send);
fuzzer.expect(expect);
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -614,18 +529,13 @@
expect.add(new TextFrame().setPayload("hello, world"));
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try(StacklessLogging supress = new StacklessLogging(Parser.class))
+ try(Fuzzer fuzzer = new Fuzzer(this);StacklessLogging supress = new StacklessLogging(Parser.class))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
fuzzer.send(send);
fuzzer.expect(expect);
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -645,18 +555,13 @@
expect.add(new TextFrame().setPayload("hello, world"));
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try(StacklessLogging supress = new StacklessLogging(Parser.class))
+ try(Fuzzer fuzzer = new Fuzzer(this);StacklessLogging supress = new StacklessLogging(Parser.class))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.PER_FRAME);
fuzzer.send(send);
fuzzer.expect(expect);
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -676,8 +581,7 @@
expect.add(new TextFrame().setPayload("hello, world"));
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try(StacklessLogging supress = new StacklessLogging(Parser.class))
+ try(Fuzzer fuzzer = new Fuzzer(this);StacklessLogging supress = new StacklessLogging(Parser.class))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.SLOW);
@@ -685,10 +589,6 @@
fuzzer.send(send);
fuzzer.expect(expect);
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -706,17 +606,12 @@
List<WebSocketFrame> expect = new ArrayList<>();
expect.add(new CloseInfo(StatusCode.PROTOCOL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try(StacklessLogging supress = new StacklessLogging(Parser.class))
+ try(Fuzzer fuzzer = new Fuzzer(this);StacklessLogging supress = new StacklessLogging(Parser.class))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
fuzzer.send(send);
fuzzer.expect(expect);
}
- finally
- {
- fuzzer.close();
- }
}
}
diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase6.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase6.java
index 6ead418..c11aebf 100644
--- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase6.java
+++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase6.java
@@ -90,18 +90,13 @@
expect.add(new TextFrame());
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try
+ try (Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
fuzzer.send(send);
fuzzer.expect(expect);
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -120,18 +115,13 @@
expect.add(new TextFrame());
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try
+ try (Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
fuzzer.send(send);
fuzzer.expect(expect);
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -150,18 +140,13 @@
expect.add(new TextFrame().setPayload("middle"));
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try
+ try (Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
fuzzer.send(send);
fuzzer.expect(expect);
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -172,7 +157,7 @@
{
String utf1 = "Hello-\uC2B5@\uC39F\uC3A4";
String utf2 = "\uC3BC\uC3A0\uC3A1-UTF-8!!";
-
+
ByteBuffer b1 = ByteBuffer.wrap(StringUtil.getUtf8Bytes(utf1));
ByteBuffer b2 = ByteBuffer.wrap(StringUtil.getUtf8Bytes(utf2));
@@ -189,18 +174,13 @@
expect.add(new TextFrame().setPayload(e1));
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try
+ try (Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
fuzzer.send(send);
fuzzer.expect(expect);
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -220,18 +200,13 @@
expect.add(new TextFrame().setPayload(ByteBuffer.wrap(msg)));
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try
+ try (Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
fuzzer.send(send);
fuzzer.expect(expect);
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -250,18 +225,13 @@
expect.add(new TextFrame().setPayload(ByteBuffer.wrap(msg)));
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try
+ try (Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
fuzzer.send(send);
fuzzer.expect(expect);
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -279,18 +249,13 @@
List<WebSocketFrame> expect = new ArrayList<>();
expect.add(new CloseInfo(StatusCode.BAD_PAYLOAD).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try
+ try (Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
fuzzer.send(send);
fuzzer.expect(expect);
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -311,8 +276,7 @@
List<WebSocketFrame> expect = new ArrayList<>();
expect.add(new CloseInfo(StatusCode.BAD_PAYLOAD).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try
+ try (Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
@@ -325,10 +289,6 @@
fuzzer.expect(expect);
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -351,8 +311,7 @@
List<WebSocketFrame> expect = new ArrayList<>();
expect.add(new CloseInfo(StatusCode.BAD_PAYLOAD).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try
+ try (Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
@@ -363,10 +322,6 @@
fuzzer.send(new ContinuationFrame().setPayload(ByteBuffer.wrap(part3)).setFin(true));
fuzzer.expect(expect);
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -393,15 +348,13 @@
List<WebSocketFrame> expect = new ArrayList<>();
expect.add(new CloseInfo(StatusCode.BAD_PAYLOAD).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try
+ try (Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
ByteBuffer net = fuzzer.asNetworkBuffer(send);
- int splits[] =
- { 17, 21, net.limit() };
+ int splits[] = { 17, 21, net.limit() };
ByteBuffer part1 = net.slice(); // Header + good UTF
part1.limit(splits[0]);
@@ -419,12 +372,6 @@
fuzzer.send(part3); // the rest (shouldn't work)
fuzzer.expect(expect);
-
- fuzzer.expectServerDisconnect(Fuzzer.DisconnectMode.UNCLEAN);
- }
- finally
- {
- fuzzer.close();
}
}
}
@@ -445,8 +392,7 @@
List<WebSocketFrame> expect = new ArrayList<>();
expect.add(new CloseInfo(StatusCode.BAD_PAYLOAD).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try(StacklessLogging scope = new StacklessLogging(Parser.class))
+ try (Fuzzer fuzzer = new Fuzzer(this); StacklessLogging scope = new StacklessLogging(Parser.class))
{
fuzzer.connect();
@@ -460,9 +406,5 @@
fuzzer.expect(expect);
}
- finally
- {
- fuzzer.close();
- }
}
}
diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase6_BadUTF.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase6_BadUTF.java
index 7c61776..3ff1643 100644
--- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase6_BadUTF.java
+++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase6_BadUTF.java
@@ -163,18 +163,15 @@
List<WebSocketFrame> expect = new ArrayList<>();
expect.add(new CloseInfo(StatusCode.BAD_PAYLOAD).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try(StacklessLogging supress = new StacklessLogging(Parser.class))
+ try (Fuzzer fuzzer = new Fuzzer(this))
{
- fuzzer.connect();
- fuzzer.setSendMode(Fuzzer.SendMode.BULK);
- fuzzer.send(send);
- fuzzer.expect(expect);
- fuzzer.expectServerDisconnect(Fuzzer.DisconnectMode.UNCLEAN);
- }
- finally
- {
- fuzzer.close();
+ try (StacklessLogging supress = new StacklessLogging(Parser.class))
+ {
+ fuzzer.connect();
+ fuzzer.setSendMode(Fuzzer.SendMode.BULK);
+ fuzzer.send(send);
+ fuzzer.expect(expect);
+ }
}
}
}
diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase6_GoodUTF.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase6_GoodUTF.java
index 8eebe6e..f5e9cbe 100644
--- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase6_GoodUTF.java
+++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase6_GoodUTF.java
@@ -139,17 +139,12 @@
expect.add(new TextFrame().setPayload(clone(msg)));
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try
+ try(Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
fuzzer.send(send);
fuzzer.expect(expect);
}
- finally
- {
- fuzzer.close();
- }
}
}
diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase7.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase7.java
index 8c60551..b8ad71b 100644
--- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase7.java
+++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase7.java
@@ -64,18 +64,13 @@
expect.add(new TextFrame().setPayload("Hello World"));
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try
+ try(Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
fuzzer.send(send);
fuzzer.expect(expect);
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -91,8 +86,7 @@
List<WebSocketFrame> expect = new ArrayList<>();
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try
+ try(Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
@@ -100,10 +94,6 @@
fuzzer.expect(expect);
fuzzer.expectNoMoreFrames();
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -119,8 +109,7 @@
List<WebSocketFrame> expect = new ArrayList<>();
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try
+ try(Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
@@ -128,10 +117,6 @@
fuzzer.expect(expect);
fuzzer.expectNoMoreFrames();
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -147,8 +132,7 @@
List<WebSocketFrame> expect = new ArrayList<>();
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try
+ try(Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
@@ -156,10 +140,6 @@
fuzzer.expect(expect);
fuzzer.expectNoMoreFrames();
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -176,8 +156,7 @@
List<WebSocketFrame> expect = new ArrayList<>();
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try
+ try(Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
@@ -185,10 +164,6 @@
fuzzer.expect(expect);
fuzzer.expectNoMoreFrames();
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -210,8 +185,7 @@
expect.add(new TextFrame().setPayload(clone(buf)));
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try
+ try(Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
@@ -219,10 +193,6 @@
fuzzer.expect(expect);
fuzzer.expectNoMoreFrames();
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -237,8 +207,7 @@
List<WebSocketFrame> expect = new ArrayList<>();
expect.add(new CloseFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try
+ try(Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
@@ -246,10 +215,6 @@
fuzzer.expect(expect);
fuzzer.expectNoMoreFrames();
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -258,8 +223,7 @@
@Test
public void testCase7_3_2() throws Exception
{
- byte payload[] = new byte[]
- { 0x00 };
+ byte payload[] = new byte[] { 0x00 };
ByteBuffer buf = ByteBuffer.wrap(payload);
List<WebSocketFrame> send = new ArrayList<>();
@@ -268,8 +232,7 @@
List<WebSocketFrame> expect = new ArrayList<>();
expect.add(new CloseInfo(StatusCode.PROTOCOL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try(StacklessLogging scope = new StacklessLogging(Parser.class))
+ try (Fuzzer fuzzer = new Fuzzer(this); StacklessLogging scope = new StacklessLogging(Parser.class))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
@@ -277,10 +240,6 @@
fuzzer.expect(expect);
fuzzer.expectNoMoreFrames();
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -295,8 +254,7 @@
List<WebSocketFrame> expect = new ArrayList<>();
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try
+ try(Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
@@ -304,10 +262,6 @@
fuzzer.expect(expect);
fuzzer.expectNoMoreFrames();
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -322,8 +276,7 @@
List<WebSocketFrame> expect = new ArrayList<>();
expect.add(new CloseInfo(StatusCode.NORMAL,"Hic").asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try
+ try(Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
@@ -331,10 +284,6 @@
fuzzer.expect(expect);
fuzzer.expectNoMoreFrames();
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -353,8 +302,7 @@
List<WebSocketFrame> expect = new ArrayList<>();
expect.add(new CloseInfo(StatusCode.NORMAL,reason).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try(StacklessLogging logging = new StacklessLogging(AbstractWebSocketConnection.class))
+ try (Fuzzer fuzzer = new Fuzzer(this); StacklessLogging logging = new StacklessLogging(AbstractWebSocketConnection.class))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
@@ -362,10 +310,6 @@
fuzzer.expect(expect);
fuzzer.expectNoMoreFrames();
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -390,8 +334,7 @@
List<WebSocketFrame> expect = new ArrayList<>();
expect.add(new CloseInfo(StatusCode.BAD_PAYLOAD).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try(StacklessLogging scope = new StacklessLogging(Parser.class,CloseInfo.class))
+ try (Fuzzer fuzzer = new Fuzzer(this); StacklessLogging scope = new StacklessLogging(Parser.class,CloseInfo.class))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
@@ -399,9 +342,5 @@
fuzzer.expect(expect);
fuzzer.expectNoMoreFrames();
}
- finally
- {
- fuzzer.close();
- }
}
}
diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase7_BadStatusCodes.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase7_BadStatusCodes.java
index b3626f1..c76e174 100644
--- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase7_BadStatusCodes.java
+++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase7_BadStatusCodes.java
@@ -98,8 +98,7 @@
List<WebSocketFrame> expect = new ArrayList<>();
expect.add(new CloseInfo(StatusCode.PROTOCOL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try
+ try(Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
@@ -107,10 +106,6 @@
fuzzer.expect(expect);
fuzzer.expectNoMoreFrames();
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -131,8 +126,7 @@
List<WebSocketFrame> expect = new ArrayList<>();
expect.add(new CloseInfo(StatusCode.PROTOCOL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try
+ try(Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
@@ -140,9 +134,5 @@
fuzzer.expect(expect);
fuzzer.expectNoMoreFrames();
}
- finally
- {
- fuzzer.close();
- }
}
}
diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase7_GoodStatusCodes.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase7_GoodStatusCodes.java
index 425f657..5e8da15 100644
--- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase7_GoodStatusCodes.java
+++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase7_GoodStatusCodes.java
@@ -93,8 +93,7 @@
List<WebSocketFrame> expect = new ArrayList<>();
expect.add(new CloseFrame().setPayload(clone(payload)));
- Fuzzer fuzzer = new Fuzzer(this);
- try
+ try(Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
@@ -102,10 +101,6 @@
fuzzer.expect(expect);
fuzzer.expectNoMoreFrames();
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -125,8 +120,7 @@
List<WebSocketFrame> expect = new ArrayList<>();
expect.add(new CloseFrame().setPayload(clone(payload)));
- Fuzzer fuzzer = new Fuzzer(this);
- try
+ try(Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
@@ -134,9 +128,5 @@
fuzzer.expect(expect);
fuzzer.expectNoMoreFrames();
}
- finally
- {
- fuzzer.close();
- }
}
}
diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase9.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase9.java
index 3950394..274e91d 100644
--- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase9.java
+++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase9.java
@@ -96,17 +96,12 @@
expect.add(toDataFrame(opcode).setPayload(copyOf(msg)));
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try
+ try(Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
fuzzer.send(send);
- fuzzer.expect(expect,TimeUnit.SECONDS,8);
- }
- finally
- {
- fuzzer.close();
+ fuzzer.expect(expect,8,TimeUnit.SECONDS);
}
}
@@ -124,18 +119,13 @@
expect.add(toDataFrame(opcode).setPayload(clone(buf)));
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try
+ try(Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.SLOW);
fuzzer.setSlowSendSegmentSize(segmentSize);
fuzzer.send(send);
- fuzzer.expect(expect,TimeUnit.SECONDS,8);
- }
- finally
- {
- fuzzer.close();
+ fuzzer.expect(expect,8,TimeUnit.SECONDS);
}
}
@@ -157,18 +147,13 @@
expect.add(new TextFrame().setPayload(msg));
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try
+ try(Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
fuzzer.send(send);
fuzzer.expect(expect);
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -189,25 +174,19 @@
expect.add(new TextFrame().setPayload(clone(buf)));
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try
+ try(Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
fuzzer.send(send);
fuzzer.expect(expect);
}
- finally
- {
- fuzzer.close();
- }
}
/**
* Echo 1MB text message (1 frame)
*/
@Test
- @Stress("High I/O use")
public void testCase9_1_3() throws Exception
{
byte utf[] = new byte[1 * MBYTE];
@@ -222,17 +201,12 @@
expect.add(new TextFrame().setPayload(clone(buf)));
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try
+ try(Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
fuzzer.send(send);
- fuzzer.expect(expect,TimeUnit.SECONDS,4);
- }
- finally
- {
- fuzzer.close();
+ fuzzer.expect(expect,4,TimeUnit.SECONDS);
}
}
@@ -240,7 +214,6 @@
* Echo 4MB text message (1 frame)
*/
@Test
- @Stress("High I/O use")
public void testCase9_1_4() throws Exception
{
byte utf[] = new byte[4 * MBYTE];
@@ -255,17 +228,12 @@
expect.add(new TextFrame().setPayload(clone(buf)));
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try
+ try(Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
fuzzer.send(send);
- fuzzer.expect(expect,TimeUnit.SECONDS,8);
- }
- finally
- {
- fuzzer.close();
+ fuzzer.expect(expect,8,TimeUnit.SECONDS);
}
}
@@ -288,17 +256,12 @@
expect.add(new TextFrame().setPayload(clone(buf)));
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try
+ try(Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
fuzzer.send(send);
- fuzzer.expect(expect,TimeUnit.SECONDS,16);
- }
- finally
- {
- fuzzer.close();
+ fuzzer.expect(expect,16,TimeUnit.SECONDS);
}
}
@@ -321,17 +284,12 @@
expect.add(new TextFrame().setPayload(clone(buf)));
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try
+ try(Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
fuzzer.send(send);
- fuzzer.expect(expect,TimeUnit.SECONDS,32);
- }
- finally
- {
- fuzzer.close();
+ fuzzer.expect(expect,32,TimeUnit.SECONDS);
}
}
@@ -352,18 +310,13 @@
expect.add(new BinaryFrame().setPayload(copyOf(data)));
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try
+ try(Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
fuzzer.send(send);
fuzzer.expect(expect);
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -384,18 +337,13 @@
expect.add(new BinaryFrame().setPayload(clone(buf)));
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try
+ try(Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
fuzzer.send(send);
fuzzer.expect(expect);
}
- finally
- {
- fuzzer.close();
- }
}
/**
@@ -417,17 +365,12 @@
expect.add(new BinaryFrame().setPayload(clone(buf)));
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try
+ try(Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
fuzzer.send(send);
- fuzzer.expect(expect,TimeUnit.SECONDS,4);
- }
- finally
- {
- fuzzer.close();
+ fuzzer.expect(expect,4,TimeUnit.SECONDS);
}
}
@@ -450,17 +393,12 @@
expect.add(new BinaryFrame().setPayload(clone(buf)));
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try
+ try(Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
fuzzer.send(send);
- fuzzer.expect(expect,TimeUnit.SECONDS,8);
- }
- finally
- {
- fuzzer.close();
+ fuzzer.expect(expect,8,TimeUnit.SECONDS);
}
}
@@ -483,17 +421,12 @@
expect.add(new BinaryFrame().setPayload(clone(buf)));
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try
+ try(Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
fuzzer.send(send);
- fuzzer.expect(expect,TimeUnit.SECONDS,16);
- }
- finally
- {
- fuzzer.close();
+ fuzzer.expect(expect,16,TimeUnit.SECONDS);
}
}
@@ -516,17 +449,12 @@
expect.add(new BinaryFrame().setPayload(clone(buf)));
expect.add(new CloseInfo(StatusCode.NORMAL).asFrame());
- Fuzzer fuzzer = new Fuzzer(this);
- try
+ try(Fuzzer fuzzer = new Fuzzer(this))
{
fuzzer.connect();
fuzzer.setSendMode(Fuzzer.SendMode.BULK);
fuzzer.send(send);
- fuzzer.expect(expect,TimeUnit.SECONDS,32);
- }
- finally
- {
- fuzzer.close();
+ fuzzer.expect(expect,32,TimeUnit.SECONDS);
}
}
diff --git a/jetty-websocket/websocket-server/src/test/resources/jetty-logging.properties b/jetty-websocket/websocket-server/src/test/resources/jetty-logging.properties
index 994503c..fda5d88 100644
--- a/jetty-websocket/websocket-server/src/test/resources/jetty-logging.properties
+++ b/jetty-websocket/websocket-server/src/test/resources/jetty-logging.properties
@@ -4,7 +4,7 @@
# org.eclipse.jetty.io.WriteFlusher.LEVEL=DEBUG
# org.eclipse.jetty.websocket.LEVEL=DEBUG
# org.eclipse.jetty.websocket.LEVEL=INFO
-# org.eclipse.jetty.websocket.common.io.LEVEL=DEBUG
+org.eclipse.jetty.websocket.common.io.LEVEL=DEBUG
# org.eclipse.jetty.websocket.server.ab.LEVEL=DEBUG
# org.eclipse.jetty.websocket.common.Parser.LEVEL=DEBUG
# org.eclipse.jetty.websocket.common.Generator.LEVEL=DEBUG
diff --git a/tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/SessionRenewTest.java b/tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/SessionRenewTest.java
index e629638..9a8d616 100644
--- a/tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/SessionRenewTest.java
+++ b/tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/SessionRenewTest.java
@@ -21,11 +21,30 @@
import java.io.File;
import org.eclipse.jetty.server.SessionManager;
+import org.eclipse.jetty.util.IO;
+import org.junit.After;
+import org.junit.Before;
import org.junit.Test;
public class SessionRenewTest extends AbstractSessionRenewTest
{
-
+ File tmpDir;
+
+ @Before
+ public void before() throws Exception
+ {
+ tmpDir = File.createTempFile("hash-session-renew-test", null);
+ tmpDir.delete();
+ tmpDir.mkdirs();
+ tmpDir.deleteOnExit();
+ }
+
+ @After
+ public void after()
+ {
+ IO.delete(tmpDir);
+ }
+
@Override
public AbstractTestServer createServer(int port, int max, int scavenge)
{
@@ -37,9 +56,7 @@
{
HashSessionManager sessionManager = (HashSessionManager)super.newSessionManager();
sessionManager.setSavePeriod(2);
- File tmpDir = new File(System.getProperty("java.io.tmpdir"), "hash-session-renew-test");
- tmpDir.deleteOnExit();
- tmpDir.mkdirs();
+
try
{
sessionManager.setStoreDirectory(tmpDir);