NIFI-4959: Remove flowfiles and close connection for Bad Requests causing IOException

This closes #2544.

Signed-off-by: Mark Payne <markap14@hotmail.com>
This commit is contained in:
Marco Gaido 2018-03-14 16:27:17 +01:00 committed by Mark Payne
parent 3f0aa6e13c
commit 86f162b611
1 changed files with 18 additions and 2 deletions

View File

@ -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;
}