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

exceptionfactory 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 b4ab5b0d581 NIFI-15625 Remove Transfer-Encoding Header from Replicated 
Requests (#10919)
b4ab5b0d581 is described below

commit b4ab5b0d581e2eac33be7f3c0eb15bffc41ad287
Author: Rajmund Takács <[email protected]>
AuthorDate: Thu Feb 19 16:05:29 2026 +0100

    NIFI-15625 Remove Transfer-Encoding Header from Replicated Requests (#10919)
    
    - Added Transfer-Encoding to disallowed headers for framework replicated 
requests according to RFC 9112 Section 6.1 and 6.2
    
    Signed-off-by: David Handermann <[email protected]>
---
 .../client/StandardHttpReplicationClient.java      |  2 +-
 .../client/TestStandardHttpReplicationClient.java  | 49 ++++++++++++++++++++++
 2 files changed, 50 insertions(+), 1 deletion(-)

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 549be0b98fa..b78a67cdcdd 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
@@ -59,7 +59,7 @@ import java.util.zip.GZIPInputStream;
 public class StandardHttpReplicationClient implements HttpReplicationClient {
     private static final Set<String> REQUEST_BODY_METHODS = Set.of("PATCH", 
"POST", "PUT");
 
-    private static final Set<String> DISALLOWED_HEADERS = Set.of("connection", 
"content-length", "expect", "host", "upgrade");
+    private static final Set<String> DISALLOWED_HEADERS = Set.of("connection", 
"content-length", "transfer-encoding", "expect", "host", "upgrade");
 
     private static final int CONTENT_LENGTH_NOT_FOUND = -1;
 
diff --git 
a/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/test/java/org/apache/nifi/cluster/coordination/http/replication/client/TestStandardHttpReplicationClient.java
 
b/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/test/java/org/apache/nifi/cluster/coordination/http/replication/client/TestStandardHttpReplicationClient.java
index 485011309a4..fbbd4473df3 100644
--- 
a/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/test/java/org/apache/nifi/cluster/coordination/http/replication/client/TestStandardHttpReplicationClient.java
+++ 
b/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/test/java/org/apache/nifi/cluster/coordination/http/replication/client/TestStandardHttpReplicationClient.java
@@ -45,6 +45,7 @@ import java.util.Set;
 import static java.net.HttpURLConnection.HTTP_OK;
 import static org.junit.jupiter.api.Assertions.assertArrayEquals;
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertInstanceOf;
 import static org.junit.jupiter.api.Assertions.assertNotEquals;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
@@ -69,6 +70,18 @@ class TestStandardHttpReplicationClient {
 
     private static final String APPLICATION_JSON = "application/json";
 
+    private static final String TRANSFER_ENCODING_LOWERCASED = 
"transfer-encoding";
+
+    private static final String CHUNKED = "chunked";
+
+    private static final String CONNECTION_LOWERCASED = "connection";
+
+    private static final String KEEP_ALIVE = "keep-alive";
+
+    private static final String HOST_LOWERCASED = "host";
+
+    private static final String EXAMPLE_HOST = "example.com";
+
     private static final URI REPLICATE_URI = 
URI.create("http://localhost/nifi-api/flow/current-user";);
 
     private static final String URI_QUERY = "recursive=false";
@@ -195,6 +208,42 @@ class TestStandardHttpReplicationClient {
         assertResponseFound(response);
     }
 
+    @Test
+    void testReplicatePostBodyFilterOutDisallowedHeaders() throws IOException {
+        final Map<String, String> headers = Map.of(
+                CONTENT_TYPE_LOWERCASED, APPLICATION_JSON,
+                TRANSFER_ENCODING_LOWERCASED, CHUNKED,
+                CONNECTION_LOWERCASED, KEEP_ALIVE,
+                HOST_LOWERCASED, EXAMPLE_HOST
+        );
+        final Map<String, String> requestEntity = Collections.emptyMap();
+        final PreparedRequest preparedRequest = 
client.prepareRequest(POST_METHOD, headers, requestEntity);
+
+        final ArgumentCaptor<String> headerKeyCaptor = 
ArgumentCaptor.forClass(String.class);
+
+        when(webClientService.method(any())).thenReturn(httpRequestUriSpec);
+        when(httpRequestUriSpec.uri(any())).thenReturn(httpRequestBodySpec);
+        when(httpRequestBodySpec.header(headerKeyCaptor.capture(), 
anyString())).thenReturn(httpRequestBodySpec);
+        when(httpRequestBodySpec.retrieve()).thenReturn(httpResponseEntity);
+
+        when(httpResponseEntity.statusCode()).thenReturn(HTTP_OK);
+        when(httpResponseEntity.headers()).thenReturn(httpResponseHeaders);
+
+        final ByteArrayInputStream responseBody = new 
ByteArrayInputStream(EMPTY_MAP_SERIALIZED);
+        when(httpResponseEntity.body()).thenReturn(responseBody);
+
+        final Response response = client.replicate(preparedRequest, 
REPLICATE_URI);
+
+        assertResponseFound(response);
+
+        final Set<String> disallowedHeaderKeys = 
Set.of(TRANSFER_ENCODING_LOWERCASED, CONNECTION_LOWERCASED, HOST_LOWERCASED);
+        final List<String> actualHeaderKeys = headerKeyCaptor.getAllValues();
+        assertFalse(
+                
actualHeaderKeys.stream().map(String::toLowerCase).anyMatch(disallowedHeaderKeys::contains),
+                () -> "Disallowed headers found in " + actualHeaderKeys
+        );
+    }
+
     @Test
     void testReplicateGetMultivaluedMap() throws IOException {
         final Map<String, String> headers = 
Map.of(PreparedRequestHeader.CONTENT_TYPE.getHeader(), APPLICATION_JSON);

Reply via email to