diff --git a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/PostHTTP.java b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/PostHTTP.java index 2aaf8008de..760c069a2c 100644 --- a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/PostHTTP.java +++ b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/PostHTTP.java @@ -227,10 +227,9 @@ public class PostHTTP extends AbstractProcessor { .build(); public static final PropertyDescriptor CHUNKED_ENCODING = new PropertyDescriptor.Builder() .name("Use Chunked Encoding") - .description("Specifies whether or not to use Chunked Encoding to send the data. If false, the entire content of the FlowFile will be buffered into memory.") - .required(true) + .description("Specifies whether or not to use Chunked Encoding to send the data. This property is ignored in the event the contents are compressed " + + "or sent as FlowFiles.") .allowableValues("true", "false") - .defaultValue("true") .build(); public static final PropertyDescriptor SSL_CONTEXT_SERVICE = new PropertyDescriptor.Builder() .name("SSL Context Service") @@ -331,6 +330,15 @@ public class PostHTTP extends AbstractProcessor { .build()); } + boolean sendAsFlowFile = context.getProperty(SEND_AS_FLOWFILE).asBoolean(); + int compressionLevel = context.getProperty(COMPRESSION_LEVEL).asInteger(); + boolean chunkedSet = context.getProperty(CHUNKED_ENCODING).isSet(); + + if(compressionLevel == 0 && !sendAsFlowFile && !chunkedSet) { + results.add(new ValidationResult.Builder().valid(false).subject(CHUNKED_ENCODING.getName()) + .explanation("if compression level is 0 and not sending as a FlowFile, then the \'"+CHUNKED_ENCODING.getName()+"\' property must be set").build()); + } + return results; } @@ -625,9 +633,21 @@ public class PostHTTP extends AbstractProcessor { out.flush(); } } - }); + }) { - entity.setChunked(context.getProperty(CHUNKED_ENCODING).asBoolean()); + @Override + public long getContentLength() { + if(compressionLevel == 0 && !sendAsFlowFile && !context.getProperty(CHUNKED_ENCODING).asBoolean() ) { + return toSend.get(0).getSize(); + } else { + return -1; + } + } + }; + + if(context.getProperty(CHUNKED_ENCODING).isSet()) { + entity.setChunked(context.getProperty(CHUNKED_ENCODING).asBoolean()); + } post.setEntity(entity); post.setConfig(requestConfig); diff --git a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestPostHTTP.java b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestPostHTTP.java index 67bd82c731..52629648c1 100644 --- a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestPostHTTP.java +++ b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestPostHTTP.java @@ -82,6 +82,7 @@ public class TestPostHTTP { runner.setProperty(PostHTTP.URL, server.getSecureUrl()); runner.setProperty(PostHTTP.SSL_CONTEXT_SERVICE, "ssl-context"); + runner.setProperty(PostHTTP.CHUNKED_ENCODING, "false"); runner.enqueue("Hello world".getBytes()); runner.run(); @@ -113,6 +114,7 @@ public class TestPostHTTP { runner.setProperty(PostHTTP.URL, server.getSecureUrl()); runner.setProperty(PostHTTP.SSL_CONTEXT_SERVICE, "ssl-context"); + runner.setProperty(PostHTTP.CHUNKED_ENCODING, "false"); runner.enqueue("Hello world".getBytes()); runner.run(); @@ -141,6 +143,7 @@ public class TestPostHTTP { runner.setProperty(PostHTTP.URL, server.getSecureUrl()); runner.setProperty(PostHTTP.SSL_CONTEXT_SERVICE, "ssl-context"); + runner.setProperty(PostHTTP.CHUNKED_ENCODING, "false"); runner.enqueue("Hello world".getBytes()); runner.run(); @@ -186,6 +189,7 @@ public class TestPostHTTP { assertEquals("World", new String(contentReceived)); assertEquals("abc", receivedAttrs.get("abc")); assertEquals("xyz.txt", receivedAttrs.get("filename")); + Assert.assertNull(receivedAttrs.get("Content-Length")); } @Test @@ -258,18 +262,21 @@ public class TestPostHTTP { final String suppliedMimeType = "text/plain"; attrs.put(CoreAttributes.MIME_TYPE.key(), suppliedMimeType); runner.enqueue("Camping is in tents.".getBytes(), attrs); + runner.setProperty(PostHTTP.CHUNKED_ENCODING, "false"); runner.run(1); runner.assertAllFlowFilesTransferred(PostHTTP.REL_SUCCESS); Map lastPostHeaders = servlet.getLastPostHeaders(); Assert.assertEquals(suppliedMimeType, lastPostHeaders.get(PostHTTP.CONTENT_TYPE_HEADER)); + Assert.assertEquals("20",lastPostHeaders.get("Content-Length")); } @Test public void testSendWithEmptyELExpression() throws Exception { setup(null); runner.setProperty(PostHTTP.URL, server.getUrl()); + runner.setProperty(PostHTTP.CHUNKED_ENCODING, "false"); final Map attrs = new HashMap<>(); attrs.put(CoreAttributes.MIME_TYPE.key(), ""); @@ -289,6 +296,7 @@ public class TestPostHTTP { final String suppliedMimeType = "text/plain"; runner.setProperty(PostHTTP.URL, server.getUrl()); runner.setProperty(PostHTTP.CONTENT_TYPE, suppliedMimeType); + runner.setProperty(PostHTTP.CHUNKED_ENCODING, "false"); final Map attrs = new HashMap<>(); attrs.put(CoreAttributes.MIME_TYPE.key(), "text/csv"); @@ -322,6 +330,7 @@ public class TestPostHTTP { Assert.assertEquals(suppliedMimeType, lastPostHeaders.get(PostHTTP.CONTENT_TYPE_HEADER)); // Ensure that a 'Content-Encoding' header was set with a 'gzip' value Assert.assertEquals(PostHTTP.CONTENT_ENCODING_GZIP_VALUE, lastPostHeaders.get(PostHTTP.CONTENT_ENCODING_HEADER)); + Assert.assertNull(lastPostHeaders.get("Content-Length")); } @Test @@ -332,6 +341,7 @@ public class TestPostHTTP { runner.setProperty(PostHTTP.URL, server.getUrl()); runner.setProperty(PostHTTP.CONTENT_TYPE, suppliedMimeType); runner.setProperty(PostHTTP.COMPRESSION_LEVEL, "0"); + runner.setProperty(PostHTTP.CHUNKED_ENCODING, "false"); final Map attrs = new HashMap<>(); attrs.put(CoreAttributes.MIME_TYPE.key(), "text/plain"); @@ -345,6 +355,7 @@ public class TestPostHTTP { Assert.assertEquals(suppliedMimeType, lastPostHeaders.get(PostHTTP.CONTENT_TYPE_HEADER)); // Ensure that the request was not sent with a 'Content-Encoding' header Assert.assertNull(lastPostHeaders.get(PostHTTP.CONTENT_ENCODING_HEADER)); + Assert.assertEquals("6200",lastPostHeaders.get("Content-Length")); } @Test @@ -370,4 +381,30 @@ public class TestPostHTTP { // Ensure that the request was not sent with a 'Content-Encoding' header Assert.assertNull(lastPostHeaders.get(PostHTTP.CONTENT_ENCODING_HEADER)); } + + @Test + public void testSendChunked() throws Exception { + setup(null); + + final String suppliedMimeType = "text/plain"; + runner.setProperty(PostHTTP.URL, server.getUrl()); + runner.setProperty(PostHTTP.CONTENT_TYPE, suppliedMimeType); + runner.setProperty(PostHTTP.CHUNKED_ENCODING, "true"); + + final Map attrs = new HashMap<>(); + attrs.put(CoreAttributes.MIME_TYPE.key(), "text/plain"); + + runner.enqueue(StringUtils.repeat("This is the song that never ends. It goes on and on my friend.", 100).getBytes(), attrs); + + runner.run(1); + runner.assertAllFlowFilesTransferred(PostHTTP.REL_SUCCESS); + + byte[] postValue = servlet.getLastPost(); + Assert.assertArrayEquals(StringUtils.repeat("This is the song that never ends. It goes on and on my friend.", 100).getBytes(),postValue); + + Map lastPostHeaders = servlet.getLastPostHeaders(); + Assert.assertEquals(suppliedMimeType, lastPostHeaders.get(PostHTTP.CONTENT_TYPE_HEADER)); + Assert.assertNull(lastPostHeaders.get("Content-Length")); + Assert.assertEquals("chunked",lastPostHeaders.get("Transfer-Encoding")); + } }