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

mosermw 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 be650f2443 NIFI-15030 Filtered blank Header Names from Responses in 
InvokeHTTP
be650f2443 is described below

commit be650f2443a856292e2f9d8b8f8d84f419a8ce97
Author: exceptionfactory <[email protected]>
AuthorDate: Tue Sep 30 20:16:47 2025 -0500

    NIFI-15030 Filtered blank Header Names from Responses in InvokeHTTP
    
    Closes #10360
    Signed-off-by: Mike Moser <[email protected]>
---
 .../nifi/processors/standard/InvokeHTTP.java       | 24 +++++++++------
 .../nifi/processors/standard/InvokeHTTPTest.java   | 34 ++++++++++++++++++++--
 2 files changed, 46 insertions(+), 12 deletions(-)

diff --git 
a/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/InvokeHTTP.java
 
b/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/InvokeHTTP.java
index 9983af9fc4..e6b3574866 100644
--- 
a/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/InvokeHTTP.java
+++ 
b/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/InvokeHTTP.java
@@ -1259,7 +1259,7 @@ public class InvokeHTTP extends AbstractProcessor {
     }
 
     /**
-     * Returns a Map of flowfile attributes from the response http headers. 
Multivalue headers are naively converted to comma separated strings.
+     * Returns a Map of FlowFile attributes from the response http headers. 
Multivalue headers are naively converted to comma separated strings.
      * Prefix is passed in to allow differentiation for these new attributes.
      */
     private Map<String, String> convertAttributesFromHeaders(final Response 
responseHttp, final String prefix) {
@@ -1267,15 +1267,21 @@ public class InvokeHTTP extends AbstractProcessor {
         final Map<String, String> attributes = new HashMap<>();
         final String trimmedPrefix = trimToEmpty(prefix);
         final Headers headers = responseHttp.headers();
-        headers.names().forEach((key) -> {
-            final List<String> values = headers.values(key);
-            // we ignore any headers with no actual values (rare)
-            if (!values.isEmpty()) {
-                // create a comma separated string from the values, this is 
stored in the map
-                final String value = StringUtils.join(values, 
MULTIPLE_HEADER_DELIMITER);
-                attributes.put(trimmedPrefix + key, value);
+        for (final String headerName : headers.names()) {
+            // Ignore blank response header names
+            if (headerName.isBlank()) {
+                continue;
+            }
+            final List<String> values = headers.values(headerName);
+            // Ignore empty response header values
+            if (values.isEmpty()) {
+                continue;
             }
-        });
+
+            final String attributeName = trimmedPrefix + headerName;
+            final String delimitedValues = StringUtils.join(values, 
MULTIPLE_HEADER_DELIMITER);
+            attributes.put(attributeName, delimitedValues);
+        }
 
         final Handshake handshake = responseHttp.handshake();
         if (handshake != null) {
diff --git 
a/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/InvokeHTTPTest.java
 
b/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/InvokeHTTPTest.java
index c7b06094e1..7d5bad7f53 100644
--- 
a/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/InvokeHTTPTest.java
+++ 
b/nifi-extension-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/InvokeHTTPTest.java
@@ -19,6 +19,7 @@ package org.apache.nifi.processors.standard;
 import mockwebserver3.MockResponse;
 import mockwebserver3.MockWebServer;
 import mockwebserver3.RecordedRequest;
+import okio.ByteString;
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang3.StringUtils;
@@ -151,6 +152,8 @@ public class InvokeHTTPTest {
 
     private static final String TLS_CONNECTION_TIMEOUT = "60 s";
 
+    private static final String EMPTY_HEADER_NAME = "";
+
     private static SSLContext sslContext;
 
     private static SSLContext trustStoreSslContext;
@@ -206,7 +209,7 @@ public class InvokeHTTPTest {
     }
 
     @AfterEach
-    public void shutdownServer() throws IOException {
+    public void shutdownServer() {
         mockWebServer.close();
     }
 
@@ -431,6 +434,27 @@ public class InvokeHTTPTest {
         responseFlowFile.assertAttributeEquals(CoreAttributes.MIME_TYPE.key(), 
TEXT_PLAIN);
     }
 
+    @Test
+    public void testRunGetHttp200SuccessEmptyHeaderName() {
+        final MockResponse response = new MockResponse.Builder()
+                .code(HTTP_OK)
+                .addHeaderLenient(EMPTY_HEADER_NAME, TEXT_PLAIN)
+                .build();
+        mockWebServer.enqueue(response);
+
+        setUrlProperty();
+        runner.enqueue(FLOW_FILE_CONTENT);
+        runner.run();
+
+        assertResponseSuccessRelationships();
+        assertRelationshipStatusCodeEquals(InvokeHTTP.RESPONSE, HTTP_OK);
+
+        final MockFlowFile responseFlowFile = getResponseFlowFile();
+        final Map<String, String> attributes = 
responseFlowFile.getAttributes();
+        assertFalse(attributes.isEmpty());
+        assertFalse(attributes.containsKey(EMPTY_HEADER_NAME), "Empty 
Attribute Name found");
+    }
+
     @Test
     public void testRunGetHttp200SuccessRequestDateHeader() throws 
InterruptedException {
         runner.setProperty(InvokeHTTP.REQUEST_DATE_HEADER_ENABLED, 
StringUtils.capitalize(Boolean.TRUE.toString()));
@@ -809,7 +833,9 @@ public class InvokeHTTPTest {
         final String contentEncoding = 
request.getHeaders().get(CONTENT_ENCODING_HEADER);
         assertEquals(ContentEncodingStrategy.GZIP.getValue().toLowerCase(), 
contentEncoding);
 
-        final byte[] body = request.getBody().toByteArray();
+        final ByteString requestBody = request.getBody();
+        assertNotNull(requestBody);
+        final byte[] body = requestBody.toByteArray();
         try (final GZIPInputStream gzipInputStream = new GZIPInputStream(new 
ByteArrayInputStream(body))) {
             final String decompressed = IOUtils.toString(gzipInputStream, 
StandardCharsets.UTF_8);
             assertEquals(FLOW_FILE_CONTENT, decompressed);
@@ -863,7 +889,9 @@ public class InvokeHTTPTest {
         final Pattern multipartPattern = 
Pattern.compile("^multipart/form-data.+$");
         assertTrue(multipartPattern.matcher(contentType).matches(), "Content 
Type not matched");
 
-        final String body = request.getBody().utf8();
+        final ByteString requestBody = request.getBody();
+        assertNotNull(requestBody);
+        final String body = requestBody.utf8();
         assertTrue(body.contains(formDataParameter), "Form Data Parameter not 
found");
     }
 

Reply via email to