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