From e014ba1775b2394b5bedc9cc5a8f8ec6338516eb Mon Sep 17 00:00:00 2001
From: Joakim Erdfelt
Date: Fri, 28 Oct 2022 19:07:55 -0500
Subject: [PATCH 01/15] limit build history to last 60 builds (#8776) (#8778)
Co-authored-by: Olivier Lamy
---
Jenkinsfile | 1 +
1 file changed, 1 insertion(+)
diff --git a/Jenkinsfile b/Jenkinsfile
index 45673cfa95c..ed20ddc5e3d 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -6,6 +6,7 @@ pipeline {
options {
skipDefaultCheckout()
durabilityHint('PERFORMANCE_OPTIMIZED')
+ buildDiscarder logRotator( numToKeepStr: '60' )
}
stages {
stage("Parallel Stage") {
From 4d0718f11c9030fcc5fd076ad079707378f5c1d6 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Tue, 1 Nov 2022 02:08:16 +0000
Subject: [PATCH 02/15] Bump asm.version from 9.3 to 9.4
Bumps `asm.version` from 9.3 to 9.4.
Updates `asm-commons` from 9.3 to 9.4
Updates `asm` from 9.3 to 9.4
Updates `asm-analysis` from 9.3 to 9.4
Updates `asm-tree` from 9.3 to 9.4
Updates `asm-util` from 9.3 to 9.4
---
updated-dependencies:
- dependency-name: org.ow2.asm:asm-commons
dependency-type: direct:development
update-type: version-update:semver-minor
- dependency-name: org.ow2.asm:asm
dependency-type: direct:development
update-type: version-update:semver-minor
- dependency-name: org.ow2.asm:asm-analysis
dependency-type: direct:development
update-type: version-update:semver-minor
- dependency-name: org.ow2.asm:asm-tree
dependency-type: direct:development
update-type: version-update:semver-minor
- dependency-name: org.ow2.asm:asm-util
dependency-type: direct:development
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot]
---
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pom.xml b/pom.xml
index 312e1bbe76e..1fd8bb2816d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -30,7 +30,7 @@
4.4.15
2.2.3
2.5.6
- 9.3
+ 9.4
4.2.0
6.3.1
1.5
From 82624a8ae55c15be939d5df80f39d6ea90908733 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Tue, 1 Nov 2022 02:13:04 +0000
Subject: [PATCH 03/15] Bump commons-compress from 1.21 to 1.22
Bumps commons-compress from 1.21 to 1.22.
---
updated-dependencies:
- dependency-name: org.apache.commons:commons-compress
dependency-type: direct:production
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot]
---
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pom.xml b/pom.xml
index 312e1bbe76e..faa9b737073 100644
--- a/pom.xml
+++ b/pom.xml
@@ -36,7 +36,7 @@
1.5
10.3.4
1.15
- 1.21
+ 1.22
2.11.0
3.12.0
2.5.2
From 95ce84bd4ac743c12d25be1fc2c655b8c53c4f30 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Tue, 1 Nov 2022 02:15:11 +0000
Subject: [PATCH 04/15] Bump plexus-utils from 3.4.2 to 3.5.0
Bumps [plexus-utils](https://github.com/codehaus-plexus/plexus-utils) from 3.4.2 to 3.5.0.
- [Release notes](https://github.com/codehaus-plexus/plexus-utils/releases)
- [Commits](https://github.com/codehaus-plexus/plexus-utils/compare/plexus-utils-3.4.2...plexus-utils-3.5.0)
---
updated-dependencies:
- dependency-name: org.codehaus.plexus:plexus-utils
dependency-type: direct:development
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot]
---
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pom.xml b/pom.xml
index 312e1bbe76e..fb5dd21c47e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -113,7 +113,7 @@
1.2.0
1.2.0
2.1.1
- 3.4.2
+ 3.5.0
2.0.2
2.1.1.RELEASE
1.2.5
From 59c1cfa3274305d0ec23c98b60fc04b661c1e1d4 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Tue, 1 Nov 2022 12:44:51 -0500
Subject: [PATCH 05/15] Bump logback-core from 1.4.1 to 1.4.4 (#8798)
Bumps [logback-core](https://github.com/qos-ch/logback) from 1.4.1 to 1.4.4.
- [Release notes](https://github.com/qos-ch/logback/releases)
- [Commits](https://github.com/qos-ch/logback/compare/v_1.4.1...v_1.4.4)
---
updated-dependencies:
- dependency-name: ch.qos.logback:logback-core
dependency-type: direct:production
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot]
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pom.xml b/pom.xml
index ef0704cbd2e..afaa7a0ffde 100644
--- a/pom.xml
+++ b/pom.xml
@@ -101,7 +101,7 @@
5.9.1
2.0.2
2.19.0
- 1.4.1
+ 1.4.4
3.0.8
10.3.6
1.8.2
From 86c0d5b3e541989318b3722eec6cef74d9ed8b45 Mon Sep 17 00:00:00 2001
From: Joakim Erdfelt
Date: Tue, 1 Nov 2022 23:55:53 -0500
Subject: [PATCH 06/15] Disable flaky test (#8816)
---
.../java/org/eclipse/jetty/quic/client/End2EndClientTest.java | 2 ++
1 file changed, 2 insertions(+)
diff --git a/jetty-quic/quic-client/src/test/java/org/eclipse/jetty/quic/client/End2EndClientTest.java b/jetty-quic/quic-client/src/test/java/org/eclipse/jetty/quic/client/End2EndClientTest.java
index ca679d04502..f332337df31 100644
--- a/jetty-quic/quic-client/src/test/java/org/eclipse/jetty/quic/client/End2EndClientTest.java
+++ b/jetty-quic/quic-client/src/test/java/org/eclipse/jetty/quic/client/End2EndClientTest.java
@@ -40,6 +40,7 @@ import org.eclipse.jetty.util.component.LifeCycle;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import static org.hamcrest.MatcherAssert.assertThat;
@@ -101,6 +102,7 @@ public class End2EndClientTest
LifeCycle.stop(server);
}
+ @Disabled("Flaky test - see Issue #8815")
@Test
public void testSimpleHTTP1() throws Exception
{
From 55a6cdad9dbd01267049d10771552d9e22584ccd Mon Sep 17 00:00:00 2001
From: Olivier Lamy
Date: Wed, 2 Nov 2022 14:56:13 +1000
Subject: [PATCH 07/15] add back dependabot for 9.4.x branch and force timezone
to try get this done on weekend (#8820)
Signed-off-by: Olivier Lamy
Signed-off-by: Olivier Lamy
---
.github/dependabot.yml | 20 ++++++++++++++++++--
1 file changed, 18 insertions(+), 2 deletions(-)
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index 8ada1181a45..14d9f75dd2d 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -7,7 +7,8 @@ updates:
schedule:
interval: "monthly"
day: "saturday"
- time: "02:00"
+ time: "10:00"
+ timezone: "Australia/Brisbane"
# Associate with milestone 10.0.x
milestone: 6
ignore:
@@ -50,7 +51,8 @@ updates:
schedule:
interval: "monthly"
day: "saturday"
- time: "02:00"
+ time: "10:00"
+ timezone: "Australia/Brisbane"
# Associate with milestone 11.0.x
milestone: 7
ignore:
@@ -95,3 +97,17 @@ updates:
versions: [ ">=5.0.0" ]
- dependency-name: "org.infinispan:*"
versions: [ ">=12" ]
+
+ - package-ecosystem: "maven"
+ directory: "/"
+ open-pull-requests-limit: 30
+ target-branch: "jetty-9.4.x"
+ schedule:
+ interval: "monthly"
+ day: "saturday"
+ time: "10:00"
+ timezone: "Australia/Brisbane"
+ ignore:
+ # Restrict updates in this branch to jetty in the 9.4.x space
+ - dependency-name: "org.infinispan:*"
+ versions: [ ">=12" ]
From 05e5a99352b3d50a846dd17f50cd16ab700aaa67 Mon Sep 17 00:00:00 2001
From: Olivier Lamy
Date: Wed, 2 Nov 2022 16:13:34 +1000
Subject: [PATCH 08/15] jetty 10.0.x use default container (#8813)
* do not switch container and use default one only
---
Jenkinsfile | 64 +++++++++++++++++++++++++----------------------------
1 file changed, 30 insertions(+), 34 deletions(-)
diff --git a/Jenkinsfile b/Jenkinsfile
index ed20ddc5e3d..7c73c0ea06e 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -14,34 +14,32 @@ pipeline {
stage("Build / Test - JDK17") {
agent { node { label 'linux' } }
steps {
- container('jetty-build') {
- timeout( time: 180, unit: 'MINUTES' ) {
- checkout scm
- mavenBuild( "jdk17", "clean install -Perrorprone", "maven3")
- // Collect up the jacoco execution results (only on main build)
- jacoco inclusionPattern: '**/org/eclipse/jetty/**/*.class',
- exclusionPattern: '' +
- // build tools
- '**/org/eclipse/jetty/ant/**' +
- ',*/org/eclipse/jetty/maven/its/**' +
- ',**/org/eclipse/jetty/its/**' +
- // example code / documentation
- ',**/org/eclipse/jetty/embedded/**' +
- ',**/org/eclipse/jetty/asyncrest/**' +
- ',**/org/eclipse/jetty/demo/**' +
- // special environments / late integrations
- ',**/org/eclipse/jetty/gcloud/**' +
- ',**/org/eclipse/jetty/infinispan/**' +
- ',**/org/eclipse/jetty/osgi/**' +
- ',**/org/eclipse/jetty/http/spi/**' +
- // test classes
- ',**/org/eclipse/jetty/tests/**' +
- ',**/org/eclipse/jetty/test/**',
- execPattern: '**/target/jacoco.exec',
- classPattern: '**/target/classes',
- sourcePattern: '**/src/main/java'
- recordIssues id: "jdk17", name: "Static Analysis jdk17", aggregatingResults: true, enabledForFailure: true, tools: [mavenConsole(), java(), checkStyle(), errorProne(), spotBugs()]
- }
+ timeout( time: 180, unit: 'MINUTES' ) {
+ checkout scm
+ mavenBuild( "jdk17", "clean install -Perrorprone", "maven3")
+ // Collect up the jacoco execution results (only on main build)
+ jacoco inclusionPattern: '**/org/eclipse/jetty/**/*.class',
+ exclusionPattern: '' +
+ // build tools
+ '**/org/eclipse/jetty/ant/**' +
+ ',*/org/eclipse/jetty/maven/its/**' +
+ ',**/org/eclipse/jetty/its/**' +
+ // example code / documentation
+ ',**/org/eclipse/jetty/embedded/**' +
+ ',**/org/eclipse/jetty/asyncrest/**' +
+ ',**/org/eclipse/jetty/demo/**' +
+ // special environments / late integrations
+ ',**/org/eclipse/jetty/gcloud/**' +
+ ',**/org/eclipse/jetty/infinispan/**' +
+ ',**/org/eclipse/jetty/osgi/**' +
+ ',**/org/eclipse/jetty/http/spi/**' +
+ // test classes
+ ',**/org/eclipse/jetty/tests/**' +
+ ',**/org/eclipse/jetty/test/**',
+ execPattern: '**/target/jacoco.exec',
+ classPattern: '**/target/classes',
+ sourcePattern: '**/src/main/java'
+ recordIssues id: "jdk17", name: "Static Analysis jdk17", aggregatingResults: true, enabledForFailure: true, tools: [mavenConsole(), java(), checkStyle(), errorProne(), spotBugs()]
}
}
}
@@ -49,12 +47,10 @@ pipeline {
stage("Build / Test - JDK11") {
agent { node { label 'linux' } }
steps {
- container( 'jetty-build' ) {
- timeout( time: 180, unit: 'MINUTES' ) {
- checkout scm
- mavenBuild( "jdk11", "clean install -Dspotbugs.skip=true -Djacoco.skip=true", "maven3")
- recordIssues id: "jdk11", name: "Static Analysis jdk11", aggregatingResults: true, enabledForFailure: true, tools: [mavenConsole(), java(), checkStyle()]
- }
+ timeout( time: 180, unit: 'MINUTES' ) {
+ checkout scm
+ mavenBuild( "jdk11", "clean install -Dspotbugs.skip=true -Djacoco.skip=true", "maven3")
+ recordIssues id: "jdk11", name: "Static Analysis jdk11", aggregatingResults: true, enabledForFailure: true, tools: [mavenConsole(), java(), checkStyle()]
}
}
}
From b37ce63588235ebd8c49777fc315fd582407e147 Mon Sep 17 00:00:00 2001
From: Joakim Erdfelt
Date: Wed, 2 Nov 2022 16:38:50 -0500
Subject: [PATCH 09/15] Issue #8779 - CompactPathRule should not drop query
section from modified URI (#8780)
* Issue #8779 - CompactPathRule should not drop query section from modified URI
Signed-off-by: Joakim Erdfelt
---
.../rewrite/handler/CompactPathRule.java | 4 +-
.../rewrite/handler/CompactPathRuleTest.java | 66 +++++++++++++++++++
2 files changed, 68 insertions(+), 2 deletions(-)
create mode 100644 jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/CompactPathRuleTest.java
diff --git a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/CompactPathRule.java b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/CompactPathRule.java
index 139f34a94f5..6e66f472d61 100644
--- a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/CompactPathRule.java
+++ b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/CompactPathRule.java
@@ -33,9 +33,9 @@ public class CompactPathRule extends Rule implements Rule.ApplyURI
}
@Override
- public void applyURI(Request request, String oldURI, String newURI) throws IOException
+ public void applyURI(Request request, String oldURI, String newURI)
{
- String uri = request.getRequestURI();
+ String uri = request.getHttpURI().getPathQuery();
if (uri.startsWith("/"))
uri = URIUtil.compactPath(uri);
request.setHttpURI(HttpURI.build(request.getHttpURI(), uri));
diff --git a/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/CompactPathRuleTest.java b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/CompactPathRuleTest.java
new file mode 100644
index 00000000000..05622693a15
--- /dev/null
+++ b/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/CompactPathRuleTest.java
@@ -0,0 +1,66 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
+//
+// This program and the accompanying materials are made available under the
+// terms of the Eclipse Public License v. 2.0 which is available at
+// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
+// which is available at https://www.apache.org/licenses/LICENSE-2.0.
+//
+// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
+// ========================================================================
+//
+
+package org.eclipse.jetty.rewrite.handler;
+
+import java.util.stream.Stream;
+
+import org.eclipse.jetty.http.HttpURI;
+import org.eclipse.jetty.util.URIUtil;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class CompactPathRuleTest extends AbstractRuleTestCase
+{
+ public static Stream scenarios()
+ {
+ return Stream.of(
+ // shouldn't change anything
+ Arguments.of("/foo", null, "/foo", null, "/foo"),
+ Arguments.of("/", null, "/", null, "/"),
+ // simple compact path
+ Arguments.of("////foo", null, "/foo", null, "/foo"),
+ // with simple query
+ Arguments.of("//foo//bar", "a=b", "/foo/bar", "a=b", "/foo/bar?a=b"),
+ // with query that has double slashes (should preserve slashes in query)
+ Arguments.of("//foo//bar", "a=b//c", "/foo/bar", "a=b//c", "/foo/bar?a=b//c")
+ );
+ }
+
+ @ParameterizedTest
+ @MethodSource("scenarios")
+ public void testCompactPathRule(String inputPath, String inputQuery, String expectedPath, String expectedQuery, String expectedPathQuery) throws Exception
+ {
+ start(false);
+
+ CompactPathRule rule = new CompactPathRule();
+
+ reset();
+ _request.setHttpURI(HttpURI.build(_request.getHttpURI(), inputPath, null, inputQuery).asImmutable());
+
+ String target = _request.getHttpURI().getDecodedPath();
+
+ String applied = rule.matchAndApply(target, _request, _response);
+ assertEquals(expectedPath, applied);
+
+ String encoded = URIUtil.encodePath(applied);
+ rule.applyURI(_request, _request.getRequestURI(), encoded);
+
+ assertEquals(expectedPath, _request.getRequestURI());
+ assertEquals(expectedQuery, _request.getQueryString());
+ assertEquals(expectedPathQuery, _request.getHttpURI().getPathQuery());
+ }
+}
From bff5b3eb8f5547afd8883029555dd46d06ed7a77 Mon Sep 17 00:00:00 2001
From: Simone Bordet
Date: Thu, 3 Nov 2022 21:56:38 +0100
Subject: [PATCH 10/15] Code cleanup.
Signed-off-by: Simone Bordet
---
.../org/eclipse/jetty/http2/HTTP2Session.java | 37 ++++++++++---------
1 file changed, 19 insertions(+), 18 deletions(-)
diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Session.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Session.java
index b2da4a0f9ef..f4b0b78cf10 100644
--- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Session.java
+++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Session.java
@@ -1501,14 +1501,15 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio
/**
* The HTTP/2 specification requires that stream ids are monotonically increasing,
- * see https://tools.ietf.org/html/rfc7540#section-5.1.1.
+ * see RFC 7540, 5.1.1.
* This implementation uses a queue to atomically reserve a stream id and claim
* a slot in the queue; the slot is then assigned the entries to write.
* Concurrent threads push slots in the queue but only one thread flushes
* the slots, up to the slot that has a non-null entries to write, therefore
* guaranteeing that frames are sent strictly in their stream id order.
* This class also coordinates the creation of streams with the close of
- * the session, see https://tools.ietf.org/html/rfc7540#section-6.8.
+ * the session, see
+ * RFC 7540, 6.8.
*/
private class StreamsState
{
@@ -1527,7 +1528,7 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio
private CloseState getCloseState()
{
- try (AutoLock l = lock.lock())
+ try (AutoLock ignored = lock.lock())
{
return closed;
}
@@ -1536,7 +1537,7 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio
private CompletableFuture shutdown()
{
CompletableFuture future;
- try (AutoLock l = lock.lock())
+ try (AutoLock ignored = lock.lock())
{
if (shutdownCallback != null)
return shutdownCallback;
@@ -1550,7 +1551,7 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio
{
boolean sendGoAway = false;
boolean tryRunZeroStreamsAction = false;
- try (AutoLock l = lock.lock())
+ try (AutoLock ignored = lock.lock())
{
switch (closed)
{
@@ -1661,7 +1662,7 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio
LOG.debug("Halting ({}) for {}", reason, HTTP2Session.this);
GoAwayFrame goAwayFrame = null;
GoAwayFrame goAwayFrameEvent;
- try (AutoLock l = lock.lock())
+ try (AutoLock ignored = lock.lock())
{
switch (closed)
{
@@ -1696,7 +1697,7 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio
{
boolean failStreams = false;
boolean tryRunZeroStreamsAction = false;
- try (AutoLock l = lock.lock())
+ try (AutoLock ignored = lock.lock())
{
switch (closed)
{
@@ -1806,7 +1807,7 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio
String reason = "input_shutdown";
Throwable cause = null;
boolean failStreams = false;
- try (AutoLock l = lock.lock())
+ try (AutoLock ignored = lock.lock())
{
switch (closed)
{
@@ -1866,7 +1867,7 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio
boolean sendGoAway = false;
GoAwayFrame goAwayFrame = null;
Throwable cause = null;
- try (AutoLock l = lock.lock())
+ try (AutoLock ignored = lock.lock())
{
switch (closed)
{
@@ -1933,7 +1934,7 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio
{
GoAwayFrame goAwayFrame;
Throwable cause;
- try (AutoLock l = lock.lock())
+ try (AutoLock ignored = lock.lock())
{
switch (closed)
{
@@ -1970,7 +1971,7 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio
private void onWriteFailure(Throwable x)
{
String reason = "write_failure";
- try (AutoLock l = lock.lock())
+ try (AutoLock ignored = lock.lock())
{
switch (closed)
{
@@ -2028,7 +2029,7 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio
// but only one moves to CLOSED and runs the action.
Runnable action = null;
CompletableFuture future;
- try (AutoLock l = lock.lock())
+ try (AutoLock ignored = lock.lock())
{
long count = streamCount.get();
if (count > 0)
@@ -2133,7 +2134,7 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio
private Stream newUpgradeStream(HeadersFrame frame, Stream.Listener listener, Consumer failFn)
{
int streamId;
- try (AutoLock l = lock.lock())
+ try (AutoLock ignored = lock.lock())
{
streamId = localStreamIds.getAndAdd(2);
HTTP2Session.this.onStreamCreated(streamId);
@@ -2153,7 +2154,7 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio
private boolean newRemoteStream(int streamId)
{
- try (AutoLock l = lock.lock())
+ try (AutoLock ignored = lock.lock())
{
switch (closed)
{
@@ -2237,7 +2238,7 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio
private int reserveSlot(Slot slot, int streamId, Consumer fail)
{
Throwable failure = null;
- try (AutoLock l = lock.lock())
+ try (AutoLock ignored = lock.lock())
{
if (closed == CloseState.NOT_CLOSED)
{
@@ -2263,7 +2264,7 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio
private void freeSlot(Slot slot, int streamId)
{
- try (AutoLock l = lock.lock())
+ try (AutoLock ignored = lock.lock())
{
slots.remove(slot);
}
@@ -2292,7 +2293,7 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio
while (true)
{
List entries;
- try (AutoLock l = lock.lock())
+ try (AutoLock ignored = lock.lock())
{
if (flushing == null)
flushing = thread;
@@ -2320,7 +2321,7 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio
@Override
public String toString()
{
- try (AutoLock l = lock.lock())
+ try (AutoLock ignored = lock.lock())
{
return String.format("state=[streams=%d,%s,goAwayRecv=%s,goAwaySent=%s,failure=%s]",
streamCount.get(),
From 2243ee5f3b634a9d20b429d15c2dfa65df0e27ee Mon Sep 17 00:00:00 2001
From: Joakim Erdfelt
Date: Fri, 4 Nov 2022 14:06:12 -0500
Subject: [PATCH 11/15] Jetty 10 - Flag flaky tests to be skipped on CI (#8865)
* @Tag("flaky") use instead of @Disabled
* Tweaking timeouts on some tests
* Tweaking timeouts on some tests
Signed-off-by: Joakim Erdfelt
Co-authored-by: Simone Bordet
---
Jenkinsfile | 2 +-
.../eclipse/jetty/quic/client/End2EndClientTest.java | 5 +++--
.../eclipse/jetty/servlets/CloseableDoSFilterTest.java | 10 ++++++++++
.../jetty/tests/distribution/DemoModulesTests.java | 4 ++--
.../jetty/tests/distribution/DistributionTests.java | 9 ++++-----
5 files changed, 20 insertions(+), 10 deletions(-)
diff --git a/Jenkinsfile b/Jenkinsfile
index 7c73c0ea06e..be8b462095f 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -106,7 +106,7 @@ def mavenBuild(jdk, cmdline, mvnName) {
"MAVEN_OPTS=-Xms2g -Xmx4g -Djava.awt.headless=true"]) {
configFileProvider(
[configFile(fileId: 'oss-settings.xml', variable: 'GLOBAL_MVN_SETTINGS')]) {
- sh "mvn --no-transfer-progress -s $GLOBAL_MVN_SETTINGS -Dmaven.repo.local=.repository -Pci -DexcludedGroups=\"external, large-disk-resource, stress, slow\" -V -B -e -Djetty.testtracker.log=true $cmdline"
+ sh "mvn --no-transfer-progress -s $GLOBAL_MVN_SETTINGS -Dmaven.repo.local=.repository -Pci -DexcludedGroups=\"external, large-disk-resource, stress, slow, flaky\" -V -B -e -Djetty.testtracker.log=true $cmdline"
}
}
}
diff --git a/jetty-quic/quic-client/src/test/java/org/eclipse/jetty/quic/client/End2EndClientTest.java b/jetty-quic/quic-client/src/test/java/org/eclipse/jetty/quic/client/End2EndClientTest.java
index f332337df31..1fffef7c044 100644
--- a/jetty-quic/quic-client/src/test/java/org/eclipse/jetty/quic/client/End2EndClientTest.java
+++ b/jetty-quic/quic-client/src/test/java/org/eclipse/jetty/quic/client/End2EndClientTest.java
@@ -40,7 +40,7 @@ import org.eclipse.jetty.util.component.LifeCycle;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import static org.hamcrest.MatcherAssert.assertThat;
@@ -102,8 +102,8 @@ public class End2EndClientTest
LifeCycle.stop(server);
}
- @Disabled("Flaky test - see Issue #8815")
@Test
+ @Tag("flaky") // Issue #8815
public void testSimpleHTTP1() throws Exception
{
ContentResponse response = client.newRequest("https://localhost:" + connector.getLocalPort())
@@ -141,6 +141,7 @@ public class End2EndClientTest
}
@Test
+ @Tag("flaky") // Issue #8815
public void testMultiThreadedHTTP1()
{
int count = 1000;
diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/CloseableDoSFilterTest.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/CloseableDoSFilterTest.java
index a162129e089..2406544c2da 100644
--- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/CloseableDoSFilterTest.java
+++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/CloseableDoSFilterTest.java
@@ -16,6 +16,8 @@ package org.eclipse.jetty.servlets;
import org.eclipse.jetty.toolchain.test.jupiter.WorkDir;
import org.eclipse.jetty.toolchain.test.jupiter.WorkDirExtension;
import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@ExtendWith(WorkDirExtension.class)
@@ -28,4 +30,12 @@ public class CloseableDoSFilterTest extends AbstractDoSFilterTest
{
startServer(workDir, CloseableDoSFilter.class);
}
+
+ @Override
+ @Test
+ @Tag("flaky")
+ public void testUnavailableIP() throws Exception
+ {
+ super.testUnavailableIP();
+ }
}
diff --git a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DemoModulesTests.java b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DemoModulesTests.java
index 09c977c42bb..cd0bdf0f54e 100644
--- a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DemoModulesTests.java
+++ b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DemoModulesTests.java
@@ -251,7 +251,7 @@ public class DemoModulesTests extends AbstractJettyHomeTest
try (JettyHomeTester.Run runConfig = distribution.start(argsConfig))
{
- assertTrue(runConfig.awaitFor(5, TimeUnit.SECONDS));
+ assertTrue(runConfig.awaitFor(20, TimeUnit.SECONDS));
assertEquals(0, runConfig.getExitValue());
int httpPort = distribution.freePort();
@@ -264,7 +264,7 @@ public class DemoModulesTests extends AbstractJettyHomeTest
};
try (JettyHomeTester.Run runStart = distribution.start(argsStart))
{
- assertTrue(runStart.awaitConsoleLogsFor("Started Server@", 10, TimeUnit.SECONDS));
+ assertTrue(runStart.awaitConsoleLogsFor("Started Server@", 20, TimeUnit.SECONDS));
startHttpClient();
ContentResponse helloResponse = client.GET("http://localhost:" + httpPort + "/test/hello");
diff --git a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DistributionTests.java b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DistributionTests.java
index 470685a7439..962a3949a27 100644
--- a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DistributionTests.java
+++ b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DistributionTests.java
@@ -43,7 +43,6 @@ import org.eclipse.jetty.http3.client.http.HttpClientTransportOverHTTP3;
import org.eclipse.jetty.io.ClientConnector;
import org.eclipse.jetty.start.FS;
import org.eclipse.jetty.tests.distribution.openid.OpenIdProvider;
-import org.eclipse.jetty.toolchain.test.PathAssert;
import org.eclipse.jetty.unixsocket.client.HttpClientTransportOverUnixSockets;
import org.eclipse.jetty.unixsocket.server.UnixSocketConnector;
import org.eclipse.jetty.util.BlockingArrayQueue;
@@ -1001,15 +1000,15 @@ public class DistributionTests extends AbstractJettyHomeTest
try (JettyHomeTester.Run run1 = distribution.start("--add-module=https,test-keystore,ssl-ini"))
{
- assertTrue(run1.awaitFor(5, TimeUnit.SECONDS));
+ assertTrue(run1.awaitFor(20, TimeUnit.SECONDS));
assertEquals(0, run1.getExitValue());
// Override the property on the command line with the correct password.
try (JettyHomeTester.Run run2 = distribution.start(pathProperty + "=cmdline"))
{
- assertTrue(run2.awaitConsoleLogsFor("Started Server@", 5, TimeUnit.SECONDS));
- PathAssert.assertFileExists("${jetty.base}/cmdline", jettyBase.resolve("cmdline"));
- PathAssert.assertNotPathExists("${jetty.base}/modbased", jettyBase.resolve("modbased"));
+ assertTrue(run2.awaitConsoleLogsFor("Started Server@", 20, TimeUnit.SECONDS));
+ assertTrue(Files.exists(jettyBase.resolve("cmdline")));
+ assertFalse(Files.exists(jettyBase.resolve("modbased")));
}
}
}
From f83b631763e44ee09aae04e96a182c050a79d284 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Fri, 4 Nov 2022 19:07:57 +0000
Subject: [PATCH 12/15] Bump testcontainers-bom from 1.17.4 to 1.17.5
Bumps [testcontainers-bom](https://github.com/testcontainers/testcontainers-java) from 1.17.4 to 1.17.5.
- [Release notes](https://github.com/testcontainers/testcontainers-java/releases)
- [Changelog](https://github.com/testcontainers/testcontainers-java/blob/main/CHANGELOG.md)
- [Commits](https://github.com/testcontainers/testcontainers-java/compare/1.17.4...1.17.5)
---
updated-dependencies:
- dependency-name: org.testcontainers:testcontainers-bom
dependency-type: direct:production
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot]
---
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pom.xml b/pom.xml
index afaa7a0ffde..ed087ee4655 100644
--- a/pom.xml
+++ b/pom.xml
@@ -118,7 +118,7 @@
2.1.1.RELEASE
1.2.5
1.2.5
- 1.17.4
+ 1.17.5
3.1.9.Final
1.6.0.Final
2.0.0.Final
From 07a1d9041cf970b0d230672e1873b390879e34fe Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Fri, 4 Nov 2022 15:39:15 -0500
Subject: [PATCH 13/15] Bump maven-shade-plugin from 3.4.0 to 3.4.1 (#8795)
Bumps [maven-shade-plugin](https://github.com/apache/maven-shade-plugin) from 3.4.0 to 3.4.1.
- [Release notes](https://github.com/apache/maven-shade-plugin/releases)
- [Commits](https://github.com/apache/maven-shade-plugin/compare/maven-shade-plugin-3.4.0...maven-shade-plugin-3.4.1)
---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-shade-plugin
dependency-type: direct:production
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot]
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pom.xml b/pom.xml
index afaa7a0ffde..51ce7fe1f71 100644
--- a/pom.xml
+++ b/pom.xml
@@ -154,7 +154,7 @@
2.5.3
3.0.0
3.3.0
- 3.4.0
+ 3.4.1
3.0.0-M5
3.2.1
3.3.2
From 031af1f2eca6823461768b75f49cda7ef7daa804 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Fri, 4 Nov 2022 20:42:12 +0000
Subject: [PATCH 14/15] Bump jboss-logmanager from 2.1.18.Final to 2.1.19.Final
Bumps jboss-logmanager from 2.1.18.Final to 2.1.19.Final.
---
updated-dependencies:
- dependency-name: org.jboss.logmanager:jboss-logmanager
dependency-type: direct:production
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot]
---
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pom.xml b/pom.xml
index 582169cf5ea..4177b2a5f33 100644
--- a/pom.xml
+++ b/pom.xml
@@ -79,7 +79,7 @@
2.2.1.Final
2.2.1.Final
3.5.0.Final
- 2.1.18.Final
+ 2.1.19.Final
3.5.0.Final
1.1
1.0.7
From cd737489f9e82fd9f3cefa003ab09668e8b5d19c Mon Sep 17 00:00:00 2001
From: Simone Bordet
Date: Thu, 3 Nov 2022 22:02:26 +0100
Subject: [PATCH 15/15] Fixes #8811 - HTTP/2 session shutdown race may cause
Server.stop() to block until stop timeout.
Now a completed future is returned from shutdown() if the session is already closed.
Moved the notification of the CompletableFuture to terminate(), which is always invoked.
Signed-off-by: Simone Bordet
---
.../http2/client/GracefulShutdownTest.java | 230 ++++++++++++++++++
.../org/eclipse/jetty/http2/HTTP2Session.java | 16 +-
2 files changed, 241 insertions(+), 5 deletions(-)
create mode 100644 jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/GracefulShutdownTest.java
diff --git a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/GracefulShutdownTest.java b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/GracefulShutdownTest.java
new file mode 100644
index 00000000000..5fd1c1c4b48
--- /dev/null
+++ b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/GracefulShutdownTest.java
@@ -0,0 +1,230 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
+//
+// This program and the accompanying materials are made available under the
+// terms of the Eclipse Public License v. 2.0 which is available at
+// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
+// which is available at https://www.apache.org/licenses/LICENSE-2.0.
+//
+// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
+// ========================================================================
+//
+
+package org.eclipse.jetty.http2.client;
+
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.eclipse.jetty.http.HttpFields;
+import org.eclipse.jetty.http.HttpMethod;
+import org.eclipse.jetty.http.HttpStatus;
+import org.eclipse.jetty.http.HttpVersion;
+import org.eclipse.jetty.http.MetaData;
+import org.eclipse.jetty.http2.HTTP2Session;
+import org.eclipse.jetty.http2.api.Session;
+import org.eclipse.jetty.http2.api.Stream;
+import org.eclipse.jetty.http2.api.server.ServerSessionListener;
+import org.eclipse.jetty.http2.frames.DataFrame;
+import org.eclipse.jetty.http2.frames.GoAwayFrame;
+import org.eclipse.jetty.http2.frames.HeadersFrame;
+import org.eclipse.jetty.util.BufferUtil;
+import org.eclipse.jetty.util.Callback;
+import org.eclipse.jetty.util.Promise;
+import org.eclipse.jetty.util.component.Graceful;
+import org.eclipse.jetty.util.component.LifeCycle;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class GracefulShutdownTest extends AbstractTest
+{
+ @Test
+ public void testGracefulShutdownWhileIdle() throws Exception
+ {
+ start(new ServerSessionListener.Adapter()
+ {
+ @Override
+ public Stream.Listener onNewStream(Stream stream, HeadersFrame frame)
+ {
+ MetaData.Response response = new MetaData.Response(HttpVersion.HTTP_2, HttpStatus.OK_200, HttpFields.EMPTY);
+ stream.headers(new HeadersFrame(stream.getId(), response, null, true), Callback.NOOP);
+ return null;
+ }
+ });
+
+ CountDownLatch clientRequestLatch = new CountDownLatch(1);
+ CountDownLatch clientGoAwayLatch = new CountDownLatch(2);
+ CountDownLatch clientCloseLatch = new CountDownLatch(1);
+ Session clientSession = newClient(new Session.Listener.Adapter()
+ {
+ @Override
+ public void onGoAway(Session session, GoAwayFrame frame)
+ {
+ // One graceful GOAWAY and one normal GOAWAY.
+ clientGoAwayLatch.countDown();
+ }
+
+ @Override
+ public void onClose(Session session, GoAwayFrame frame)
+ {
+ clientCloseLatch.countDown();
+ }
+ });
+ MetaData.Request request = newRequest(HttpMethod.GET.asString(), HttpFields.EMPTY);
+ clientSession.newStream(new HeadersFrame(request, null, true), new Stream.Listener.Adapter()
+ {
+ @Override
+ public void onHeaders(Stream stream, HeadersFrame frame)
+ {
+ MetaData.Response response = (MetaData.Response)frame.getMetaData();
+ if (frame.isEndStream() && response.getStatus() == HttpStatus.OK_200)
+ clientRequestLatch.countDown();
+ }
+ });
+
+ assertTrue(clientRequestLatch.await(5, TimeUnit.SECONDS));
+
+ // Initiate graceful shutdown on server side.
+ CompletableFuture completable = Graceful.shutdown(connector);
+
+ assertTrue(clientGoAwayLatch.await(5, TimeUnit.SECONDS));
+ assertTrue(clientCloseLatch.await(5, TimeUnit.SECONDS));
+ assertNull(completable.get(5, TimeUnit.SECONDS));
+ }
+
+ @Test
+ public void testGracefulShutdownWithPendingStream() throws Exception
+ {
+ CountDownLatch serverLatch = new CountDownLatch(1);
+ start(new ServerSessionListener.Adapter()
+ {
+ @Override
+ public Stream.Listener onNewStream(Stream stream, HeadersFrame frame)
+ {
+ return new Stream.Listener.Adapter()
+ {
+ @Override
+ public void onData(Stream stream, DataFrame frame, Callback callback)
+ {
+ if (frame.isEndStream())
+ {
+ MetaData.Response response = new MetaData.Response(HttpVersion.HTTP_2, HttpStatus.OK_200, HttpFields.EMPTY);
+ stream.headers(new HeadersFrame(stream.getId(), response, null, true), callback);
+ }
+ else
+ {
+ serverLatch.countDown();
+ callback.succeeded();
+ }
+ }
+ };
+ }
+ });
+
+ CountDownLatch clientRequestLatch = new CountDownLatch(1);
+ CountDownLatch clientGoAwayLatch = new CountDownLatch(2);
+ CountDownLatch clientCloseLatch = new CountDownLatch(1);
+ Session clientSession = newClient(new Session.Listener.Adapter()
+ {
+ @Override
+ public void onGoAway(Session session, GoAwayFrame frame)
+ {
+ // One graceful GOAWAY and one normal GOAWAY.
+ clientGoAwayLatch.countDown();
+ }
+
+ @Override
+ public void onClose(Session session, GoAwayFrame frame)
+ {
+ clientCloseLatch.countDown();
+ }
+ });
+ MetaData.Request request = newRequest(HttpMethod.GET.asString(), HttpFields.EMPTY);
+ Stream stream = clientSession.newStream(new HeadersFrame(request, null, false), new Stream.Listener.Adapter()
+ {
+ @Override
+ public void onHeaders(Stream stream, HeadersFrame frame)
+ {
+ MetaData.Response response = (MetaData.Response)frame.getMetaData();
+ if (frame.isEndStream() && response.getStatus() == HttpStatus.OK_200)
+ clientRequestLatch.countDown();
+ }
+ }).get(5, TimeUnit.SECONDS);
+ stream.data(new DataFrame(stream.getId(), BufferUtil.toBuffer("hello"), false));
+ // Make sure the server has seen the stream.
+ assertTrue(serverLatch.await(5, TimeUnit.SECONDS));
+
+ // Initiate graceful shutdown on server side.
+ CompletableFuture completable = Graceful.shutdown(connector);
+
+ // Make sure the completable is not completed yet, waiting for the stream.
+ Thread.sleep(1000);
+ assertFalse(completable.isDone());
+
+ // Complete the stream.
+ stream.data(new DataFrame(stream.getId(), BufferUtil.toBuffer("world"), true));
+
+ assertTrue(clientGoAwayLatch.await(5, TimeUnit.SECONDS));
+ assertTrue(clientCloseLatch.await(5, TimeUnit.SECONDS));
+ assertNull(completable.get(5, TimeUnit.SECONDS));
+ }
+
+ @Test
+ public void testGracefulShutdownAfterSessionAlreadyClosed() throws Exception
+ {
+ CountDownLatch serverCloseLatch = new CountDownLatch(1);
+ AtomicReference serverSessionRef = new AtomicReference<>();
+ start(new ServerSessionListener.Adapter()
+ {
+ @Override
+ public Stream.Listener onNewStream(Stream stream, HeadersFrame frame)
+ {
+ serverSessionRef.set(stream.getSession());
+ MetaData.Response response = new MetaData.Response(HttpVersion.HTTP_2, HttpStatus.OK_200, HttpFields.EMPTY);
+ stream.headers(new HeadersFrame(stream.getId(), response, null, true), Callback.NOOP);
+ return null;
+ }
+
+ @Override
+ public void onClose(Session session, GoAwayFrame frame)
+ {
+ serverCloseLatch.countDown();
+ }
+ });
+
+ CountDownLatch clientRequestLatch = new CountDownLatch(1);
+ Session clientSession = newClient(new Session.Listener.Adapter());
+ MetaData.Request request = newRequest(HttpMethod.GET.asString(), HttpFields.EMPTY);
+ clientSession.newStream(new HeadersFrame(request, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
+ {
+ @Override
+ public void onHeaders(Stream stream, HeadersFrame frame)
+ {
+ MetaData.Response response = (MetaData.Response)frame.getMetaData();
+ if (frame.isEndStream() && response.getStatus() == HttpStatus.OK_200)
+ clientRequestLatch.countDown();
+ }
+ });
+
+ assertTrue(clientRequestLatch.await(5, TimeUnit.SECONDS));
+
+ LifeCycle.stop(clientSession);
+
+ assertTrue(serverCloseLatch.await(5, TimeUnit.SECONDS));
+
+ HTTP2Session serverSession = (HTTP2Session)serverSessionRef.get();
+ assertNotNull(serverSession);
+
+ // Simulate a race condition where session.shutdown()
+ // is called after the session is closed.
+ CompletableFuture completable = serverSession.shutdown();
+ // Verify that it is completed.
+ assertTrue(completable.isDone());
+ }
+}
diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Session.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Session.java
index f4b0b78cf10..3860aa99f19 100644
--- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Session.java
+++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Session.java
@@ -1541,6 +1541,8 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio
{
if (shutdownCallback != null)
return shutdownCallback;
+ if (closed == CloseState.CLOSED)
+ return CompletableFuture.completedFuture(null);
shutdownCallback = future = new Callback.Completable();
}
goAway(GoAwayFrame.GRACEFUL, Callback.NOOP);
@@ -2028,7 +2030,6 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio
// such as onGoAway() may be in a race to finish,
// but only one moves to CLOSED and runs the action.
Runnable action = null;
- CompletableFuture future;
try (AutoLock ignored = lock.lock())
{
long count = streamCount.get();
@@ -2039,8 +2040,6 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio
return;
}
- future = shutdownCallback;
-
switch (closed)
{
case LOCALLY_CLOSED:
@@ -2080,14 +2079,21 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio
LOG.debug("Executing zero streams action on {}", HTTP2Session.this);
action.run();
}
- if (future != null)
- future.complete(null);
}
private void terminate(GoAwayFrame frame)
{
if (LOG.isDebugEnabled())
LOG.debug("Terminating {}", HTTP2Session.this);
+
+ CompletableFuture completable;
+ try (AutoLock ignored = lock.lock())
+ {
+ completable = shutdownCallback;
+ }
+ if (completable != null)
+ completable.complete(null);
+
HTTP2Session.this.terminate(failure);
notifyClose(HTTP2Session.this, frame, Callback.NOOP);
}