From ba06a9fa895b1e271f2d0a0b8e2e4d13f171e0aa Mon Sep 17 00:00:00 2001 From: Alessandro D'Armiento Date: Mon, 25 May 2020 20:28:48 +0200 Subject: [PATCH] * HandleHttpRequest.PORT is validated --- .../standard/HandleHttpRequest.java | 25 +++++++++++- .../standard/ITestHandleHttpRequest.java | 38 ++++++++++++++++++- 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/HandleHttpRequest.java b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/HandleHttpRequest.java index bdc9a99705cc..1df0f6e3f0ff 100644 --- a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/HandleHttpRequest.java +++ b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/HandleHttpRequest.java @@ -30,6 +30,8 @@ import org.apache.nifi.annotation.notification.PrimaryNodeState; import org.apache.nifi.components.AllowableValue; import org.apache.nifi.components.PropertyDescriptor; +import org.apache.nifi.components.ValidationContext; +import org.apache.nifi.components.ValidationResult; import org.apache.nifi.expression.ExpressionLanguageScope; import org.apache.nifi.flowfile.FlowFile; import org.apache.nifi.http.HttpContextMap; @@ -77,6 +79,7 @@ import java.security.Principal; import java.security.cert.X509Certificate; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.Enumeration; import java.util.HashMap; @@ -142,6 +145,8 @@ public class HandleHttpRequest extends AbstractProcessor { private static final String MIME_TYPE__MULTIPART_FORM_DATA = "multipart/form-data"; private static final Pattern URL_QUERY_PARAM_DELIMITER = Pattern.compile("&"); + private static final Long MIN_PORT = 0L; + private static final Long MAX_PORT = 65535L; // Allowable values for client auth public static final AllowableValue CLIENT_NONE = new AllowableValue("No Authentication", "No Authentication", @@ -156,7 +161,7 @@ public class HandleHttpRequest extends AbstractProcessor { .name("Listening Port") .description("The Port to listen on for incoming HTTP requests") .required(true) - .addValidator(StandardValidators.createLongValidator(0L, 65535L, true)) + .addValidator(StandardValidators.createLongValidator(MIN_PORT, MAX_PORT, true)) .expressionLanguageSupported(ExpressionLanguageScope.VARIABLE_REGISTRY) .defaultValue("80") .build(); @@ -321,6 +326,24 @@ public Set getRelationships() { return Collections.singleton(REL_SUCCESS); } + @Override + protected Collection customValidate(final ValidationContext validationContext) { + final List results = new ArrayList<>(); + + final Long port = validationContext.getProperty(PORT).evaluateAttributeExpressions().asLong(); + if (port < MIN_PORT || port > MAX_PORT) { + results.add(new ValidationResult.Builder() + .subject("Listening Port") + .input(String.valueOf(port)) + .valid(false) + .explanation(String.format(" property shoult be included between " + + "inclusive %d and %d", MIN_PORT, MAX_PORT)) + .build()); + } + + return results; + } + @OnScheduled public void clearInit(){ initialized.set(false); diff --git a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/ITestHandleHttpRequest.java b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/ITestHandleHttpRequest.java index 93510ee3a9c4..5c4440564bdd 100644 --- a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/ITestHandleHttpRequest.java +++ b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/ITestHandleHttpRequest.java @@ -134,15 +134,50 @@ public void tearDown() throws Exception { } } + @Test(timeout = 30000) + public void testValidation() throws InitializationException { + CountDownLatch serverReady = new CountDownLatch(1); + CountDownLatch requestSent = new CountDownLatch(1); + + final Long validPort = 1234L; + final Long negativePort = -1234L; + final Long tooHighPort = 165535L; + + processor = createProcessor(serverReady, requestSent); + final TestRunner runner = TestRunners.newTestRunner(processor); + + final MockHttpContextMap contextMap = new MockHttpContextMap(); + runner.addControllerService("http-context-map", contextMap); + runner.enableControllerService(contextMap); + runner.setProperty(HandleHttpRequest.HTTP_CONTEXT_MAP, "http-context-map"); + + // This configuration is invalid because the selected port is lower than 0. + runner.setVariable("listening_port", String.valueOf(negativePort)); + runner.setProperty(HandleHttpRequest.PORT, "${listening_port}"); + runner.assertNotValid(); + + // This configuration is invalid because the selected port is higher than 65535. + runner.setVariable("listening_port", String.valueOf(tooHighPort)); + runner.setProperty(HandleHttpRequest.PORT, "${listening_port}"); + runner.assertNotValid(); + + // This configuration is valid. + runner.setVariable("listening_port", String.valueOf(validPort)); + runner.setProperty(HandleHttpRequest.PORT, "${listening_port}"); + runner.assertValid(); + } + @Test(timeout = 30000) public void testRequestAddedToService() throws InitializationException, IOException, InterruptedException { CountDownLatch serverReady = new CountDownLatch(1); CountDownLatch requestSent = new CountDownLatch(1); + final int validPort = 1234; processor = createProcessor(serverReady, requestSent); final TestRunner runner = TestRunners.newTestRunner(processor); - runner.setProperty(HandleHttpRequest.PORT, "0"); + runner.setVariable("listening_port", String.valueOf(validPort)); + runner.setProperty(HandleHttpRequest.PORT, "${listening_port}"); final MockHttpContextMap contextMap = new MockHttpContextMap(); runner.addControllerService("http-context-map", contextMap); @@ -155,6 +190,7 @@ public void run() { try { serverReady.await(); final int port = ((HandleHttpRequest) runner.getProcessor()).getPort(); + assertEquals(port, validPort); final HttpURLConnection connection = (HttpURLConnection) new URL("http://localhost:" + port + "/my/path?query=true&value1=value1&value2=&value3&value4=apple=orange").openConnection();