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

exceptionfactory pushed a commit to branch support/nifi-1.x
in repository https://gitbox.apache.org/repos/asf/nifi.git


The following commit(s) were added to refs/heads/support/nifi-1.x by this push:
     new b3fb0b2713 NIFI-12516 Corrected Cluster Replicated Response Headers 
for HTTP/2
b3fb0b2713 is described below

commit b3fb0b2713d3e6f1c7ae6578b71d9e31a2aca195
Author: Mark Payne <marka...@hotmail.com>
AuthorDate: Fri Dec 15 12:12:48 2023 -0500

    NIFI-12516 Corrected Cluster Replicated Response Headers for HTTP/2
    
    The headers in the map that come back when replicating a request used to be 
in the case given; however they can be lowercased in the OkHttp Headers object 
when using HTTP/2 instead of HTTP/1.1. As a result, we need to ensure that we 
always use lower-case header names or check the map case-insensitive.
    
    This closes #8163
    
    Signed-off-by: David Handermann <exceptionfact...@apache.org>
    (cherry picked from commit 231dbde4b30bfea5b711169fe6f125c9279ec450)
---
 .../http/replication/okhttp/JacksonResponse.java   |  9 ++++--
 .../apache/nifi/web/StandardNiFiContentAccess.java | 36 ++++++++++++++++++++--
 2 files changed, 41 insertions(+), 4 deletions(-)

diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/replication/okhttp/JacksonResponse.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/replication/okhttp/JacksonResponse.java
index e4eb45cf1f..3f10d42f89 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/replication/okhttp/JacksonResponse.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/replication/okhttp/JacksonResponse.java
@@ -231,7 +231,12 @@ public class JacksonResponse extends Response {
     }
 
     @Override
-    public String getHeaderString(String name) {
-        return responseHeaders.getFirst(name);
+    public String getHeaderString(final String name) {
+        final String headerValue = responseHeaders.getFirst(name);
+        if (headerValue != null) {
+            return headerValue;
+        }
+
+        return responseHeaders.getFirst(name.toLowerCase());
     }
 }
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiContentAccess.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiContentAccess.java
index 79973fe147..7271b7ffaa 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiContentAccess.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiContentAccess.java
@@ -35,6 +35,7 @@ import java.net.URI;
 import java.net.URISyntaxException;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.regex.Matcher;
@@ -113,11 +114,11 @@ public class StandardNiFiContentAccess implements 
ContentAccess {
             }
 
             // get the file name
-            final String contentDisposition = 
responseHeaders.getFirst("Content-Disposition");
+            final String contentDisposition = getHeader(responseHeaders, 
"content-disposition");
             final String filename = 
StringUtils.substringBetween(contentDisposition, "filename=\"", "\"");
 
             // get the content type
-            final String contentType = 
responseHeaders.getFirst("Content-Type");
+            final String contentType = getHeader(responseHeaders, 
"content-type");
 
             // create the downloadable content
             return new DownloadableContent(filename, contentType, 
nodeResponse.getInputStream());
@@ -159,6 +160,37 @@ public class StandardNiFiContentAccess implements 
ContentAccess {
         }
     }
 
+    /**
+     * Returns the value of the first header in the given header map whose 
name matches the given header name.
+     * In HTTP 2.0, all header names should be lower-case. Before that, they 
were not necessarily. The spec, however,
+     * indicates that header names are case-insensitive. That said, the code 
has them stored in a Map, and the keys in Maps
+     * are not case-insensitive. This method allows us to access the value of 
the first header with the given name,
+     * ignoring case.
+     *
+     * @param headers the map containing all headers
+     * @param headerName the case-insensitive name of the header to retrieve
+     * @return the value of the first header with the given name, or 
<code>null</code> if the header is not found
+     */
+    private String getHeader(final MultivaluedMap<String, String> headers, 
final String headerName) {
+        if (headers == null || headers.isEmpty() || headerName == null || 
headerName.isBlank()) {
+            return null;
+        }
+
+        final String exactMatch = headers.getFirst(headerName);
+        if (exactMatch != null) {
+            return exactMatch;
+        }
+
+        for (final Map.Entry<String, List<String>> entry : headers.entrySet()) 
{
+            if (entry.getKey().equalsIgnoreCase(headerName)) {
+                final List<String> values = entry.getValue();
+                return values == null || values.isEmpty() ? null : 
values.get(0);
+            }
+        }
+
+        return null;
+    }
+
     private DownloadableContent getFlowFileContent(final String connectionId, 
final String flowfileId, final String dataUri) {
         // user authorization is handled once we have the actual content so we 
can utilize the flow file attributes in the resource context
         return serviceFacade.getContent(connectionId, flowfileId, dataUri);

Reply via email to