From 5f1dcd0a2c57fc7118fee859b23462b4b259156c Mon Sep 17 00:00:00 2001 From: BLasan Date: Fri, 8 Nov 2024 07:57:33 +0530 Subject: [PATCH] fixes: https://github.com/wso2/api-manager/issues/3228 --- .../configdto/HttpClientConfigurationDTO.java | 12 ++++++- .../proxy/ExtendedProxyRoutePlanner.java | 35 +++++++++++++------ .../common/gateway/CommonAPIUtilTestCase.java | 8 +++-- .../wso2/carbon/apimgt/impl/APIConstants.java | 1 + .../impl/internal/APIManagerComponent.java | 14 +++++++- .../repository/conf/api-manager.xml.j2 | 1 + 6 files changed, 55 insertions(+), 16 deletions(-) diff --git a/components/apimgt/org.wso2.carbon.apimgt.common.gateway/src/main/java/org/wso2/carbon/apimgt/common/gateway/configdto/HttpClientConfigurationDTO.java b/components/apimgt/org.wso2.carbon.apimgt.common.gateway/src/main/java/org/wso2/carbon/apimgt/common/gateway/configdto/HttpClientConfigurationDTO.java index c21ab71c4571..8495ef06e9a4 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.common.gateway/src/main/java/org/wso2/carbon/apimgt/common/gateway/configdto/HttpClientConfigurationDTO.java +++ b/components/apimgt/org.wso2.carbon.apimgt.common.gateway/src/main/java/org/wso2/carbon/apimgt/common/gateway/configdto/HttpClientConfigurationDTO.java @@ -37,6 +37,7 @@ public class HttpClientConfigurationDTO { private String proxyUsername; private char[] proxyPassword = new char[]{}; private String[] nonProxyHosts = new String[]{}; + private String[] targetProxyHosts = new String[]{}; private String proxyProtocol; private SSLContext sslContext; private HostnameVerifier hostnameVerifier; @@ -80,6 +81,10 @@ public String[] getNonProxyHosts() { return Arrays.copyOf(nonProxyHosts, nonProxyHosts.length); } + public String[] getTargetProxyHosts() { + return Arrays.copyOf(targetProxyHosts, targetProxyHosts.length); + } + public String getProxyProtocol() { return proxyProtocol; } @@ -106,6 +111,7 @@ public static class Builder { private String proxyUsername; private char[] proxyPassword = new char[]{}; private String[] nonProxyHosts = new String[]{}; + private String[] targetProxyHosts = new String[]{}; private String proxyProtocol; private SSLContext sslContext; private HostnameVerifier hostnameVerifier; @@ -119,7 +125,7 @@ public Builder withConnectionParams(int connectionLimit, int maximumConnectionsP } public Builder withProxy(String proxyHost, int proxyPort, String proxyUsername, String proxyPassword, - String proxyProtocol, String[] nonProxyHosts) { + String proxyProtocol, String[] nonProxyHosts, String[] targetProxyHosts) { this.proxyEnabled = true; this.proxyHost = proxyHost; this.proxyPort = proxyPort; @@ -128,6 +134,9 @@ public Builder withProxy(String proxyHost, int proxyPort, String proxyUsername, this.proxyProtocol = proxyProtocol; this.nonProxyHosts = nonProxyHosts != null ? Arrays.copyOf(nonProxyHosts, nonProxyHosts.length) : new String[]{}; + this.targetProxyHosts = targetProxyHosts != null ? + Arrays.copyOf(targetProxyHosts, targetProxyHosts.length) : + new String[] {}; return this; } @@ -154,6 +163,7 @@ public HttpClientConfigurationDTO build() { configuration.proxyPassword = this.proxyPassword; configuration.proxyProtocol = this.proxyProtocol; configuration.nonProxyHosts = this.nonProxyHosts; + configuration.targetProxyHosts = this.targetProxyHosts; configuration.hostnameVerifier = this.hostnameVerifier; if (this.sslContext != null) { configuration.sslContext = this.sslContext; diff --git a/components/apimgt/org.wso2.carbon.apimgt.common.gateway/src/main/java/org/wso2/carbon/apimgt/common/gateway/proxy/ExtendedProxyRoutePlanner.java b/components/apimgt/org.wso2.carbon.apimgt.common.gateway/src/main/java/org/wso2/carbon/apimgt/common/gateway/proxy/ExtendedProxyRoutePlanner.java index 1057124ac440..f5abc2d4a6cd 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.common.gateway/src/main/java/org/wso2/carbon/apimgt/common/gateway/proxy/ExtendedProxyRoutePlanner.java +++ b/components/apimgt/org.wso2.carbon.apimgt.common.gateway/src/main/java/org/wso2/carbon/apimgt/common/gateway/proxy/ExtendedProxyRoutePlanner.java @@ -65,20 +65,33 @@ private boolean doesTargetMatchNonProxy(HttpHost target) { String uriHost = target.getHostName(); String uriScheme = target.getSchemeName(); String[] nonProxyHosts = configuration.getNonProxyHosts(); - int nphLength = nonProxyHosts != null ? nonProxyHosts.length : 0; - if (nonProxyHosts == null || nphLength < 1) { - log.debug("scheme:'" + uriScheme + "', host:'" + uriHost + "' : DEFAULT (0 non proxy host)"); - return false; + String[] targetProxyHosts = configuration.getTargetProxyHosts(); + + if (nonProxyHosts != null) { + for (String nonProxyHost : nonProxyHosts) { + if ("*".equals(nonProxyHost)) { + return true; + } + if (uriHost.matches(nonProxyHost)) { + log.debug("sheme:'" + uriScheme + "', host:'" + uriHost + "' matches nonProxyHost '" + nonProxyHost + + "' : NO PROXY"); + return true; + } + } } - for (String nonProxyHost : nonProxyHosts) { - if (uriHost.matches(nonProxyHost)) { - log.debug("scheme:'" + uriScheme + "', host:'" + uriHost + "' matches nonProxyHost '" + - nonProxyHost + "' : NO PROXY"); - return true; + + if (targetProxyHosts != null) { + for (String targetProxyHost : targetProxyHosts) { + if ("*".equals(targetProxyHost)) { + return false; + } + if (uriHost.matches(targetProxyHost)) { + return false; + } } } - log.debug("scheme:'" + uriScheme + "', host:'" + uriHost + "' : DEFAULT (no match of " + nphLength + - " non proxy host)"); + + log.debug("sheme:'" + uriScheme + "', host:'" + uriHost + "' : DEFAULT (no match of non proxy hosts)"); return false; } diff --git a/components/apimgt/org.wso2.carbon.apimgt.common.gateway/src/test/java/org/wso2/carbon/apimgt/common/gateway/CommonAPIUtilTestCase.java b/components/apimgt/org.wso2.carbon.apimgt.common.gateway/src/test/java/org/wso2/carbon/apimgt/common/gateway/CommonAPIUtilTestCase.java index 7ad16899b411..c57c00dde314 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.common.gateway/src/test/java/org/wso2/carbon/apimgt/common/gateway/CommonAPIUtilTestCase.java +++ b/components/apimgt/org.wso2.carbon.apimgt.common.gateway/src/test/java/org/wso2/carbon/apimgt/common/gateway/CommonAPIUtilTestCase.java @@ -96,7 +96,7 @@ public void testGetHttpClientWithProxy() { .withSSLContext(sslContext) // proxyProtocol here is https (due to existing limitation) .withProxy(proxyHost, proxyServer.getPort(), proxyUsername, "random", proxyProtocol, - new String[]{"localhost"}) + new String[]{"localhost"}, new String[]{}) .build(); HttpClient clientForNonProxyHost = null; clientForNonProxyHost = CommonAPIUtil.getHttpClient("https", nonProxyHostBasedProxyConfig); @@ -112,7 +112,8 @@ public void testGetHttpClientWithProxy() { HttpClientConfigurationDTO configuration = builder .withConnectionParams(connectionLimit, maximumConnectionsPerRoute, connectionTimeout) .withSSLContext(sslContext) - .withProxy(proxyHost, proxyServer.getPort(), proxyUsername, proxyPassword, proxyProtocol, nonProxyHosts) + .withProxy(proxyHost, proxyServer.getPort(), proxyUsername, proxyPassword, proxyProtocol, nonProxyHosts, + new String[] {}) .build(); HttpClient client = null; @@ -132,7 +133,8 @@ public void testGetHttpClientWithProxy() { HttpClientConfigurationDTO configWithWrongProxyCredentials = builder .withConnectionParams(connectionLimit, maximumConnectionsPerRoute, connectionTimeout) .withSSLContext(sslContext) - .withProxy(proxyHost, proxyServer.getPort(), proxyUsername, "random", proxyProtocol, nonProxyHosts) + .withProxy(proxyHost, proxyServer.getPort(), proxyUsername, "random", proxyProtocol, nonProxyHosts, + new String[] {}) .build(); HttpClient clientWithWrongProxyCreds = null; clientWithWrongProxyCreds = CommonAPIUtil.getHttpClient("https", configWithWrongProxyCredentials); diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIConstants.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIConstants.java index 0b2a678b5ddf..c39bd1caf150 100755 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIConstants.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIConstants.java @@ -1548,6 +1548,7 @@ private OAuthConstants() { public static final String PROXY_USERNAME = "ProxyConfig.Username"; public static final String PROXY_PASSWORD = "ProxyConfig.Password"; public static final String NON_PROXY_HOSTS = "ProxyConfig.NonProxyHosts"; + public static final String TARGET_PROXY_HOSTS = "ProxyConfig.TargetProxyHosts"; public static final String PROXY_PROTOCOL = "ProxyConfig.Protocol"; public static final String KEYMANAGER_HOSTNAME = "keyManagerHostname"; diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/internal/APIManagerComponent.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/internal/APIManagerComponent.java index b6c3cde8becc..e665d2d91e45 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/internal/APIManagerComponent.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/internal/APIManagerComponent.java @@ -1042,9 +1042,10 @@ void populateHttpClientConfiguration() { String proxyUsername = configuration.getFirstProperty(APIConstants.PROXY_USERNAME); String proxyPassword = configuration.getFirstProperty(APIConstants.PROXY_PASSWORD); String[] nonProxyHosts = getNonProxyHostsListByNonProxyHostsStringConfiguration(configuration); + String[] targetProxyHosts = getTargetProxyHostsStringConfiguration(configuration); String proxyProtocol = configuration.getFirstProperty(APIConstants.PROXY_PROTOCOL); builder = builder.withProxy(proxyHost, proxyPort, proxyUsername, proxyPassword, proxyProtocol, - nonProxyHosts); + nonProxyHosts, targetProxyHosts); } SSLContext sslContext = null; @@ -1098,6 +1099,17 @@ String[] getNonProxyHostsListByNonProxyHostsStringConfiguration(APIManagerConfig return nonProxyHostsString != null ? nonProxyHostsString.split("\\|") : null; } + /** + * Populates list of TargetProxyHosts for given targetProxyHostsString through APIManager Configuration + * + * @param config APIManager Configuration + * @return String array of target proxy list + */ + String[] getTargetProxyHostsStringConfiguration(APIManagerConfiguration config) { + String targetProxyHostsString = config.getFirstProperty(APIConstants.TARGET_PROXY_HOSTS); + return targetProxyHostsString != null ? targetProxyHostsString.split("\\|") : null; + } + @Reference( name = "apim.workflow.task.service", service = org.wso2.carbon.apimgt.api.model.WorkflowTaskService.class, diff --git a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/conf_templates/templates/repository/conf/api-manager.xml.j2 b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/conf_templates/templates/repository/conf/api-manager.xml.j2 index 86e7b7d51648..456792368c00 100644 --- a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/conf_templates/templates/repository/conf/api-manager.xml.j2 +++ b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/conf_templates/templates/repository/conf/api-manager.xml.j2 @@ -1681,6 +1681,7 @@ {{apim.proxy_config.username}} {{apim.proxy_config.password}} {{apim.proxy_config.nonProxyHosts}} + {{apim.proxy_config.targetProxyHosts}} {{apim.proxy_config.protocol}}