You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by mc...@apache.org on 2015/11/23 21:46:39 UTC

[28/50] [abbrv] nifi git commit: NIFI-1086 Provide refactoring of InvokeHTTP NIFI-980 Add support for HTTP Digest authentication to InvokeHttp NIFI-1080 Provide additional InvokeHttp unit tests NIFI-1133 InvokeHTTP Processor does not save Location header

http://git-wip-us.apache.org/repos/asf/nifi/blob/8c2323dc/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/util/TestInvokeHttpCommon.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/util/TestInvokeHttpCommon.java b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/util/TestInvokeHttpCommon.java
index 88dfcdb..b44f015 100644
--- a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/util/TestInvokeHttpCommon.java
+++ b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/util/TestInvokeHttpCommon.java
@@ -24,9 +24,16 @@ import org.apache.nifi.provenance.ProvenanceEventRecord;
 import org.apache.nifi.provenance.ProvenanceEventType;
 import org.apache.nifi.util.MockFlowFile;
 import org.apache.nifi.util.TestRunner;
+import org.eclipse.jetty.security.ConstraintSecurityHandler;
+import org.eclipse.jetty.security.DefaultIdentityService;
+import org.eclipse.jetty.security.HashLoginService;
+import org.eclipse.jetty.security.ServerAuthException;
+import org.eclipse.jetty.security.authentication.DigestAuthenticator;
+import org.eclipse.jetty.server.Authentication;
 import org.eclipse.jetty.server.Handler;
 import org.eclipse.jetty.server.Request;
 import org.eclipse.jetty.server.handler.AbstractHandler;
+import org.eclipse.jetty.util.security.Password;
 import org.junit.Assert;
 import org.junit.Test;
 
@@ -67,7 +74,7 @@ public abstract class TestInvokeHttpCommon {
         final DateHandler dh = new DateHandler();
         addHandler(dh);
 
-        runner.setProperty(InvokeHTTP.Config.PROP_URL, url);
+        runner.setProperty(InvokeHTTP.PROP_URL, url);
         createFlowFiles(runner);
         runner.run();
 
@@ -94,47 +101,368 @@ public abstract class TestInvokeHttpCommon {
     public void test200() throws Exception {
         addHandler(new GetOrHeadHandler());
 
-        runner.setProperty(InvokeHTTP.Config.PROP_URL, url + "/status/200");
+        runner.setProperty(InvokeHTTP.PROP_URL, url + "/status/200");
 
         createFlowFiles(runner);
 
+        // Verify only one FlowFile gets created/sent
+        runner.run();
         runner.run();
 
-        runner.assertTransferCount(InvokeHTTP.Config.REL_SUCCESS_REQ, 1);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_SUCCESS_RESP, 1);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_RETRY, 0);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_NO_RETRY, 0);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_FAILURE, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_SUCCESS_REQ, 1);
+        runner.assertTransferCount(InvokeHTTP.REL_RESPONSE, 1);
+        runner.assertTransferCount(InvokeHTTP.REL_RETRY, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_NO_RETRY, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_FAILURE, 0);
 
         // expected in request status.code and status.message
         // original flow file (+attributes)
-        final MockFlowFile bundle = runner.getFlowFilesForRelationship(InvokeHTTP.Config.REL_SUCCESS_REQ).get(0);
+        final MockFlowFile bundle = runner.getFlowFilesForRelationship(InvokeHTTP.REL_SUCCESS_REQ).get(0);
         bundle.assertContentEquals("Hello".getBytes("UTF-8"));
-        bundle.assertAttributeEquals(InvokeHTTP.Config.STATUS_CODE, "200");
-        bundle.assertAttributeEquals(InvokeHTTP.Config.STATUS_MESSAGE, "OK");
+        bundle.assertAttributeEquals(InvokeHTTP.STATUS_CODE, "200");
+        bundle.assertAttributeEquals(InvokeHTTP.STATUS_MESSAGE, "OK");
         bundle.assertAttributeEquals("Foo", "Bar");
 
         // expected in response
         // status code, status message, all headers from server response --> ff attributes
         // server response message body into payload of ff
-        final MockFlowFile bundle1 = runner.getFlowFilesForRelationship(InvokeHTTP.Config.REL_SUCCESS_RESP).get(0);
+        final MockFlowFile bundle1 = runner.getFlowFilesForRelationship(InvokeHTTP.REL_RESPONSE).get(0);
         bundle1.assertContentEquals("/status/200".getBytes("UTF-8"));
-        bundle1.assertAttributeEquals(InvokeHTTP.Config.STATUS_CODE, "200");
-        bundle1.assertAttributeEquals(InvokeHTTP.Config.STATUS_MESSAGE, "OK");
+        bundle1.assertAttributeEquals(InvokeHTTP.STATUS_CODE, "200");
+        bundle1.assertAttributeEquals(InvokeHTTP.STATUS_MESSAGE, "OK");
+        bundle1.assertAttributeEquals("Foo", "Bar");
+        bundle1.assertAttributeEquals("Content-Type", "text/plain; charset=ISO-8859-1");
+
+        final List<ProvenanceEventRecord> provEvents = runner.getProvenanceEvents();
+        assertEquals(2, provEvents.size());
+        boolean forkEvent = false;
+        boolean fetchEvent = false;
+        for (final ProvenanceEventRecord event : provEvents) {
+            if (event.getEventType() == ProvenanceEventType.FORK) {
+                forkEvent = true;
+            } else if (event.getEventType() == ProvenanceEventType.FETCH) {
+                fetchEvent = true;
+            }
+        }
+
+        assertTrue(forkEvent);
+        assertTrue(fetchEvent);
+    }
+
+    @Test
+    public void testOutputResponseRegardless() throws Exception {
+        addHandler(new GetOrHeadHandler());
+
+        runner.setProperty(InvokeHTTP.PROP_URL, url + "/status/200");
+        runner.setProperty(InvokeHTTP.PROP_METHOD, "POST");
+        runner.setProperty(InvokeHTTP.PROP_OUTPUT_RESPONSE_REGARDLESS,"true");
+
+        createFlowFiles(runner);
+
+        runner.run();
+
+        runner.assertTransferCount(InvokeHTTP.REL_SUCCESS_REQ, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_RESPONSE, 1);
+        runner.assertTransferCount(InvokeHTTP.REL_RETRY, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_NO_RETRY, 1);
+        runner.assertTransferCount(InvokeHTTP.REL_FAILURE, 0);
+
+        // expected in request status.code and status.message
+        // original flow file (+attributes)
+        final MockFlowFile bundle = runner.getFlowFilesForRelationship(InvokeHTTP.REL_NO_RETRY).get(0);
+        bundle.assertContentEquals("Hello".getBytes("UTF-8"));
+        bundle.assertAttributeEquals(InvokeHTTP.STATUS_CODE, "404");
+        bundle.assertAttributeEquals(InvokeHTTP.STATUS_MESSAGE, "Not Found");
+        bundle.assertAttributeEquals("Foo", "Bar");
+
+        // expected in response
+        // status code, status message, all headers from server response --> ff attributes
+        // server response message body into payload of ff
+        final MockFlowFile bundle1 = runner.getFlowFilesForRelationship(InvokeHTTP.REL_RESPONSE).get(0);
+        bundle1.assertContentEquals("NO".getBytes("UTF-8"));
+        bundle1.assertAttributeEquals(InvokeHTTP.STATUS_CODE, "404");
+        bundle1.assertAttributeEquals(InvokeHTTP.STATUS_MESSAGE, "Not Found");
         bundle1.assertAttributeEquals("Foo", "Bar");
         bundle1.assertAttributeEquals("Content-Type", "text/plain; charset=ISO-8859-1");
     }
 
     @Test
