This is an automated email from the ASF dual-hosted git repository.

pvillard31 pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/nifi.git


The following commit(s) were added to refs/heads/main by this push:
     new ede36cdc8a2 NIFI-16152 Switched from Jersey to Jetty for gzip 
compression (#11489)
ede36cdc8a2 is described below

commit ede36cdc8a2c81ae30ff125f2e7ae3c6b747670c
Author: David Handermann <[email protected]>
AuthorDate: Thu Jul 30 16:03:37 2026 -0500

    NIFI-16152 Switched from Jersey to Jetty for gzip compression (#11489)
    
    - Added drain and close for replicated request response body to handle gzip 
encoded responses
---
 .../replication/StandardAsyncClusterResponse.java  |  19 +++
 .../replication/ThreadPoolRequestReplicator.java   |  12 +-
 .../client/StandardHttpReplicationClient.java      |  18 +++
 .../http/replication/io/ReplicatedResponse.java    |  72 ++++++-----
 .../apache/nifi/cluster/manager/NodeResponse.java  |  10 +-
 .../nifi-framework/nifi-web/nifi-jetty/pom.xml     |   8 ++
 .../org/apache/nifi/web/server/JettyServer.java    |   9 +-
 .../nifi/web/server/StandardServerProvider.java    |  27 ++++
 .../handler/UnsupportedContentEncodingHandler.java |  47 +++++++
 .../web/server/StandardServerProviderTest.java     |  58 +++++++++
 .../apache/nifi/web/NiFiWebApiResourceConfig.java  |   7 +-
 ...equestContentLengthExceededExceptionMapper.java |  44 +++++++
 ...stContentLengthExceededExceptionMapperTest.java |  42 +++++++
 .../web/security/requests/ContentLengthFilter.java |  17 +--
 .../RequestContentLengthExceededException.java     |  27 ++++
 .../security/requests/ContentLengthFilterTest.java | 138 +++++++++++++++++++++
 nifi-framework-bundle/nifi-jetty-nar/pom.xml       |  10 ++
 nifi-framework-bundle/nifi-server-nar-bom/pom.xml  |  12 ++
 .../provenance/GetLatestProvenanceEventsIT.java    |   2 +-
 19 files changed, 521 insertions(+), 58 deletions(-)

diff --git 
a/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/replication/StandardAsyncClusterResponse.java
 
b/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/replication/StandardAsyncClusterResponse.java
index 78532d8e525..a007ad1344d 100644
--- 
a/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/replication/StandardAsyncClusterResponse.java
+++ 
b/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/replication/StandardAsyncClusterResponse.java
@@ -17,6 +17,7 @@
 
 package org.apache.nifi.cluster.coordination.http.replication;
 
+import jakarta.ws.rs.core.Response;
 import org.apache.nifi.cluster.coordination.http.HttpResponseMapper;
 import org.apache.nifi.cluster.manager.NodeResponse;
 import org.apache.nifi.cluster.protocol.NodeIdentifier;
@@ -216,6 +217,7 @@ public class StandardAsyncClusterResponse implements 
AsyncClusterResponse {
 
         final long start = System.nanoTime();
         mergedResponse = responseMapper.mapResponses(uri, method, 
nodeResponses, merge);
+        closeUnusedResponses(nodeResponses);
         final long nanos = System.nanoTime() - start;
         addTiming("Map/Merge Responses", "All Nodes", nanos);
 
@@ -329,6 +331,23 @@ public class StandardAsyncClusterResponse implements 
AsyncClusterResponse {
             + ", responses=" + getCompletedNodeIdentifiers().size() + "/" + 
responseMap.size() + "]";
     }
 
+    private void closeUnusedResponses(final Set<NodeResponse> nodeResponses) {
+        final Response clientMergedResponse = 
mergedResponse.getClientResponse();
+        if (mergedResponse.getUpdatedEntity() != null) {
+            // Close merged response since Updated Entity used in place of 
stream
+            clientMergedResponse.close();
+        }
+
+        for (final NodeResponse nodeResponse : nodeResponses) {
+            final Response clientNodeResponse = 
nodeResponse.getClientResponse();
+            if (clientMergedResponse == clientNodeResponse) {
+                continue;
+            }
+
+            nodeResponse.close();
+        }
+    }
+
     private static class ResponseHolder {
         private final long nanoStart;
         private long requestNanos;
diff --git 
a/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/replication/ThreadPoolRequestReplicator.java
 
b/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/replication/ThreadPoolRequestReplicator.java
index df948c7045f..9fe079cc26f 100644
--- 
a/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/replication/ThreadPoolRequestReplicator.java
+++ 
b/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/replication/ThreadPoolRequestReplicator.java
@@ -523,8 +523,13 @@ public class ThreadPoolRequestReplicator implements 
RequestReplicator, Closeable
                         // If all nodes responded with 202-Accepted, then we 
can replicate the original request
                         // to all nodes and we are finished.
                         if (dissentingCount == 0) {
-                            logger.debug("Received verification from all {} 
nodes that mutable request {} {} can be made", numNodes, method, uri.getPath());
-                            replicate(nodeIds, method, uri, entity, headers, 
false, clusterResponse, true, merge, monitor);
+                            try {
+                                logger.debug("Received verification from all 
{} nodes that mutable request {} {} can be made", numNodes, method, 
uri.getPath());
+                                replicate(nodeIds, method, uri, entity, 
headers, false, clusterResponse, true, merge, monitor);
+                            } finally {
+                                // Close HTTP Responses after replication 
completed
+                                nodeResponses.forEach(NodeResponse::close);
+                            }
                             return;
                         }
 
@@ -582,6 +587,9 @@ public class ThreadPoolRequestReplicator implements 
RequestReplicator, Closeable
                                     clusterResponse.setFailure(failure, 
response.getNodeId());
                                 }
                             }
+
+                            // Close verification responses for cancelled 
transactions
+                            nodeResponses.forEach(NodeResponse::close);
                         } finally {
                             if (monitor != null) {
                                 synchronized (monitor) {
diff --git 
a/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/replication/client/StandardHttpReplicationClient.java
 
b/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/replication/client/StandardHttpReplicationClient.java
index b34322d54fc..b010176fad6 100644
--- 
a/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/replication/client/StandardHttpReplicationClient.java
+++ 
b/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/replication/client/StandardHttpReplicationClient.java
@@ -17,6 +17,7 @@
 package org.apache.nifi.cluster.coordination.http.replication.client;
 
 import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.core.JsonParser;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import 
com.fasterxml.jackson.module.jakarta.xmlbind.JakartaXmlBindAnnotationIntrospector;
 import jakarta.ws.rs.core.MultivaluedHashMap;
@@ -41,6 +42,7 @@ import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.OutputStream;
 import java.io.UncheckedIOException;
 import java.net.URI;
 import java.util.LinkedHashMap;
@@ -113,6 +115,8 @@ public class StandardHttpReplicationClient implements 
HttpReplicationClient {
 
         
objectMapper.setDefaultPropertyInclusion(JsonInclude.Value.construct(JsonInclude.Include.NON_NULL,
 JsonInclude.Include.ALWAYS));
         objectMapper.setAnnotationIntrospector(new 
JakartaXmlBindAnnotationIntrospector(objectMapper.getTypeFactory()));
+        // Disable closing source streams to allow draining and subsequent 
closing
+        objectMapper.disable(JsonParser.Feature.AUTO_CLOSE_SOURCE);
 
         jsonSerializer = new JsonEntitySerializer(objectMapper);
         xmlSerializer = new XmlEntitySerializer();
@@ -208,11 +212,25 @@ public class StandardHttpReplicationClient implements 
HttpReplicationClient {
 
         final InputStream responseBody = 
getResponseBody(responseEntity.body(), headers);
         final Runnable closeCallback = () -> {
+            try {
+                // Drain raw response stream before closing the Response Entity
+                
responseEntity.body().transferTo(OutputStream.nullOutputStream());
+            } catch (final IOException e) {
+                logger.debug("Drain failed for Replicated {} {} HTTP {}", 
method, location, statusCode, e);
+            }
+
             try {
                 responseEntity.close();
             } catch (final IOException e) {
                 logger.warn("Close failed for Replicated {} {} HTTP {}", 
method, location, statusCode, e);
             }
+
+            try {
+                // Release resources for gzip wrapped streams
+                responseBody.close();
+            } catch (final IOException e) {
+                logger.warn("Close failed for Replicated Response Body {} {} 
HTTP {}", method, location, statusCode, e);
+            }
         };
 
         final long elapsed = System.currentTimeMillis() - started;
diff --git 
a/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/replication/io/ReplicatedResponse.java
 
b/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/replication/io/ReplicatedResponse.java
index 46d16516cf3..8528425a6af 100644
--- 
a/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/replication/io/ReplicatedResponse.java
+++ 
b/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/replication/io/ReplicatedResponse.java
@@ -17,8 +17,6 @@
 
 package org.apache.nifi.cluster.coordination.http.replication.io;
 
-import com.fasterxml.jackson.core.JsonFactory;
-import com.fasterxml.jackson.core.JsonParser;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import jakarta.ws.rs.core.EntityTag;
 import jakarta.ws.rs.core.GenericType;
@@ -51,7 +49,7 @@ public class ReplicatedResponse extends Response {
     private static final int MAXIMUM_BUFFER_SIZE = 1048576;
     private static final int CONTENT_LENGTH_UNKNOWN = -1;
 
-    private final ObjectMapper codec;
+    private final ObjectMapper objectMapper;
     private final InputStream responseBody;
     private final MultivaluedMap<String, String> responseHeaders;
     private final URI location;
@@ -59,12 +57,12 @@ public class ReplicatedResponse extends Response {
     private final Runnable closeCallback;
     private final int contentLength;
 
-    private final JsonFactory jsonFactory = new JsonFactory();
-
     private final byte[] bufferedResponseBody;
 
+    private Object bufferedEntity;
+
     public ReplicatedResponse(
-            final ObjectMapper codec,
+            final ObjectMapper objectMapper,
             final InputStream responseBody,
             final MultivaluedMap<String, String> responseHeaders,
             final URI location,
@@ -72,7 +70,7 @@ public class ReplicatedResponse extends Response {
             final int contentLength,
             final Runnable closeCallback
     ) {
-        this.codec = codec;
+        this.objectMapper = objectMapper;
         this.responseBody = responseBody;
         this.responseHeaders = responseHeaders;
         this.location = location;
@@ -101,42 +99,30 @@ public class ReplicatedResponse extends Response {
 
     @Override
     public Object getEntity() {
-        final InputStream responseBodyStream = getResponseBodyStream();
-
-        try {
-            final JsonParser parser = 
jsonFactory.createParser(responseBodyStream);
-            parser.setCodec(codec);
-            return parser.readValueAs(Object.class);
-        } catch (final Exception e) {
-            throw new RuntimeException("Failed to parse response", e);
+        if (bufferedEntity == null) {
+            // Read response entity to buffered entity to support multiple 
invocations
+            bufferedEntity = readResponseEntity(Object.class);
         }
+
+        return bufferedEntity;
     }
 
     @Override
     @SuppressWarnings("unchecked")
-    public <T> T readEntity(Class<T> entityType) {
-        final InputStream responseBodyStream = getResponseBodyStream();
+    public <T> T readEntity(final Class<T> entityType) {
+        final T entity;
 
+        // Return raw response body stream when requested without buffering
         if (InputStream.class.equals(entityType)) {
-            return (T) responseBodyStream;
-        }
-
-        if (String.class.equals(entityType)) {
-            try {
-                final byte[] responseBytes = responseBodyStream.readAllBytes();
-                return (T) new String(responseBytes, StandardCharsets.UTF_8);
-            } catch (final IOException e) {
-                throw new UncheckedIOException("Read Replicated Response Body 
to String failed for %s".formatted(location), e);
-            }
+            return (T) getResponseBodyStream();
         }
 
-        try {
-            final JsonParser parser = 
jsonFactory.createParser(responseBodyStream);
-            parser.setCodec(codec);
-            return parser.readValueAs(entityType);
-        } catch (final Exception e) {
-            throw new RuntimeException("Failed to parse response as entity of 
type " + entityType, e);
+        if (bufferedEntity == null) {
+            // Read response entity to buffered entity to support multiple 
invocations
+            bufferedEntity = readResponseEntity(entityType);
         }
+        entity = (T) bufferedEntity;
+        return entity;
     }
 
     @Override
@@ -287,6 +273,26 @@ public class ReplicatedResponse extends Response {
         return responseBodyStream;
     }
 
+    @SuppressWarnings("unchecked")
+    private <T> T readResponseEntity(final Class<T> entityType) {
+        final InputStream responseBodyStream = getResponseBodyStream();
+
+        if (String.class.equals(entityType)) {
+            try {
+                final byte[] responseBytes = responseBodyStream.readAllBytes();
+                return (T) new String(responseBytes, StandardCharsets.UTF_8);
+            } catch (final IOException e) {
+                throw new UncheckedIOException("Read Replicated Response Body 
to String failed for %s".formatted(location), e);
+            }
+        }
+
+        try {
+            return objectMapper.readValue(responseBodyStream, entityType);
+        } catch (final Exception e) {
+            throw new RuntimeException("Failed to parse response as Entity 
[%s] for %s".formatted(entityType, location), e);
+        }
+    }
+
     private static byte[] readResponseBody(final InputStream inputStream, 
final URI location, final int statusCode) {
         try {
             return inputStream.readAllBytes();
diff --git 
a/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/NodeResponse.java
 
b/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/NodeResponse.java
index ec6cf7870a5..52fc617ec4c 100644
--- 
a/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/NodeResponse.java
+++ 
b/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/NodeResponse.java
@@ -29,6 +29,7 @@ import org.apache.nifi.web.api.entity.Entity;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.io.Closeable;
 import java.io.InputStream;
 import java.net.URI;
 import java.util.List;
@@ -47,7 +48,7 @@ import java.util.concurrent.TimeUnit;
  * This class overrides hashCode and equals and considers two instances to be 
equal if they have the equal NodeIdentifiers.
  *
  */
-public class NodeResponse {
+public class NodeResponse implements Closeable {
 
     private static final Logger logger = 
LoggerFactory.getLogger(NodeResponse.class);
     private final String httpMethod;
@@ -269,4 +270,11 @@ public class NodeResponse {
             
.append(",Duration=").append(TimeUnit.MILLISECONDS.convert(requestDurationNanos,
 TimeUnit.NANOSECONDS)).append(" ms]");
         return sb.toString();
     }
+
+    @Override
+    public void close() {
+        if (response != null) {
+            response.close();
+        }
+    }
 }
diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/pom.xml 
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/pom.xml
index 3516f3d47e5..e27f886ddcb 100644
--- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/pom.xml
+++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/pom.xml
@@ -85,6 +85,14 @@
             <artifactId>nifi-web-servlet-shared</artifactId>
             <version>2.11.0-SNAPSHOT</version>
         </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty.compression</groupId>
+            <artifactId>jetty-compression-server</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty.compression</groupId>
+            <artifactId>jetty-compression-gzip</artifactId>
+        </dependency>
         <dependency>
             <groupId>org.eclipse.jetty</groupId>
             <artifactId>jetty-deploy</artifactId>
diff --git 
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/main/java/org/apache/nifi/web/server/JettyServer.java
 
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/main/java/org/apache/nifi/web/server/JettyServer.java
index 706a349d086..1cce71048a6 100644
--- 
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/main/java/org/apache/nifi/web/server/JettyServer.java
+++ 
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/main/java/org/apache/nifi/web/server/JettyServer.java
@@ -69,6 +69,7 @@ import 
org.apache.nifi.web.server.filter.LogoutCompleteRedirectFilter;
 import org.apache.nifi.web.server.filter.RequestFilterProvider;
 import org.apache.nifi.web.server.filter.RestApiRequestFilterProvider;
 import org.apache.nifi.web.server.filter.StandardRequestFilterProvider;
+import org.eclipse.jetty.compression.server.CompressionHandler;
 import org.eclipse.jetty.deploy.StandardDeployer;
 import org.eclipse.jetty.ee.webapp.WebAppClassLoader;
 import org.eclipse.jetty.ee11.servlet.ErrorPageErrorHandler;
@@ -222,7 +223,13 @@ public class JettyServer implements NiFiServer, 
ExtensionUiLoader {
                 deployer = new StandardDeployer(contextHandlerCollection);
                 server.addBean(deployer);
 
-                serverHandlerCollection.addHandler(contextHandlerCollection);
+                // Deploy the web applications beneath the CompressionHandler
+                final CompressionHandler compressionHandler = 
serverHandlerCollection.getDescendant(CompressionHandler.class);
+                if (compressionHandler == null) {
+                    throw new IllegalStateException("Compression Handler not 
configured: Server Provider configuration failed");
+                } else {
+                    compressionHandler.setHandler(contextHandlerCollection);
+                }
             } else {
                 throw new IllegalStateException("Server Handler not 
Handler.Collection: Server Provider configuration failed");
             }
diff --git 
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/main/java/org/apache/nifi/web/server/StandardServerProvider.java
 
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/main/java/org/apache/nifi/web/server/StandardServerProvider.java
index e09e4d1067d..ad5a02be511 100644
--- 
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/main/java/org/apache/nifi/web/server/StandardServerProvider.java
+++ 
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/main/java/org/apache/nifi/web/server/StandardServerProvider.java
@@ -21,8 +21,12 @@ import org.apache.nifi.util.NiFiProperties;
 import org.apache.nifi.web.server.connector.FrameworkServerConnectorFactory;
 import org.apache.nifi.web.server.handler.ContextPathRedirectPatternRule;
 import org.apache.nifi.web.server.handler.HeaderWriterHandler;
+import org.apache.nifi.web.server.handler.UnsupportedContentEncodingHandler;
 import org.apache.nifi.web.server.log.RequestLogProvider;
 import org.apache.nifi.web.server.log.StandardRequestLogProvider;
+import org.eclipse.jetty.compression.gzip.GzipCompression;
+import org.eclipse.jetty.compression.server.CompressionConfig;
+import org.eclipse.jetty.compression.server.CompressionHandler;
 import org.eclipse.jetty.rewrite.handler.RedirectPatternRule;
 import org.eclipse.jetty.rewrite.handler.RewriteHandler;
 import org.eclipse.jetty.server.Handler;
@@ -47,6 +51,8 @@ import javax.net.ssl.SSLContext;
  * Standard implementation of Server Provider with default Handlers
  */
 class StandardServerProvider implements ServerProvider {
+    private static final String ROOT_PATH = "/";
+
     private static final String ALL_PATHS_PATTERN = "/*";
 
     private static final String FRONTEND_CONTEXT_PATH = "/nifi";
@@ -139,6 +145,27 @@ class StandardServerProvider implements ServerProvider {
         // Set Handler for standard response headers
         standardHandler.addHandler(new HeaderWriterHandler());
 
+        // Reject requests that declare a Content-Encoding because request 
bodies are not decompressed
+        standardHandler.addHandler(new UnsupportedContentEncodingHandler());
+
+        // Set Handler for response compression
+        standardHandler.addHandler(getCompressionHandler());
+
         return standardHandler;
     }
+
+    private CompressionHandler getCompressionHandler() {
+        final GzipCompression gzipCompression = new GzipCompression();
+        final CompressionHandler compressionHandler = new CompressionHandler();
+        compressionHandler.putCompression(gzipCompression);
+
+        final CompressionConfig compressionConfig = CompressionConfig.builder()
+                .defaults()
+                // Disable decompression of requests
+                .decompressExcludeEncoding(gzipCompression.getEncodingName())
+                .build();
+        compressionHandler.putConfiguration(ROOT_PATH, compressionConfig);
+
+        return compressionHandler;
+    }
 }
diff --git 
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/main/java/org/apache/nifi/web/server/handler/UnsupportedContentEncodingHandler.java
 
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/main/java/org/apache/nifi/web/server/handler/UnsupportedContentEncodingHandler.java
new file mode 100644
index 00000000000..d3668665384
--- /dev/null
+++ 
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/main/java/org/apache/nifi/web/server/handler/UnsupportedContentEncodingHandler.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.web.server.handler;
+
+import org.eclipse.jetty.http.HttpHeader;
+import org.eclipse.jetty.http.HttpStatus;
+import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Response;
+import org.eclipse.jetty.util.Callback;
+
+/**
+ * Handler that rejects requests declaring an unsupported Content-Encoding
+ */
+public class UnsupportedContentEncodingHandler extends Handler.Abstract {
+
+    private static final String IDENTITY_ENCODING = "identity";
+
+    private static final String UNSUPPORTED_MESSAGE = "Content-Encoding not 
supported";
+
+    @Override
+    public boolean handle(final Request request, final Response response, 
final Callback callback) {
+        final String contentEncoding = 
request.getHeaders().get(HttpHeader.CONTENT_ENCODING);
+
+        // A request without a Content-Encoding, or one declaring only the 
identity encoding, is passed to later Handlers
+        if (contentEncoding == null || contentEncoding.isBlank() || 
IDENTITY_ENCODING.equalsIgnoreCase(contentEncoding.trim())) {
+            return false;
+        }
+
+        Response.writeError(request, response, callback, 
HttpStatus.UNSUPPORTED_MEDIA_TYPE_415, UNSUPPORTED_MESSAGE);
+        return true;
+    }
+}
diff --git 
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/test/java/org/apache/nifi/web/server/StandardServerProviderTest.java
 
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/test/java/org/apache/nifi/web/server/StandardServerProviderTest.java
index 65c815a08a9..f7a79dcfcae 100644
--- 
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/test/java/org/apache/nifi/web/server/StandardServerProviderTest.java
+++ 
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/test/java/org/apache/nifi/web/server/StandardServerProviderTest.java
@@ -23,8 +23,12 @@ import org.apache.nifi.security.ssl.EphemeralKeyStoreBuilder;
 import org.apache.nifi.security.ssl.StandardSslContextBuilder;
 import org.apache.nifi.util.NiFiProperties;
 import org.apache.nifi.web.server.handler.HeaderWriterHandler;
+import org.apache.nifi.web.server.handler.UnsupportedContentEncodingHandler;
 import org.apache.nifi.web.servlet.shared.ProxyHeader;
+import org.eclipse.jetty.compression.server.CompressionConfig;
+import org.eclipse.jetty.compression.server.CompressionHandler;
 import org.eclipse.jetty.http.HttpHeader;
+import org.eclipse.jetty.http.HttpMethod;
 import org.eclipse.jetty.http.HttpStatus;
 import org.eclipse.jetty.rewrite.handler.RewriteHandler;
 import org.eclipse.jetty.server.Connector;
@@ -51,6 +55,7 @@ import java.time.Duration;
 import java.util.List;
 import java.util.Optional;
 import java.util.Properties;
+import java.util.Set;
 import java.util.concurrent.TimeUnit;
 import javax.net.ssl.SSLContext;
 import javax.security.auth.x500.X500Principal;
@@ -151,6 +156,59 @@ class StandardServerProviderTest {
         assertHttpConnectorFound(server);
     }
 
+    @Test
+    void testGetServerCompressionHandlerCompressesResponses() {
+        final Properties applicationProperties = new Properties();
+        applicationProperties.setProperty(NiFiProperties.WEB_HTTP_PORT, 
RANDOM_PORT);
+        final NiFiProperties properties = 
NiFiProperties.createBasicNiFiProperties((String) null, applicationProperties);
+
+        final StandardServerProvider provider = new 
StandardServerProvider(null);
+
+        final Server server = provider.getServer(properties);
+
+        final Handler.Collection handlerCollection = (Handler.Collection) 
server.getHandler();
+        final CompressionHandler compressionHandler = 
handlerCollection.getDescendant(CompressionHandler.class);
+        assertNotNull(compressionHandler);
+
+        final CompressionConfig compressionConfig = 
compressionHandler.getConfiguration("/");
+        assertNotNull(compressionConfig);
+
+        final Set<String> compressMethods = 
compressionConfig.getCompressIncludeMethods();
+        assertTrue(compressMethods.contains(HttpMethod.GET.asString()));
+        assertTrue(compressMethods.contains(HttpMethod.POST.asString()));
+
+        final UnsupportedContentEncodingHandler 
unsupportedContentEncodingHandler = 
handlerCollection.getDescendant(UnsupportedContentEncodingHandler.class);
+        assertNotNull(unsupportedContentEncodingHandler);
+    }
+
+    @Timeout(15)
+    @Test
+    void testGetServerRejectsCompressedRequestBody() throws Exception {
+        final Properties applicationProperties = new Properties();
+        applicationProperties.setProperty(NiFiProperties.WEB_HTTP_PORT, 
RANDOM_PORT);
+        final NiFiProperties properties = 
NiFiProperties.createBasicNiFiProperties((String) null, applicationProperties);
+
+        final StandardServerProvider provider = new 
StandardServerProvider(null);
+
+        final Server server = provider.getServer(properties);
+
+        try {
+            startServer(server);
+            final URI localhostUri = 
UriComponentsBuilder.fromUri(server.getURI()).host(LOCALHOST_NAME).build().toUri();
+
+            try (HttpClient httpClient = 
HttpClient.newBuilder().connectTimeout(TIMEOUT).build()) {
+                final HttpRequest compressedRequest = 
HttpRequest.newBuilder(localhostUri)
+                        .version(HttpClient.Version.HTTP_1_1)
+                        .header(HttpHeader.CONTENT_ENCODING.asString(), "gzip")
+                        .POST(HttpRequest.BodyPublishers.ofByteArray(new 
byte[]{1, 2, 3}))
+                        .build();
+                assertResponseStatusCode(httpClient, compressedRequest, 
HttpStatus.UNSUPPORTED_MEDIA_TYPE_415);
+            }
+        } finally {
+            server.stop();
+        }
+    }
+
     @Test
     void testGetServerHttps() {
         final Properties applicationProperties = new Properties();
diff --git 
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiWebApiResourceConfig.java
 
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiWebApiResourceConfig.java
index 8eece65de4e..ff4591c4132 100644
--- 
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiWebApiResourceConfig.java
+++ 
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiWebApiResourceConfig.java
@@ -46,6 +46,7 @@ import 
org.apache.nifi.web.api.config.NodeDisconnectionExceptionMapper;
 import org.apache.nifi.web.api.config.NodeReconnectionExceptionMapper;
 import org.apache.nifi.web.api.config.NotFoundExceptionMapper;
 import org.apache.nifi.web.api.config.RangeNotSatisfiableExceptionMapper;
+import 
org.apache.nifi.web.api.config.RequestContentLengthExceededExceptionMapper;
 import org.apache.nifi.web.api.config.ResourceNotFoundExceptionMapper;
 import org.apache.nifi.web.api.config.ThrowableMapper;
 import org.apache.nifi.web.api.config.UnknownNodeExceptionMapper;
@@ -56,9 +57,7 @@ import org.apache.nifi.web.api.filter.RedirectResourceFilter;
 import org.apache.nifi.web.util.ObjectMapperResolver;
 import org.glassfish.jersey.jackson.JacksonFeature;
 import org.glassfish.jersey.media.multipart.MultiPartFeature;
-import org.glassfish.jersey.message.GZipEncoder;
 import org.glassfish.jersey.server.ResourceConfig;
-import org.glassfish.jersey.server.filter.EncodingFilter;
 import org.springframework.context.ApplicationContext;
 import org.springframework.web.context.support.WebApplicationContextUtils;
 
@@ -135,6 +134,7 @@ public class NiFiWebApiResourceConfig extends 
ResourceConfig {
         register(NodeDisconnectionExceptionMapper.class);
         register(NodeReconnectionExceptionMapper.class);
         register(RangeNotSatisfiableExceptionMapper.class);
+        register(RequestContentLengthExceededExceptionMapper.class);
         register(ResourceNotFoundExceptionMapper.class);
         register(NotFoundExceptionMapper.class);
         register(UnknownNodeExceptionMapper.class);
@@ -142,9 +142,6 @@ public class NiFiWebApiResourceConfig extends 
ResourceConfig {
         register(ValidationExceptionMapper.class);
         register(WebApplicationExceptionMapper.class);
         register(ThrowableMapper.class);
-
-        // gzip
-        EncodingFilter.enableFor(this, GZipEncoder.class);
     }
 
 }
diff --git 
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/config/RequestContentLengthExceededExceptionMapper.java
 
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/config/RequestContentLengthExceededExceptionMapper.java
new file mode 100644
index 00000000000..edecbd4684f
--- /dev/null
+++ 
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/config/RequestContentLengthExceededExceptionMapper.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.web.api.config;
+
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.ext.ExceptionMapper;
+import jakarta.ws.rs.ext.Provider;
+import 
org.apache.nifi.web.security.requests.RequestContentLengthExceededException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Map Request Content Length Exceeded Exception to HTTP 413 response status
+ */
+@Provider
+public class RequestContentLengthExceededExceptionMapper implements 
ExceptionMapper<RequestContentLengthExceededException> {
+
+    private static final Logger logger = 
LoggerFactory.getLogger(RequestContentLengthExceededExceptionMapper.class);
+
+    @Override
+    public Response toResponse(final RequestContentLengthExceededException 
exception) {
+        logger.info("HTTP 413 Content Too Large: {}", exception.getMessage());
+
+        return Response.status(Response.Status.REQUEST_ENTITY_TOO_LARGE)
+                .entity(exception.getMessage())
+                .type(MediaType.TEXT_PLAIN_TYPE)
+                .build();
+    }
+}
diff --git 
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/web/api/config/RequestContentLengthExceededExceptionMapperTest.java
 
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/web/api/config/RequestContentLengthExceededExceptionMapperTest.java
new file mode 100644
index 00000000000..1add6145fcd
--- /dev/null
+++ 
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/web/api/config/RequestContentLengthExceededExceptionMapperTest.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.web.api.config;
+
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Response;
+import 
org.apache.nifi.web.security.requests.RequestContentLengthExceededException;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+class RequestContentLengthExceededExceptionMapperTest {
+
+    private static final String MESSAGE = "Content Too Large";
+
+    private final RequestContentLengthExceededExceptionMapper mapper = new 
RequestContentLengthExceededExceptionMapper();
+
+    @Test
+    void testToResponseRequestEntityTooLarge() {
+        final RequestContentLengthExceededException exception = new 
RequestContentLengthExceededException(MESSAGE);
+
+        try (Response response = mapper.toResponse(exception)) {
+            
assertEquals(Response.Status.REQUEST_ENTITY_TOO_LARGE.getStatusCode(), 
response.getStatus());
+            assertEquals(MESSAGE, response.getEntity());
+            assertEquals(MediaType.TEXT_PLAIN_TYPE, response.getMediaType());
+        }
+    }
+}
diff --git 
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/requests/ContentLengthFilter.java
 
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/requests/ContentLengthFilter.java
index 1200e7f2c9d..2eb0d6e0f90 100644
--- 
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/requests/ContentLengthFilter.java
+++ 
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/requests/ContentLengthFilter.java
@@ -96,19 +96,6 @@ public class ContentLengthFilter implements Filter {
         }
     }
 
-    @Override
-    public void destroy() {
-    }
-
-    /**
-     * Returns the currently configured max content length in bytes.
-     *
-     * @return the max content length
-     */
-    public int getMaxContentLength() {
-        return maxContentLength;
-    }
-
     /**
      * Returns {@code true} if this request is subject to the filter 
operation, {@code false} if not.
      *
@@ -137,7 +124,7 @@ public class ContentLengthFilter implements Filter {
 
     // This wrapper ensures that the input stream of the wrapped request is 
not read past the given maximum.
     private static class LimitedContentLengthRequest extends 
HttpServletRequestWrapper {
-        private int maxRequestLength;
+        private final int maxRequestLength;
 
         public LimitedContentLengthRequest(HttpServletRequest request, int 
maxLength) {
             super(request);
@@ -174,7 +161,7 @@ public class ContentLengthFilter implements Filter {
 
                     inputStreamByteCounter += 1;
                     if (inputStreamByteCounter > maxRequestLength) {
-                        throw new IOException(String.format("Request input 
stream longer than %d B.", maxRequestLength));
+                        throw new 
RequestContentLengthExceededException("Content Too Large: exceeded " + 
formatSize(maxRequestLength));
                     }
                     return read;
                 }
diff --git 
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/requests/RequestContentLengthExceededException.java
 
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/requests/RequestContentLengthExceededException.java
new file mode 100644
index 00000000000..3be44ebf2da
--- /dev/null
+++ 
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/requests/RequestContentLengthExceededException.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.web.security.requests;
+
+/**
+ * Request Content Length Exceeded Exception indicating HTTP 413 response 
status
+ */
+public class RequestContentLengthExceededException extends RuntimeException {
+
+    public RequestContentLengthExceededException(final String message) {
+        super(message);
+    }
+}
diff --git 
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/java/org/apache/nifi/web/security/requests/ContentLengthFilterTest.java
 
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/java/org/apache/nifi/web/security/requests/ContentLengthFilterTest.java
new file mode 100644
index 00000000000..64b611f87c6
--- /dev/null
+++ 
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/java/org/apache/nifi/web/security/requests/ContentLengthFilterTest.java
@@ -0,0 +1,138 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.web.security.requests;
+
+import jakarta.servlet.FilterChain;
+import jakarta.servlet.FilterConfig;
+import jakarta.servlet.ReadListener;
+import jakarta.servlet.ServletInputStream;
+import jakarta.servlet.ServletOutputStream;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import org.junit.jupiter.api.Test;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+class ContentLengthFilterTest {
+
+    private static final int MAX_LENGTH = 1000;
+
+    private static final int WITHIN_LIMIT_LENGTH = 500;
+
+    private static final int OVERSIZED_LENGTH = 2000;
+
+    private static final String REQUEST_URI = "/nifi-api/process-groups/root";
+
+    private static final int UNKNOWN_CONTENT_LENGTH_VALUE = -1;
+
+    @Test
+    void 
testDecompressedBodyExceedingLimitThrowsRequestContentLengthExceededException() 
throws Exception {
+        final ContentLengthFilter filter = createFilter();
+
+        // Create post request with unknown Content-Length header and 
compressed content exceeding configured limits
+        final HttpServletRequest request = 
createPostRequest(UNKNOWN_CONTENT_LENGTH_VALUE, OVERSIZED_LENGTH);
+        final HttpServletResponse response = mock(HttpServletResponse.class);
+
+        final FilterChain readingChain = (req, res) -> {
+            final InputStream inputStream = req.getInputStream();
+            inputStream.readAllBytes();
+        };
+
+        assertThrows(RequestContentLengthExceededException.class, () -> 
filter.doFilter(request, response, readingChain));
+    }
+
+    @Test
+    void testDecompressedBodyWithinLimitConsumedSuccessfully() throws 
Exception {
+        final ContentLengthFilter filter = createFilter();
+
+        final HttpServletRequest request = 
createPostRequest(UNKNOWN_CONTENT_LENGTH_VALUE, WITHIN_LIMIT_LENGTH);
+        final HttpServletResponse response = mock(HttpServletResponse.class);
+
+        final FilterChain readingChain = (req, res) -> {
+            final InputStream inputStream = req.getInputStream();
+            inputStream.readAllBytes();
+        };
+
+        filter.doFilter(request, response, readingChain);
+    }
+
+    @Test
+    void testDeclaredContentLengthExceedingLimitRejectedWithPayloadTooLarge() 
throws Exception {
+        final ContentLengthFilter filter = createFilter();
+
+        final HttpServletRequest request = createPostRequest(OVERSIZED_LENGTH, 
OVERSIZED_LENGTH);
+        final HttpServletResponse response = mock(HttpServletResponse.class);
+        
when(response.getOutputStream()).thenReturn(mock(ServletOutputStream.class));
+
+        final FilterChain chain = mock(FilterChain.class);
+
+        filter.doFilter(request, response, chain);
+
+        
verify(response).setStatus(HttpServletResponse.SC_REQUEST_ENTITY_TOO_LARGE);
+    }
+
+    private ContentLengthFilter createFilter() throws Exception {
+        final ContentLengthFilter filter = new ContentLengthFilter();
+        final FilterConfig filterConfig = mock(FilterConfig.class);
+        
when(filterConfig.getInitParameter(ContentLengthFilter.MAX_LENGTH_INIT_PARAM)).thenReturn(Integer.toString(MAX_LENGTH));
+        filter.init(filterConfig);
+        return filter;
+    }
+
+    private HttpServletRequest createPostRequest(final int 
declaredContentLength, final int bodyLength) throws IOException {
+        final HttpServletRequest request = mock(HttpServletRequest.class);
+        when(request.getMethod()).thenReturn("POST");
+        when(request.getRequestURI()).thenReturn(REQUEST_URI);
+        when(request.getContentLength()).thenReturn(declaredContentLength);
+        when(request.getInputStream()).thenReturn(new 
ByteArrayServletInputStream(new byte[bodyLength]));
+        return request;
+    }
+
+    private static class ByteArrayServletInputStream extends 
ServletInputStream {
+        private final ByteArrayInputStream inputStream;
+
+        private ByteArrayServletInputStream(final byte[] bytes) {
+            this.inputStream = new ByteArrayInputStream(bytes);
+        }
+
+        @Override
+        public boolean isFinished() {
+            return inputStream.available() == 0;
+        }
+
+        @Override
+        public boolean isReady() {
+            return true;
+        }
+
+        @Override
+        public void setReadListener(final ReadListener readListener) {
+        }
+
+        @Override
+        public int read() {
+            return inputStream.read();
+        }
+    }
+}
diff --git a/nifi-framework-bundle/nifi-jetty-nar/pom.xml 
b/nifi-framework-bundle/nifi-jetty-nar/pom.xml
index e1b501a9856..45bd22d2bc3 100644
--- a/nifi-framework-bundle/nifi-jetty-nar/pom.xml
+++ b/nifi-framework-bundle/nifi-jetty-nar/pom.xml
@@ -81,6 +81,16 @@
             <artifactId>jetty-xml</artifactId>
             <scope>compile</scope>
         </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty.compression</groupId>
+            <artifactId>jetty-compression-server</artifactId>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty.compression</groupId>
+            <artifactId>jetty-compression-gzip</artifactId>
+            <scope>compile</scope>
+        </dependency>
         <dependency>
             <groupId>org.eclipse.jetty</groupId>
             <artifactId>jetty-deploy</artifactId>
diff --git a/nifi-framework-bundle/nifi-server-nar-bom/pom.xml 
b/nifi-framework-bundle/nifi-server-nar-bom/pom.xml
index 760e20b2ee4..79f55f1c738 100644
--- a/nifi-framework-bundle/nifi-server-nar-bom/pom.xml
+++ b/nifi-framework-bundle/nifi-server-nar-bom/pom.xml
@@ -98,6 +98,18 @@
                         <groupId>org.springframework</groupId>
                         <artifactId>spring-web</artifactId>
                     </exclusion>
+                    <exclusion>
+                        <groupId>org.eclipse.jetty</groupId>
+                        <artifactId>jetty-rewrite</artifactId>
+                    </exclusion>
+                    <exclusion>
+                        <groupId>org.eclipse.jetty.compression</groupId>
+                        <artifactId>jetty-compression-gzip</artifactId>
+                    </exclusion>
+                    <exclusion>
+                        <groupId>org.eclipse.jetty.compression</groupId>
+                        <artifactId>jetty-compression-server</artifactId>
+                    </exclusion>
                 </exclusions>
             </dependency>
         </dependencies>
diff --git 
a/nifi-system-tests/nifi-system-test-suite/src/test/java/org/apache/nifi/tests/system/provenance/GetLatestProvenanceEventsIT.java
 
b/nifi-system-tests/nifi-system-test-suite/src/test/java/org/apache/nifi/tests/system/provenance/GetLatestProvenanceEventsIT.java
index 382fe843472..32e6b2eabaf 100644
--- 
a/nifi-system-tests/nifi-system-test-suite/src/test/java/org/apache/nifi/tests/system/provenance/GetLatestProvenanceEventsIT.java
+++ 
b/nifi-system-tests/nifi-system-test-suite/src/test/java/org/apache/nifi/tests/system/provenance/GetLatestProvenanceEventsIT.java
@@ -68,7 +68,7 @@ public class GetLatestProvenanceEventsIT extends NiFiSystemIT 
{
             final LatestProvenanceEventsEntity entity = 
getNifiClient().getProvenanceClient().getLatestEvents(reverse.getId());
             final List<ProvenanceEventDTO> events = 
entity.getLatestProvenanceEvents().getProvenanceEvents();
             return events.size() == expectedEventCount;
-        });
+        }, 250);
 
         final LatestProvenanceEventsEntity entity = 
getNifiClient().getProvenanceClient().getLatestEvents(reverse.getId());
         final List<ProvenanceEventDTO> events = 
entity.getLatestProvenanceEvents().getProvenanceEvents();

Reply via email to