mirror of https://github.com/apache/nifi.git
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 <exceptionfactory@apache.org>
This commit is contained in:
parent
b0f30d6860
commit
231dbde4b3
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue