From 86f162b611f89a483a95e362cac32153a055f057 Mon Sep 17 00:00:00 2001 From: Marco Gaido Date: Wed, 14 Mar 2018 16:27:17 +0100 Subject: [PATCH] NIFI-4959: Remove flowfiles and close connection for Bad Requests causing IOException This closes #2544. Signed-off-by: Mark Payne --- .../standard/HandleHttpRequest.java | 20 +++++++++++++++++-- 1 file changed, 18 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 5a09dab115..ad1b171849 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 @@ -39,6 +39,7 @@ import org.apache.nifi.processor.util.StandardValidators; import org.apache.nifi.processors.standard.util.HTTPUtils; import org.apache.nifi.ssl.RestrictedSSLContextService; import org.apache.nifi.ssl.SSLContextService; +import org.apache.nifi.stream.io.StreamUtils; import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.HttpConfiguration; import org.eclipse.jetty.server.HttpConnectionFactory; @@ -58,6 +59,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.ws.rs.core.Response.Status; import java.io.IOException; +import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.net.URI; import java.net.URISyntaxException; @@ -513,12 +515,26 @@ public class HandleHttpRequest extends AbstractProcessor { final long start = System.nanoTime(); final HttpServletRequest request = container.getRequest(); FlowFile flowFile = session.create(); - try { - flowFile = session.importFrom(request.getInputStream(), flowFile); + try (OutputStream flowFileOut = session.write(flowFile)) { + StreamUtils.copy(request.getInputStream(), flowFileOut); } catch (final IOException e) { + // There may be many reasons which can produce an IOException on the HTTP stream and in some of them, eg. + // bad requests, the connection to the client is not closed. In order to address also these cases, we try + // and answer with a BAD_REQUEST, which lets the client know that the request has not been correctly + // processed and makes it aware that the connection can be closed. getLogger().error("Failed to receive content from HTTP Request from {} due to {}", new Object[]{request.getRemoteAddr(), e}); session.remove(flowFile); + + try { + HttpServletResponse response = container.getResponse(); + response.sendError(Status.BAD_REQUEST.getStatusCode()); + response.flushBuffer(); + container.getContext().complete(); + } catch (final IOException ioe) { + getLogger().warn("Failed to send HTTP response to {} due to {}", + new Object[]{request.getRemoteAddr(), ioe}); + } return; }