diff --git a/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/JAASPrincipal.java b/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/JAASPrincipal.java
index 027c239b498..0566764292b 100644
--- a/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/JAASPrincipal.java
+++ b/jetty-jaas/src/main/java/org/eclipse/jetty/jaas/JAASPrincipal.java
@@ -30,7 +30,7 @@ public class JAASPrincipal implements Principal, Serializable
{
private static final long serialVersionUID = -5538962177019315479L;
- private String _name = null;
+ private final String _name;
public JAASPrincipal(String userName)
{
diff --git a/jetty-osgi/jetty-osgi-boot-jsp/build.properties b/jetty-osgi/jetty-osgi-boot-jsp/build.properties
deleted file mode 100644
index 6d10c98886e..00000000000
--- a/jetty-osgi/jetty-osgi-boot-jsp/build.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-source.. = src/main/java/
-output.. = target/classes/
-bin.includes = META-INF/,\
- .
-src.includes = META-INF/
diff --git a/jetty-osgi/jetty-osgi-boot-warurl/build.properties b/jetty-osgi/jetty-osgi-boot-warurl/build.properties
deleted file mode 100644
index 6d10c98886e..00000000000
--- a/jetty-osgi/jetty-osgi-boot-warurl/build.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-source.. = src/main/java/
-output.. = target/classes/
-bin.includes = META-INF/,\
- .
-src.includes = META-INF/
diff --git a/jetty-osgi/jetty-osgi-boot/build.properties b/jetty-osgi/jetty-osgi-boot/build.properties
deleted file mode 100644
index ba1366d0903..00000000000
--- a/jetty-osgi/jetty-osgi-boot/build.properties
+++ /dev/null
@@ -1,8 +0,0 @@
-source.. = src/main/java/
-output.. = target/classes/
-bin.includes = META-INF/,\
- .,\
- jettyhome/
-bin.excludes = jettyhome/logs/*.log,\
- jettyhome/lib/*
-src.includes = jettyhome/
diff --git a/jetty-osgi/jetty-osgi-httpservice/build.properties b/jetty-osgi/jetty-osgi-httpservice/build.properties
deleted file mode 100644
index 5fc538bc83f..00000000000
--- a/jetty-osgi/jetty-osgi-httpservice/build.properties
+++ /dev/null
@@ -1,4 +0,0 @@
-source.. = src/main/java/
-output.. = target/classes/
-bin.includes = META-INF/,\
- .
diff --git a/jetty-runner/pom.xml b/jetty-runner/pom.xml
index 6d80a15729a..aac41008896 100644
--- a/jetty-runner/pom.xml
+++ b/jetty-runner/pom.xml
@@ -11,8 +11,9 @@
target/distribution
${project.groupId}.runner
+ false
- http://www.eclipse.org/jetty
+
@@ -35,21 +36,38 @@
-
- org.apache.felix
- maven-bundle-plugin
-
-
- true
-
-
org.apache.maven.plugins
- maven-jar-plugin
+ maven-invoker-plugin
+
+
+ integration-test
+ integration-test
+
+ install
+ integration-test
+ verify
+
+
+
-
- ${project.build.outputDirectory}/META-INF/MANIFEST.MF
-
+ ${java.home}
+
+ ${java.home}
+
+ ${it.debug}
+ src/it
+ 600
+ ${project.build.directory}/it
+ ${project.build.directory}/local-repo
+ src/it/settings.xml
+ ${skipTests}
+
+ ${maven.dependency.plugin.version}
+
+
+ clean
+
@@ -63,6 +81,28 @@
true
+
+ org.apache.felix
+ maven-bundle-plugin
+
+
+ true
+
+ ${project.build.directory}/NON_USED_MANIFEST
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+
+
+ src/main/resources/MANIFEST.MF
+
+ org.eclipse.jetty.runner.Runner
+
+
+
+
diff --git a/jetty-runner/src/it/settings.xml b/jetty-runner/src/it/settings.xml
new file mode 100644
index 00000000000..d64bdb89034
--- /dev/null
+++ b/jetty-runner/src/it/settings.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+ it-repo
+
+ true
+
+
+
+ local.central
+ @localRepositoryUrl@
+
+ true
+
+
+ true
+
+
+
+
+
+ local.central
+ @localRepositoryUrl@
+
+ true
+
+
+ true
+
+
+
+
+
+
diff --git a/jetty-runner/src/it/test-jar-manifest/invoker.properties b/jetty-runner/src/it/test-jar-manifest/invoker.properties
new file mode 100644
index 00000000000..86f8ef2b751
--- /dev/null
+++ b/jetty-runner/src/it/test-jar-manifest/invoker.properties
@@ -0,0 +1 @@
+invoker.goals = generate-resources
diff --git a/jetty-runner/src/it/test-jar-manifest/pom.xml b/jetty-runner/src/it/test-jar-manifest/pom.xml
new file mode 100644
index 00000000000..b5fbdd16132
--- /dev/null
+++ b/jetty-runner/src/it/test-jar-manifest/pom.xml
@@ -0,0 +1,63 @@
+
+
+
+ 4.0.0
+
+
+
+ org.eclipse.jetty.its
+ jetty-runner-it-test
+ 1.0.0-SNAPSHOT
+ war
+
+
+
+ UTF-8
+
+
+
+
+
+ org.eclipse.jetty
+ jetty-runner
+ @project.version@
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-dependency-plugin
+ @maven.dependency.plugin.version@
+
+
+ copy-jetty-runner
+ generate-resources
+
+ copy
+
+
+
+
+ org.eclipse.jetty
+ jetty-runner
+ @project.version@
+ jar
+ false
+ ${project.build.directory}/
+ jetty-runner.jar
+
+
+ false
+ true
+
+
+
+
+
+
+
+
diff --git a/jetty-runner/src/it/test-jar-manifest/postbuild.groovy b/jetty-runner/src/it/test-jar-manifest/postbuild.groovy
new file mode 100644
index 00000000000..da1a6d99e3c
--- /dev/null
+++ b/jetty-runner/src/it/test-jar-manifest/postbuild.groovy
@@ -0,0 +1,10 @@
+import java.util.jar.*
+
+File artifact = new File( basedir, "target/jetty-runner.jar" )
+assert artifact.exists()
+
+JarFile jar = new JarFile( artifact );
+
+Attributes manifest = jar.getManifest().getMainAttributes();
+
+assert manifest.getValue( new Attributes.Name( "Main-Class" ) ).equals( "org.eclipse.jetty.runner.Runner" )
diff --git a/jetty-runner/src/main/resources/MANIFEST.MF b/jetty-runner/src/main/resources/MANIFEST.MF
new file mode 100644
index 00000000000..fa816753df9
--- /dev/null
+++ b/jetty-runner/src/main/resources/MANIFEST.MF
@@ -0,0 +1 @@
+Comment: Jetty Runner
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/Callback.java b/jetty-util/src/main/java/org/eclipse/jetty/util/Callback.java
index 7eea663e59a..0f1740f05e6 100644
--- a/jetty-util/src/main/java/org/eclipse/jetty/util/Callback.java
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/Callback.java
@@ -128,7 +128,18 @@ public interface Callback extends Invocable
}
};
}
-
+
+ static Callback from(Runnable completed)
+ {
+ return new Completing()
+ {
+ public void completed()
+ {
+ completed.run();
+ }
+ };
+ }
+
class Completing implements Callback
{
@Override
diff --git a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketSession.java b/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketSession.java
index ff70a34a422..d63666d2a26 100644
--- a/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketSession.java
+++ b/jetty-websocket/javax-websocket-common/src/main/java/org/eclipse/jetty/websocket/javax/common/JavaxWebSocketSession.java
@@ -18,24 +18,6 @@
package org.eclipse.jetty.websocket.javax.common;
-import org.eclipse.jetty.util.SharedBlockingCallback;
-import org.eclipse.jetty.util.component.AbstractLifeCycle;
-import org.eclipse.jetty.util.log.Log;
-import org.eclipse.jetty.util.log.Logger;
-import org.eclipse.jetty.websocket.core.ExtensionConfig;
-import org.eclipse.jetty.websocket.core.FrameHandler;
-import org.eclipse.jetty.websocket.javax.common.decoders.AvailableDecoders;
-import org.eclipse.jetty.websocket.javax.common.encoders.AvailableEncoders;
-import org.eclipse.jetty.websocket.javax.common.util.ReflectUtils;
-
-import javax.websocket.CloseReason;
-import javax.websocket.EndpointConfig;
-import javax.websocket.Extension;
-import javax.websocket.MessageHandler;
-import javax.websocket.RemoteEndpoint.Async;
-import javax.websocket.RemoteEndpoint.Basic;
-import javax.websocket.Session;
-import javax.websocket.WebSocketContainer;
import java.io.IOException;
import java.net.URI;
import java.security.Principal;
@@ -48,6 +30,25 @@ import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
+import javax.websocket.CloseReason;
+import javax.websocket.EndpointConfig;
+import javax.websocket.Extension;
+import javax.websocket.MessageHandler;
+import javax.websocket.RemoteEndpoint.Async;
+import javax.websocket.RemoteEndpoint.Basic;
+import javax.websocket.Session;
+import javax.websocket.WebSocketContainer;
+
+import org.eclipse.jetty.util.SharedBlockingCallback;
+import org.eclipse.jetty.util.component.AbstractLifeCycle;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.websocket.core.ExtensionConfig;
+import org.eclipse.jetty.websocket.core.FrameHandler;
+import org.eclipse.jetty.websocket.javax.common.decoders.AvailableDecoders;
+import org.eclipse.jetty.websocket.javax.common.encoders.AvailableEncoders;
+import org.eclipse.jetty.websocket.javax.common.util.ReflectUtils;
+
/**
* Client Session for the JSR.
*/
@@ -535,7 +536,7 @@ public class JavaxWebSocketSession extends AbstractLifeCycle implements javax.we
@Override
public boolean isOpen()
{
- return coreSession.isOpen();
+ return coreSession.isOutputOpen();
}
/**
diff --git a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/LocalServer.java b/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/LocalServer.java
index f07ee22c3bd..c1099963f54 100644
--- a/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/LocalServer.java
+++ b/jetty-websocket/javax-websocket-tests/src/main/java/org/eclipse/jetty/websocket/javax/tests/LocalServer.java
@@ -32,7 +32,14 @@ import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.http.pathmap.PathSpec;
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.MappedByteBufferPool;
-import org.eclipse.jetty.server.*;
+import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.HttpConfiguration;
+import org.eclipse.jetty.server.HttpConnectionFactory;
+import org.eclipse.jetty.server.LocalConnector;
+import org.eclipse.jetty.server.SecureRequestCustomizer;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.ServerConnector;
+import org.eclipse.jetty.server.SslConnectionFactory;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/misbehaving/MisbehavingClassTest.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/misbehaving/MisbehavingClassTest.java
index a2e57690c41..a7dff0dcaa4 100644
--- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/misbehaving/MisbehavingClassTest.java
+++ b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/client/misbehaving/MisbehavingClassTest.java
@@ -18,6 +18,13 @@
package org.eclipse.jetty.websocket.javax.tests.client.misbehaving;
+import java.io.IOException;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+
+import javax.websocket.ContainerProvider;
+import javax.websocket.WebSocketContainer;
+
import org.eclipse.jetty.util.log.StacklessLogging;
import org.eclipse.jetty.websocket.core.internal.WebSocketChannel;
import org.eclipse.jetty.websocket.javax.tests.CoreServer;
@@ -25,12 +32,6 @@ import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
-import javax.websocket.ContainerProvider;
-import javax.websocket.WebSocketContainer;
-import java.io.IOException;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
-
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is;
diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/quotes/QuotesDecoderTextStreamTest.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/quotes/QuotesDecoderTextStreamTest.java
index a0a90cdfcad..8c2112de515 100644
--- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/quotes/QuotesDecoderTextStreamTest.java
+++ b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/quotes/QuotesDecoderTextStreamTest.java
@@ -38,7 +38,9 @@ import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.*;
+import static org.hamcrest.Matchers.allOf;
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.is;
/**
* Tests a {@link javax.websocket.Decoder.TextStream} automatic decoding to a Socket onMessage parameter
diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/MemoryUsageTest.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/MemoryUsageTest.java
index e5d6ab10216..b47cb19030b 100644
--- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/MemoryUsageTest.java
+++ b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/MemoryUsageTest.java
@@ -25,7 +25,12 @@ import java.net.URI;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
-import javax.websocket.*;
+import javax.websocket.ContainerProvider;
+import javax.websocket.Endpoint;
+import javax.websocket.EndpointConfig;
+import javax.websocket.MessageHandler;
+import javax.websocket.Session;
+import javax.websocket.WebSocketContainer;
import javax.websocket.server.ServerContainer;
import javax.websocket.server.ServerEndpointConfig;
diff --git a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/WebSocketServerContainerExecutorTest.java b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/WebSocketServerContainerExecutorTest.java
index 0f47ed9be2e..edaaa030aef 100644
--- a/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/WebSocketServerContainerExecutorTest.java
+++ b/jetty-websocket/javax-websocket-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/server/WebSocketServerContainerExecutorTest.java
@@ -31,7 +31,13 @@ import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import javax.websocket.*;
+import javax.websocket.ContainerProvider;
+import javax.websocket.Endpoint;
+import javax.websocket.EndpointConfig;
+import javax.websocket.OnError;
+import javax.websocket.OnMessage;
+import javax.websocket.Session;
+import javax.websocket.WebSocketContainer;
import javax.websocket.server.ServerEndpoint;
import org.eclipse.jetty.client.HttpClient;
diff --git a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/WebSocketSessionImpl.java b/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/WebSocketSessionImpl.java
index eff766bc247..58f02e6f479 100644
--- a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/WebSocketSessionImpl.java
+++ b/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/WebSocketSessionImpl.java
@@ -18,6 +18,11 @@
package org.eclipse.jetty.websocket.common;
+import java.io.IOException;
+import java.net.SocketAddress;
+import java.time.Duration;
+import java.util.Objects;
+
import org.eclipse.jetty.util.component.Dumpable;
import org.eclipse.jetty.websocket.api.CloseStatus;
import org.eclipse.jetty.websocket.api.Session;
@@ -27,11 +32,6 @@ import org.eclipse.jetty.websocket.api.UpgradeResponse;
import org.eclipse.jetty.websocket.api.WebSocketBehavior;
import org.eclipse.jetty.websocket.core.FrameHandler;
-import java.io.IOException;
-import java.net.SocketAddress;
-import java.time.Duration;
-import java.util.Objects;
-
public class WebSocketSessionImpl implements Session, Dumpable
{
private final FrameHandler.CoreSession coreSession;
@@ -160,7 +160,7 @@ public class WebSocketSessionImpl implements Session, Dumpable
@Override
public boolean isOpen()
{
- return remoteEndpoint.getCoreSession().isOpen();
+ return remoteEndpoint.getCoreSession().isOutputOpen();
}
@Override
diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/CloseStatus.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/CloseStatus.java
index 3759dc90012..4e9f30de364 100644
--- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/CloseStatus.java
+++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/CloseStatus.java
@@ -18,14 +18,13 @@
package org.eclipse.jetty.websocket.core;
-import org.eclipse.jetty.util.BufferUtil;
-import org.eclipse.jetty.util.Utf8Appendable;
-import org.eclipse.jetty.util.Utf8StringBuilder;
-
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
-import java.util.function.Supplier;
+
+import org.eclipse.jetty.util.BufferUtil;
+import org.eclipse.jetty.util.Utf8Appendable;
+import org.eclipse.jetty.util.Utf8StringBuilder;
/**
* Representation of a WebSocket Close (status code & reason)
@@ -194,7 +193,7 @@ public class CloseStatus
int len = 2; // status code
- byte reasonBytes[] = null;
+ byte[] reasonBytes = null;
if (reason != null)
{
@@ -208,7 +207,7 @@ public class CloseStatus
ByteBuffer buf = BufferUtil.allocate(len);
BufferUtil.flipToFill(buf);
buf.put((byte)((statusCode >>> 8) & 0xFF));
- buf.put((byte)((statusCode >>> 0) & 0xFF));
+ buf.put((byte)(statusCode & 0xFF));
if ((reasonBytes != null) && (reasonBytes.length > 0))
{
diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/FrameHandler.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/FrameHandler.java
index 2ab1908c355..80ef69c586d 100644
--- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/FrameHandler.java
+++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/FrameHandler.java
@@ -270,7 +270,7 @@ public interface FrameHandler extends IncomingFrames
/**
* @return True if the websocket is open outbound
*/
- boolean isOpen();
+ boolean isOutputOpen();
/**
* If using BatchMode.ON or BatchMode.AUTO, trigger a flush of enqueued / batched frames.
@@ -374,7 +374,7 @@ public interface FrameHandler extends IncomingFrames
}
@Override
- public boolean isOpen()
+ public boolean isOutputOpen()
{
return false;
}
diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/ExtensionStack.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/ExtensionStack.java
index 52ec3df0af1..fa903261f14 100644
--- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/ExtensionStack.java
+++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/ExtensionStack.java
@@ -19,18 +19,15 @@
package org.eclipse.jetty.websocket.core.internal;
import java.io.IOException;
-import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.ListIterator;
-import java.util.Queue;
import java.util.stream.Collectors;
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.DecoratedObjectFactory;
-import org.eclipse.jetty.util.IteratingCallback;
import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject;
import org.eclipse.jetty.util.component.Dumpable;
@@ -201,7 +198,7 @@ public class ExtensionStack implements IncomingFrames, OutgoingFrames, Dumpable
outgoing.sendFrame(frame, callback, batch);
}
- public void connect(IncomingFrames incoming, OutgoingFrames outgoing, WebSocketChannel webSocketChannel)
+ public void initialize(IncomingFrames incoming, OutgoingFrames outgoing, WebSocketChannel webSocketChannel)
{
if (extensions == null)
throw new IllegalStateException();
diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/FrameFlusher.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/FrameFlusher.java
index 48a57003c60..211c50c9668 100644
--- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/FrameFlusher.java
+++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/FrameFlusher.java
@@ -18,6 +18,7 @@
package org.eclipse.jetty.websocket.core.internal;
+import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayDeque;
import java.util.ArrayList;
@@ -74,6 +75,18 @@ public class FrameFlusher extends IteratingCallback
}
}
+ public void onClose()
+ {
+ Throwable cause = null;
+ synchronized (this)
+ {
+ if (!queue.isEmpty())
+ cause = new IOException("Closed");
+ }
+ if (cause!=null)
+ onCompleteFailure(cause);
+ }
+
@Override
protected Action process() throws Throwable
{
diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/WebSocketChannel.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/WebSocketChannel.java
index c93d8222f04..ec4e158044a 100644
--- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/WebSocketChannel.java
+++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/WebSocketChannel.java
@@ -20,16 +20,19 @@ package org.eclipse.jetty.websocket.core.internal;
import java.io.IOException;
import java.net.SocketAddress;
-import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.net.URI;
import java.time.Duration;
+import java.util.ArrayDeque;
import java.util.List;
import java.util.Map;
+import java.util.Queue;
import java.util.concurrent.Executor;
+import java.util.concurrent.TimeoutException;
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.util.Callback;
+import org.eclipse.jetty.util.IteratingCallback;
import org.eclipse.jetty.util.Utf8Appendable;
import org.eclipse.jetty.util.component.Dumpable;
import org.eclipse.jetty.util.log.Log;
@@ -62,6 +65,7 @@ public class WebSocketChannel implements IncomingFrames, FrameHandler.CoreSessio
private final FrameHandler handler;
private final Negotiated negotiated;
private final boolean demanding;
+ private final Flusher flusher = new Flusher();
private WebSocketConnection connection;
private boolean autoFragment = WebSocketConstants.DEFAULT_AUTO_FRAGMENT;
@@ -79,7 +83,7 @@ public class WebSocketChannel implements IncomingFrames, FrameHandler.CoreSessio
this.behavior = behavior;
this.negotiated = negotiated;
this.demanding = handler.isDemanding();
- negotiated.getExtensions().connect(new IncomingAdaptor(), new OutgoingAdaptor(), this);
+ negotiated.getExtensions().initialize(new IncomingAdaptor(), new OutgoingAdaptor(), this);
}
/**
@@ -153,7 +157,7 @@ public class WebSocketChannel implements IncomingFrames, FrameHandler.CoreSessio
if (frame.getOpCode() == OpCode.CLOSE)
{
if (!(frame instanceof ParsedFrame)) // already check in parser
- CloseStatus.getCloseStatus(frame);
+ CloseStatus.getCloseStatus(frame); // return ignored as get used to validate there is a closeStatus
}
}
else
@@ -235,9 +239,14 @@ public class WebSocketChannel implements IncomingFrames, FrameHandler.CoreSessio
}
@Override
- public boolean isOpen()
+ public boolean isOutputOpen()
{
- return channelState.isOutOpen();
+ return channelState.isOutputOpen();
+ }
+
+ public boolean isClosed()
+ {
+ return channelState.isClosed();
}
public void setWebSocketConnection(WebSocketConnection connection)
@@ -282,99 +291,94 @@ public class WebSocketChannel implements IncomingFrames, FrameHandler.CoreSessio
public void onClosed(Throwable cause)
{
- onClosed(cause, new CloseStatus(CloseStatus.NO_CLOSE, cause == null?null:cause.toString()));
+ CloseStatus closeStatus = new CloseStatus(CloseStatus.NO_CLOSE, cause == null?null:cause.toString());
+ if (channelState.onClosed(closeStatus))
+ closeConnection(cause, closeStatus);
}
- public void onClosed(Throwable cause, CloseStatus closeStatus)
+ public void closeConnection(Throwable cause, CloseStatus closeStatus)
{
- if (channelState.onClosed(closeStatus))
- {
- connection.cancelDemand();
+ connection.cancelDemand();
- // Forward Errors to Local WebSocket EndPoint
+ // Forward Errors to Local WebSocket EndPoint
+ if (cause!=null)
+ {
try
{
handler.onError(cause);
}
catch (Throwable e)
{
- cause.addSuppressed(e);
+ if (e != cause)
+ cause.addSuppressed(e);
LOG.warn(cause);
}
-
- try
- {
- handler.onClosed(closeStatus);
- }
- catch (Exception e)
- {
- LOG.warn(e);
- }
- }
- }
-
- /**
- * Process an Error event seen by the Session and/or Connection
- *
- * @param cause the cause
- */
- public void processError(Throwable cause)
- {
- CloseStatus closeStatus;
-
- if (cause instanceof Utf8Appendable.NotUtf8Exception)
- {
- closeStatus = new CloseStatus(CloseStatus.BAD_PAYLOAD, cause.getMessage());
- }
- else if (cause instanceof SocketTimeoutException)
- {
- // A path often seen in Windows
- closeStatus = new CloseStatus(CloseStatus.SHUTDOWN, cause.getMessage());
- }
- else if (cause instanceof IOException)
- {
- closeStatus = new CloseStatus(CloseStatus.PROTOCOL, cause.getMessage());
- }
- else if (cause instanceof SocketException)
- {
- // A path unique to Unix
- closeStatus = new CloseStatus(CloseStatus.SHUTDOWN, cause.getMessage());
- }
- else if (cause instanceof CloseException)
- {
- CloseException ce = (CloseException)cause;
- closeStatus = new CloseStatus(ce.getStatusCode(), ce.getMessage());
- }
- else if (cause instanceof WebSocketTimeoutException)
- {
- closeStatus = new CloseStatus(CloseStatus.SHUTDOWN, cause.getMessage());
- }
- else
- {
- LOG.warn("Unhandled Error (closing connection)", cause);
-
- // Exception on end-user WS-Endpoint.
- // Fast-fail & close connection with reason.
- int statusCode = CloseStatus.SERVER_ERROR;
- if (behavior == Behavior.CLIENT)
- statusCode = CloseStatus.POLICY_VIOLATION;
-
- closeStatus = new CloseStatus(statusCode, cause.getMessage());
}
try
{
- // TODO can we avoid the illegal state exception in outClosed
- close(closeStatus, Callback.NOOP, false);
+ handler.onClosed(closeStatus);
}
- catch (IllegalStateException e)
+ catch (Throwable e)
{
- if (cause == null)
- cause = e;
- else
- cause.addSuppressed(e);
+ LOG.warn(e);
}
- onClosed(cause, closeStatus);
+
+ if (connection.getEndPoint().isOpen())
+ connection.close();
+ }
+
+ AbnormalCloseStatus abnormalCloseStatusFor(Throwable cause)
+ {
+ int code;
+ if (cause instanceof ProtocolException)
+ code = CloseStatus.PROTOCOL;
+ else if (cause instanceof CloseException)
+ code = ((CloseException)cause).getStatusCode();
+ else if (cause instanceof Utf8Appendable.NotUtf8Exception)
+ code = CloseStatus.BAD_PAYLOAD;
+ else if (cause instanceof WebSocketTimeoutException || cause instanceof TimeoutException || cause instanceof SocketTimeoutException)
+ code = CloseStatus.SHUTDOWN;
+ else if (behavior == Behavior.CLIENT)
+ code = CloseStatus.POLICY_VIOLATION;
+ else
+ code = CloseStatus.SERVER_ERROR;
+
+ return new AbnormalCloseStatus(code, cause.getMessage());
+ }
+
+ /**
+ * Process an Error that originated from the connection.
+ * For protocol causes, send and abnormal close frame
+ * otherwise just close the connection.
+ *
+ * @param cause the cause
+ */
+ public void processConnectionError(Throwable cause)
+ {
+ if (LOG.isDebugEnabled())
+ LOG.debug("processConnectionError {} {}", this, cause);
+
+ CloseStatus closeStatus = abnormalCloseStatusFor(cause);
+
+ if (closeStatus.getCode() == CloseStatus.PROTOCOL)
+ close(closeStatus, Callback.NOOP, false);
+ else if (channelState.onClosed(closeStatus))
+ closeConnection(cause, closeStatus);
+ }
+
+ /**
+ * Process an Error that originated from the handler.
+ * Send an abnormal close frame to ensure connection is closed.
+ *
+ * @param cause the cause
+ */
+ public void processHandlerError(Throwable cause)
+ {
+ if (LOG.isDebugEnabled())
+ LOG.debug("processHandlerError {} {}", this, cause);
+
+ close(abnormalCloseStatusFor(cause), Callback.NOOP, false);
}
/**
@@ -393,27 +397,27 @@ public class WebSocketChannel implements IncomingFrames, FrameHandler.CoreSessio
if (LOG.isDebugEnabled())
LOG.debug("ConnectionState: Transition to CONNECTED");
- try
- {
- // Open connection and handler
- channelState.onOpen();
- handler.onOpen(this);
- if (!demanding)
- connection.demand(1);
+ // Open connection and handler
+ channelState.onOpen();
+ handler.onOpen(this);
+ if (!demanding)
+ connection.demand(1);
- if (LOG.isDebugEnabled())
- LOG.debug("ConnectionState: Transition to OPEN");
- }
- catch (Throwable t)
- {
- LOG.warn("Error during OPEN", t);
- // TODO: this must trigger onError AND onClose
- processError(new CloseException(CloseStatus.SERVER_ERROR, t));
- }
+ if (LOG.isDebugEnabled())
+ LOG.debug("ConnectionState: Transition to OPEN");
}
catch (Throwable t)
{
- processError(t); // Handle error
+ LOG.warn("Error during OPEN", t);
+ try
+ {
+ handler.onError(t);
+ }
+ catch (Exception e)
+ {
+ t.addSuppressed(e);
+ }
+ processHandlerError(new CloseException(CloseStatus.SERVER_ERROR, t));
}
}
@@ -454,73 +458,73 @@ public class WebSocketChannel implements IncomingFrames, FrameHandler.CoreSessio
@Override
public void sendFrame(Frame frame, Callback callback, boolean batch)
{
- synchronized(this)
- {
- if (LOG.isDebugEnabled())
- LOG.debug("sendFrame({}, {}, {})", frame, callback, batch);
+ if (LOG.isDebugEnabled())
+ LOG.debug("sendFrame({}, {}, {})", frame, callback, batch);
- boolean closed;
+ try
+ {
+ assertValidOutgoing(frame);
+ }
+ catch (Throwable ex)
+ {
+ callback.failed(ex);
+ return;
+ }
+
+ try
+ {
+ synchronized(flusher)
+ {
+ boolean closeConnection = channelState.onOutgoingFrame(frame);
+
+ if (frame.getOpCode() == OpCode.CLOSE)
+ {
+ if (LOG.isDebugEnabled())
+ LOG.debug("close({}, {}, {})", CloseStatus.getCloseStatus(frame), callback, batch);
+
+ if (closeConnection)
+ {
+ callback = new Callback.Nested(callback)
+ {
+ @Override
+ public void completed()
+ {
+ closeConnection(null, channelState.getCloseStatus());
+ }
+ };
+ }
+ }
+
+ flusher.queue.offer(new FrameEntry(frame, callback, batch));
+ }
+ flusher.iterate();
+ }
+ catch (Throwable ex)
+ {
try
- {
- assertValidOutgoing(frame);
- closed = channelState.checkOutgoing(frame);
- }
- catch (Throwable ex)
{
callback.failed(ex);
- return;
}
-
- if (frame.getOpCode() == OpCode.CLOSE)
+ finally
{
- if (LOG.isDebugEnabled())
- LOG.debug("close({}, {}, {})", CloseStatus.getCloseStatus(frame), callback, batch);
-
- if (closed)
+ if (frame.getOpCode() == OpCode.CLOSE)
{
- callback = new Callback.Nested(callback)
- {
- @Override
- public void completed()
- {
- try
- {
- handler.onClosed(channelState.getCloseStatus());
- }
- catch (Throwable e)
- {
- try
- {
- handler.onError(e);
- }
- catch (Throwable e2)
- {
- e.addSuppressed(e2);
- LOG.warn(e);
- }
- }
- finally
- {
- connection.close();
- }
- }
- };
+ CloseStatus closeStatus = CloseStatus.getCloseStatus(frame);
+ if (closeStatus instanceof AbnormalCloseStatus)
+ closeConnection(null, closeStatus);
}
}
-
- negotiated.getExtensions().sendFrame(frame, callback, batch);
}
- connection.sendFrameQueue();
}
@Override
public void flush(Callback callback)
{
- synchronized(this)
+ synchronized(flusher)
{
- negotiated.getExtensions().sendFrame(FrameFlusher.FLUSH_FRAME, callback, false);
+ flusher.queue.offer(new FrameEntry(FrameFlusher.FLUSH_FRAME, callback, false));
}
- connection.sendFrameQueue();
+ flusher.iterate();
}
@Override
@@ -613,14 +617,13 @@ public class WebSocketChannel implements IncomingFrames, FrameHandler.CoreSessio
LOG.debug("receiveFrame({}, {}) - connectionState={}, handler={}",
frame, callback, channelState, handler);
-
- boolean closed = channelState.checkIncoming(frame);
+ boolean closeConnection = channelState.onIncomingFrame(frame);
// Handle inbound close
if (frame.getOpCode() == OpCode.CLOSE)
{
connection.cancelDemand();
- if (closed)
+ if (closeConnection)
{
callback = new Callback.Nested(callback)
{
@@ -640,7 +643,7 @@ public class WebSocketChannel implements IncomingFrames, FrameHandler.CoreSessio
@Override
public void completed()
{
- if (channelState.isOutOpen())
+ if (channelState.isOutputOpen())
{
CloseStatus closeStatus = CloseStatus.getCloseStatus(frame);
@@ -648,8 +651,9 @@ public class WebSocketChannel implements IncomingFrames, FrameHandler.CoreSessio
LOG.debug("ConnectionState: sending close response {}", closeStatus);
// this may race with a rare application close but errors are ignored
+ if (closeStatus==null)
+ closeStatus = CloseStatus.NO_CODE_STATUS;
close(closeStatus.getCode(), closeStatus.getReason(), Callback.NOOP);
- return;
}
}
};
@@ -735,8 +739,9 @@ public class WebSocketChannel implements IncomingFrames, FrameHandler.CoreSessio
@Override
public String toString()
{
- return String.format("WSChannel@%x{%s,%s,af=%b,i/o=%d/%d,fs=%d}->%s",
+ return String.format("WSChannel@%x{%s,%s,%s,af=%b,i/o=%d/%d,fs=%d}->%s",
hashCode(),
+ behavior,
channelState,
negotiated,
autoFragment,
@@ -745,4 +750,67 @@ public class WebSocketChannel implements IncomingFrames, FrameHandler.CoreSessio
maxFrameSize,
handler);
}
+
+ static class AbnormalCloseStatus extends CloseStatus
+ {
+ public AbnormalCloseStatus(int statusCode, String reasonPhrase)
+ {
+ super(statusCode, reasonPhrase);
+ }
+ }
+
+ private class Flusher extends IteratingCallback
+ {
+ private final Queue queue = new ArrayDeque<>();
+ FrameEntry entry;
+
+ @Override
+ protected Action process() throws Throwable
+ {
+ synchronized (this)
+ {
+ entry = queue.poll();
+ }
+ if (entry==null)
+ return Action.IDLE;
+
+ negotiated.getExtensions().sendFrame(entry.frame, this, entry.batch);
+ return Action.SCHEDULED;
+ }
+
+ @Override
+ public void succeeded()
+ {
+ entry.callback.succeeded();
+ super.succeeded();
+ }
+
+ @Override
+ protected void onCompleteFailure(Throwable cause)
+ {
+ entry.callback.failed(cause);
+ Queue entries;
+ synchronized (this)
+ {
+ entries = new ArrayDeque<>(queue);
+ queue.clear();
+ }
+ entries.forEach(e-> failEntry(cause, e));
+ }
+
+ private void failEntry(Throwable cause, FrameEntry e)
+ {
+ try
+ {
+ e.callback.failed(cause);
+ }
+ catch(Throwable x)
+ {
+ if (cause != x)
+ cause.addSuppressed(x);
+ LOG.warn(cause);
+ }
+ }
+ }
+
}
diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/WebSocketChannelState.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/WebSocketChannelState.java
index b467dd2a89f..815959e940a 100644
--- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/WebSocketChannelState.java
+++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/WebSocketChannelState.java
@@ -33,8 +33,8 @@ public class WebSocketChannelState
CONNECTING,
CONNECTED,
OPEN,
- ICLOSED,
- OCLOSED,
+ ISHUT,
+ OSHUT,
CLOSED
}
@@ -68,7 +68,11 @@ public class WebSocketChannelState
@Override
public String toString()
{
- return _channelState.toString();
+ return String.format("%s@%x{%s,i=%s,o=%s,c=%s}",getClass().getSimpleName(),hashCode(),
+ _channelState,
+ OpCode.name(_incomingContinuation),
+ OpCode.name(_outgoingContinuation),
+ _closeStatus);
}
@@ -85,16 +89,16 @@ public class WebSocketChannelState
return getState()==State.CLOSED;
}
- public boolean isInOpen()
+ public boolean isInputOpen()
{
State state = getState();
- return (state==State.OPEN || state==State.OCLOSED);
+ return (state==State.OPEN || state==State.OSHUT);
}
- public boolean isOutOpen()
+ public boolean isOutputOpen()
{
State state = getState();
- return (state==State.OPEN || state==State.ICLOSED);
+ return (state==State.OPEN || state==State.ISHUT);
}
public CloseStatus getCloseStatus()
@@ -118,28 +122,39 @@ public class WebSocketChannelState
}
}
- public boolean checkOutgoing(Frame frame) throws ProtocolException
+ public boolean onOutgoingFrame(Frame frame) throws ProtocolException
{
byte opcode = frame.getOpCode();
boolean fin = frame.isFin();
synchronized (this)
{
- if (!isOutOpen())
+ if (!isOutputOpen())
+ {
+ if (opcode == OpCode.CLOSE && CloseStatus.getCloseStatus(frame) instanceof WebSocketChannel.AbnormalCloseStatus)
+ _channelState = State.CLOSED;
throw new IllegalStateException(_channelState.toString());
+ }
if (opcode == OpCode.CLOSE)
{
_closeStatus = CloseStatus.getCloseStatus(frame);
+ if (_closeStatus instanceof WebSocketChannel.AbnormalCloseStatus)
+ {
+ _channelState = State.CLOSED;
+ return true;
+ }
switch (_channelState)
{
case OPEN:
- _channelState = State.OCLOSED;
+ _channelState = State.OSHUT;
return false;
- case ICLOSED:
+
+ case ISHUT:
_channelState = State.CLOSED;
return true;
+
default:
throw new IllegalStateException(_channelState.toString());
}
@@ -153,14 +168,14 @@ public class WebSocketChannelState
return false;
}
- public boolean checkIncoming(Frame frame) throws ProtocolException
+ public boolean onIncomingFrame(Frame frame) throws ProtocolException
{
byte opcode = frame.getOpCode();
boolean fin = frame.isFin();
synchronized (this)
{
- if (!isInOpen())
+ if (!isInputOpen())
throw new IllegalStateException(_channelState.toString());
if (opcode == OpCode.CLOSE)
@@ -170,9 +185,9 @@ public class WebSocketChannelState
switch (_channelState)
{
case OPEN:
- _channelState = State.ICLOSED;
+ _channelState = State.ISHUT;
return false;
- case OCLOSED:
+ case OSHUT:
_channelState = State.CLOSED;
return true;
default:
diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/WebSocketConnection.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/WebSocketConnection.java
index 743642065ff..3d5757542f7 100644
--- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/WebSocketConnection.java
+++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/core/internal/WebSocketConnection.java
@@ -18,6 +18,13 @@
package org.eclipse.jetty.websocket.core.internal;
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.nio.ByteBuffer;
+import java.util.Objects;
+import java.util.Random;
+import java.util.concurrent.Executor;
+
import org.eclipse.jetty.io.AbstractConnection;
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.Connection;
@@ -34,13 +41,6 @@ import org.eclipse.jetty.websocket.core.MessageTooLargeException;
import org.eclipse.jetty.websocket.core.ProtocolException;
import org.eclipse.jetty.websocket.core.WebSocketTimeoutException;
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.nio.ByteBuffer;
-import java.util.Objects;
-import java.util.Random;
-import java.util.concurrent.Executor;
-
/**
* Provides the implementation of {@link org.eclipse.jetty.io.Connection} that is suitable for WebSocket
*/
@@ -167,22 +167,44 @@ public class WebSocketConnection extends AbstractConnection implements Connectio
if (LOG.isDebugEnabled())
LOG.debug("onClose() of physical connection");
- // TODO review all close paths
- IOException e = new IOException("Closed");
- channel.onClosed(e);
+ if (!channel.isClosed())
+ {
+ IOException e = new IOException("Closed");
+ channel.onClosed(e);
+ }
+ flusher.onClose();
+
super.onClose();
}
+
@Override
public boolean onIdleExpired()
{
if (LOG.isDebugEnabled())
LOG.debug("onIdleExpired()");
- channel.processError(new WebSocketTimeoutException("Connection Idle Timeout"));
+ // treat as a handler error because socket is still open
+ channel.processHandlerError(new WebSocketTimeoutException("Connection Idle Timeout"));
return true;
}
+ /**
+ * Event for no activity on connection (read or write)
+ *
+ * @return true to signal that the endpoint must be closed, false to keep the endpoint open
+ */
+ @Override
+ protected boolean onReadTimeout(Throwable timeout)
+ {
+ if (LOG.isDebugEnabled())
+ LOG.debug("onReadTimeout()");
+
+ // treat as a handler error because socket is still open
+ channel.processHandlerError(new WebSocketTimeoutException("Timeout on Read", timeout));
+ return false;
+ }
+
protected void onFrame(Parser.ParsedFrame frame)
{
if (LOG.isDebugEnabled())
@@ -219,7 +241,7 @@ public class WebSocketConnection extends AbstractConnection implements Connectio
referenced.release();
// notify session & endpoint
- channel.processError(cause);
+ channel.processHandlerError(cause);
}
});
}
@@ -431,7 +453,7 @@ public class WebSocketConnection extends AbstractConnection implements Connectio
LOG.warn(t.toString());
BufferUtil.clear(networkBuffer.getBuffer());
releaseNetworkBuffer();
- channel.processError(t);
+ channel.processConnectionError(t);
}
}
@@ -476,18 +498,6 @@ public class WebSocketConnection extends AbstractConnection implements Connectio
super.onOpen();
}
- /**
- * Event for no activity on connection (read or write)
- *
- * @return true to signal that the endpoint must be closed, false to keep the endpoint open
- */
- @Override
- protected boolean onReadTimeout(Throwable timeout)
- {
- channel.processError(new WebSocketTimeoutException("Timeout on Read", timeout));
- return false;
- }
-
@Override
public void setInputBufferSize(int inputBufferSize)
{
@@ -577,7 +587,6 @@ public class WebSocketConnection extends AbstractConnection implements Connectio
/**
* Enqueue a Frame to be sent.
- * @see #sendFrameQueue()
* @param frame The frame to queue
* @param callback The callback to call once the frame is sent
* @param batch True if batch mode is to be used
@@ -592,10 +601,6 @@ public class WebSocketConnection extends AbstractConnection implements Connectio
wsf.setMask(mask);
}
flusher.enqueue(frame, callback, batch);
- }
-
- void sendFrameQueue()
- {
flusher.iterate();
}
@@ -610,7 +615,7 @@ public class WebSocketConnection extends AbstractConnection implements Connectio
public void onCompleteFailure(Throwable x)
{
super.onCompleteFailure(x);
- channel.processError(x);
+ channel.processConnectionError(x);
}
}
}
diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/WebSocketCloseTest.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/WebSocketCloseTest.java
index 84484d5406c..1bd0b5478cc 100644
--- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/WebSocketCloseTest.java
+++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/WebSocketCloseTest.java
@@ -18,6 +18,11 @@
package org.eclipse.jetty.websocket.core;
+import java.net.Socket;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.NetworkConnector;
import org.eclipse.jetty.server.Server;
@@ -39,11 +44,6 @@ import org.eclipse.jetty.websocket.core.server.internal.RFC6455Handshaker;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
-import java.net.Socket;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
import static org.eclipse.jetty.util.Callback.NOOP;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
@@ -65,7 +65,7 @@ public class WebSocketCloseTest extends WebSocketTester
enum State
{
- OPEN, ICLOSED, OCLOSED
+ OPEN, ISHUT, OSHUT
}
@AfterEach
@@ -93,7 +93,7 @@ public class WebSocketCloseTest extends WebSocketTester
break;
}
- case ICLOSED:
+ case ISHUT:
{
TestFrameHandler serverHandler = new TestFrameHandler();
@@ -109,12 +109,12 @@ public class WebSocketCloseTest extends WebSocketTester
assertNotNull(frame);
assertThat(new CloseStatus(frame.getPayload()).getCode(), is(CloseStatus.NORMAL));
- assertThat(server.handler.getCoreSession().toString(), containsString("ICLOSED"));
- LOG.info("Server: ICLOSED");
+ assertThat(server.handler.getCoreSession().toString(), containsString("ISHUT"));
+ LOG.info("Server: ISHUT");
break;
}
- case OCLOSED:
+ case OSHUT:
{
TestFrameHandler serverHandler = new TestFrameHandler();
@@ -129,8 +129,8 @@ public class WebSocketCloseTest extends WebSocketTester
assertNotNull(frame);
assertThat(new CloseStatus(frame.getPayload()).getCode(), is(CloseStatus.NORMAL));
- assertThat(server.handler.getCoreSession().toString(), containsString("OCLOSED"));
- LOG.info("Server: OCLOSED");
+ assertThat(server.handler.getCoreSession().toString(), containsString("OSHUT"));
+ LOG.info("Server: OSHUT");
break;
}
@@ -140,7 +140,7 @@ public class WebSocketCloseTest extends WebSocketTester
@Test
public void serverClose_ICLOSED() throws Exception
{
- setup(State.ICLOSED);
+ setup(State.ISHUT);
server.handler.receivedCallback.poll().succeeded();
Frame frame = receiveFrame(client.getInputStream());
@@ -154,7 +154,7 @@ public class WebSocketCloseTest extends WebSocketTester
@Test
public void serverDifferentClose_ICLOSED() throws Exception
{
- setup(State.ICLOSED);
+ setup(State.ISHUT);
server.sendFrame(CloseStatus.toFrame(CloseStatus.SHUTDOWN));
server.handler.receivedCallback.poll().succeeded();
@@ -171,7 +171,7 @@ public class WebSocketCloseTest extends WebSocketTester
{
try (StacklessLogging stackless = new StacklessLogging(WebSocketChannel.class))
{
- setup(State.ICLOSED);
+ setup(State.ISHUT);
server.handler.receivedCallback.poll().failed(new Exception("test failure"));
Frame frame = receiveFrame(client.getInputStream());
@@ -186,7 +186,7 @@ public class WebSocketCloseTest extends WebSocketTester
@Test
public void clientClose_OCLOSED() throws Exception
{
- setup(State.OCLOSED);
+ setup(State.OSHUT);
server.handler.getCoreSession().demand(1);
client.getOutputStream().write(RawFrameBuilder.buildClose(new CloseStatus(CloseStatus.NORMAL), true));
assertNotNull(server.handler.receivedFrames.poll(10, TimeUnit.SECONDS));
@@ -201,7 +201,7 @@ public class WebSocketCloseTest extends WebSocketTester
@Test
public void clientDifferentClose_OCLOSED() throws Exception
{
- setup(State.OCLOSED);
+ setup(State.OSHUT);
server.handler.getCoreSession().demand(1);
client.getOutputStream().write(RawFrameBuilder.buildClose(new CloseStatus(CloseStatus.BAD_PAYLOAD), true));
assertNotNull(server.handler.receivedFrames.poll(10, TimeUnit.SECONDS));
@@ -218,7 +218,7 @@ public class WebSocketCloseTest extends WebSocketTester
{
try (StacklessLogging stackless = new StacklessLogging(WebSocketChannel.class))
{
- setup(State.OCLOSED);
+ setup(State.OSHUT);
server.handler.getCoreSession().demand(1);
client.getOutputStream().write(RawFrameBuilder.buildClose(new CloseStatus(CloseStatus.NORMAL), true));
assertNotNull(server.handler.receivedFrames.poll(10, TimeUnit.SECONDS));
@@ -246,7 +246,7 @@ public class WebSocketCloseTest extends WebSocketTester
@Test
public void clientSendsBadFrame_OCLOSED() throws Exception
{
- setup(State.OCLOSED);
+ setup(State.OSHUT);
client.getOutputStream().write(RawFrameBuilder.buildFrame(OpCode.PONG, "pong frame not masked", false));
server.handler.getCoreSession().demand(1);
@@ -258,7 +258,7 @@ public class WebSocketCloseTest extends WebSocketTester
@Test
public void clientSendsBadFrame_ICLOSED() throws Exception
{
- setup(State.ICLOSED);
+ setup(State.ISHUT);
client.getOutputStream().write(RawFrameBuilder.buildFrame(OpCode.PONG, "pong frame not masked", false));
assertFalse(server.handler.closed.await(250, TimeUnit.MILLISECONDS));
@@ -286,7 +286,7 @@ public class WebSocketCloseTest extends WebSocketTester
@Test
public void clientAborts_OCLOSED() throws Exception
{
- setup(State.OCLOSED);
+ setup(State.OSHUT);
client.close();
assertFalse(server.handler.closed.await(250, TimeUnit.MILLISECONDS));
@@ -299,7 +299,7 @@ public class WebSocketCloseTest extends WebSocketTester
@Test
public void clientAborts_ICLOSED() throws Exception
{
- setup(State.ICLOSED);
+ setup(State.ISHUT);
client.close();
assertFalse(server.handler.closed.await(250, TimeUnit.MILLISECONDS));
@@ -330,7 +330,7 @@ public class WebSocketCloseTest extends WebSocketTester
@Test
public void onFrameThrows_OCLOSED() throws Exception
{
- setup(State.OCLOSED);
+ setup(State.OSHUT);
client.getOutputStream().write(RawFrameBuilder.buildFrame(OpCode.BINARY, "binary", true));
@@ -478,7 +478,7 @@ public class WebSocketCloseTest extends WebSocketTester
public boolean isOpen()
{
- return handler.getCoreSession().isOpen();
+ return handler.getCoreSession().isOutputOpen();
}
}
}
diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/client/WebSocketClientServerTest.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/client/WebSocketClientServerTest.java
index 4e0ecedf18c..f564272c260 100644
--- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/client/WebSocketClientServerTest.java
+++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/client/WebSocketClientServerTest.java
@@ -18,6 +18,11 @@
package org.eclipse.jetty.websocket.core.client;
+import java.net.URI;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.NetworkConnector;
import org.eclipse.jetty.server.Server;
@@ -45,11 +50,6 @@ import org.hamcrest.Matchers;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
-import java.net.URI;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -208,7 +208,7 @@ public class WebSocketClientServerTest
public boolean isOpen()
{
- return handler.getCoreSession().isOpen();
+ return handler.getCoreSession().isOutputOpen();
}
}
@@ -272,7 +272,7 @@ public class WebSocketClientServerTest
public boolean isOpen()
{
- return handler.getCoreSession().isOpen();
+ return handler.getCoreSession().isOutputOpen();
}
}
diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/extensions/ExtensionStackTest.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/extensions/ExtensionStackTest.java
index a35121e05f2..d5276089157 100644
--- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/extensions/ExtensionStackTest.java
+++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/extensions/ExtensionStackTest.java
@@ -18,6 +18,9 @@
package org.eclipse.jetty.websocket.core.extensions;
+import java.util.ArrayList;
+import java.util.List;
+
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.MappedByteBufferPool;
import org.eclipse.jetty.util.DecoratedObjectFactory;
@@ -35,9 +38,6 @@ import org.eclipse.jetty.websocket.core.internal.IdentityExtension;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
-import java.util.ArrayList;
-import java.util.List;
-
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -80,7 +80,7 @@ public class ExtensionStackTest
// Setup Listeners
IncomingFrames session = new IncomingFramesCapture();
OutgoingFrames connection = new OutgoingFramesCapture();
- stack.connect(session, connection, null);
+ stack.initialize(session, connection, null);
// Dump
LOG.debug("{}", stack.dump());
@@ -104,7 +104,7 @@ public class ExtensionStackTest
// Setup Listeners
IncomingFrames session = new IncomingFramesCapture();
OutgoingFrames connection = new OutgoingFramesCapture();
- stack.connect(session, connection, null);
+ stack.initialize(session, connection, null);
// Dump
LOG.debug("{}", stack.dump());
diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/extensions/ValidationExtensionTest.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/extensions/ValidationExtensionTest.java
index 62c3463a862..901982f5209 100644
--- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/extensions/ValidationExtensionTest.java
+++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/extensions/ValidationExtensionTest.java
@@ -18,6 +18,10 @@
package org.eclipse.jetty.websocket.core.extensions;
+import java.net.Socket;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.TimeUnit;
+
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.NetworkConnector;
import org.eclipse.jetty.server.Server;
@@ -44,10 +48,6 @@ import org.eclipse.jetty.websocket.core.server.WebSocketUpgradeHandler;
import org.eclipse.jetty.websocket.core.server.internal.RFC6455Handshaker;
import org.junit.jupiter.api.Test;
-import java.net.Socket;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.TimeUnit;
-
import static org.eclipse.jetty.util.Callback.NOOP;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
@@ -218,7 +218,7 @@ public class ValidationExtensionTest extends WebSocketTester
public boolean isOpen()
{
- return handler.getCoreSession().isOpen();
+ return handler.getCoreSession().isOutputOpen();
}
}
}
diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/server/WebSocketServerTest.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/server/WebSocketServerTest.java
index 86f8f0c7142..b48d4be1dcf 100644
--- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/server/WebSocketServerTest.java
+++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/core/server/WebSocketServerTest.java
@@ -18,6 +18,12 @@
package org.eclipse.jetty.websocket.core.server;
+import java.net.Socket;
+import java.nio.ByteBuffer;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.NetworkConnector;
@@ -46,12 +52,6 @@ import org.hamcrest.MatcherAssert;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.Test;
-import java.net.Socket;
-import java.nio.ByteBuffer;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicReference;
-
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
@@ -547,7 +547,7 @@ public class WebSocketServerTest extends WebSocketTester
public boolean isOpen()
{
- return handler.getCoreSession().isOpen();
+ return handler.getCoreSession().isOutputOpen();
}
}
}
diff --git a/pom.xml b/pom.xml
index edc3a6f21b3..04978dd7924 100644
--- a/pom.xml
+++ b/pom.xml
@@ -436,7 +436,7 @@
org.apache.maven.plugins
maven-assembly-plugin
- 3.1.0
+ 3.1.1
org.eclipse.jetty.toolchain