+    public void testOutputResponseRegardlessWithOutputInAttribute() throws Exception {
+        addHandler(new GetOrHeadHandler());
+
+        runner.setProperty(InvokeHTTP.PROP_URL, url + "/status/200");
+        runner.setProperty(InvokeHTTP.PROP_METHOD, "POST");
+        runner.setProperty(InvokeHTTP.PROP_OUTPUT_RESPONSE_REGARDLESS,"true");
+        runner.setProperty(InvokeHTTP.PROP_PUT_OUTPUT_IN_ATTRIBUTE,"outputBody");
+
+        createFlowFiles(runner);
+
+        runner.run();
+
+        runner.assertTransferCount(InvokeHTTP.REL_SUCCESS_REQ, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_RESPONSE, 1);
+        runner.assertTransferCount(InvokeHTTP.REL_RETRY, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_NO_RETRY, 1);
+        runner.assertTransferCount(InvokeHTTP.REL_FAILURE, 0);
+
+        // expected in request status.code and status.message
+        // original flow file (+attributes)
+        final MockFlowFile bundle = runner.getFlowFilesForRelationship(InvokeHTTP.REL_NO_RETRY).get(0);
+        bundle.assertContentEquals("Hello".getBytes("UTF-8"));
+        bundle.assertAttributeEquals(InvokeHTTP.STATUS_CODE, "404");
+        bundle.assertAttributeEquals(InvokeHTTP.STATUS_MESSAGE, "Not Found");
+        bundle.assertAttributeEquals("outputBody", "NO");
+        bundle.assertAttributeEquals("Foo", "Bar");
+
+        // expected in response
+        // status code, status message, all headers from server response --> ff attributes
+        // server response message body into payload of ff
+        final MockFlowFile bundle1 = runner.getFlowFilesForRelationship(InvokeHTTP.REL_RESPONSE).get(0);
+        bundle1.assertContentEquals("NO".getBytes("UTF-8"));
+        bundle1.assertAttributeEquals(InvokeHTTP.STATUS_CODE, "404");
+        bundle1.assertAttributeEquals(InvokeHTTP.STATUS_MESSAGE, "Not Found");
+        bundle1.assertAttributeEquals("Foo", "Bar");
+        bundle1.assertAttributeEquals("Content-Type", "text/plain; charset=ISO-8859-1");
+    }
+
+    @Test
+    public void testOutputResponseRegardlessWithOutputInAttributeLarge() throws Exception {
+        addHandler(new GetLargeHandler());
+
+        runner.setProperty(InvokeHTTP.PROP_URL, url + "/status/200");
+        runner.setProperty(InvokeHTTP.PROP_METHOD, "POST");
+        runner.setProperty(InvokeHTTP.PROP_OUTPUT_RESPONSE_REGARDLESS,"true");
+        runner.setProperty(InvokeHTTP.PROP_PUT_OUTPUT_IN_ATTRIBUTE,"outputBody");
+        runner.setProperty(InvokeHTTP.PROP_PUT_ATTRIBUTE_MAX_LENGTH,"11");
+
+        createFlowFiles(runner);
+
+        runner.run();
+
+        runner.assertTransferCount(InvokeHTTP.REL_SUCCESS_REQ, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_RESPONSE, 1);
+        runner.assertTransferCount(InvokeHTTP.REL_RETRY, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_NO_RETRY, 1);
+        runner.assertTransferCount(InvokeHTTP.REL_FAILURE, 0);
+
+        // expected in request status.code and status.message
+        // original flow file (+attributes)
+        final MockFlowFile bundle = runner.getFlowFilesForRelationship(InvokeHTTP.REL_NO_RETRY).get(0);
+        bundle.assertContentEquals("Hello".getBytes("UTF-8"));
+        bundle.assertAttributeEquals(InvokeHTTP.STATUS_CODE, "404");
+        bundle.assertAttributeEquals(InvokeHTTP.STATUS_MESSAGE, "Not Found");
+        bundle.assertAttributeEquals("outputBody", "Lorem ipsum");
+        bundle.assertAttributeEquals("Foo", "Bar");
+
+        // expected in response
+        // status code, status message, all headers from server response --> ff attributes
+        // server response message body into payload of ff
+        final MockFlowFile bundle1 = runner.getFlowFilesForRelationship(InvokeHTTP.REL_RESPONSE).get(0);
+        bundle1.assertContentEquals("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. "
+                + "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor "
+                + "in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, "
+                + "sunt in culpa qui officia deserunt mollit anim id est laborum.");
+        bundle1.assertAttributeEquals(InvokeHTTP.STATUS_CODE, "404");
+        bundle1.assertAttributeEquals(InvokeHTTP.STATUS_MESSAGE, "Not Found");
+        bundle1.assertAttributeEquals("Foo", "Bar");
+        bundle1.assertAttributeEquals("Content-Type", "text/plain; charset=ISO-8859-1");
+    }
+
+
+    @Test
+    public void testMultipleSameHeaders() throws Exception {
+        addHandler(new GetMultipleHeaderHandler());
+
+        runner.setProperty(InvokeHTTP.PROP_URL, url + "/status/200");
+
+        createFlowFiles(runner);
+
+        runner.run();
+
+        runner.assertTransferCount(InvokeHTTP.REL_SUCCESS_REQ, 1);
+        runner.assertTransferCount(InvokeHTTP.REL_RESPONSE, 1);
+        runner.assertTransferCount(InvokeHTTP.REL_RETRY, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_NO_RETRY, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_FAILURE, 0);
+
+        // expected in request status.code and status.message
+        // original flow file (+attributes)
+        final MockFlowFile bundle = runner.getFlowFilesForRelationship(InvokeHTTP.REL_SUCCESS_REQ).get(0);
+        bundle.assertContentEquals("Hello".getBytes("UTF-8"));
+        bundle.assertAttributeEquals(InvokeHTTP.STATUS_CODE, "200");
+        bundle.assertAttributeEquals(InvokeHTTP.STATUS_MESSAGE, "OK");
+        bundle.assertAttributeEquals("Foo", "Bar");
+
+        // expected in response
+        // status code, status message, all headers from server response --> ff attributes
+        // server response message body into payload of ff
+        final MockFlowFile bundle1 = runner.getFlowFilesForRelationship(InvokeHTTP.REL_RESPONSE).get(0);
+        bundle1.assertContentEquals("/status/200".getBytes("UTF-8"));
+        bundle1.assertAttributeEquals(InvokeHTTP.STATUS_CODE, "200");
+        bundle1.assertAttributeEquals(InvokeHTTP.STATUS_MESSAGE, "OK");
+        bundle1.assertAttributeEquals("Foo", "Bar");
+        bundle1.assertAttributeEquals("double", "1, 2");
+        bundle1.assertAttributeEquals("Content-Type", "text/plain; charset=ISO-8859-1");
+    }
+
+    @Test
+    public void testPutResponseHeadersInRequest() throws Exception {
+        addHandler(new GetMultipleHeaderHandler());
+
+        runner.setProperty(InvokeHTTP.PROP_URL, url + "/status/200");
+        runner.setProperty(InvokeHTTP.PROP_ADD_HEADERS_TO_REQUEST, "true");
+
+        createFlowFiles(runner);
+
+        runner.run();
+
+        runner.assertTransferCount(InvokeHTTP.REL_SUCCESS_REQ, 1);
+        runner.assertTransferCount(InvokeHTTP.REL_RESPONSE, 1);
+        runner.assertTransferCount(InvokeHTTP.REL_RETRY, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_NO_RETRY, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_FAILURE, 0);
+
+        // expected in request status.code and status.message
+        // original flow file (+all attributes from response)
+        final MockFlowFile bundle = runner.getFlowFilesForRelationship(InvokeHTTP.REL_SUCCESS_REQ).get(0);
+        bundle.assertContentEquals("Hello".getBytes("UTF-8"));
+        bundle.assertAttributeEquals(InvokeHTTP.STATUS_CODE, "200");
+        bundle.assertAttributeEquals(InvokeHTTP.STATUS_MESSAGE, "OK");
+        bundle.assertAttributeEquals("Foo", "Bar");
+        bundle.assertAttributeEquals("double", "1, 2");
+        bundle.assertAttributeEquals("Content-Type", "text/plain; charset=ISO-8859-1");
+
+        // expected in response
+        // status code, status message, all headers from server response --> ff attributes
+        // server response message body into payload of ff
+        final MockFlowFile bundle1 = runner.getFlowFilesForRelationship(InvokeHTTP.REL_RESPONSE).get(0);
+        bundle1.assertContentEquals("/status/200".getBytes("UTF-8"));
+        bundle1.assertAttributeEquals(InvokeHTTP.STATUS_CODE, "200");
+        bundle1.assertAttributeEquals(InvokeHTTP.STATUS_MESSAGE, "OK");
+        bundle1.assertAttributeEquals("Foo", "Bar");
+        bundle1.assertAttributeEquals("double", "1, 2");
+        bundle1.assertAttributeEquals("Content-Type", "text/plain; charset=ISO-8859-1");
+    }
+
+    @Test
+    public void testToRequestAttribute() throws Exception {
+        addHandler(new GetOrHeadHandler());
+
+        runner.setProperty(InvokeHTTP.PROP_URL, url + "/status/200");
+        runner.setProperty(InvokeHTTP.PROP_PUT_OUTPUT_IN_ATTRIBUTE,"outputBody");
+
+        createFlowFiles(runner);
+
+        runner.run();
+
+        runner.assertTransferCount(InvokeHTTP.REL_SUCCESS_REQ, 1);
+        runner.assertTransferCount(InvokeHTTP.REL_RESPONSE, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_RETRY, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_NO_RETRY, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_FAILURE, 0);
+
+        // expected in request status.code, status.message and body of response in attribute
+        // original flow file (+attributes)
+        final MockFlowFile bundle = runner.getFlowFilesForRelationship(InvokeHTTP.REL_SUCCESS_REQ).get(0);
+        bundle.assertContentEquals("Hello".getBytes("UTF-8"));
+        bundle.assertAttributeEquals("outputBody", "/status/200");
+        bundle.assertAttributeEquals(InvokeHTTP.STATUS_CODE, "200");
+        bundle.assertAttributeEquals(InvokeHTTP.STATUS_MESSAGE, "OK");
+        bundle.assertAttributeEquals("Foo", "Bar");
+    }
+
+    @Test
+    public void testNoInput() throws Exception {
+        addHandler(new GetOrHeadHandler());
+
+        runner.setProperty(InvokeHTTP.PROP_URL, url + "/status/200");
+        runner.setProperty(InvokeHTTP.PROP_METHOD,"GET");
+        runner.setIncomingConnection(false);
+        runner.setNonLoopConnection(false);
+
+        runner.run();
+
+        runner.assertTransferCount(InvokeHTTP.REL_SUCCESS_REQ, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_RESPONSE, 1);
+        runner.assertTransferCount(InvokeHTTP.REL_RETRY, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_NO_RETRY, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_FAILURE, 0);
+
+        // expected in response
+        // status code, status message, all headers from server response --> ff attributes
+        // server response message body into payload of ff
+        final MockFlowFile bundle1 = runner.getFlowFilesForRelationship(InvokeHTTP.REL_RESPONSE).get(0);
+        bundle1.assertContentEquals("/status/200".getBytes("UTF-8"));
+        bundle1.assertAttributeEquals(InvokeHTTP.STATUS_CODE, "200");
+        bundle1.assertAttributeEquals(InvokeHTTP.STATUS_MESSAGE, "OK");
+        bundle1.assertAttributeEquals("Content-Type", "text/plain; charset=ISO-8859-1");
+    }
+
+    @Test
+    public void testNoInputFail() throws Exception {
+        addHandler(new GetOrHeadHandler());
+
+        runner.setProperty(InvokeHTTP.PROP_URL, url + "/status/200");
+        runner.setProperty(InvokeHTTP.PROP_METHOD, "POST");
+        runner.setIncomingConnection(false);
+        runner.setNonLoopConnection(false);
+
+        runner.run();
+
+        runner.assertTransferCount(InvokeHTTP.REL_SUCCESS_REQ, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_RESPONSE, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_RETRY, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_NO_RETRY, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_FAILURE, 0);
+
+        runner.setProperty(InvokeHTTP.PROP_METHOD,"OPTION");
+
+        runner.run();
+
+        runner.assertTransferCount(InvokeHTTP.REL_SUCCESS_REQ, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_RESPONSE, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_RETRY, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_NO_RETRY, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_FAILURE, 0);
+    }
+
+    @Test
+    public void testNoInputSendToAttribute() throws Exception {
+        addHandler(new GetOrHeadHandler());
+
+        runner.setProperty(InvokeHTTP.PROP_URL, url + "/status/200");
+        runner.setProperty(InvokeHTTP.PROP_PUT_OUTPUT_IN_ATTRIBUTE, "outputBody");
+        runner.setIncomingConnection(false);
+        runner.setNonLoopConnection(false);
+
+        runner.run();
+
+        runner.assertTransferCount(InvokeHTTP.REL_SUCCESS_REQ, 1);
+        runner.assertTransferCount(InvokeHTTP.REL_RESPONSE, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_RETRY, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_NO_RETRY, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_FAILURE, 0);
+
+        // expected in request
+        // status code, status message, no ff content
+        // server response message body into attribute of ff
+        final MockFlowFile bundle1 = runner.getFlowFilesForRelationship(InvokeHTTP.REL_SUCCESS_REQ).get(0);
+        bundle1.assertContentEquals("".getBytes("UTF-8"));
+        bundle1.assertAttributeEquals("outputBody", "/status/200");
+        bundle1.assertAttributeEquals(InvokeHTTP.STATUS_CODE, "200");
+        bundle1.assertAttributeEquals(InvokeHTTP.STATUS_MESSAGE, "OK");
+    }
+
+    @Test
     public void test200Auth() throws Exception {
         addHandler(new BasicAuthHandler());
 
         final String username = "basic_user";
         final String password = "basic_password";
 
-        runner.setProperty(InvokeHTTP.Config.PROP_URL, url + "/status/200");
-        runner.setProperty(InvokeHTTP.Config.PROP_BASIC_AUTH_USERNAME, username);
-        runner.setProperty(InvokeHTTP.Config.PROP_BASIC_AUTH_PASSWORD, password);
+        runner.setProperty(InvokeHTTP.PROP_URL, url + "/status/200");
+        runner.setProperty(InvokeHTTP.PROP_BASIC_AUTH_USERNAME, username);
+        runner.setProperty(InvokeHTTP.PROP_BASIC_AUTH_PASSWORD, password);
         final byte[] creds = String.format("%s:%s", username, password).getBytes(StandardCharsets.UTF_8);
         final String expAuth = String.format("Basic %s", new String(encodeBase64(creds)));
 
@@ -142,28 +470,28 @@ public abstract class TestInvokeHttpCommon {
 
         runner.run();
 
-        runner.assertTransferCount(InvokeHTTP.Config.REL_SUCCESS_REQ, 1);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_SUCCESS_RESP, 1);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_RETRY, 0);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_NO_RETRY, 0);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_FAILURE, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_SUCCESS_REQ, 1);
+        runner.assertTransferCount(InvokeHTTP.REL_RESPONSE, 1);
+        runner.assertTransferCount(InvokeHTTP.REL_RETRY, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_NO_RETRY, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_FAILURE, 0);
 
         // expected in request status.code and status.message
         // original flow file (+attributes)
-        final MockFlowFile bundle = runner.getFlowFilesForRelationship(InvokeHTTP.Config.REL_SUCCESS_REQ).get(0);
+        final MockFlowFile bundle = runner.getFlowFilesForRelationship(InvokeHTTP.REL_SUCCESS_REQ).get(0);
         bundle.assertContentEquals("Hello".getBytes("UTF-8"));
-        bundle.assertAttributeEquals(InvokeHTTP.Config.STATUS_CODE, "200");
-        bundle.assertAttributeEquals(InvokeHTTP.Config.STATUS_MESSAGE, "OK");
+        bundle.assertAttributeEquals(InvokeHTTP.STATUS_CODE, "200");
+        bundle.assertAttributeEquals(InvokeHTTP.STATUS_MESSAGE, "OK");
         bundle.assertAttributeEquals("Foo", "Bar");
 
         // expected in response
         // status code, status message, all headers from server response --> ff attributes
         // server response message body into payload of ff
-        final MockFlowFile bundle1 = runner.getFlowFilesForRelationship(InvokeHTTP.Config.REL_SUCCESS_RESP).get(0);
+        final MockFlowFile bundle1 = runner.getFlowFilesForRelationship(InvokeHTTP.REL_RESPONSE).get(0);
         final String bundle1Content = new String(bundle1.toByteArray(), StandardCharsets.UTF_8);
         assertTrue(bundle1Content.startsWith(expAuth)); // use startsWith instead of equals so we can ignore line endings
-        bundle1.assertAttributeEquals(InvokeHTTP.Config.STATUS_CODE, "200");
-        bundle1.assertAttributeEquals(InvokeHTTP.Config.STATUS_MESSAGE, "OK");
+        bundle1.assertAttributeEquals(InvokeHTTP.STATUS_CODE, "200");
+        bundle1.assertAttributeEquals(InvokeHTTP.STATUS_MESSAGE, "OK");
         bundle1.assertAttributeEquals("Foo", "Bar");
         bundle1.assertAttributeEquals("Content-Type", "text/plain; charset=ISO-8859-1");
 
@@ -190,55 +518,140 @@ public abstract class TestInvokeHttpCommon {
         final String username = "basic_user";
         final String password = "basic_password";
 
-        runner.setProperty(InvokeHTTP.Config.PROP_URL, url + "/status/401");
-        runner.setProperty(InvokeHTTP.Config.PROP_BASIC_AUTH_USERNAME, username);
-        runner.setProperty(InvokeHTTP.Config.PROP_BASIC_AUTH_PASSWORD, password);
+        runner.setProperty(InvokeHTTP.PROP_URL, url + "/status/401");
+        runner.setProperty(InvokeHTTP.PROP_BASIC_AUTH_USERNAME, username);
+        runner.setProperty(InvokeHTTP.PROP_BASIC_AUTH_PASSWORD, password);
 
         createFlowFiles(runner);
 
         runner.run();
 
-        runner.assertTransferCount(InvokeHTTP.Config.REL_SUCCESS_REQ, 0);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_SUCCESS_RESP, 0);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_RETRY, 0);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_NO_RETRY, 1);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_FAILURE, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_SUCCESS_REQ, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_RESPONSE, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_RETRY, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_NO_RETRY, 1);
+        runner.assertTransferCount(InvokeHTTP.REL_FAILURE, 0);
 
         // expected in request status.code and status.message
         // original flow file (+attributes)
-        final MockFlowFile bundle = runner.getFlowFilesForRelationship(InvokeHTTP.Config.REL_NO_RETRY).get(0);
-        bundle.assertAttributeEquals(InvokeHTTP.Config.STATUS_CODE, "401");
-        bundle.assertAttributeEquals(InvokeHTTP.Config.STATUS_MESSAGE, "Unauthorized");
+        final MockFlowFile bundle = runner.getFlowFilesForRelationship(InvokeHTTP.REL_NO_RETRY).get(0);
+        bundle.assertAttributeEquals(InvokeHTTP.STATUS_CODE, "401");
+        bundle.assertAttributeEquals(InvokeHTTP.STATUS_MESSAGE, "Unauthorized");
+        bundle.assertAttributeEquals("Foo", "Bar");
+        final String actual = new String(bundle.toByteArray(), StandardCharsets.UTF_8);
+        final String expected = "Hello";
+        Assert.assertEquals(expected, actual);
+
+        final String response = bundle.getAttribute(InvokeHTTP.RESPONSE_BODY);
+        assertEquals(response, "Get off my lawn!"+System.lineSeparator());
+    }
+
+    @Test
+    public void test200DigestAuth() throws Exception {
+        addHandler(new DigestAuthHandler());
+        final String username = "basic_user";
+        final String password = "basic_password";
+
+        runner.setProperty(InvokeHTTP.PROP_URL, url + "/status/200");
+        runner.setProperty(InvokeHTTP.PROP_BASIC_AUTH_USERNAME, username);
+        runner.setProperty(InvokeHTTP.PROP_BASIC_AUTH_PASSWORD, password);
+        runner.setProperty(InvokeHTTP.PROP_DIGEST_AUTH,"true");
+
+        createFlowFiles(runner);
+
+        runner.run();
+
+        runner.assertTransferCount(InvokeHTTP.REL_SUCCESS_REQ, 1);
+        runner.assertTransferCount(InvokeHTTP.REL_RESPONSE, 1);
+        runner.assertTransferCount(InvokeHTTP.REL_RETRY, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_NO_RETRY, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_FAILURE, 0);
+
+        //expected in request status.code and status.message
+        //original flow file (+attributes)
+        final MockFlowFile bundle = runner.getFlowFilesForRelationship(InvokeHTTP.REL_SUCCESS_REQ).get(0);
+        bundle.assertAttributeEquals(InvokeHTTP.STATUS_CODE, "200");
+        bundle.assertAttributeEquals(InvokeHTTP.STATUS_MESSAGE, "OK");
+        bundle.assertAttributeEquals("Foo", "Bar");
+        final String actual = new String(bundle.toByteArray(), StandardCharsets.UTF_8);
+        final String expected = "Hello";
+        Assert.assertEquals(expected, actual);
+
+        //expected in response
+        //status code, status message, all headers from server response --> ff attributes
+        //server response message body into payload of ff
+        final MockFlowFile bundle1 = runner.getFlowFilesForRelationship(InvokeHTTP.REL_RESPONSE).get(0);
+        bundle1.assertContentEquals(("DIGEST"+System.lineSeparator()).getBytes("UTF-8"));
+        bundle1.assertAttributeEquals(InvokeHTTP.STATUS_CODE, "200");
+        bundle1.assertAttributeEquals(InvokeHTTP.STATUS_MESSAGE, "OK");
+        bundle1.assertAttributeEquals("Foo", "Bar");
+        bundle1.assertAttributeEquals("Content-Type", "text/plain; charset=ISO-8859-1");
+    }
+
+    @Test
+    public void test401DigestNotAuth() throws Exception {
+        addHandler(new DigestAuthHandler());
+
+        runner.setProperty(InvokeHTTP.PROP_URL, url + "/status/200");
+        runner.setProperty(InvokeHTTP.PROP_DIGEST_AUTH,"false");
+        runner.setProperty(InvokeHTTP.PROP_PUT_ATTRIBUTE_MAX_LENGTH,"512");
+
+        createFlowFiles(runner);
+
+        runner.run();
+
+        runner.assertTransferCount(InvokeHTTP.REL_SUCCESS_REQ, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_RESPONSE, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_RETRY, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_NO_RETRY, 1);
+        runner.assertTransferCount(InvokeHTTP.REL_FAILURE, 0);
+
+        //expected in request status.code and status.message
+        //original flow file (+attributes)
+        final MockFlowFile bundle = runner.getFlowFilesForRelationship(InvokeHTTP.REL_NO_RETRY).get(0);
+        bundle.assertAttributeEquals(InvokeHTTP.STATUS_CODE, "401");
+        bundle.assertAttributeEquals(InvokeHTTP.STATUS_MESSAGE, "Unauthorized");
         bundle.assertAttributeEquals("Foo", "Bar");
         final String actual = new String(bundle.toByteArray(), StandardCharsets.UTF_8);
         final String expected = "Hello";
         Assert.assertEquals(expected, actual);
 
-        final String response = bundle.getAttribute(InvokeHTTP.Config.RESPONSE_BODY);
-        assertEquals(response, "Get off my lawn!");
+        final String response = bundle.getAttribute(InvokeHTTP.RESPONSE_BODY);
+        assertEquals("<html>\n" +
+                "<head>\n" +
+                "<meta http-equiv=\"Content-Type\" content=\"text/html;charset=ISO-8859-1\"/>\n" +
+                "<title>Error 401 </title>\n" +
+                "</head>\n" +
+                "<body>\n" +
+                "<h2>HTTP ERROR: 401</h2>\n" +
+                "<p>Problem accessing /status/200. Reason:\n" +
+                "<pre>    Unauthorized</pre></p>\n" +
+                "<hr /><i><small>Powered by Jetty://</small></i>\n" +
+                "</body>\n" +
+                "</html>\n", response);
     }
 
     @Test
     public void test500() throws Exception {
         addHandler(new GetOrHeadHandler());
 
-        runner.setProperty(InvokeHTTP.Config.PROP_URL, url + "/status/500");
+        runner.setProperty(InvokeHTTP.PROP_URL, url + "/status/500");
 
         createFlowFiles(runner);
 
         runner.run();
-        runner.assertTransferCount(InvokeHTTP.Config.REL_SUCCESS_REQ, 0);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_SUCCESS_RESP, 0);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_RETRY, 1);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_NO_RETRY, 0);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_FAILURE, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_SUCCESS_REQ, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_RESPONSE, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_RETRY, 1);
+        runner.assertTransferCount(InvokeHTTP.REL_NO_RETRY, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_FAILURE, 0);
 
         // expected in response
-        final MockFlowFile bundle = runner.getFlowFilesForRelationship(InvokeHTTP.Config.REL_RETRY).get(0);
+        final MockFlowFile bundle = runner.getFlowFilesForRelationship(InvokeHTTP.REL_RETRY).get(0);
         final String actual = new String(bundle.toByteArray(), StandardCharsets.UTF_8);
-        bundle.assertAttributeEquals(InvokeHTTP.Config.STATUS_CODE, "500");
-        bundle.assertAttributeEquals(InvokeHTTP.Config.STATUS_MESSAGE, "Server Error");
-        bundle.assertAttributeEquals(InvokeHTTP.Config.RESPONSE_BODY, "/status/500");
+        bundle.assertAttributeEquals(InvokeHTTP.STATUS_CODE, "500");
+        bundle.assertAttributeEquals(InvokeHTTP.STATUS_MESSAGE, "Server Error");
+        bundle.assertAttributeEquals(InvokeHTTP.RESPONSE_BODY, "/status/500");
 
         final String expected = "Hello";
         Assert.assertEquals(expected, actual);
@@ -250,23 +663,23 @@ public abstract class TestInvokeHttpCommon {
     public void test300() throws Exception {
         addHandler(new GetOrHeadHandler());
 
-        runner.setProperty(InvokeHTTP.Config.PROP_URL, url + "/status/302");
+        runner.setProperty(InvokeHTTP.PROP_URL, url + "/status/302");
 
         createFlowFiles(runner);
 
         runner.run();
-        runner.assertTransferCount(InvokeHTTP.Config.REL_SUCCESS_REQ, 0);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_SUCCESS_RESP, 0);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_RETRY, 0);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_NO_RETRY, 1);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_FAILURE, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_SUCCESS_REQ, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_RESPONSE, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_RETRY, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_NO_RETRY, 1);
+        runner.assertTransferCount(InvokeHTTP.REL_FAILURE, 0);
         // getMyFlowFiles();
         // expected in response
-        final MockFlowFile bundle = runner.getFlowFilesForRelationship(InvokeHTTP.Config.REL_NO_RETRY).get(0);
+        final MockFlowFile bundle = runner.getFlowFilesForRelationship(InvokeHTTP.REL_NO_RETRY).get(0);
         final String actual = new String(bundle.toByteArray(), StandardCharsets.UTF_8);
 
-        bundle.assertAttributeEquals(InvokeHTTP.Config.STATUS_CODE, "302");
-        bundle.assertAttributeEquals(InvokeHTTP.Config.STATUS_MESSAGE, "Found");
+        bundle.assertAttributeEquals(InvokeHTTP.STATUS_CODE, "302");
+        bundle.assertAttributeEquals(InvokeHTTP.STATUS_MESSAGE, "Found");
         final String expected = "Hello";
         Assert.assertEquals(expected, actual);
         bundle.assertAttributeEquals("Foo", "Bar");
@@ -277,23 +690,23 @@ public abstract class TestInvokeHttpCommon {
     public void test304() throws Exception {
         addHandler(new GetOrHeadHandler());
 
-        runner.setProperty(InvokeHTTP.Config.PROP_URL, url + "/status/304");
+        runner.setProperty(InvokeHTTP.PROP_URL, url + "/status/304");
 
         createFlowFiles(runner);
 
         runner.run();
-        runner.assertTransferCount(InvokeHTTP.Config.REL_SUCCESS_REQ, 0);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_SUCCESS_RESP, 0);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_RETRY, 0);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_NO_RETRY, 1);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_FAILURE, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_SUCCESS_REQ, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_RESPONSE, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_RETRY, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_NO_RETRY, 1);
+        runner.assertTransferCount(InvokeHTTP.REL_FAILURE, 0);
         // getMyFlowFiles();
         // expected in response
-        final MockFlowFile bundle = runner.getFlowFilesForRelationship(InvokeHTTP.Config.REL_NO_RETRY).get(0);
+        final MockFlowFile bundle = runner.getFlowFilesForRelationship(InvokeHTTP.REL_NO_RETRY).get(0);
         final String actual = new String(bundle.toByteArray(), StandardCharsets.UTF_8);
 
-        bundle.assertAttributeEquals(InvokeHTTP.Config.STATUS_CODE, "304");
-        bundle.assertAttributeEquals(InvokeHTTP.Config.STATUS_MESSAGE, "Not Modified");
+        bundle.assertAttributeEquals(InvokeHTTP.STATUS_CODE, "304");
+        bundle.assertAttributeEquals(InvokeHTTP.STATUS_MESSAGE, "Not Modified");
         final String expected = "Hello";
         Assert.assertEquals(expected, actual);
         bundle.assertAttributeEquals("Foo", "Bar");
@@ -304,24 +717,24 @@ public abstract class TestInvokeHttpCommon {
     public void test400() throws Exception {
         addHandler(new GetOrHeadHandler());
 
-        runner.setProperty(InvokeHTTP.Config.PROP_URL, url + "/status/400");
+        runner.setProperty(InvokeHTTP.PROP_URL, url + "/status/400");
 
         createFlowFiles(runner);
 
         runner.run();
-        runner.assertTransferCount(InvokeHTTP.Config.REL_SUCCESS_REQ, 0);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_SUCCESS_RESP, 0);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_RETRY, 0);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_NO_RETRY, 1);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_FAILURE, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_SUCCESS_REQ, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_RESPONSE, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_RETRY, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_NO_RETRY, 1);
+        runner.assertTransferCount(InvokeHTTP.REL_FAILURE, 0);
         // getMyFlowFiles();
         // expected in response
-        final MockFlowFile bundle = runner.getFlowFilesForRelationship(InvokeHTTP.Config.REL_NO_RETRY).get(0);
+        final MockFlowFile bundle = runner.getFlowFilesForRelationship(InvokeHTTP.REL_NO_RETRY).get(0);
         final String actual = new String(bundle.toByteArray(), StandardCharsets.UTF_8);
 
-        bundle.assertAttributeEquals(InvokeHTTP.Config.STATUS_CODE, "400");
-        bundle.assertAttributeEquals(InvokeHTTP.Config.STATUS_MESSAGE, "Bad Request");
-        bundle.assertAttributeEquals(InvokeHTTP.Config.RESPONSE_BODY, "/status/400");
+        bundle.assertAttributeEquals(InvokeHTTP.STATUS_CODE, "400");
+        bundle.assertAttributeEquals(InvokeHTTP.STATUS_MESSAGE, "Bad Request");
+        bundle.assertAttributeEquals(InvokeHTTP.RESPONSE_BODY, "/status/400");
         final String expected = "Hello";
         Assert.assertEquals(expected, actual);
         bundle.assertAttributeEquals("Foo", "Bar");
@@ -332,25 +745,25 @@ public abstract class TestInvokeHttpCommon {
     public void test412() throws Exception {
         addHandler(new GetOrHeadHandler());
 
-        runner.setProperty(InvokeHTTP.Config.PROP_URL, url + "/status/412");
-        runner.setProperty(InvokeHTTP.Config.PROP_METHOD, "GET");
+        runner.setProperty(InvokeHTTP.PROP_URL, url + "/status/412");
+        runner.setProperty(InvokeHTTP.PROP_METHOD, "GET");
 
         createFlowFiles(runner);
 
         runner.run();
-        runner.assertTransferCount(InvokeHTTP.Config.REL_SUCCESS_REQ, 0);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_SUCCESS_RESP, 0);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_RETRY, 0);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_NO_RETRY, 1);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_FAILURE, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_SUCCESS_REQ, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_RESPONSE, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_RETRY, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_NO_RETRY, 1);
+        runner.assertTransferCount(InvokeHTTP.REL_FAILURE, 0);
 
         // expected in response
-        final MockFlowFile bundle = runner.getFlowFilesForRelationship(InvokeHTTP.Config.REL_NO_RETRY).get(0);
+        final MockFlowFile bundle = runner.getFlowFilesForRelationship(InvokeHTTP.REL_NO_RETRY).get(0);
         final String actual = new String(bundle.toByteArray(), StandardCharsets.UTF_8);
 
-        bundle.assertAttributeEquals(InvokeHTTP.Config.STATUS_CODE, "412");
-        bundle.assertAttributeEquals(InvokeHTTP.Config.STATUS_MESSAGE, "Precondition Failed");
-        bundle.assertAttributeEquals(InvokeHTTP.Config.RESPONSE_BODY, "/status/412");
+        bundle.assertAttributeEquals(InvokeHTTP.STATUS_CODE, "412");
+        bundle.assertAttributeEquals(InvokeHTTP.STATUS_MESSAGE, "Precondition Failed");
+        bundle.assertAttributeEquals(InvokeHTTP.RESPONSE_BODY, "/status/412");
         final String expected = "Hello";
         Assert.assertEquals(expected, actual);
         bundle.assertAttributeEquals("Foo", "Bar");
@@ -361,28 +774,28 @@ public abstract class TestInvokeHttpCommon {
     public void testHead() throws Exception {
         addHandler(new GetOrHeadHandler());
 
-        runner.setProperty(InvokeHTTP.Config.PROP_METHOD, "HEAD");
-        runner.setProperty(InvokeHTTP.Config.PROP_URL, url + "/status/200");
+        runner.setProperty(InvokeHTTP.PROP_METHOD, "HEAD");
+        runner.setProperty(InvokeHTTP.PROP_URL, url + "/status/200");
 
         createFlowFiles(runner);
 
         runner.run();
-        runner.assertTransferCount(InvokeHTTP.Config.REL_SUCCESS_REQ, 1);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_SUCCESS_RESP, 1);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_RETRY, 0);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_NO_RETRY, 0);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_FAILURE, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_SUCCESS_REQ, 1);
+        runner.assertTransferCount(InvokeHTTP.REL_RESPONSE, 1);
+        runner.assertTransferCount(InvokeHTTP.REL_RETRY, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_NO_RETRY, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_FAILURE, 0);
 
-        final MockFlowFile bundle = runner.getFlowFilesForRelationship(InvokeHTTP.Config.REL_SUCCESS_REQ).get(0);
+        final MockFlowFile bundle = runner.getFlowFilesForRelationship(InvokeHTTP.REL_SUCCESS_REQ).get(0);
         bundle.assertContentEquals("Hello".getBytes("UTF-8"));
-        bundle.assertAttributeEquals(InvokeHTTP.Config.STATUS_CODE, "200");
-        bundle.assertAttributeEquals(InvokeHTTP.Config.STATUS_MESSAGE, "OK");
+        bundle.assertAttributeEquals(InvokeHTTP.STATUS_CODE, "200");
+        bundle.assertAttributeEquals(InvokeHTTP.STATUS_MESSAGE, "OK");
         bundle.assertAttributeEquals("Foo", "Bar");
 
-        final MockFlowFile bundle1 = runner.getFlowFilesForRelationship(InvokeHTTP.Config.REL_SUCCESS_RESP).get(0);
+        final MockFlowFile bundle1 = runner.getFlowFilesForRelationship(InvokeHTTP.REL_RESPONSE).get(0);
         bundle1.assertContentEquals("".getBytes("UTF-8"));
-        bundle1.assertAttributeEquals(InvokeHTTP.Config.STATUS_CODE, "200");
-        bundle1.assertAttributeEquals(InvokeHTTP.Config.STATUS_MESSAGE, "OK");
+        bundle1.assertAttributeEquals(InvokeHTTP.STATUS_CODE, "200");
+        bundle1.assertAttributeEquals(InvokeHTTP.STATUS_MESSAGE, "OK");
         bundle1.assertAttributeEquals("Foo", "Bar");
         bundle1.assertAttributeEquals("Content-Type", "text/plain");
         final String actual1 = new String(bundle1.toByteArray(), StandardCharsets.UTF_8);
@@ -394,28 +807,28 @@ public abstract class TestInvokeHttpCommon {
     public void testPost() throws Exception {
         addHandler(new PostHandler());
 
-        runner.setProperty(InvokeHTTP.Config.PROP_METHOD, "POST");
-        runner.setProperty(InvokeHTTP.Config.PROP_URL, url + "/post");
+        runner.setProperty(InvokeHTTP.PROP_METHOD, "POST");
+        runner.setProperty(InvokeHTTP.PROP_URL, url + "/post");
 
         createFlowFiles(runner);
 
         runner.run();
-        runner.assertTransferCount(InvokeHTTP.Config.REL_SUCCESS_REQ, 1);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_SUCCESS_RESP, 1);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_RETRY, 0);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_NO_RETRY, 0);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_FAILURE, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_SUCCESS_REQ, 1);
+        runner.assertTransferCount(InvokeHTTP.REL_RESPONSE, 1);
+        runner.assertTransferCount(InvokeHTTP.REL_RETRY, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_NO_RETRY, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_FAILURE, 0);
 
-        final MockFlowFile bundle = runner.getFlowFilesForRelationship(InvokeHTTP.Config.REL_SUCCESS_REQ).get(0);
+        final MockFlowFile bundle = runner.getFlowFilesForRelationship(InvokeHTTP.REL_SUCCESS_REQ).get(0);
         bundle.assertContentEquals("Hello".getBytes("UTF-8"));
-        bundle.assertAttributeEquals(InvokeHTTP.Config.STATUS_CODE, "200");
-        bundle.assertAttributeEquals(InvokeHTTP.Config.STATUS_MESSAGE, "OK");
+        bundle.assertAttributeEquals(InvokeHTTP.STATUS_CODE, "200");
+        bundle.assertAttributeEquals(InvokeHTTP.STATUS_MESSAGE, "OK");
         bundle.assertAttributeEquals("Foo", "Bar");
 
-        final MockFlowFile bundle1 = runner.getFlowFilesForRelationship(InvokeHTTP.Config.REL_SUCCESS_RESP).get(0);
+        final MockFlowFile bundle1 = runner.getFlowFilesForRelationship(InvokeHTTP.REL_RESPONSE).get(0);
         bundle1.assertContentEquals("".getBytes("UTF-8"));
-        bundle1.assertAttributeEquals(InvokeHTTP.Config.STATUS_CODE, "200");
-        bundle1.assertAttributeEquals(InvokeHTTP.Config.STATUS_MESSAGE, "OK");
+        bundle1.assertAttributeEquals(InvokeHTTP.STATUS_CODE, "200");
+        bundle1.assertAttributeEquals(InvokeHTTP.STATUS_MESSAGE, "OK");
         bundle1.assertAttributeEquals("Foo", "Bar");
         bundle1.assertAttributeNotExists("Content-Type");
 
@@ -426,30 +839,30 @@ public abstract class TestInvokeHttpCommon {
 
     @Test
     public void testPut() throws Exception {
-        addHandler(new PostHandler());
+        addHandler(new PutHandler());
 
-        runner.setProperty(InvokeHTTP.Config.PROP_METHOD, "PUT");
-        runner.setProperty(InvokeHTTP.Config.PROP_URL, url + "/post");
+        runner.setProperty(InvokeHTTP.PROP_METHOD, "PUT");
+        runner.setProperty(InvokeHTTP.PROP_URL, url + "/post");
 
         createFlowFiles(runner);
 
         runner.run();
-        runner.assertTransferCount(InvokeHTTP.Config.REL_SUCCESS_REQ, 1);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_SUCCESS_RESP, 1);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_RETRY, 0);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_NO_RETRY, 0);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_FAILURE, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_SUCCESS_REQ, 1);
+        runner.assertTransferCount(InvokeHTTP.REL_RESPONSE, 1);
+        runner.assertTransferCount(InvokeHTTP.REL_RETRY, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_NO_RETRY, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_FAILURE, 0);
 
-        final MockFlowFile bundle = runner.getFlowFilesForRelationship(InvokeHTTP.Config.REL_SUCCESS_REQ).get(0);
+        final MockFlowFile bundle = runner.getFlowFilesForRelationship(InvokeHTTP.REL_SUCCESS_REQ).get(0);
         bundle.assertContentEquals("Hello".getBytes("UTF-8"));
-        bundle.assertAttributeEquals(InvokeHTTP.Config.STATUS_CODE, "200");
-        bundle.assertAttributeEquals(InvokeHTTP.Config.STATUS_MESSAGE, "OK");
+        bundle.assertAttributeEquals(InvokeHTTP.STATUS_CODE, "200");
+        bundle.assertAttributeEquals(InvokeHTTP.STATUS_MESSAGE, "OK");
         bundle.assertAttributeEquals("Foo", "Bar");
 
-        final MockFlowFile bundle1 = runner.getFlowFilesForRelationship(InvokeHTTP.Config.REL_SUCCESS_RESP).get(0);
+        final MockFlowFile bundle1 = runner.getFlowFilesForRelationship(InvokeHTTP.REL_RESPONSE).get(0);
         bundle1.assertContentEquals("".getBytes("UTF-8"));
-        bundle1.assertAttributeEquals(InvokeHTTP.Config.STATUS_CODE, "200");
-        bundle1.assertAttributeEquals(InvokeHTTP.Config.STATUS_MESSAGE, "OK");
+        bundle1.assertAttributeEquals(InvokeHTTP.STATUS_CODE, "200");
+        bundle1.assertAttributeEquals(InvokeHTTP.STATUS_MESSAGE, "OK");
         bundle1.assertAttributeEquals("Foo", "Bar");
         bundle1.assertAttributeNotExists("Content-Type");
 
@@ -462,28 +875,28 @@ public abstract class TestInvokeHttpCommon {
     public void testDelete() throws Exception {
         addHandler(new DeleteHandler());
 
-        runner.setProperty(InvokeHTTP.Config.PROP_METHOD, "DELETE");
-        runner.setProperty(InvokeHTTP.Config.PROP_URL, url + "/status/200");
+        runner.setProperty(InvokeHTTP.PROP_METHOD, "DELETE");
+        runner.setProperty(InvokeHTTP.PROP_URL, url + "/status/200");
 
         createFlowFiles(runner);
 
         runner.run();
-        runner.assertTransferCount(InvokeHTTP.Config.REL_SUCCESS_REQ, 1);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_SUCCESS_RESP, 1);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_RETRY, 0);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_NO_RETRY, 0);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_FAILURE, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_SUCCESS_REQ, 1);
+        runner.assertTransferCount(InvokeHTTP.REL_RESPONSE, 1);
+        runner.assertTransferCount(InvokeHTTP.REL_RETRY, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_NO_RETRY, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_FAILURE, 0);
 
-        final MockFlowFile bundle = runner.getFlowFilesForRelationship(InvokeHTTP.Config.REL_SUCCESS_REQ).get(0);
+        final MockFlowFile bundle = runner.getFlowFilesForRelationship(InvokeHTTP.REL_SUCCESS_REQ).get(0);
         bundle.assertContentEquals("Hello".getBytes("UTF-8"));
-        bundle.assertAttributeEquals(InvokeHTTP.Config.STATUS_CODE, "200");
-        bundle.assertAttributeEquals(InvokeHTTP.Config.STATUS_MESSAGE, "OK");
+        bundle.assertAttributeEquals(InvokeHTTP.STATUS_CODE, "200");
+        bundle.assertAttributeEquals(InvokeHTTP.STATUS_MESSAGE, "OK");
         bundle.assertAttributeEquals("Foo", "Bar");
 
-        final MockFlowFile bundle1 = runner.getFlowFilesForRelationship(InvokeHTTP.Config.REL_SUCCESS_RESP).get(0);
+        final MockFlowFile bundle1 = runner.getFlowFilesForRelationship(InvokeHTTP.REL_RESPONSE).get(0);
         bundle1.assertContentEquals("".getBytes("UTF-8"));
-        bundle1.assertAttributeEquals(InvokeHTTP.Config.STATUS_CODE, "200");
-        bundle1.assertAttributeEquals(InvokeHTTP.Config.STATUS_MESSAGE, "OK");
+        bundle1.assertAttributeEquals(InvokeHTTP.STATUS_CODE, "200");
+        bundle1.assertAttributeEquals(InvokeHTTP.STATUS_MESSAGE, "OK");
         bundle1.assertAttributeEquals("Foo", "Bar");
         final String actual1 = new String(bundle1.toByteArray(), StandardCharsets.UTF_8);
         final String expected1 = "";
@@ -494,28 +907,28 @@ public abstract class TestInvokeHttpCommon {
     public void testOptions() throws Exception {
         addHandler(new OptionsHandler());
 
-        runner.setProperty(InvokeHTTP.Config.PROP_METHOD, "OPTIONS");
-        runner.setProperty(InvokeHTTP.Config.PROP_URL, url + "/status/200");
+        runner.setProperty(InvokeHTTP.PROP_METHOD, "OPTIONS");
+        runner.setProperty(InvokeHTTP.PROP_URL, url + "/status/200");
 
         createFlowFiles(runner);
 
         runner.run();
-        runner.assertTransferCount(InvokeHTTP.Config.REL_SUCCESS_REQ, 1);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_SUCCESS_RESP, 1);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_RETRY, 0);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_NO_RETRY, 0);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_FAILURE, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_SUCCESS_REQ, 1);
+        runner.assertTransferCount(InvokeHTTP.REL_RESPONSE, 1);
+        runner.assertTransferCount(InvokeHTTP.REL_RETRY, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_NO_RETRY, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_FAILURE, 0);
 
-        final MockFlowFile bundle = runner.getFlowFilesForRelationship(InvokeHTTP.Config.REL_SUCCESS_REQ).get(0);
+        final MockFlowFile bundle = runner.getFlowFilesForRelationship(InvokeHTTP.REL_SUCCESS_REQ).get(0);
         bundle.assertContentEquals("Hello".getBytes("UTF-8"));
-        bundle.assertAttributeEquals(InvokeHTTP.Config.STATUS_CODE, "200");
-        bundle.assertAttributeEquals(InvokeHTTP.Config.STATUS_MESSAGE, "OK");
+        bundle.assertAttributeEquals(InvokeHTTP.STATUS_CODE, "200");
+        bundle.assertAttributeEquals(InvokeHTTP.STATUS_MESSAGE, "OK");
         bundle.assertAttributeEquals("Foo", "Bar");
 
-        final MockFlowFile bundle1 = runner.getFlowFilesForRelationship(InvokeHTTP.Config.REL_SUCCESS_RESP).get(0);
+        final MockFlowFile bundle1 = runner.getFlowFilesForRelationship(InvokeHTTP.REL_RESPONSE).get(0);
         bundle1.assertContentEquals("/status/200".getBytes("UTF-8"));
-        bundle1.assertAttributeEquals(InvokeHTTP.Config.STATUS_CODE, "200");
-        bundle1.assertAttributeEquals(InvokeHTTP.Config.STATUS_MESSAGE, "OK");
+        bundle1.assertAttributeEquals(InvokeHTTP.STATUS_CODE, "200");
+        bundle1.assertAttributeEquals(InvokeHTTP.STATUS_MESSAGE, "OK");
         bundle1.assertAttributeEquals("Foo", "Bar");
     }
 
