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); }