mirror of https://github.com/apache/nifi.git
NIFI-12925 Updated ListenHTTP to return 405 for TRACE and OPTIONS
This closes #8548 Signed-off-by: David Handermann <exceptionfactory@apache.org>d
This commit is contained in:
parent
d5ff51b6e4
commit
5c150ffd78
|
@ -82,7 +82,8 @@ import java.util.regex.Pattern;
|
|||
@Tags({"ingest", "http", "https", "rest", "listen"})
|
||||
@CapabilityDescription("Starts an HTTP Server and listens on a given base path to transform incoming requests into FlowFiles. "
|
||||
+ "The default URI of the Service will be http://{hostname}:{port}/contentListener. Only HEAD and POST requests are "
|
||||
+ "supported. GET, PUT, and DELETE will result in an error and the HTTP response status code 405. "
|
||||
+ "supported. GET, PUT, DELETE, OPTIONS and TRACE will result in an error and the HTTP response status code 405; "
|
||||
+ "CONNECT will also result in an error and the HTTP response status code 400. "
|
||||
+ "GET is supported on <service_URI>/healthcheck. If the service is available, it returns \"200 OK\" with the content \"OK\". "
|
||||
+ "The health check functionality can be configured to be accessible via a different port. "
|
||||
+ "For details see the documentation of the \"Listening Port for health check requests\" property."
|
||||
|
|
|
@ -157,6 +157,22 @@ public class ListenHTTPServlet extends HttpServlet {
|
|||
}
|
||||
}
|
||||
|
||||
private void notAllowed(final HttpServletRequest request, final HttpServletResponse response) throws IOException {
|
||||
response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "Method Not Allowed");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doTrace(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException {
|
||||
notAllowed(request, response);
|
||||
logger.debug("Denying TRACE request; method not allowed.");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doOptions(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException {
|
||||
notAllowed(request, response);
|
||||
logger.debug("Denying OPTIONS request; method not allowed.");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doPost(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException {
|
||||
|
||||
|
|
|
@ -103,8 +103,13 @@ public class TestListenHTTP {
|
|||
|
||||
private static final int SOCKET_CONNECT_TIMEOUT = 100;
|
||||
private static final long SERVER_START_TIMEOUT = 1200000;
|
||||
|
||||
private static final String HTTP_POST = "POST";
|
||||
private static final String HTTP_TRACE = "TRACE";
|
||||
private static final String HTTP_OPTIONS = "OPTIONS";
|
||||
|
||||
private static final Duration CLIENT_CALL_TIMEOUT = Duration.ofSeconds(10);
|
||||
public static final String LOCALHOST_DN = "CN=localhost";
|
||||
private static final String LOCALHOST_DN = "CN=localhost";
|
||||
|
||||
private static TlsConfiguration serverConfiguration;
|
||||
private static TlsConfiguration serverTls_1_3_Configuration;
|
||||
|
@ -374,14 +379,14 @@ public class TestListenHTTP {
|
|||
public void testSecureServerTrustStoreConfiguredClientAuthenticationRequired() throws Exception {
|
||||
configureProcessorSslContextService(ListenHTTP.ClientAuthentication.REQUIRED, serverConfiguration);
|
||||
final int port = startSecureServer();
|
||||
assertThrows(IOException.class, () -> postMessage(null, true, port, false));
|
||||
assertThrows(IOException.class, () -> sendMessage(null, true, port, false, HTTP_POST));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSecureServerTrustStoreNotConfiguredClientAuthenticationNotRequired() throws Exception {
|
||||
configureProcessorSslContextService(ListenHTTP.ClientAuthentication.AUTO, serverNoTruststoreConfiguration);
|
||||
final int port = startSecureServer();
|
||||
final int responseCode = postMessage(null, true, port, true);
|
||||
final int responseCode = sendMessage(null, true, port, true, HTTP_POST);
|
||||
assertEquals(HttpServletResponse.SC_NO_CONTENT, responseCode);
|
||||
}
|
||||
|
||||
|
@ -471,7 +476,7 @@ public class TestListenHTTP {
|
|||
"\"3\",\"rec3\",\"103\"\n" +
|
||||
"\"4\",\"rec4\",\"104\"\n";
|
||||
|
||||
startWebServerAndSendMessages(Collections.singletonList(""), HttpServletResponse.SC_OK, false, false);
|
||||
startWebServerAndSendMessages(Collections.singletonList(""), HttpServletResponse.SC_OK, false, false, HTTP_POST);
|
||||
List<MockFlowFile> mockFlowFiles = runner.getFlowFilesForRelationship(RELATIONSHIP_SUCCESS);
|
||||
|
||||
runner.assertTransferCount(RELATIONSHIP_SUCCESS, 1);
|
||||
|
@ -495,7 +500,7 @@ public class TestListenHTTP {
|
|||
parser.addRecord(keys.get(i), names.get(i), codes.get(i));
|
||||
}
|
||||
|
||||
startWebServerAndSendMessages(Collections.singletonList(""), HttpServletResponse.SC_BAD_REQUEST, false, false);
|
||||
startWebServerAndSendMessages(Collections.singletonList(""), HttpServletResponse.SC_BAD_REQUEST, false, false, HTTP_POST);
|
||||
|
||||
runner.assertTransferCount(RELATIONSHIP_SUCCESS, 0);
|
||||
}
|
||||
|
@ -533,6 +538,22 @@ public class TestListenHTTP {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOptionsNotAllowed() throws Exception {
|
||||
final List<String> messages = new ArrayList<>();
|
||||
messages.add("payload 1");
|
||||
|
||||
startWebServerAndSendMessages(messages, HttpServletResponse.SC_METHOD_NOT_ALLOWED, false, false, HTTP_OPTIONS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTraceNotAllowed() throws Exception {
|
||||
final List<String> messages = new ArrayList<>();
|
||||
messages.add("payload 1");
|
||||
|
||||
startWebServerAndSendMessages(messages, HttpServletResponse.SC_METHOD_NOT_ALLOWED, false, false, HTTP_TRACE);
|
||||
}
|
||||
|
||||
private MockRecordParser setupRecordReaderTest() throws InitializationException {
|
||||
final MockRecordParser parser = new MockRecordParser();
|
||||
final MockRecordWriter writer = new MockRecordWriter();
|
||||
|
@ -556,16 +577,16 @@ public class TestListenHTTP {
|
|||
return startWebServer();
|
||||
}
|
||||
|
||||
private int postMessage(final String message, boolean secure, final int port, boolean clientAuthRequired) throws IOException {
|
||||
final OkHttpClient okHttpClient = getOkHttpClient(secure, clientAuthRequired);
|
||||
final Request.Builder requestBuilder = new Request.Builder();
|
||||
final String url = buildUrl(secure, port);
|
||||
requestBuilder.url(url);
|
||||
|
||||
private int sendMessage(final String message, final boolean secure, final int port, boolean clientAuthRequired, final String httpMethod) throws IOException {
|
||||
final byte[] bytes = message == null ? new byte[]{} : message.getBytes(StandardCharsets.UTF_8);
|
||||
final RequestBody requestBody = RequestBody.create(bytes, APPLICATION_OCTET_STREAM);
|
||||
final Request request = requestBuilder.post(requestBody).build();
|
||||
final String url = buildUrl(secure, port);
|
||||
final Request.Builder requestBuilder = new Request.Builder();
|
||||
final Request request = requestBuilder.method(httpMethod, requestBody)
|
||||
.url(url)
|
||||
.build();
|
||||
|
||||
final OkHttpClient okHttpClient = getOkHttpClient(secure, clientAuthRequired);
|
||||
try (final Response response = okHttpClient.newCall(request).execute()) {
|
||||
return response.code();
|
||||
}
|
||||
|
@ -597,7 +618,7 @@ public class TestListenHTTP {
|
|||
messages.add(null);
|
||||
messages.add("payload 2");
|
||||
|
||||
startWebServerAndSendMessages(messages, returnCode, secure, twoWaySsl);
|
||||
startWebServerAndSendMessages(messages, returnCode, secure, twoWaySsl, HTTP_POST);
|
||||
|
||||
List<MockFlowFile> mockFlowFiles = runner.getFlowFilesForRelationship(RELATIONSHIP_SUCCESS);
|
||||
|
||||
|
@ -647,11 +668,12 @@ public class TestListenHTTP {
|
|||
return listeningPort;
|
||||
}
|
||||
|
||||
private void startWebServerAndSendMessages(final List<String> messages, final int expectedStatusCode, final boolean secure, final boolean clientAuthRequired) throws Exception {
|
||||
private void startWebServerAndSendMessages(final List<String> messages, final int expectedStatusCode, final boolean secure, final boolean clientAuthRequired,
|
||||
final String httpMethod) throws Exception {
|
||||
final int port = startWebServer();
|
||||
|
||||
for (final String message : messages) {
|
||||
final int statusCode = postMessage(message, secure, port, clientAuthRequired);
|
||||
final int statusCode = sendMessage(message, secure, port, clientAuthRequired, httpMethod);
|
||||
assertEquals(expectedStatusCode, statusCode, "HTTP Status Code not matched");
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue