You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by pv...@apache.org on 2018/01/24 16:52:11 UTC

nifi git commit: NIFI-4790 - support HTTPS Proxy in InvokeHTTP

Repository: nifi
Updated Branches:
  refs/heads/master 84848f7cb -> 37271e824


NIFI-4790 - support HTTPS Proxy in InvokeHTTP

Signed-off-by: Pierre Villard <pi...@gmail.com>

This closes #2426.


Project: http://git-wip-us.apache.org/repos/asf/nifi/repo
Commit: http://git-wip-us.apache.org/repos/asf/nifi/commit/37271e82
Tree: http://git-wip-us.apache.org/repos/asf/nifi/tree/37271e82
Diff: http://git-wip-us.apache.org/repos/asf/nifi/diff/37271e82

Branch: refs/heads/master
Commit: 37271e82414b9386bb735b61ef54e891300117bf
Parents: 84848f7
Author: Marco Gaido <ma...@gmail.com>
Authored: Fri Jan 19 11:02:56 2018 +0100
Committer: Pierre Villard <pi...@gmail.com>
Committed: Wed Jan 24 17:51:28 2018 +0100

----------------------------------------------------------------------
 .../nifi/processors/standard/InvokeHTTP.java    | 40 ++++++++++++++++++--
 1 file changed, 36 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/nifi/blob/37271e82/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/InvokeHTTP.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/InvokeHTTP.java b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/InvokeHTTP.java
index 300e9cb..5f6e66c 100644
--- a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/InvokeHTTP.java
+++ b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/InvokeHTTP.java
@@ -148,6 +148,9 @@ public final class InvokeHTTP extends AbstractProcessor {
             EXCEPTION_CLASS, EXCEPTION_MESSAGE,
             "uuid", "filename", "path")));
 
+    public static final String HTTP = "http";
+    public static final String HTTPS = "https";
+
     // properties
     public static final PropertyDescriptor PROP_METHOD = new PropertyDescriptor.Builder()
             .name("HTTP Method")
@@ -213,11 +216,21 @@ public final class InvokeHTTP extends AbstractProcessor {
 
     public static final PropertyDescriptor PROP_SSL_CONTEXT_SERVICE = new PropertyDescriptor.Builder()
             .name("SSL Context Service")
-            .description("The SSL Context Service used to provide client certificate information for TLS/SSL (https) connections.")
+            .description("The SSL Context Service used to provide client certificate information for TLS/SSL (https) connections."
+                    + " It is also used to connect to HTTPS Proxy.")
             .required(false)
             .identifiesControllerService(SSLContextService.class)
             .build();
 
+    public static final PropertyDescriptor PROP_PROXY_TYPE = new PropertyDescriptor.Builder()
+            .name("Proxy Type")
+            .displayName("Proxy Type")
+            .description("The type of the proxy we are connecting to. Must be either " + HTTP + " or " + HTTPS)
+            .defaultValue(HTTP)
+            .expressionLanguageSupported(true)
+            .addValidator(StandardValidators.NON_EMPTY_EL_VALIDATOR)
+            .build();
+
     public static final PropertyDescriptor PROP_PROXY_HOST = new PropertyDescriptor.Builder()
             .name("Proxy Host")
             .description("The fully qualified hostname or IP address of the proxy server")
@@ -388,6 +401,7 @@ public final class InvokeHTTP extends AbstractProcessor {
             PROP_BASIC_AUTH_PASSWORD,
             PROP_PROXY_HOST,
             PROP_PROXY_PORT,
+            PROP_PROXY_TYPE,
             PROP_PROXY_USER,
             PROP_PROXY_PASSWORD,
             PROP_PUT_OUTPUT_IN_ATTRIBUTE,
@@ -509,10 +523,22 @@ public final class InvokeHTTP extends AbstractProcessor {
         if ((proxyUserSet && !proxyPwdSet) || (!proxyUserSet && proxyPwdSet)) {
             results.add(new ValidationResult.Builder().subject("Proxy User and Password").valid(false).explanation("If Proxy Username or Proxy Password is set, both must be set").build());
         }
-        if(proxyUserSet && !proxyHostSet) {
+        if (proxyUserSet && !proxyHostSet) {
             results.add(new ValidationResult.Builder().subject("Proxy").valid(false).explanation("If Proxy username is set, proxy host must be set").build());
         }
 
+        final String proxyType = validationContext.getProperty(PROP_PROXY_TYPE).evaluateAttributeExpressions().getValue();
+
+        if (!HTTP.equals(proxyType) && !HTTPS.equals(proxyType)) {
+            results.add(new ValidationResult.Builder().subject(PROP_PROXY_TYPE.getDisplayName()).valid(false)
+                    .explanation(PROP_PROXY_TYPE.getDisplayName() + " must be either " + HTTP + " or " + HTTPS).build());
+        }
+
+        if (HTTPS.equals(proxyType)
+                && !validationContext.getProperty(PROP_SSL_CONTEXT_SERVICE).isSet()) {
+            results.add(new ValidationResult.Builder().subject("SSL Context Service").valid(false).explanation("If Proxy Type is HTTPS, SSL Context Service must be set").build());
+        }
+
         return results;
     }
 
@@ -525,9 +551,12 @@ public final class InvokeHTTP extends AbstractProcessor {
         // Add a proxy if set
         final String proxyHost = context.getProperty(PROP_PROXY_HOST).evaluateAttributeExpressions().getValue();
         final Integer proxyPort = context.getProperty(PROP_PROXY_PORT).evaluateAttributeExpressions().asInteger();
+        final String proxyType = context.getProperty(PROP_PROXY_TYPE).evaluateAttributeExpressions().getValue();
+        boolean isHttpsProxy = false;
         if (proxyHost != null && proxyPort != null) {
             final Proxy proxy = new Proxy(Type.HTTP, new InetSocketAddress(proxyHost, proxyPort));
             okHttpClientBuilder.proxy(proxy);
+            isHttpsProxy = HTTPS.equals(proxyType);
         }
 
         // Set timeouts
@@ -542,7 +571,7 @@ public final class InvokeHTTP extends AbstractProcessor {
 
         // check if the ssl context is set and add the factory if so
         if (sslContext != null) {
-            setSslSocketFactory(okHttpClientBuilder, sslService, sslContext);
+            setSslSocketFactory(okHttpClientBuilder, sslService, sslContext, isHttpsProxy);
         }
 
         // check the trusted hostname property and override the HostnameVerifier
@@ -566,7 +595,7 @@ public final class InvokeHTTP extends AbstractProcessor {
         In-depth documentation on Java Secure Socket Extension (JSSE) Classes and interfaces:
             https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html#JSSEClasses
      */
-    private void setSslSocketFactory(OkHttpClient.Builder okHttpClientBuilder, SSLContextService sslService, SSLContext sslContext)
+    private void setSslSocketFactory(OkHttpClient.Builder okHttpClientBuilder, SSLContextService sslService, SSLContext sslContext, boolean setAsSocketFactory)
             throws IOException, KeyStoreException, CertificateException, NoSuchAlgorithmException, UnrecoverableKeyException, KeyManagementException {
 
         final KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
@@ -622,6 +651,9 @@ public final class InvokeHTTP extends AbstractProcessor {
 
         final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
         okHttpClientBuilder.sslSocketFactory(sslSocketFactory, x509TrustManager);
+        if (setAsSocketFactory) {
+            okHttpClientBuilder.socketFactory(sslSocketFactory);
+        }
     }
 
     private void setAuthenticator(OkHttpClient.Builder okHttpClientBuilder, ProcessContext context) {