@@ -523,34 +936,36 @@ public abstract class TestInvokeHttpCommon {
     public void testSendAttributes() throws Exception {
         addHandler(new AttributesSentHandler());
 
-        runner.setProperty(InvokeHTTP.Config.PROP_URL, url + "/status/200");
-        runner.setProperty(InvokeHTTP.Config.PROP_ATTRIBUTES_TO_SEND, "Foo");
+        runner.setProperty(InvokeHTTP.PROP_URL, url + "/status/200");
+        runner.setProperty(InvokeHTTP.PROP_ATTRIBUTES_TO_SEND, "F.*");
+        runner.setProperty("dynamicHeader","yes!");
 
         createFlowFiles(runner);
 
         runner.run();
 
-        runner.assertTransferCount(InvokeHTTP.Config.REL_SUCCESS_REQ, 1);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_SUCCESS_RESP, 1);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_RETRY, 0);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_NO_RETRY, 0);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_FAILURE, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_SUCCESS_REQ, 1);
+        runner.assertTransferCount(InvokeHTTP.REL_RESPONSE, 1);
+        runner.assertTransferCount(InvokeHTTP.REL_RETRY, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_NO_RETRY, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_FAILURE, 0);
 
         //expected in request status.code and status.message
         //original flow file (+attributes)
-        final MockFlowFile bundle = runner.getFlowFilesForRelationship(InvokeHTTP.Config.REL_SUCCESS_REQ).get(0);
+        final MockFlowFile bundle = runner.getFlowFilesForRelationship(InvokeHTTP.REL_SUCCESS_REQ).get(0);
         bundle.assertContentEquals("Hello".getBytes("UTF-8"));
-        bundle.assertAttributeEquals(InvokeHTTP.Config.STATUS_CODE, "200");
-        bundle.assertAttributeEquals(InvokeHTTP.Config.STATUS_MESSAGE, "OK");
+        bundle.assertAttributeEquals(InvokeHTTP.STATUS_CODE, "200");
+        bundle.assertAttributeEquals(InvokeHTTP.STATUS_MESSAGE, "OK");
         bundle.assertAttributeEquals("Foo", "Bar");
 
         //expected in response
         //status code, status message, all headers from server response --> ff attributes
         //server response message body into payload of ff
-        final MockFlowFile bundle1 = runner.getFlowFilesForRelationship(InvokeHTTP.Config.REL_SUCCESS_RESP).get(0);
+        final MockFlowFile bundle1 = runner.getFlowFilesForRelationship(InvokeHTTP.REL_RESPONSE).get(0);
         bundle1.assertContentEquals("Bar".getBytes("UTF-8"));
-        bundle1.assertAttributeEquals(InvokeHTTP.Config.STATUS_CODE, "200");
-        bundle1.assertAttributeEquals(InvokeHTTP.Config.STATUS_MESSAGE, "OK");
+        bundle1.assertAttributeEquals(InvokeHTTP.STATUS_CODE, "200");
+        bundle1.assertAttributeEquals(InvokeHTTP.STATUS_MESSAGE, "OK");
+        bundle1.assertAttributeEquals("dynamicHeader","yes!");
         bundle1.assertAttributeEquals("Foo", "Bar");
         bundle1.assertAttributeEquals("Content-Type", "text/plain; charset=ISO-8859-1");
     }
@@ -559,19 +974,19 @@ public abstract class TestInvokeHttpCommon {
     public void testReadTimeout() throws Exception {
         addHandler(new ReadTimeoutHandler());
 
-        runner.setProperty(InvokeHTTP.Config.PROP_URL, url + "/status/200");
-        runner.setProperty(InvokeHTTP.Config.PROP_READ_TIMEOUT, "5 secs");
+        runner.setProperty(InvokeHTTP.PROP_URL, url + "/status/200");
+        runner.setProperty(InvokeHTTP.PROP_READ_TIMEOUT, "5 secs");
 
         createFlowFiles(runner);
 
         runner.run();
-        runner.assertTransferCount(InvokeHTTP.Config.REL_SUCCESS_REQ, 0);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_SUCCESS_RESP, 0);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_RETRY, 0);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_NO_RETRY, 0);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_FAILURE, 1);
+        runner.assertTransferCount(InvokeHTTP.REL_SUCCESS_REQ, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_RESPONSE, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_RETRY, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_NO_RETRY, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_FAILURE, 1);
 
-        final MockFlowFile bundle = runner.getFlowFilesForRelationship(InvokeHTTP.Config.REL_FAILURE).get(0);
+        final MockFlowFile bundle = runner.getFlowFilesForRelationship(InvokeHTTP.REL_FAILURE).get(0);
 
         final String actual = new String(bundle.toByteArray(), StandardCharsets.UTF_8);
         final String expected = "Hello";
@@ -586,17 +1001,17 @@ public abstract class TestInvokeHttpCommon {
         // this is the bad urls
         final String badurlport = "http://localhost:" + 445;
 
-        runner.setProperty(InvokeHTTP.Config.PROP_URL, badurlport + "/doesnotExist");
+        runner.setProperty(InvokeHTTP.PROP_URL, badurlport + "/doesnotExist");
         createFlowFiles(runner);
 
         runner.run();
-        runner.assertTransferCount(InvokeHTTP.Config.REL_SUCCESS_REQ, 0);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_SUCCESS_RESP, 0);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_RETRY, 0);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_NO_RETRY, 0);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_FAILURE, 1);
+        runner.assertTransferCount(InvokeHTTP.REL_SUCCESS_REQ, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_RESPONSE, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_RETRY, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_NO_RETRY, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_FAILURE, 1);
 
-        final MockFlowFile bundle = runner.getFlowFilesForRelationship(InvokeHTTP.Config.REL_FAILURE).get(0);
+        final MockFlowFile bundle = runner.getFlowFilesForRelationship(InvokeHTTP.REL_FAILURE).get(0);
 
         final String actual = new String(bundle.toByteArray(), StandardCharsets.UTF_8);
         final String expected = "Hello";
@@ -610,17 +1025,17 @@ public abstract class TestInvokeHttpCommon {
 
         final String badurlhost = "http://localhOOst:" + 445;
 
-        runner.setProperty(InvokeHTTP.Config.PROP_URL, badurlhost + "/doesnotExist");
+        runner.setProperty(InvokeHTTP.PROP_URL, badurlhost + "/doesnotExist");
         createFlowFiles(runner);
 
         runner.run();
-        runner.assertTransferCount(InvokeHTTP.Config.REL_SUCCESS_REQ, 0);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_SUCCESS_RESP, 0);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_RETRY, 0);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_NO_RETRY, 0);
-        runner.assertTransferCount(InvokeHTTP.Config.REL_FAILURE, 1);
+        runner.assertTransferCount(InvokeHTTP.REL_SUCCESS_REQ, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_RESPONSE, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_RETRY, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_NO_RETRY, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_FAILURE, 1);
 
-        final MockFlowFile bundle = runner.getFlowFilesForRelationship(InvokeHTTP.Config.REL_FAILURE).get(0);
+        final MockFlowFile bundle = runner.getFlowFilesForRelationship(InvokeHTTP.REL_FAILURE).get(0);
 
         final String actual = new String(bundle.toByteArray(), StandardCharsets.UTF_8);
         final String expected = "Hello";
@@ -628,6 +1043,46 @@ public abstract class TestInvokeHttpCommon {
         bundle.assertAttributeEquals("Foo", "Bar");
     }
 
