This is an automated email from the ASF dual-hosted git repository. alopresto pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nifi.git
The following commit(s) were added to refs/heads/master by this push: new 1cadc72 NIFI-6019 Removes "trusted hostname" property. NIFI-6019 Adds support for excluded HTTP headers. 1cadc72 is described below commit 1cadc722229ad50cf569ee107eaeeb95dc216ea2 Author: Troy Melhase <t...@troy.io> AuthorDate: Tue Apr 23 13:36:48 2019 -0800 NIFI-6019 Removes "trusted hostname" property. NIFI-6019 Adds support for excluded HTTP headers. This closes #3452. Signed-off-by: Andy LoPresto <alopre...@apache.org> --- .../nifi/processors/standard/InvokeHTTP.java | 43 +++++++++++++--------- .../standard/util/TestInvokeHttpCommon.java | 26 +++++++++++++ 2 files changed, 52 insertions(+), 17 deletions(-) diff --git a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/InvokeHTTP.java b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/InvokeHTTP.java index 8926ba2..0fe5dab 100644 --- a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/InvokeHTTP.java +++ b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/InvokeHTTP.java @@ -30,7 +30,6 @@ import okhttp3.Request; import okhttp3.RequestBody; import okhttp3.Response; import okhttp3.ResponseBody; -import okhttp3.internal.tls.OkHostnameVerifier; import okio.BufferedSink; import org.apache.commons.io.input.TeeInputStream; import org.apache.commons.lang3.StringUtils; @@ -54,6 +53,7 @@ import org.apache.nifi.logging.ComponentLog; import org.apache.nifi.processor.AbstractProcessor; import org.apache.nifi.processor.DataUnit; import org.apache.nifi.processor.ProcessContext; +import org.apache.nifi.processor.ProcessorInitializationContext; import org.apache.nifi.processor.ProcessSession; import org.apache.nifi.processor.Relationship; import org.apache.nifi.processor.exception.ProcessException; @@ -155,6 +155,9 @@ public final class InvokeHTTP extends AbstractProcessor { EXCEPTION_CLASS, EXCEPTION_MESSAGE, "uuid", "filename", "path"))); + // Set of HTTP header names explicitly excluded from requests. + private static final Map<String, String> excludedHeaders = new HashMap<String, String>(); + public static final String HTTP = "http"; public static final String HTTPS = "https"; @@ -360,15 +363,6 @@ public final class InvokeHTTP extends AbstractProcessor { .allowableValues("true", "false") .build(); - public static final PropertyDescriptor PROP_TRUSTED_HOSTNAME = new PropertyDescriptor.Builder() - .name("Trusted Hostname") - .description("Bypass the normal truststore hostname verifier to allow the specified remote hostname as trusted. " - + "Enabling this property has MITM security implications, use wisely. Will still accept other connections based " - + "on the normal truststore hostname verifier. Only valid with SSL (HTTPS) connections.") - .addValidator(StandardValidators.NON_EMPTY_VALIDATOR) - .required(false) - .build(); - public static final PropertyDescriptor PROP_ADD_HEADERS_TO_REQUEST = new PropertyDescriptor.Builder() .name("Add Response Headers to Request") .description("Enabling this property saves all the response headers to the original request. This may be when the response headers are needed " @@ -438,7 +432,6 @@ public final class InvokeHTTP extends AbstractProcessor { PROP_PUT_ATTRIBUTE_MAX_LENGTH, PROP_DIGEST_AUTH, PROP_OUTPUT_RESPONSE_REGARDLESS, - PROP_TRUSTED_HOSTNAME, PROP_ADD_HEADERS_TO_REQUEST, PROP_CONTENT_TYPE, PROP_SEND_BODY, @@ -492,6 +485,13 @@ public final class InvokeHTTP extends AbstractProcessor { private final AtomicReference<OkHttpClient> okHttpClientAtomicReference = new AtomicReference<>(); + protected void init(ProcessorInitializationContext context) { + excludedHeaders.put("Trusted Hostname", "HTTP request header '{}' excluded. " + + "Update processor to use the SSLContextService instead. " + + "See the Access Policies section in the System Administrator's Guide."); + + } + @Override protected List<PropertyDescriptor> getSupportedPropertyDescriptors() { return PROPERTIES; @@ -573,6 +573,14 @@ public final class InvokeHTTP extends AbstractProcessor { ProxyConfiguration.validateProxySpec(validationContext, results, PROXY_SPECS); + for (String headerKey : validationContext.getProperties().values()) { + if (excludedHeaders.containsKey(headerKey)) { + // We're not using the header message format string here, just this + // static validation message string: + results.add(new ValidationResult.Builder().subject(headerKey).valid(false).explanation("Matches excluded HTTP header name").build()); + } + } + return results; } @@ -631,12 +639,6 @@ public final class InvokeHTTP extends AbstractProcessor { setSslSocketFactory(okHttpClientBuilder, sslService, sslContext, isHttpsProxy); } - // check the trusted hostname property and override the HostnameVerifier - String trustedHostname = trimToEmpty(context.getProperty(PROP_TRUSTED_HOSTNAME).getValue()); - if (!trustedHostname.isEmpty()) { - okHttpClientBuilder.hostnameVerifier(new OverrideHostnameVerifier(trustedHostname, OkHostnameVerifier.INSTANCE)); - } - setAuthenticator(okHttpClientBuilder, context); useChunked = context.getProperty(PROP_USE_CHUNKED_ENCODING).asBoolean(); @@ -1021,8 +1023,15 @@ public final class InvokeHTTP extends AbstractProcessor { requestBuilder = requestBuilder.addHeader("Date", DATE_FORMAT.print(System.currentTimeMillis())); } + final ComponentLog logger = getLogger(); for (String headerKey : dynamicPropertyNames) { String headerValue = context.getProperty(headerKey).evaluateAttributeExpressions(requestFlowFile).getValue(); + + // don't include any of the excluded headers, log instead + if (excludedHeaders.containsKey(headerKey)) { + logger.warn(excludedHeaders.get(headerKey), new Object[]{headerKey}); + continue; + } requestBuilder = requestBuilder.addHeader(headerKey, headerValue); } diff --git a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/util/TestInvokeHttpCommon.java b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/util/TestInvokeHttpCommon.java index 3304e62..39b96bf 100644 --- a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/util/TestInvokeHttpCommon.java +++ b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/util/TestInvokeHttpCommon.java @@ -1448,6 +1448,32 @@ public abstract class TestInvokeHttpCommon { Assert.assertEquals("chunked",header); } + @Test + public void testTrustedHostname() throws Exception { + addHandler(new GetOrHeadHandler()); + + runner.setProperty(InvokeHTTP.PROP_URL, url + "/status/200"); + runner.setProperty("Trusted Hostname", "https://example.com/"); + runner.assertValid(); + + runner.setProperty(InvokeHTTP.PROP_METHOD, "GET"); + runner.setProperty(InvokeHTTP.PROP_OUTPUT_RESPONSE_REGARDLESS,"true"); + runner.setProperty(InvokeHTTP.PROP_PUT_OUTPUT_IN_ATTRIBUTE,"outputBody"); + runner.assertValid(); + + createFlowFiles(runner); + runner.run(); + + runner.assertValid(); + + runner.assertTransferCount(InvokeHTTP.REL_SUCCESS_REQ, 1); + runner.assertTransferCount(InvokeHTTP.REL_RESPONSE, 1); + runner.assertTransferCount(InvokeHTTP.REL_RETRY, 0); + runner.assertTransferCount(InvokeHTTP.REL_NO_RETRY,0); + runner.assertTransferCount(InvokeHTTP.REL_FAILURE, 0); + runner.assertPenalizeCount(0); + } + public static void createFlowFiles(final TestRunner testRunner) throws UnsupportedEncodingException { final Map<String, String> attributes = new HashMap<>();