diff --git a/jetty-core/jetty-websocket/jetty-websocket-core-client/src/main/java/org/eclipse/jetty/websocket/core/client/CoreClientUpgradeRequest.java b/jetty-core/jetty-websocket/jetty-websocket-core-client/src/main/java/org/eclipse/jetty/websocket/core/client/CoreClientUpgradeRequest.java index 251c91b7fa1..914f6945b47 100644 --- a/jetty-core/jetty-websocket/jetty-websocket-core-client/src/main/java/org/eclipse/jetty/websocket/core/client/CoreClientUpgradeRequest.java +++ b/jetty-core/jetty-websocket/jetty-websocket-core-client/src/main/java/org/eclipse/jetty/websocket/core/client/CoreClientUpgradeRequest.java @@ -250,17 +250,6 @@ public abstract class CoreClientUpgradeRequest implements Response.CompleteListe int status = response.getStatus(); String responseLine = status + " " + response.getReason(); - if (!upgraded) - { - // We have failed to upgrade but have received a response, so notify the listener. - Throwable listenerError = notifyUpgradeListeners((listener) -> listener.onHandshakeResponse(request, response)); - if (listenerError != null) - { - if (LOG.isDebugEnabled()) - LOG.debug("error from listener", listenerError); - } - } - if (result.isFailed()) { if (LOG.isDebugEnabled()) @@ -281,6 +270,17 @@ public abstract class CoreClientUpgradeRequest implements Response.CompleteListe return; } + if (!upgraded) + { + // We have failed to upgrade but have received a response, so notify the listener. + Throwable listenerError = notifyUpgradeListeners((listener) -> listener.onHandshakeResponse(request, response)); + if (listenerError != null) + { + if (LOG.isDebugEnabled()) + LOG.debug("error from listener", listenerError); + } + } + if (status != HttpStatus.SWITCHING_PROTOCOLS_101) { // Failed to upgrade (other reason) diff --git a/jetty-core/jetty-websocket/jetty-websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/ClientResponseTest.java b/jetty-core/jetty-websocket/jetty-websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/ClientResponseTest.java index ee6d4112ab6..2020b13caa4 100644 --- a/jetty-core/jetty-websocket/jetty-websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/ClientResponseTest.java +++ b/jetty-core/jetty-websocket/jetty-websocket-jetty-tests/src/test/java/org/eclipse/jetty/websocket/tests/client/ClientResponseTest.java @@ -13,6 +13,7 @@ package org.eclipse.jetty.websocket.tests.client; +import java.io.EOFException; import java.net.URI; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; @@ -22,6 +23,7 @@ import org.eclipse.jetty.client.Request; import org.eclipse.jetty.client.Response; import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.io.Content; +import org.eclipse.jetty.io.EofException; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.server.handler.ContextHandler; @@ -120,4 +122,44 @@ public class ClientResponseTest assertThat(response.getHeaders().get("specialHeader"), equalTo("value123")); assertThat(content, equalTo("failed by test")); } + + @Test + public void testServerAbort() throws Exception + { + before((req, resp, cb) -> + { + req.getConnectionMetaData().getConnection().getEndPoint().close(); + cb.failed(new EofException()); + return null; + }); + + EchoSocket clientEndpoint = new EchoSocket(); + URI uri = URI.create("ws://localhost:" + _connector.getLocalPort()); + ClientUpgradeRequest upgradeRequest = new ClientUpgradeRequest(); + + CompletableFuture onHandShakeRequest = new CompletableFuture<>(); + CompletableFuture onHandShakeResponse = new CompletableFuture<>(); + JettyUpgradeListener upgradeListener = new JettyUpgradeListener() + { + @Override + public void onHandshakeRequest(Request request) + { + onHandShakeRequest.complete(null); + } + + @Override + public void onHandshakeResponse(Request request, Response response) + { + onHandShakeResponse.complete(null); + } + }; + + Throwable t = assertThrows(Throwable.class, () -> + _client.connect(clientEndpoint, uri, upgradeRequest, upgradeListener).get(5, TimeUnit.SECONDS)); + assertThat(t, instanceOf(ExecutionException.class)); + assertThat(t.getCause(), instanceOf(EOFException.class)); + + assertDoesNotThrow(() -> onHandShakeRequest.get(5, TimeUnit.SECONDS)); + assertThrows(Throwable.class, () -> onHandShakeResponse.get(1, TimeUnit.SECONDS)); + } }