+    @Test
+    public void testArbitraryRequest() throws Exception {
+        addHandler(new FetchHandler());
+
+        runner.setProperty(InvokeHTTP.PROP_URL, url + "/status/200");
+        runner.setProperty(InvokeHTTP.PROP_METHOD,"FETCH");
+
+        createFlowFiles(runner);
+
+        runner.run();
+
+        runner.assertTransferCount(InvokeHTTP.REL_SUCCESS_REQ, 1);
+        runner.assertTransferCount(InvokeHTTP.REL_RESPONSE, 1);
+        runner.assertTransferCount(InvokeHTTP.REL_RETRY, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_NO_RETRY, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_FAILURE, 0);
+
+        //expected in request status.code and status.message
+        //original flow file (+attributes)
+        final MockFlowFile bundle = runner.getFlowFilesForRelationship(InvokeHTTP.REL_SUCCESS_REQ).get(0);
+        bundle.assertAttributeEquals(InvokeHTTP.STATUS_CODE, "200");
+        bundle.assertAttributeEquals(InvokeHTTP.STATUS_MESSAGE, "OK");
+        final String actual = new String(bundle.toByteArray(), StandardCharsets.UTF_8);
+        final String expected = "Hello";
+        Assert.assertEquals(expected, actual);
+        bundle.assertAttributeEquals("Foo", "Bar");
+
+        //expected in response
+        //status code, status message, all headers from server response --> ff attributes
+        //server response message body into payload of ff
+        final MockFlowFile bundle1 = runner.getFlowFilesForRelationship(InvokeHTTP.REL_RESPONSE).get(0);
+        bundle1.assertContentEquals("/status/200".getBytes("UTF-8"));
+        bundle1.assertAttributeEquals(InvokeHTTP.STATUS_CODE, "200");
+        bundle1.assertAttributeEquals(InvokeHTTP.STATUS_MESSAGE, "OK");
+        bundle1.assertAttributeEquals("Foo", "Bar");
+        bundle1.assertAttributeEquals("Content-Type", "text/plain; charset=ISO-8859-1");
+        final String actual1 = new String(bundle1.toByteArray(), StandardCharsets.UTF_8);
+        final String expected1 = "/status/200";
+        Assert.assertEquals(expected1, actual1);
+    }
 
     public static void createFlowFiles(final TestRunner testRunner) throws UnsupportedEncodingException {
         final Map<String, String> attributes = new HashMap<>();
@@ -638,7 +1093,7 @@ public abstract class TestInvokeHttpCommon {
     }
 
 
-    private static class DateHandler extends AbstractHandler {
+    protected static class DateHandler extends AbstractHandler {
 
         private String dateString;
 
@@ -654,7 +1109,7 @@ public abstract class TestInvokeHttpCommon {
         }
     }
 
-    private static class PostHandler extends AbstractHandler {
+    public static class PostHandler extends AbstractHandler {
 
         @Override
         public void handle(String target, Request baseRequest,
@@ -663,15 +1118,42 @@ public abstract class TestInvokeHttpCommon {
 
             baseRequest.setHandled(true);
 
-            assertEquals("/post", target);
+            if("POST".equals(request.getMethod())) {
+                assertEquals("application/plain-text",request.getHeader("Content-Type"));
+                final String body = request.getReader().readLine();
+                assertEquals("Hello", body);
+            } else {
+                response.setStatus(404);
+                response.setContentType("text/plain");
+                response.setContentLength(0);
+            }
+
+        }
+    }
 
-            final String body = request.getReader().readLine();
-            assertEquals("Hello", body);
+    public static class PutHandler extends AbstractHandler {
+
+        @Override
+        public void handle(String target, Request baseRequest,
+                           HttpServletRequest request, HttpServletResponse response)
+                throws IOException, ServletException {
+
+            baseRequest.setHandled(true);
+
+            if("PUT".equalsIgnoreCase(request.getMethod())) {
+                assertEquals("application/plain-text",request.getHeader("Content-Type"));
+                final String body = request.getReader().readLine();
+                assertEquals("Hello", body);
+            } else {
+                response.setStatus(404);
+                response.setContentType("text/plain");
+                response.setContentLength(0);
+            }
 
         }
     }
 
-    private static class GetOrHeadHandler extends AbstractHandler {
+    public static class GetOrHeadHandler extends AbstractHandler {
 
         @Override
         public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
@@ -688,12 +1170,91 @@ public abstract class TestInvokeHttpCommon {
                     writer.print(target);
                     writer.flush();
                 }
+            } else if(!"HEAD".equalsIgnoreCase(request.getMethod())) {
+                response.setStatus(404);
+                response.setContentType("text/plain");
+                String body = "NO";
+                response.setContentLength(body.length());
+                response.setContentType("text/plain");
+
+                try (PrintWriter writer = response.getWriter()) {
+                    writer.print(body);
+                    writer.flush();
+                }
             }
 
         }
     }
 
-    private static class DeleteHandler extends AbstractHandler {
+    public static class GetLargeHandler extends AbstractHandler {
+
+        @Override
+        public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
+            baseRequest.setHandled(true);
+
+            final int status = Integer.valueOf(target.substring("/status".length() + 1));
+            response.setStatus(status);
+
+            response.setContentType("text/plain");
+            response.setContentLength(target.length());
+
+            if ("GET".equalsIgnoreCase(request.getMethod())) {
+                try (PrintWriter writer = response.getWriter()) {
+                    writer.print(target);
+                    writer.flush();
+                }
+            } else {
+                response.setStatus(404);
+                response.setContentType("text/plain");
+
+                //Lorem Ipsum
+                String body = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. "
+                        + "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor "
+                        + "in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, "
+                        + "sunt in culpa qui officia deserunt mollit anim id est laborum.";
+
+                response.setContentLength(body.length());
+                response.setContentType("text/plain");
+
+                try (PrintWriter writer = response.getWriter()) {
+                    writer.print(body);
+                    writer.flush();
+                }
+            }
+
+        }
+    }
+
+    public static class GetMultipleHeaderHandler extends AbstractHandler {
+
+        @Override
+        public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
+            baseRequest.setHandled(true);
+
+            final int status = Integer.valueOf(target.substring("/status".length() + 1));
+            response.setStatus(status);
+
+            response.setContentType("text/plain");
+            response.setContentLength(target.length());
+
+            if ("GET".equalsIgnoreCase(request.getMethod())) {
+                response.addHeader("double", "1");
+                response.addHeader("double", "2");
+
+                try (PrintWriter writer = response.getWriter()) {
+                    writer.print(target);
+                    writer.flush();
+                }
+            } else {
+                response.setStatus(404);
+                response.setContentType("text/plain");
+                response.setContentLength(0);
+            }
+
+        }
+    }
+
+    public static class DeleteHandler extends AbstractHandler {
 
         @Override
         public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
@@ -711,7 +1272,7 @@ public abstract class TestInvokeHttpCommon {
         }
     }
 
-    private static class OptionsHandler extends AbstractHandler {
+    public static class OptionsHandler extends AbstractHandler {
 
         @Override
         public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
@@ -735,7 +1296,7 @@ public abstract class TestInvokeHttpCommon {
         }
     }
 
-    private static class AttributesSentHandler extends AbstractHandler {
+    public static class AttributesSentHandler extends AbstractHandler {
 
         @Override
         public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
@@ -743,12 +1304,12 @@ public abstract class TestInvokeHttpCommon {
 
             if ("Get".equalsIgnoreCase(request.getMethod())) {
                 String headerValue = request.getHeader("Foo");
+                response.setHeader("dynamicHeader",request.getHeader("dynamicHeader"));
                 final int status = Integer.valueOf(target.substring("/status".length() + 1));
                 response.setStatus(status);
                 response.setContentLength(headerValue.length());
                 response.setContentType("text/plain");
 
-
                 try (PrintWriter writer = response.getWriter()) {
                     writer.print(headerValue);
                     writer.flush();
@@ -761,7 +1322,7 @@ public abstract class TestInvokeHttpCommon {
         }
     }
 
-    private static class ReadTimeoutHandler extends AbstractHandler {
+    public static class ReadTimeoutHandler extends AbstractHandler {
 
         @Override
         public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
@@ -792,9 +1353,7 @@ public abstract class TestInvokeHttpCommon {
         }
     }
 
-
-
-    private static class BasicAuthHandler extends AbstractHandler {
+    public static class BasicAuthHandler extends AbstractHandler {
 
         private String authString;
 
@@ -827,4 +1386,66 @@ public abstract class TestInvokeHttpCommon {
         }
     }
 
+    public static class DigestAuthHandler extends AbstractHandler {
+
+        private DigestAuthenticator digestAuthenticator;
+
+        private DigestAuthHandler() {
+            digestAuthenticator = new DigestAuthenticator();
+            ConstraintSecurityHandler securityHandler = new ConstraintSecurityHandler();
+
+            HashLoginService hashLoginService = new HashLoginService("realm");
+            hashLoginService.putUser("basic_user", new Password("basic_password"), new String[]{"realm"});
+            securityHandler.setLoginService(hashLoginService);
+            securityHandler.setIdentityService(new DefaultIdentityService());
+            digestAuthenticator.setConfiguration(securityHandler);
+        }
+
+
+        @Override
+        public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse
+                response)throws IOException, ServletException {
+            baseRequest.setHandled(true);
+
+            try {
+                Authentication authentication = digestAuthenticator.validateRequest(request, response, true);
+
+                if (authentication instanceof Authentication.User) {
+                    response.setContentType("text/plain");
+                    Authentication.User user = (Authentication.User) authentication;
+                    response.getWriter().println(user.getAuthMethod());
+                } else if (authentication instanceof Authentication.ResponseSent) {
+                    Authentication.ResponseSent responseSent = (Authentication.ResponseSent) authentication;
+                }
+            } catch (ServerAuthException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    public static class FetchHandler extends AbstractHandler {
+
+        @Override
+        public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
+            baseRequest.setHandled(true);
+
+
+            if ("Fetch".equalsIgnoreCase(request.getMethod())) {
+                final int status = Integer.valueOf(target.substring("/status".length() + 1));
+                response.setStatus(status);
+                response.setContentType("text/plain");
+                response.setContentLength(target.length());
+
+                try (PrintWriter writer = response.getWriter()) {
+                    writer.print(target);
+                    writer.flush();
+                }
+            } else {
+
+                response.setStatus(404);
+                response.setContentType("text/plain");
+                response.setContentLength(target.length());
+            }
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/8c2323dc/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 8a8cdb0..0708812 100644
--- a/pom.xml
+++ b/pom.xml
@@ -97,6 +97,44 @@
         <hadoop.guava.version>12.0.1</hadoop.guava.version>
         <yammer.metrics.version>2.2.0</yammer.metrics.version>
     </properties>
+
+
+    <repositories>
+        <repository>
+            <id>central</id>
+            <!-- This should be at top, it makes maven try the central repo first and then others and hence faster dep resolution -->
+            <name>Maven Repository</name>
+            <url>https://repo1.maven.org/maven2</url>
+            <releases>
+                <enabled>true</enabled>
+            </releases>
+            <snapshots>
+                <enabled>false</enabled>
+            </snapshots>
+        </repository>
+        <repository>
+            <id>apache-repo</id>
+            <name>Apache Repository</name>
+            <url>https://repository.apache.org/content/repositories/releases</url>
+            <releases>
+                <enabled>true</enabled>
+            </releases>
+            <snapshots>
+                <enabled>false</enabled>
+            </snapshots>
+        </repository>
+        <repository>
+            <id>jcenter</id>
+            <url>http://jcenter.bintray.com </url>
+            <snapshots>
+                <enabled>false</enabled>
+            </snapshots>
+            <releases>
+                <enabled>true</enabled>
+            </releases>
+        </repository>
+    </repositories>
+
     <dependencyManagement>
         <dependencies>
             <dependency>