From 6143e4358f621c76ff6393656aa7626680907b3e Mon Sep 17 00:00:00 2001 From: Lachlan Roberts Date: Wed, 30 Mar 2022 11:02:30 +1100 Subject: [PATCH 01/17] do not expect section ack for zero required insert count Signed-off-by: Lachlan Roberts --- .../java/org/eclipse/jetty/http3/qpack/QpackDecoder.java | 9 ++++++--- .../java/org/eclipse/jetty/http3/qpack/QpackEncoder.java | 8 ++++++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/jetty-http3/http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/QpackDecoder.java b/jetty-http3/http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/QpackDecoder.java index 4129979ca68..5beff005e92 100644 --- a/jetty-http3/http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/QpackDecoder.java +++ b/jetty-http3/http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/QpackDecoder.java @@ -166,7 +166,8 @@ public class QpackDecoder implements Dumpable if (LOG.isDebugEnabled()) LOG.debug("Decoded: streamId={}, metadata={}", streamId, metaData); _metaDataNotifications.add(new MetaDataNotification(streamId, metaData, handler)); - _instructions.add(new SectionAcknowledgmentInstruction(streamId)); + if (requiredInsertCount > 0) + _instructions.add(new SectionAcknowledgmentInstruction(streamId)); } else { @@ -236,7 +237,8 @@ public class QpackDecoder implements Dumpable int insertCount = _context.getDynamicTable().getInsertCount(); for (EncodedFieldSection encodedFieldSection : _encodedFieldSections) { - if (encodedFieldSection.getRequiredInsertCount() <= insertCount) + int requiredInsertCount = encodedFieldSection.getRequiredInsertCount(); + if (requiredInsertCount <= insertCount) { long streamId = encodedFieldSection.getStreamId(); MetaData metaData = encodedFieldSection.decode(_context, _maxHeaderSize); @@ -244,7 +246,8 @@ public class QpackDecoder implements Dumpable LOG.debug("Decoded: streamId={}, metadata={}", streamId, metaData); _metaDataNotifications.add(new MetaDataNotification(streamId, metaData, encodedFieldSection.getHandler())); - _instructions.add(new SectionAcknowledgmentInstruction(streamId)); + if (requiredInsertCount > 0) + _instructions.add(new SectionAcknowledgmentInstruction(streamId)); } } } diff --git a/jetty-http3/http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/QpackEncoder.java b/jetty-http3/http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/QpackEncoder.java index 7105b5257bf..e96ba17767f 100644 --- a/jetty-http3/http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/QpackEncoder.java +++ b/jetty-http3/http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/QpackEncoder.java @@ -193,7 +193,15 @@ public class QpackEncoder implements Dumpable requiredInsertCount = entryRequiredInsertCount; } + // We should not expect section acknowledgements for 0 required insert count. sectionInfo.setRequiredInsertCount(requiredInsertCount); + if (requiredInsertCount == 0) + { + streamInfo.remove(sectionInfo); + if (streamInfo.isEmpty()) + _streamInfoMap.remove(streamId); + } + int base = dynamicTable.getBase(); int encodedInsertCount = encodeInsertCount(requiredInsertCount, dynamicTable.getCapacity()); boolean signBit = base < requiredInsertCount; From 5c760ae5a3970745c7107a73ccdf4b7271da0a5e Mon Sep 17 00:00:00 2001 From: Lachlan Roberts Date: Tue, 12 Apr 2022 14:53:53 +1000 Subject: [PATCH 02/17] Issue #4414 - add option to exclude paths from GzipHandler request inflation. Signed-off-by: Lachlan Roberts --- .../server/handler/gzip/GzipHandler.java | 136 +++++++++++++++++- .../jetty/servlet/GzipHandlerTest.java | 45 ++++++ 2 files changed, 180 insertions(+), 1 deletion(-) diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/gzip/GzipHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/gzip/GzipHandler.java index a65547806b8..65becfe88bd 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/gzip/GzipHandler.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/gzip/GzipHandler.java @@ -168,6 +168,7 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory // non-static, as other GzipHandler instances may have different configurations private final IncludeExclude _methods = new IncludeExclude<>(); private final IncludeExclude _paths = new IncludeExclude<>(PathSpecSet.class); + private final IncludeExclude _inflatePaths = new IncludeExclude<>(PathSpecSet.class); private final IncludeExclude _mimeTypes = new IncludeExclude<>(AsciiLowerCaseSet.class); private HttpField _vary = GzipHttpOutputInterceptor.VARY_ACCEPT_ENCODING; @@ -354,6 +355,41 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory } } + /** + * Adds excluded Path Specs for request filtering on request inflation. + * + *

+ * There are 2 syntaxes supported, Servlet url-pattern based, and + * Regex based. This means that the initial characters on the path spec + * line are very strict, and determine the behavior of the path matching. + *

    + *
  • If the spec starts with '^' the spec is assumed to be + * a regex based path spec and will match with normal Java regex rules.
  • + *
  • If the spec starts with '/' then spec is assumed to be + * a Servlet url-pattern rules path spec for either an exact match + * or prefix based match.
  • + *
  • If the spec starts with '*.' then spec is assumed to be + * a Servlet url-pattern rules path spec for a suffix based match.
  • + *
  • All other syntaxes are unsupported
  • + *
+ *

+ * Note: inclusion takes precedence over exclude. + * + * @param pathspecs Path specs (as per servlet spec) to exclude. If a + * ServletContext is available, the paths are relative to the context path, + * otherwise they are absolute.
+ * For backward compatibility the pathspecs may be comma separated strings, but this + * will not be supported in future versions. + * @see #addIncludedInflationPaths(String...) + */ + public void addExcludedInflationPaths(String... pathspecs) + { + for (String p : pathspecs) + { + _inflatePaths.exclude(StringUtil.csvSplit(p)); + } + } + /** * Adds included HTTP Methods (eg: POST, PATCH, DELETE) for filtering. * @@ -440,6 +476,38 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory } } + /** + * Add included Path Specs for filtering on request inflation. + * + *

+ * There are 2 syntaxes supported, Servlet url-pattern based, and + * Regex based. This means that the initial characters on the path spec + * line are very strict, and determine the behavior of the path matching. + *

    + *
  • If the spec starts with '^' the spec is assumed to be + * a regex based path spec and will match with normal Java regex rules.
  • + *
  • If the spec starts with '/' then spec is assumed to be + * a Servlet url-pattern rules path spec for either an exact match + * or prefix based match.
  • + *
  • If the spec starts with '*.' then spec is assumed to be + * a Servlet url-pattern rules path spec for a suffix based match.
  • + *
  • All other syntaxes are unsupported
  • + *
+ *

