From 103e350943233c6a780ab1086b2da9872df7c312 Mon Sep 17 00:00:00 2001 From: exceptionfactory Date: Thu, 25 Jan 2024 16:12:04 -0600 Subject: [PATCH] NIFI-12676 Fixed Servlet Registration in HandleHttpRequest This closes #8304. Signed-off-by: Joseph Witt --- .../standard/HandleHttpRequest.java | 8 +-- .../standard/HandleHttpRequestTest.java | 61 ++++++++++++++++++- 2 files changed, 64 insertions(+), 5 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 de7ff1ad7a..6cc07da11a 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 @@ -51,9 +51,8 @@ import org.apache.nifi.scheduling.ExecutionNode; import org.apache.nifi.ssl.RestrictedSSLContextService; import org.apache.nifi.ssl.SSLContextService; import org.apache.nifi.stream.io.StreamUtils; +import org.eclipse.jetty.ee10.servlet.ServletContextHandler; import org.eclipse.jetty.ee10.servlet.ServletContextRequest; -import org.eclipse.jetty.ee10.servlet.ServletHandler; -import org.eclipse.jetty.ee10.servlet.ServletHolder; import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; @@ -485,8 +484,9 @@ public class HandleHttpRequest extends AbstractProcessor { } } }; - final ServletHandler servletHandler = new ServletHandler(); - servletHandler.addServlet(new ServletHolder(standardServlet)); + final ServletContextHandler handler = new ServletContextHandler(); + handler.addServlet(standardServlet, "/"); + server.setHandler(handler); this.server = server; server.start(); diff --git a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/HandleHttpRequestTest.java b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/HandleHttpRequestTest.java index 0bc5ae8b3f..5ccc1ab2c7 100644 --- a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/HandleHttpRequestTest.java +++ b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/HandleHttpRequestTest.java @@ -27,6 +27,17 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URL; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Mockito.when; @ExtendWith(MockitoExtension.class) @@ -36,14 +47,19 @@ class HandleHttpRequestTest { private static final String MINIMUM_THREADS = "8"; + private static final String URL_FORMAT = "http://127.0.0.1:%d"; + @Mock HttpContextMap httpContextMap; TestRunner runner; + HandleHttpRequest handleHttpRequest; + @BeforeEach void setRunner() throws InitializationException { - runner = TestRunners.newTestRunner(HandleHttpRequest.class); + handleHttpRequest = new HandleHttpRequest(); + runner = TestRunners.newTestRunner(handleHttpRequest); when(httpContextMap.getIdentifier()).thenReturn(CONTEXT_MAP_ID); runner.addControllerService(CONTEXT_MAP_ID, httpContextMap); @@ -72,4 +88,47 @@ class HandleHttpRequestTest { runner.assertTransferCount(HandleHttpRequest.REL_SUCCESS, 0); } + + @Test + void testRunMethodNotAllowed() throws InterruptedException { + runner.setProperty(HandleHttpRequest.HTTP_CONTEXT_MAP, CONTEXT_MAP_ID); + runner.setProperty(HandleHttpRequest.MAXIMUM_THREADS, MINIMUM_THREADS); + runner.setProperty(HandleHttpRequest.PORT, "0"); + runner.setProperty(HandleHttpRequest.ALLOW_GET, Boolean.FALSE.toString()); + + runner.run(1, false); + runner.assertTransferCount(HandleHttpRequest.REL_SUCCESS, 0); + + final AtomicInteger responseCodeHolder = new AtomicInteger(); + final CountDownLatch countDownLatch = new CountDownLatch(1); + final Thread requestThread = Thread.ofVirtual().unstarted(() -> { + try { + final URL url = getUrl(); + final HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.connect(); + final int responseCode = connection.getResponseCode(); + responseCodeHolder.set(responseCode); + countDownLatch.countDown(); + } catch (final IOException e) { + throw new RuntimeException(e); + } + }); + requestThread.start(); + + final boolean completed = countDownLatch.await(5, TimeUnit.SECONDS); + assertTrue(completed, "HTTP request failed"); + assertEquals(HttpURLConnection.HTTP_BAD_METHOD, responseCodeHolder.get()); + + runner.run(1, true, false); + } + + private URL getUrl() { + final int port = handleHttpRequest.getPort(); + final URI uri = URI.create(URL_FORMAT.formatted(port)); + try { + return uri.toURL(); + } catch (final MalformedURLException e) { + throw new RuntimeException(e); + } + } }