+ * Note: inclusion takes precedence over exclusion. + * + * @param pathspecs Path specs (as per servlet spec) to include. If a + * ServletContext is available, the paths are relative to the context path, + * otherwise they are absolute + */ + public void addIncludedInflationPaths(String... pathspecs) + { + for (String p : pathspecs) + { + _inflatePaths.include(StringUtil.csvSplit(p)); + } + } + @Override public DeflaterPool.Entry getDeflaterEntry(Request request, long contentLength) { @@ -495,6 +563,18 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory return excluded.toArray(new String[0]); } + /** + * Get the current filter list of excluded Path Specs for request inflation. + * + * @return the filter list of excluded Path Specs + * @see #getIncludedInflationPaths() + */ + public String[] getExcludedInflationPaths() + { + Set excluded = _inflatePaths.getExcluded(); + return excluded.toArray(new String[0]); + } + /** * Get the current filter list of included HTTP Methods * @@ -531,6 +611,18 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory return includes.toArray(new String[0]); } + /** + * Get the current filter list of included Path Specs for request inflation. + * + * @return the filter list of included Path Specs + * @see #getExcludedInflationPaths() + */ + public String[] getIncludedInflationPaths() + { + Set includes = _inflatePaths.getIncluded(); + return includes.toArray(new String[0]); + } + /** * Get the minimum size, in bytes, that a response {@code Content-Length} must be * before compression will trigger. @@ -585,7 +677,7 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory // Handle request inflation HttpFields httpFields = baseRequest.getHttpFields(); - boolean inflated = _inflateBufferSize > 0 && httpFields.contains(HttpHeader.CONTENT_ENCODING, "gzip"); + boolean inflated = _inflateBufferSize > 0 && httpFields.contains(HttpHeader.CONTENT_ENCODING, "gzip") && isPathInflatable(path); if (inflated) { if (LOG.isDebugEnabled()) @@ -750,6 +842,20 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory return _paths.test(requestURI); } + /** + * Test if the provided Request URI is allowed to be inflated based on the Path Specs filters. + * + * @param requestURI the request uri + * @return whether decompressing is allowed for the given the path. + */ + protected boolean isPathInflatable(String requestURI) + { + if (requestURI == null) + return true; + + return _inflatePaths.test(requestURI); + } + /** * Set the excluded filter list of HTTP methods (replacing any previously set) * @@ -799,6 +905,20 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory _paths.exclude(pathspecs); } + /** + * Set the excluded filter list of Path specs (replacing any previously set) + * + * @param pathspecs Path specs (as per servlet spec) to exclude from inflation. If a + * ServletContext is available, the paths are relative to the context path, + * otherwise they are absolute. + * @see #setIncludedInflatePaths(String...) + */ + public void setExcludedInflatePaths(String... pathspecs) + { + _inflatePaths.getExcluded().clear(); + _inflatePaths.exclude(pathspecs); + } + /** * Set of supported {@link DispatcherType} that this filter will operate on. * @@ -861,6 +981,20 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory _paths.include(pathspecs); } + /** + * Set the included filter list of Path specs (replacing any previously set) + * + * @param pathspecs Path specs (as per servlet spec) to include for inflation. If a + * ServletContext is available, the paths are relative to the context path, + * otherwise they are absolute + * @see #setExcludedInflatePaths(String...) + */ + public void setIncludedInflatePaths(String... pathspecs) + { + _inflatePaths.getIncluded().clear(); + _inflatePaths.include(pathspecs); + } + /** * Set the minimum response size to trigger dynamic compression. *

diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/GzipHandlerTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/GzipHandlerTest.java index e754fe0784e..e71eed85a18 100644 --- a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/GzipHandlerTest.java +++ b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/GzipHandlerTest.java @@ -40,6 +40,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.http.CompressedContentFormat; +import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.http.HttpTester; import org.eclipse.jetty.server.HttpOutput; import org.eclipse.jetty.server.LocalConnector; @@ -55,6 +56,7 @@ import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalToIgnoringCase; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.not; @@ -688,6 +690,49 @@ public class GzipHandlerTest assertEquals(__icontent, testOut.toString("UTF8")); } + @Test + public void testIncludeExcludeGzipHandlerInflate() throws Exception + { + gzipHandler.addExcludedInflationPaths("/ctx/echo/exclude"); + gzipHandler.addIncludedInflationPaths("/ctx/echo/include"); + + String message = "hello world"; + byte[] gzippedMessage = gzipContent(message); + + // The included path does deflate the content. + HttpTester.Response response = sendGzipRequest("/ctx/echo/include", message); + assertThat(response.getStatus(), equalTo(HttpStatus.OK_200)); + assertThat(response.getContent(), equalTo(message)); + + // The excluded path does not deflate the content. + response = sendGzipRequest("/ctx/echo/exclude", message); + assertThat(response.getStatus(), equalTo(HttpStatus.OK_200)); + assertThat(response.getContentBytes(), equalTo(gzippedMessage)); + } + + private byte[] gzipContent(String content) throws IOException + { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + GZIPOutputStream output = new GZIPOutputStream(baos); + output.write(content.getBytes(StandardCharsets.UTF_8)); + output.close(); + return baos.toByteArray(); + } + + private HttpTester.Response sendGzipRequest(String uri, String data) throws Exception + { + HttpTester.Request request = HttpTester.newRequest(); + request.setMethod("GET"); + request.setURI(uri); + request.setVersion("HTTP/1.0"); + request.setHeader("Host", "tester"); + request.setHeader("Content-Type", "text/plain"); + request.setHeader("Content-Encoding", "gzip"); + request.setContent(gzipContent(data)); + + return HttpTester.parseResponse(_connector.getResponse(request.generate())); + } + @Test public void testAddGetPaths() { From 39c478461b92adceeb7a442037d27690bcec8770 Mon Sep 17 00:00:00 2001 From: Lachlan Roberts Date: Tue, 5 Apr 2022 19:12:45 +1000 Subject: [PATCH 03/17] Fix StatisticsHandler in the case a Handler throws exception. Signed-off-by: Lachlan Roberts --- .../server/handler/StatisticsHandler.java | 32 +++++++++-- .../server/handler/StatisticsHandlerTest.java | 57 +++++++++++++++++++ 2 files changed, 85 insertions(+), 4 deletions(-) diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/StatisticsHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/StatisticsHandler.java index 0a7f728e69d..92635d764bd 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/StatisticsHandler.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/StatisticsHandler.java @@ -55,6 +55,7 @@ public class StatisticsHandler extends HandlerWrapper implements Graceful private final LongAdder _expires = new LongAdder(); private final LongAdder _errors = new LongAdder(); + private final LongAdder _responsesThrown = new LongAdder(); private final LongAdder _responses1xx = new LongAdder(); private final LongAdder _responses2xx = new LongAdder(); private final LongAdder _responses3xx = new LongAdder(); @@ -91,7 +92,7 @@ public class StatisticsHandler extends HandlerWrapper implements Graceful long elapsed = System.currentTimeMillis() - request.getTimeStamp(); _requestStats.decrement(); _requestTimeStats.record(elapsed); - updateResponse(request); + updateResponse(request, false); _asyncWaitStats.decrement(); if (_shutdown.isShutdown()) @@ -166,10 +167,16 @@ public class StatisticsHandler extends HandlerWrapper implements Graceful _asyncDispatches.increment(); } + boolean thrownError = false; try { handler.handle(path, baseRequest, request, response); } + catch (Throwable t) + { + thrownError = true; + throw t; + } finally { final long now = System.currentTimeMillis(); @@ -189,7 +196,7 @@ public class StatisticsHandler extends HandlerWrapper implements Graceful { _requestStats.decrement(); _requestTimeStats.record(dispatched); - updateResponse(baseRequest); + updateResponse(baseRequest, thrownError); } } @@ -198,10 +205,14 @@ public class StatisticsHandler extends HandlerWrapper implements Graceful } } - protected void updateResponse(Request request) + protected void updateResponse(Request request, boolean thrownError) { Response response = request.getResponse(); - if (request.isHandled()) + if (thrownError) + { + _responsesThrown.increment(); + } + else if (request.isHandled()) { switch (response.getStatus() / 100) { @@ -537,6 +548,18 @@ public class StatisticsHandler extends HandlerWrapper implements Graceful return _responses5xx.intValue(); } + /** + * @return the number of requests that threw an exception during handling + * since {@link #statsReset()} was last called. These may have resulted in + * some error responses which were unrecorded by the {@link StatisticsHandler}. + */ + @ManagedAttribute("number of requests that threw an exception during handling") + public int getResponsesThrown() + { + return _responsesThrown.intValue(); + } + + /** * @return the milliseconds since the statistics were started with {@link #statsReset()}. */ @@ -590,6 +613,7 @@ public class StatisticsHandler extends HandlerWrapper implements Graceful sb.append("3xx responses: ").append(getResponses3xx()).append("
\n"); sb.append("4xx responses: ").append(getResponses4xx()).append("
\n"); sb.append("5xx responses: ").append(getResponses5xx()).append("
\n"); + sb.append("responses thrown: ").append(getResponsesThrown()).append("
\n"); sb.append("Bytes sent total: ").append(getResponsesBytesTotal()).append("
\n"); return sb.toString(); diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/handler/StatisticsHandlerTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/handler/StatisticsHandlerTest.java index f15f135a409..797ec36164e 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/handler/StatisticsHandlerTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/handler/StatisticsHandlerTest.java @@ -30,14 +30,17 @@ import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.io.ConnectionStatistics; +import org.eclipse.jetty.server.HttpChannel; import org.eclipse.jetty.server.LocalConnector; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.util.log.StacklessLogging; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.greaterThanOrEqualTo; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -420,6 +423,60 @@ public class StatisticsHandlerTest barrier[3].await(); } + @Test + public void testThrownResponse() throws Exception + { + _statsHandler.setHandler(new AbstractHandler() + { + @Override + public void handle(String path, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws IOException + { + try + { + throw new IllegalStateException("expected"); + } + catch (IllegalStateException e) + { + throw e; + } + catch (Exception e) + { + throw new IOException(e); + } + } + }); + _server.start(); + + try (StacklessLogging ignored = new StacklessLogging(HttpChannel.class)) + { + String request = "GET / HTTP/1.1\r\n" + + "Host: localhost\r\n" + + "\r\n"; + String response = _connector.getResponse(request); + assertThat(response, containsString("HTTP/1.1 500 Server Error")); + } + + assertEquals(1, _statsHandler.getRequests()); + assertEquals(0, _statsHandler.getRequestsActive()); + assertEquals(1, _statsHandler.getRequestsActiveMax()); + + assertEquals(1, _statsHandler.getDispatched()); + assertEquals(0, _statsHandler.getDispatchedActive()); + assertEquals(1, _statsHandler.getDispatchedActiveMax()); + + assertEquals(0, _statsHandler.getAsyncRequests()); + assertEquals(0, _statsHandler.getAsyncDispatches()); + assertEquals(0, _statsHandler.getExpires()); + + // We get no recorded status, but we get a recorded thrown response. + assertEquals(0, _statsHandler.getResponses1xx()); + assertEquals(0, _statsHandler.getResponses2xx()); + assertEquals(0, _statsHandler.getResponses3xx()); + assertEquals(0, _statsHandler.getResponses4xx()); + assertEquals(0, _statsHandler.getResponses5xx()); + assertEquals(1, _statsHandler.getResponsesThrown()); + } + @Test public void waitForSuspendedRequestTest() throws Exception { From fcd0222d2cc95570225b0c6cc40a5ecb659fe4a2 Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Wed, 4 May 2022 06:59:17 -0500 Subject: [PATCH 04/17] Issue #7837 - fix compilation error Signed-off-by: Joakim Erdfelt --- .../org/eclipse/jetty/server/handler/StatisticsHandlerTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/handler/StatisticsHandlerTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/handler/StatisticsHandlerTest.java index 797ec36164e..5183f8fa94a 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/handler/StatisticsHandlerTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/handler/StatisticsHandlerTest.java @@ -30,11 +30,11 @@ import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.io.ConnectionStatistics; +import org.eclipse.jetty.logging.StacklessLogging; import org.eclipse.jetty.server.HttpChannel; import org.eclipse.jetty.server.LocalConnector; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.util.log.StacklessLogging; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; From 685d617a1b5b456ed4baa479e52da39c6e042cde Mon Sep 17 00:00:00 2001 From: Lachlan Roberts Date: Thu, 5 May 2022 16:09:55 +1000 Subject: [PATCH 05/17] Issue #7802 - add testing for qpack section acknowledgement Signed-off-by: Lachlan Roberts --- .../jetty/http3/qpack/QpackTestUtil.java | 60 ++++++++++++++ .../qpack/SectionAcknowledgmentTest.java | 79 +++++++++++++++++++ 2 files changed, 139 insertions(+) create mode 100644 jetty-http3/http3-qpack/src/test/java/org/eclipse/jetty/http3/qpack/SectionAcknowledgmentTest.java diff --git a/jetty-http3/http3-qpack/src/test/java/org/eclipse/jetty/http3/qpack/QpackTestUtil.java b/jetty-http3/http3-qpack/src/test/java/org/eclipse/jetty/http3/qpack/QpackTestUtil.java index 5645bdfd605..78174a1965b 100644 --- a/jetty-http3/http3-qpack/src/test/java/org/eclipse/jetty/http3/qpack/QpackTestUtil.java +++ b/jetty-http3/http3-qpack/src/test/java/org/eclipse/jetty/http3/qpack/QpackTestUtil.java @@ -16,6 +16,10 @@ package org.eclipse.jetty.http3.qpack; import java.nio.ByteBuffer; import java.util.List; +import org.eclipse.jetty.http.HttpField; +import org.eclipse.jetty.http.HttpFields; +import org.eclipse.jetty.http.HttpVersion; +import org.eclipse.jetty.http.MetaData; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.NullByteBufferPool; import org.eclipse.jetty.util.BufferUtil; @@ -27,6 +31,23 @@ import static org.hamcrest.Matchers.is; public class QpackTestUtil { + public static ByteBuffer toBuffer(Instruction... instructions) + { + ByteBufferPool.Lease lease = new ByteBufferPool.Lease(new NullByteBufferPool()); + for (Instruction instruction : instructions) + { + instruction.encode(lease); + } + ByteBuffer combinedBuffer = BufferUtil.allocate(Math.toIntExact(lease.getTotalLength())); + BufferUtil.clearToFill(combinedBuffer); + for (ByteBuffer buffer : lease.getByteBuffers()) + { + combinedBuffer.put(buffer); + } + BufferUtil.flipToFlush(combinedBuffer, 0); + return combinedBuffer; + } + public static Matcher equalsHex(String expectedString) { expectedString = expectedString.replaceAll("\\s+", ""); @@ -56,4 +77,43 @@ public class QpackTestUtil { return BufferUtil.toHexString(toBuffer(List.of(instruction))); } + + public static ByteBuffer encode(QpackEncoder encoder, long streamId, MetaData metaData) throws QpackException + { + ByteBuffer buffer = BufferUtil.allocate(1024); + BufferUtil.clearToFill(buffer); + encoder.encode(buffer, streamId, metaData); + BufferUtil.flipToFlush(buffer, 0); + return buffer; + } + + public static HttpFields.Mutable toHttpFields(HttpField field) + { + return HttpFields.build().add(field); + } + + public static MetaData toMetaData(String name, String value) + { + return toMetaData(toHttpFields(new HttpField(name, value))); + } + + public static MetaData toMetaData(String method, String path, String scheme) + { + return toMetaData(method, path, scheme, null); + } + + public static MetaData toMetaData(String method, String path, String scheme, HttpFields.Mutable fields) + { + if (fields == null) + fields = HttpFields.build(); + fields.put(":scheme", scheme); + fields.put(":method", method); + fields.put(":path", path); + return new MetaData(HttpVersion.HTTP_3, fields); + } + + public static MetaData toMetaData(HttpFields fields) + { + return new MetaData(HttpVersion.HTTP_3, fields); + } } diff --git a/jetty-http3/http3-qpack/src/test/java/org/eclipse/jetty/http3/qpack/SectionAcknowledgmentTest.java b/jetty-http3/http3-qpack/src/test/java/org/eclipse/jetty/http3/qpack/SectionAcknowledgmentTest.java new file mode 100644 index 00000000000..b0446f304fd --- /dev/null +++ b/jetty-http3/http3-qpack/src/test/java/org/eclipse/jetty/http3/qpack/SectionAcknowledgmentTest.java @@ -0,0 +1,79 @@ +// +// ======================================================================== +// 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.http3.qpack; + +import java.nio.ByteBuffer; + +import org.eclipse.jetty.http3.qpack.internal.instruction.SectionAcknowledgmentInstruction; +import org.eclipse.jetty.util.BufferUtil; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.eclipse.jetty.http3.qpack.QpackTestUtil.encode; +import static org.eclipse.jetty.http3.qpack.QpackTestUtil.toBuffer; +import static org.eclipse.jetty.http3.qpack.QpackTestUtil.toMetaData; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; + +public class SectionAcknowledgmentTest +{ + private static final int MAX_BLOCKED_STREAMS = 5; + private static final int MAX_HEADER_SIZE = 1024; + + private QpackEncoder _encoder; + private QpackDecoder _decoder; + private TestDecoderHandler _decoderHandler; + private TestEncoderHandler _encoderHandler; + + @BeforeEach + public void before() + { + _encoderHandler = new TestEncoderHandler(); + _decoderHandler = new TestDecoderHandler(); + _encoder = new QpackEncoder(_encoderHandler, MAX_BLOCKED_STREAMS); + _decoder = new QpackDecoder(_decoderHandler, MAX_HEADER_SIZE); + } + + @Test + public void testSectionAcknowledgmentForZeroRequiredInsertCountOnDecoder() throws Exception + { + // Encode a header with only a value contained in the static table. + ByteBuffer buffer = encode(_encoder, 0, toMetaData("GET", "/", "http")); + + // No instruction since no addition to table. + Instruction instruction = _encoderHandler.getInstruction(); + assertNull(instruction); + + // Decoding should generate no instruction. + _decoder.decode(0, buffer, _decoderHandler); + instruction = _decoderHandler.getInstruction(); + assertNull(instruction); + } + + @Test + public void testSectionAcknowledgmentForZeroRequiredInsertCountOnEncoder() throws Exception + { + // Encode a header with only a value contained in the static table. + ByteBuffer buffer = encode(_encoder, 0, toMetaData("GET", "/", "http")); + System.err.println(BufferUtil.toDetailString(buffer)); + + // Parsing a section ack instruction on the encoder when we are not expecting it should result in QPACK_DECODER_STREAM_ERROR. + SectionAcknowledgmentInstruction instruction = new SectionAcknowledgmentInstruction(0); + ByteBuffer instructionBuffer = toBuffer(instruction); + QpackException error = assertThrows(QpackException.class, () -> _encoder.parseInstructions(instructionBuffer)); + assertThat(error.getMessage(), containsString("No StreamInfo for 0")); + } +} From 92070e83dd97a27b0660a26045e73c76da43280d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 5 May 2022 12:16:36 -0500 Subject: [PATCH 06/17] Bump mongo-java-driver from 3.2.2 to 3.12.11 (#7915) Bumps [mongo-java-driver](https://github.com/mongodb/mongo-java-driver) from 3.2.2 to 3.12.11. - [Release notes](https://github.com/mongodb/mongo-java-driver/releases) - [Commits](https://github.com/mongodb/mongo-java-driver/compare/r3.2.2...r3.12.11) --- updated-dependencies: - dependency-name: org.mongodb:mongo-java-driver dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Olivier Lamy --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 60558f5c728..e2f2ee39823 100644 --- a/pom.xml +++ b/pom.xml @@ -109,7 +109,7 @@ 0.13.1 1.8.0 3.8.4 - 3.2.2 + 3.12.11 0.9.1 8.1.0 6.0.0 From ebd82035fd187ce56256d85fcbb0db6dd7e363a7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 5 May 2022 15:21:25 -0500 Subject: [PATCH 07/17] Bump org.apache.aries.spifly.dynamic.bundle from 1.3.4 to 1.3.5 (#7877) * Bump org.apache.aries.spifly.dynamic.bundle from 1.3.4 to 1.3.5 Bumps org.apache.aries.spifly.dynamic.bundle from 1.3.4 to 1.3.5. --- updated-dependencies: - dependency-name: org.apache.aries.spifly:org.apache.aries.spifly.dynamic.bundle dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Bump org.apache.aries.spifly.dynamic.bundle from 1.3.4 to 1.3.5 (#7878) * Bump org.apache.aries.spifly.dynamic.bundle from 1.3.4 to 1.3.5 * Fixing dependency upper bounds * Remove wrapping of conscrypt jar as it now has appropriate manifest. Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Joakim Erdfelt Co-authored-by: Jan Bartel Signed-off-by: Joakim Erdfelt Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Joakim Erdfelt Co-authored-by: Jan Bartel --- jetty-osgi/test-jetty-osgi/pom.xml | 2 +- .../test/TestJettyOSGiBootHTTP2Conscrypt.java | 7 +------ pom.xml | 21 ++++++++++++++++++- 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/jetty-osgi/test-jetty-osgi/pom.xml b/jetty-osgi/test-jetty-osgi/pom.xml index e519002bf49..09b2c4471a9 100644 --- a/jetty-osgi/test-jetty-osgi/pom.xml +++ b/jetty-osgi/test-jetty-osgi/pom.xml @@ -216,7 +216,7 @@ org.apache.aries.spifly org.apache.aries.spifly.dynamic.bundle - 1.3.4 + 1.3.5 test diff --git a/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootHTTP2Conscrypt.java b/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootHTTP2Conscrypt.java index ce5051f01f5..6d81b4ad8c9 100644 --- a/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootHTTP2Conscrypt.java +++ b/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootHTTP2Conscrypt.java @@ -45,7 +45,6 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.ops4j.pax.exam.CoreOptions.mavenBundle; -import static org.ops4j.pax.exam.CoreOptions.wrappedBundle; @RunWith(PaxExam.class) @ExamReactorStrategy(PerClass.class) @@ -89,11 +88,7 @@ public class TestJettyOSGiBootHTTP2Conscrypt res.add(CoreOptions.systemProperty("jetty.alpn.protocols").value("h2,http/1.1")); res.add(CoreOptions.systemProperty("jetty.sslContext.provider").value("Conscrypt")); - res.add(wrappedBundle(mavenBundle().groupId("org.conscrypt").artifactId("conscrypt-openjdk-uber").versionAsInProject()) - .imports("javax.net.ssl,*") - .exports("org.conscrypt;version=" + System.getProperty("conscrypt-version")) - .instructions("Bundle-NativeCode=META-INF/native/libconscrypt_openjdk_jni-linux-x86_64.so") - .start()); + res.add(mavenBundle().groupId("org.conscrypt").artifactId("conscrypt-openjdk-uber").versionAsInProject().start()); res.add(mavenBundle().groupId("org.eclipse.jetty.osgi").artifactId("jetty-osgi-alpn").versionAsInProject().noStart()); res.add(mavenBundle().groupId("org.eclipse.jetty").artifactId("jetty-alpn-conscrypt-server").versionAsInProject().start()); res.add(mavenBundle().groupId("org.eclipse.jetty").artifactId("jetty-alpn-server").versionAsInProject().start()); diff --git a/pom.xml b/pom.xml index e2f2ee39823..76489bf50d3 100644 --- a/pom.xml +++ b/pom.xml @@ -32,7 +32,7 @@ 2.5.3 9.3 4.2.0 - 5.3.0 + 6.2.0 1.5 10.2 1.15 @@ -113,6 +113,8 @@ 0.9.1 8.1.0 6.0.0 + 1.2.0 + 1.2.0 2.1.1 3.4.1 2.0.0-alpha6 @@ -1965,14 +1967,31 @@ org.osgi + org.osgi.core ${org.osgi.core.version} + + org.osgi + + osgi.core + ${org.osgi.core.version} + org.osgi osgi.annotation ${org.osgi.annotation.version} + + org.osgi + org.osgi.util.function + ${org.osgi.util.function.version} + + + org.osgi + org.osgi.util.promise + ${org.osgi.util.promise.version} + org.ow2.asm asm From de5c486c08bed7d9c211a3025bad9e407436d14b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 May 2022 13:50:43 -0500 Subject: [PATCH 08/17] Bump protostream from 4.4.2.Final to 4.4.3.Final (#7925) Bumps [protostream](https://github.com/infinispan/protostream) from 4.4.2.Final to 4.4.3.Final. - [Release notes](https://github.com/infinispan/protostream/releases) - [Commits](https://github.com/infinispan/protostream/compare/4.4.2.Final...4.4.3.Final) --- updated-dependencies: - dependency-name: org.infinispan.protostream:protostream dependency-type: direct:development update-type: version-update:semver-patch ... 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 76489bf50d3..a5f6f57ddaf 100644 --- a/pom.xml +++ b/pom.xml @@ -51,7 +51,7 @@ 2.2 2.14.5 4.2.5 - 4.4.2.Final + 4.4.3.Final 11.0.15.Final 2.13.2 2.13.2 From c2c1ea8d9a126895544fdba2f1610f94cb8df377 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 May 2022 16:24:40 -0500 Subject: [PATCH 09/17] Bump maven-bundle-plugin from 5.1.4 to 5.1.5 (#7933) * Bump maven-bundle-plugin from 5.1.4 to 5.1.5 Bumps maven-bundle-plugin from 5.1.4 to 5.1.5. --- updated-dependencies: - dependency-name: org.apache.felix:maven-bundle-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Standardize maven-bundle-plugin usage (to avoid build error) Signed-off-by: Joakim Erdfelt Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Joakim Erdfelt --- demos/demo-mock-resources/pom.xml | 33 +++++++---------- jetty-alpn/jetty-alpn-client/pom.xml | 19 +++------- .../jetty-gcloud-session-manager/pom.xml | 21 ++++------- jetty-jaspi/pom.xml | 19 +++------- jetty-openid/pom.xml | 19 +++------- jetty-security/pom.xml | 17 +++------ jetty-websocket/websocket-core-client/pom.xml | 18 +++------ jetty-websocket/websocket-core-common/pom.xml | 31 ++++++---------- .../websocket-javax-client/pom.xml | 37 ++++++++----------- .../websocket-javax-common/pom.xml | 23 ++++-------- .../websocket-javax-server/pom.xml | 31 ++++++---------- jetty-websocket/websocket-javax-tests/pom.xml | 23 ++++-------- .../websocket-jetty-server/pom.xml | 7 +++- jetty-websocket/websocket-jetty-tests/pom.xml | 23 ++++-------- pom.xml | 2 +- tests/test-websocket-autobahn/pom.xml | 23 ++++-------- 16 files changed, 125 insertions(+), 221 deletions(-) diff --git a/demos/demo-mock-resources/pom.xml b/demos/demo-mock-resources/pom.xml index 684273ac6f6..ae2d0d96b69 100644 --- a/demos/demo-mock-resources/pom.xml +++ b/demos/demo-mock-resources/pom.xml @@ -17,26 +17,19 @@ org.apache.felix maven-bundle-plugin true - - - - manifest - - - - org.eclipse.jetty.demos.demo-mock-resources - Mock resources used for testing - - com.acme;version="${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion}" - - - javax.sql, javax.transaction;version="1.1", javax.mail;version="1.4.1" - - <_nouses>true - - - - + + + org.eclipse.jetty.demos.demo-mock-resources + Mock resources used for testing + + com.acme;version="${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion}" + + + javax.sql, javax.transaction;version="1.1", javax.mail;version="1.4.1" + + <_nouses>true + + diff --git a/jetty-alpn/jetty-alpn-client/pom.xml b/jetty-alpn/jetty-alpn-client/pom.xml index 6d8b9b22668..d025b8826f7 100644 --- a/jetty-alpn/jetty-alpn-client/pom.xml +++ b/jetty-alpn/jetty-alpn-client/pom.xml @@ -17,19 +17,12 @@ org.apache.felix maven-bundle-plugin true - - - - manifest - - - - ${osgi.slf4j.import.packages},org.eclipse.jetty.alpn;resolution:=optional,* - osgi.extender; filter:="(osgi.extender=osgi.serviceloader.processor)";resolution:=optional, osgi.serviceloader; filter:="(osgi.serviceloader=org.eclipse.jetty.io.ssl.ALPNProcessor$Client)";resolution:=optional;cardinality:=multiple - - - - + + + ${osgi.slf4j.import.packages},org.eclipse.jetty.alpn;resolution:=optional,* + osgi.extender; filter:="(osgi.extender=osgi.serviceloader.processor)";resolution:=optional, osgi.serviceloader; filter:="(osgi.serviceloader=org.eclipse.jetty.io.ssl.ALPNProcessor$Client)";resolution:=optional;cardinality:=multiple + + diff --git a/jetty-gcloud/jetty-gcloud-session-manager/pom.xml b/jetty-gcloud/jetty-gcloud-session-manager/pom.xml index fe8551303af..0e71e1ed5e2 100644 --- a/jetty-gcloud/jetty-gcloud-session-manager/pom.xml +++ b/jetty-gcloud/jetty-gcloud-session-manager/pom.xml @@ -50,20 +50,13 @@ org.apache.felix maven-bundle-plugin true - - - - manifest - - - - - org.eclipse.jetty.gcloud.session.*;version="${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion}" - - - - - + + + + org.eclipse.jetty.gcloud.session.*;version="${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion}" + + + org.apache.maven.plugins diff --git a/jetty-jaspi/pom.xml b/jetty-jaspi/pom.xml index 3d2860b2a4a..323271e5bfd 100644 --- a/jetty-jaspi/pom.xml +++ b/jetty-jaspi/pom.xml @@ -21,19 +21,12 @@ org.apache.felix maven-bundle-plugin true - - - - manifest - - - - osgi.extender; filter:="(osgi.extender=osgi.serviceloader.registrar)" - osgi.serviceloader;osgi.serviceloader=org.eclipse.jetty.security.Authenticator$Factory - - - - + + + osgi.extender; filter:="(osgi.extender=osgi.serviceloader.registrar)" + osgi.serviceloader;osgi.serviceloader=org.eclipse.jetty.security.Authenticator$Factory + + diff --git a/jetty-openid/pom.xml b/jetty-openid/pom.xml index 98638813058..18763b03066 100644 --- a/jetty-openid/pom.xml +++ b/jetty-openid/pom.xml @@ -21,19 +21,12 @@ org.apache.felix maven-bundle-plugin true - - - - manifest - - - - osgi.extender; filter:="(osgi.extender=osgi.serviceloader.registrar)" - osgi.serviceloader;osgi.serviceloader=org.eclipse.jetty.security.Authenticator$Factory - - - - + + + osgi.extender; filter:="(osgi.extender=osgi.serviceloader.registrar)" + osgi.serviceloader;osgi.serviceloader=org.eclipse.jetty.security.Authenticator$Factory + + diff --git a/jetty-security/pom.xml b/jetty-security/pom.xml index 14eaf4aaeeb..299d14250d4 100644 --- a/jetty-security/pom.xml +++ b/jetty-security/pom.xml @@ -21,18 +21,11 @@ org.apache.felix maven-bundle-plugin true - - - - manifest - - - - osgi.serviceloader; filter:="(osgi.serviceloader=org.eclipse.jetty.security.Authenticator$Factory)";resolution:=optional;cardinality:=multiple, osgi.extender; filter:="(osgi.extender=osgi.serviceloader.processor)";resolution:=optional - - - - + + + osgi.serviceloader; filter:="(osgi.serviceloader=org.eclipse.jetty.security.Authenticator$Factory)";resolution:=optional;cardinality:=multiple, osgi.extender; filter:="(osgi.extender=osgi.serviceloader.processor)";resolution:=optional + + diff --git a/jetty-websocket/websocket-core-client/pom.xml b/jetty-websocket/websocket-core-client/pom.xml index 9a85efd1657..50820878688 100644 --- a/jetty-websocket/websocket-core-client/pom.xml +++ b/jetty-websocket/websocket-core-client/pom.xml @@ -36,19 +36,11 @@ org.apache.felix maven-bundle-plugin true - - - generate-manifest - - manifest - - - - *,org.eclipse.jetty.websocket.core.client.internal.* - - - - + + + *,org.eclipse.jetty.websocket.core.client.internal.* + + diff --git a/jetty-websocket/websocket-core-common/pom.xml b/jetty-websocket/websocket-core-common/pom.xml index 420fb7bd217..b9de374d97c 100644 --- a/jetty-websocket/websocket-core-common/pom.xml +++ b/jetty-websocket/websocket-core-common/pom.xml @@ -35,25 +35,18 @@ org.apache.felix maven-bundle-plugin true - - - generate-manifest - - manifest - - - - *,org.eclipse.jetty.websocket.core.common.internal.* - - osgi.extender; filter:="(osgi.extender=osgi.serviceloader.registrar)" - - - osgi.serviceloader; osgi.serviceloader=org.eclipse.jetty.websocket.core.Extension - - - - - + + + Jetty Websocket Core Common + *,org.eclipse.jetty.websocket.core.common.internal.* + + osgi.extender; filter:="(osgi.extender=osgi.serviceloader.registrar)"; resolution:=optional + + + osgi.serviceloader; osgi.serviceloader=org.eclipse.jetty.websocket.core.Extension + + + diff --git a/jetty-websocket/websocket-javax-client/pom.xml b/jetty-websocket/websocket-javax-client/pom.xml index 471ce858527..96d30c26367 100644 --- a/jetty-websocket/websocket-javax-client/pom.xml +++ b/jetty-websocket/websocket-javax-client/pom.xml @@ -59,28 +59,21 @@ org.apache.felix maven-bundle-plugin true - - - - manifest - - - - javax.websocket.client Implementation - - org.eclipse.jetty.websocket.javax.client.*;version="${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion}" - - - osgi.extender; filter:="(osgi.extender=osgi.serviceloader.registrar)";resolution:=optional - - - osgi.serviceloader;osgi.serviceloader=javax.websocket.ContainerProvider, - osgi.serviceloader;osgi.serviceloader=javax.servlet.ServletContainerInitializer - - - - - + + + javax.websocket.client Implementation + + org.eclipse.jetty.websocket.javax.client.*;version="${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion}" + + + osgi.extender; filter:="(osgi.extender=osgi.serviceloader.registrar)";resolution:=optional + + + osgi.serviceloader;osgi.serviceloader=javax.websocket.ContainerProvider, + osgi.serviceloader;osgi.serviceloader=javax.servlet.ServletContainerInitializer + + + diff --git a/jetty-websocket/websocket-javax-common/pom.xml b/jetty-websocket/websocket-javax-common/pom.xml index 0a7c213c2ab..c2fd8443557 100644 --- a/jetty-websocket/websocket-javax-common/pom.xml +++ b/jetty-websocket/websocket-javax-common/pom.xml @@ -20,21 +20,14 @@ org.apache.felix maven-bundle-plugin true - - - - manifest - - - - javax.websocket.client Implementation - - org.eclipse.jetty.websocket.javax.*;version="${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion}" - - - - - + + + javax.websocket.client Implementation + + org.eclipse.jetty.websocket.javax.*;version="${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion}" + + + diff --git a/jetty-websocket/websocket-javax-server/pom.xml b/jetty-websocket/websocket-javax-server/pom.xml index 2336c0cf157..cac3d32e4a9 100644 --- a/jetty-websocket/websocket-javax-server/pom.xml +++ b/jetty-websocket/websocket-javax-server/pom.xml @@ -56,25 +56,18 @@ org.apache.felix maven-bundle-plugin true - - - - manifest - - - - javax.websocket.server Implementation - - org.eclipse.jetty.websocket.javax.server.*;version="${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion}" - - osgi.extender; filter:="(osgi.extender=osgi.serviceloader.registrar)";resolution:=optional - - osgi.serviceloader;osgi.serviceloader=org.eclipse.jetty.webapp.Configuration,osgi.serviceloader;osgi.serviceloader=javax.servlet.ServletContainerInitializer,osgi.serviceloader;osgi.serviceloader=javax.websocket.server.ServerEndpointConfig$Configurator - - - - - + + + javax.websocket.server Implementation + + org.eclipse.jetty.websocket.javax.server.*;version="${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion}" + + osgi.extender; filter:="(osgi.extender=osgi.serviceloader.registrar)";resolution:=optional + + osgi.serviceloader;osgi.serviceloader=org.eclipse.jetty.webapp.Configuration,osgi.serviceloader;osgi.serviceloader=javax.servlet.ServletContainerInitializer,osgi.serviceloader;osgi.serviceloader=javax.websocket.server.ServerEndpointConfig$Configurator + + + diff --git a/jetty-websocket/websocket-javax-tests/pom.xml b/jetty-websocket/websocket-javax-tests/pom.xml index b257c34191c..4f82517cb88 100644 --- a/jetty-websocket/websocket-javax-tests/pom.xml +++ b/jetty-websocket/websocket-javax-tests/pom.xml @@ -77,21 +77,14 @@ org.apache.felix maven-bundle-plugin true - - - - manifest - - - - javax.websocket Integration Tests - - org.eclipse.jetty.websocket.javax.tests.*;version="${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion}" - - - - - + + + javax.websocket Integration Tests + + org.eclipse.jetty.websocket.javax.tests.*;version="${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion}" + + + diff --git a/jetty-websocket/websocket-jetty-server/pom.xml b/jetty-websocket/websocket-jetty-server/pom.xml index 6912f5abf06..2f1460fd60d 100644 --- a/jetty-websocket/websocket-jetty-server/pom.xml +++ b/jetty-websocket/websocket-jetty-server/pom.xml @@ -64,9 +64,12 @@ Jetty Websocket Server - osgi.extender; filter:="(osgi.extender=osgi.serviceloader.registrar)";resolution:=optional + + osgi.extender; filter:="(osgi.extender=osgi.serviceloader.registrar)";resolution:=optional + - osgi.serviceloader;osgi.serviceloader=org.eclipse.jetty.webapp.Configuration,osgi.serviceloader;osgi.serviceloader=javax.servlet.ServletContainerInitializer + osgi.serviceloader;osgi.serviceloader=org.eclipse.jetty.webapp.Configuration, + osgi.serviceloader;osgi.serviceloader=javax.servlet.ServletContainerInitializer diff --git a/jetty-websocket/websocket-jetty-tests/pom.xml b/jetty-websocket/websocket-jetty-tests/pom.xml index e4d5e03e08d..e3e025ca5d6 100644 --- a/jetty-websocket/websocket-jetty-tests/pom.xml +++ b/jetty-websocket/websocket-jetty-tests/pom.xml @@ -98,21 +98,14 @@ org.apache.felix maven-bundle-plugin true - - - - manifest - - - - jetty.websocket Integration Tests - - org.eclipse.jetty.websocket.jetty.tests.*;version="${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion}" - - - - - + + + jetty.websocket Integration Tests + + org.eclipse.jetty.websocket.jetty.tests.*;version="${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion}" + + + org.apache.maven.plugins diff --git a/pom.xml b/pom.xml index a5f6f57ddaf..2e1a9227ad7 100644 --- a/pom.xml +++ b/pom.xml @@ -141,7 +141,7 @@ 4.1 3.1.0 3.3.0 - 5.1.4 + 5.1.5 3.2.0 3.1.2 3.10.1 diff --git a/tests/test-websocket-autobahn/pom.xml b/tests/test-websocket-autobahn/pom.xml index bd95c43d0b9..b864159a6f0 100644 --- a/tests/test-websocket-autobahn/pom.xml +++ b/tests/test-websocket-autobahn/pom.xml @@ -91,21 +91,14 @@ org.apache.felix maven-bundle-plugin true - - - - manifest - - - - jetty.websocket Autobahn Tests - - org.eclipse.jetty.websocket.jetty.tests.*;version="${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion}" - - - - - + + + jetty.websocket Autobahn Tests + + org.eclipse.jetty.websocket.jetty.tests.*;version="${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion}" + + + From 6e88e02d001ff603598c6844d46ac4ca2f04109a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 May 2022 09:23:59 +0000 Subject: [PATCH 10/17] Bump kerb-simplekdc from 2.0.1 to 2.0.2 Bumps kerb-simplekdc from 2.0.1 to 2.0.2. --- updated-dependencies: - dependency-name: org.apache.kerby:kerb-simplekdc dependency-type: direct:development 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 2e1a9227ad7..02d5cfc1e2a 100644 --- a/pom.xml +++ b/pom.xml @@ -101,7 +101,7 @@ 2.4.8 9.0.52 5.8.2 - 2.0.1 + 2.0.2 2.17.2 1.3.0-alpha14 3.0.4 From 5d882eaaaf62a98324c07e886e3845e78c052c31 Mon Sep 17 00:00:00 2001 From: Olivier Lamy Date: Mon, 9 May 2022 21:58:12 +1000 Subject: [PATCH 11/17] revert back to bundle plugin 5.1.4 the bug makes the need of using clean for every build (#7965) --- pom.xml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 2e1a9227ad7..c84d0e513f5 100644 --- a/pom.xml +++ b/pom.xml @@ -141,7 +141,7 @@ 4.1 3.1.0 3.3.0 - 5.1.5 + 5.1.4 3.2.0 3.1.2 3.10.1 @@ -815,7 +815,6 @@ org.apache.felix maven-bundle-plugin ${maven.bundle.plugin.version} - true jar From 135896181b957bbe76b7ebde9826e717e0c9158b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 May 2022 06:15:47 -0500 Subject: [PATCH 12/17] Bump tycho-p2-repository-plugin from 2.7.2 to 2.7.3 (#7972) Bumps tycho-p2-repository-plugin from 2.7.2 to 2.7.3. --- updated-dependencies: - dependency-name: org.eclipse.tycho:tycho-p2-repository-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- jetty-p2/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jetty-p2/pom.xml b/jetty-p2/pom.xml index ff1baa4ddfa..2361427106d 100644 --- a/jetty-p2/pom.xml +++ b/jetty-p2/pom.xml @@ -12,7 +12,7 @@ Generates a (maven based) P2 Updatesite pom - 2.7.2 + 2.7.3 From 2c812f631e3a5c2fd69147f34f5c65cd36dd2137 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 May 2022 06:33:35 -0500 Subject: [PATCH 13/17] Bump logback-core from 1.3.0-alpha14 to 1.3.0-alpha15 (#7971) Bumps [logback-core](https://github.com/qos-ch/logback) from 1.3.0-alpha14 to 1.3.0-alpha15. - [Release notes](https://github.com/qos-ch/logback/releases) - [Commits](https://github.com/qos-ch/logback/compare/v_1.3.0-alpha14...v_1.3.0-alpha15) --- updated-dependencies: - dependency-name: ch.qos.logback:logback-core dependency-type: direct:production update-type: version-update:semver-patch ... 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 1919316a5b1..c155dece9fb 100644 --- a/pom.xml +++ b/pom.xml @@ -103,7 +103,7 @@ 5.8.2 2.0.2 2.17.2 - 1.3.0-alpha14 + 1.3.0-alpha15 3.0.4 10.3.6 0.13.1 From b705091afb9158b39590fa36b9b84795524a8f0b Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Wed, 11 May 2022 17:28:18 +0200 Subject: [PATCH 14/17] Fixes #7935 - Review HTTP/2 error handling (#7938) * Fixes #7935 - Review HTTP/2 error handling Now returning error handling code as a Runnable. Updates after review. Signed-off-by: Simone Bordet --- .../http2/server/HttpChannelOverHTTP2.java | 12 +- .../jetty/http2/server/BadURITest.java | 149 ++++++++++++++++++ 2 files changed, 153 insertions(+), 8 deletions(-) create mode 100644 jetty-http2/http2-server/src/test/java/org/eclipse/jetty/http2/server/BadURITest.java diff --git a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpChannelOverHTTP2.java b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpChannelOverHTTP2.java index 7154ca97f4c..3a06483c1ba 100644 --- a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpChannelOverHTTP2.java +++ b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpChannelOverHTTP2.java @@ -158,13 +158,11 @@ public class HttpChannelOverHTTP2 extends HttpChannel implements Closeable, Writ { if (LOG.isDebugEnabled()) LOG.debug("onRequest", x); - onBadMessage(x); - return null; + return () -> onBadMessage(x); } catch (Throwable x) { - onBadMessage(new BadMessageException(HttpStatus.INTERNAL_SERVER_ERROR_500, null, x)); - return null; + return () -> onBadMessage(new BadMessageException(HttpStatus.INTERNAL_SERVER_ERROR_500, null, x)); } } @@ -190,13 +188,11 @@ public class HttpChannelOverHTTP2 extends HttpChannel implements Closeable, Writ } catch (BadMessageException x) { - onBadMessage(x); - return null; + return () -> onBadMessage(x); } catch (Throwable x) { - onBadMessage(new BadMessageException(HttpStatus.INTERNAL_SERVER_ERROR_500, null, x)); - return null; + return () -> onBadMessage(new BadMessageException(HttpStatus.INTERNAL_SERVER_ERROR_500, null, x)); } } diff --git a/jetty-http2/http2-server/src/test/java/org/eclipse/jetty/http2/server/BadURITest.java b/jetty-http2/http2-server/src/test/java/org/eclipse/jetty/http2/server/BadURITest.java new file mode 100644 index 00000000000..5ff2dced496 --- /dev/null +++ b/jetty-http2/http2-server/src/test/java/org/eclipse/jetty/http2/server/BadURITest.java @@ -0,0 +1,149 @@ +// +// ======================================================================== +// 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.server; + +import java.io.OutputStream; +import java.net.Socket; +import java.nio.ByteBuffer; +import java.util.HashMap; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.eclipse.jetty.http.HostPortHttpField; +import org.eclipse.jetty.http.HttpFields; +import org.eclipse.jetty.http.HttpMethod; +import org.eclipse.jetty.http.HttpScheme; +import org.eclipse.jetty.http.HttpVersion; +import org.eclipse.jetty.http.MetaData; +import org.eclipse.jetty.http2.frames.HeadersFrame; +import org.eclipse.jetty.http2.frames.PrefaceFrame; +import org.eclipse.jetty.http2.frames.SettingsFrame; +import org.eclipse.jetty.http2.generator.Generator; +import org.eclipse.jetty.io.ByteBufferPool; +import org.eclipse.jetty.server.Handler; +import org.eclipse.jetty.server.HttpConfiguration; +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.ServerConnector; +import org.eclipse.jetty.server.handler.AbstractHandler; +import org.eclipse.jetty.server.handler.ErrorHandler; +import org.eclipse.jetty.util.BufferUtil; +import org.eclipse.jetty.util.component.LifeCycle; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class BadURITest +{ + private Server server; + private ServerConnector connector; + + protected void startServer(Handler handler) throws Exception + { + server = new Server(); + connector = new ServerConnector(server, 1, 1, new HTTP2CServerConnectionFactory(new HttpConfiguration())); + server.addConnector(connector); + server.setHandler(handler); + server.start(); + } + + @AfterEach + public void dispose() + { + LifeCycle.stop(server); + } + + @Test + public void testBadURI() throws Exception + { + CountDownLatch handlerLatch = new CountDownLatch(1); + startServer(new AbstractHandler() + { + @Override + public void handle(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) + { + jettyRequest.setHandled(true); + handlerLatch.countDown(); + } + }); + + // Remove existing ErrorHandlers. + for (ErrorHandler errorHandler : server.getBeans(ErrorHandler.class)) + { + server.removeBean(errorHandler); + } + + server.addBean(new ErrorHandler() + { + @Override + public ByteBuffer badMessageError(int status, String reason, HttpFields.Mutable fields) + { + // Return a very large buffer that will cause HTTP/2 flow control exhaustion and/or TCP congestion. + return ByteBuffer.allocateDirect(128 * 1024 * 1024); + } + }); + + ByteBufferPool byteBufferPool = connector.getByteBufferPool(); + Generator generator = new Generator(byteBufferPool); + + // Craft a request with a bad URI, it will not hit the Handler. + MetaData.Request metaData1 = new MetaData.Request( + HttpMethod.GET.asString(), + HttpScheme.HTTP.asString(), + new HostPortHttpField("localhost:" + connector.getLocalPort()), + // Use an ambiguous path parameter so that the URI is invalid. + "/foo/..;/bar", + HttpVersion.HTTP_2, + HttpFields.EMPTY, + -1 + ); + ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool); + generator.control(lease, new PrefaceFrame()); + generator.control(lease, new SettingsFrame(new HashMap<>(), false)); + generator.control(lease, new HeadersFrame(1, metaData1, null, true)); + + try (Socket client = new Socket("localhost", connector.getLocalPort())) + { + OutputStream output = client.getOutputStream(); + for (ByteBuffer buffer : lease.getByteBuffers()) + { + output.write(BufferUtil.toArray(buffer)); + } + + // Wait for the first request be processed on the server. + Thread.sleep(1000); + + // Send a second request and verify that it hits the Handler. + lease.recycle(); + MetaData.Request metaData2 = new MetaData.Request( + HttpMethod.GET.asString(), + HttpScheme.HTTP.asString(), + new HostPortHttpField("localhost:" + connector.getLocalPort()), + "/valid", + HttpVersion.HTTP_2, + HttpFields.EMPTY, + -1 + ); + generator.control(lease, new HeadersFrame(3, metaData2, null, true)); + for (ByteBuffer buffer : lease.getByteBuffers()) + { + output.write(BufferUtil.toArray(buffer)); + } + assertTrue(handlerLatch.await(5, TimeUnit.SECONDS)); + } + } +} From b47d9c41d7b9ecc90844be545f2aee618447419e Mon Sep 17 00:00:00 2001 From: markslater Date: Wed, 11 May 2022 22:08:28 +0100 Subject: [PATCH 15/17] #7880 retain resource service configuration (#7881) * #7880 PrecompressedFormats set on ResourceService are used in DefaultServlet unless overridden by an InitParameter. * #7880 Fix checkstyle violations. * #7880 Fix NPEs. --- .../eclipse/jetty/servlet/DefaultServlet.java | 22 ++++++--- .../jetty/servlet/DefaultServletTest.java | 46 +++++++++++++++++++ 2 files changed, 62 insertions(+), 6 deletions(-) diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/DefaultServlet.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/DefaultServlet.java index bb573ee04a9..b580148be21 100644 --- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/DefaultServlet.java +++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/DefaultServlet.java @@ -16,6 +16,7 @@ package org.eclipse.jetty.servlet; import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.Optional; import java.util.StringTokenizer; import javax.servlet.ServletContext; import javax.servlet.ServletException; @@ -170,7 +171,7 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory, Welc _resourceService.setAcceptRanges(getInitBoolean("acceptRanges", _resourceService.isAcceptRanges())); _resourceService.setDirAllowed(getInitBoolean("dirAllowed", _resourceService.isDirAllowed())); _resourceService.setRedirectWelcome(getInitBoolean("redirectWelcome", _resourceService.isRedirectWelcome())); - _resourceService.setPrecompressedFormats(parsePrecompressedFormats(getInitParameter("precompressed"), getInitBoolean("gzip", false))); + _resourceService.setPrecompressedFormats(parsePrecompressedFormats(getInitParameter("precompressed"), getInitBoolean("gzip"), _resourceService.getPrecompressedFormats())); _resourceService.setPathInfoOnly(getInitBoolean("pathInfoOnly", _resourceService.isPathInfoOnly())); _resourceService.setEtags(getInitBoolean("etags", _resourceService.isEtags())); @@ -303,8 +304,12 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory, Welc LOG.debug("resource base = {}", _resourceBase); } - private CompressedContentFormat[] parsePrecompressedFormats(String precompressed, boolean gzip) + private CompressedContentFormat[] parsePrecompressedFormats(String precompressed, Boolean gzip, CompressedContentFormat[] dft) { + if (precompressed == null && gzip == null) + { + return dft; + } List ret = new ArrayList<>(); if (precompressed != null && precompressed.indexOf('=') > 0) { @@ -314,7 +319,7 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory, Welc String encoding = setting[0].trim(); String extension = setting[1].trim(); ret.add(new CompressedContentFormat(encoding, extension)); - if (gzip && !ret.contains(CompressedContentFormat.GZIP)) + if (gzip == Boolean.TRUE && !ret.contains(CompressedContentFormat.GZIP)) ret.add(CompressedContentFormat.GZIP); } } @@ -326,7 +331,7 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory, Welc ret.add(CompressedContentFormat.GZIP); } } - else if (gzip) + else if (gzip == Boolean.TRUE) { // gzip handling is for backwards compatibility with older Jetty ret.add(CompressedContentFormat.GZIP); @@ -367,11 +372,11 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory, Welc return value; } - private boolean getInitBoolean(String name, boolean dft) + private Boolean getInitBoolean(String name) { String value = getInitParameter(name); if (value == null || value.length() == 0) - return dft; + return null; return (value.startsWith("t") || value.startsWith("T") || value.startsWith("y") || @@ -379,6 +384,11 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory, Welc value.startsWith("1")); } + private boolean getInitBoolean(String name, boolean dft) + { + return Optional.ofNullable(getInitBoolean(name)).orElse(dft); + } + private int getInitInt(String name, int dft) { String value = getInitParameter(name); diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DefaultServletTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DefaultServletTest.java index 1acd1f5a524..1ec1f9d2c52 100644 --- a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DefaultServletTest.java +++ b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DefaultServletTest.java @@ -40,6 +40,7 @@ import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.eclipse.jetty.http.CompressedContentFormat; import org.eclipse.jetty.http.DateGenerator; import org.eclipse.jetty.http.HttpContent; import org.eclipse.jetty.http.HttpField; @@ -1968,6 +1969,51 @@ public class DefaultServletTest assertThat(body, containsString("fake gzip")); } + @Test + public void testProgrammaticCustomCompressionFormats() throws Exception + { + createFile(docRoot.resolve("data0.txt"), "Hello Text 0"); + createFile(docRoot.resolve("data0.txt.br"), "fake brotli"); + createFile(docRoot.resolve("data0.txt.gz"), "fake gzip"); + createFile(docRoot.resolve("data0.txt.bz2"), "fake bzip2"); + + ResourceService resourceService = new ResourceService(); + resourceService.setPrecompressedFormats(new CompressedContentFormat[]{ + new CompressedContentFormat("bzip2", ".bz2"), + new CompressedContentFormat("gzip", ".gz"), + new CompressedContentFormat("br", ".br") + }); + ServletHolder defholder = new ServletHolder(new DefaultServlet(resourceService)); + context.addServlet(defholder, "/"); + defholder.setInitParameter("resourceBase", docRoot.toString()); + + String rawResponse; + HttpTester.Response response; + String body; + + rawResponse = connector.getResponse("GET /context/data0.txt HTTP/1.0\r\nHost:localhost:8080\r\nAccept-Encoding:bzip2, br, gzip\r\n\r\n"); + response = HttpTester.parseResponse(rawResponse); + assertThat(response.toString(), response.getStatus(), is(HttpStatus.OK_200)); + assertThat(response, containsHeaderValue(HttpHeader.CONTENT_LENGTH, "10")); + assertThat(response, containsHeaderValue(HttpHeader.CONTENT_TYPE, "text/plain")); + assertThat(response, containsHeaderValue(HttpHeader.VARY, "Accept-Encoding")); + assertThat(response, containsHeaderValue(HttpHeader.CONTENT_ENCODING, "bzip2")); + body = response.getContent(); + assertThat(body, containsString("fake bzip2")); + + // TODO: show accept-encoding search order issue (shouldn't this request return data0.txt.br?) + + rawResponse = connector.getResponse("GET /context/data0.txt HTTP/1.0\r\nHost:localhost:8080\r\nAccept-Encoding:br, gzip\r\n\r\n"); + response = HttpTester.parseResponse(rawResponse); + assertThat(response.toString(), response.getStatus(), is(HttpStatus.OK_200)); + assertThat(response, containsHeaderValue(HttpHeader.CONTENT_LENGTH, "9")); + assertThat(response, containsHeaderValue(HttpHeader.CONTENT_TYPE, "text/plain")); + assertThat(response, containsHeaderValue(HttpHeader.VARY, "Accept-Encoding")); + assertThat(response, containsHeaderValue(HttpHeader.CONTENT_ENCODING, "gzip")); + body = response.getContent(); + assertThat(body, containsString("fake gzip")); + } + @Test public void testControlCharacter() throws Exception { From 2e98a26f036557e9b0e7aa80b598225dd5c22fbe Mon Sep 17 00:00:00 2001 From: Lachlan Roberts Date: Fri, 13 May 2022 13:49:10 +1000 Subject: [PATCH 16/17] added extra checks in SectionAcknowledgmentTest Signed-off-by: Lachlan Roberts --- .../jetty/http3/qpack/SectionAcknowledgmentTest.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/jetty-http3/http3-qpack/src/test/java/org/eclipse/jetty/http3/qpack/SectionAcknowledgmentTest.java b/jetty-http3/http3-qpack/src/test/java/org/eclipse/jetty/http3/qpack/SectionAcknowledgmentTest.java index b0446f304fd..bc2eda81ce6 100644 --- a/jetty-http3/http3-qpack/src/test/java/org/eclipse/jetty/http3/qpack/SectionAcknowledgmentTest.java +++ b/jetty-http3/http3-qpack/src/test/java/org/eclipse/jetty/http3/qpack/SectionAcknowledgmentTest.java @@ -15,6 +15,7 @@ package org.eclipse.jetty.http3.qpack; import java.nio.ByteBuffer; +import org.eclipse.jetty.http3.qpack.QpackException.SessionException; import org.eclipse.jetty.http3.qpack.internal.instruction.SectionAcknowledgmentInstruction; import org.eclipse.jetty.util.BufferUtil; import org.junit.jupiter.api.BeforeEach; @@ -25,6 +26,8 @@ import static org.eclipse.jetty.http3.qpack.QpackTestUtil.toBuffer; import static org.eclipse.jetty.http3.qpack.QpackTestUtil.toMetaData; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.greaterThan; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -68,12 +71,13 @@ public class SectionAcknowledgmentTest { // Encode a header with only a value contained in the static table. ByteBuffer buffer = encode(_encoder, 0, toMetaData("GET", "/", "http")); - System.err.println(BufferUtil.toDetailString(buffer)); + assertThat(BufferUtil.remaining(buffer), greaterThan(0L)); // Parsing a section ack instruction on the encoder when we are not expecting it should result in QPACK_DECODER_STREAM_ERROR. SectionAcknowledgmentInstruction instruction = new SectionAcknowledgmentInstruction(0); ByteBuffer instructionBuffer = toBuffer(instruction); - QpackException error = assertThrows(QpackException.class, () -> _encoder.parseInstructions(instructionBuffer)); + SessionException error = assertThrows(SessionException.class, () -> _encoder.parseInstructions(instructionBuffer)); + assertThat(error.getErrorCode(), equalTo(QpackException.QPACK_ENCODER_STREAM_ERROR)); assertThat(error.getMessage(), containsString("No StreamInfo for 0")); } } From 77f164c43cd41f71888449a88f69a27b50a7379f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 13 May 2022 09:20:21 +0000 Subject: [PATCH 17/17] Bump hawtio-default from 2.14.5 to 2.15.0 Bumps [hawtio-default](https://github.com/hawtio/hawtio) from 2.14.5 to 2.15.0. - [Release notes](https://github.com/hawtio/hawtio/releases) - [Changelog](https://github.com/hawtio/hawtio/blob/main/CHANGES.md) - [Commits](https://github.com/hawtio/hawtio/compare/hawtio-2.14.5...hawtio-2.15.0) --- updated-dependencies: - dependency-name: io.hawt:hawtio-default 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 c155dece9fb..9825141c67a 100644 --- a/pom.xml +++ b/pom.xml @@ -49,7 +49,7 @@ 31.1-jre 5.1.0 2.2 - 2.14.5 + 2.15.0 4.2.5 4.4.3.Final 11.0.15.Final