This is an automated email from the ASF dual-hosted git repository.

klease pushed a commit to branch camel-3.18.x
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/camel-3.18.x by this push:
     new 13fd26db703 Backport correction of CAMEL-18355 from main to 3.18.x
13fd26db703 is described below

commit 13fd26db7031f3e85b4dc2194249e0e2839c76c6
Author: klease <kle...@cegetel.net>
AuthorDate: Fri Aug 26 11:31:04 2022 +0200

    Backport correction of CAMEL-18355 from main to 3.18.x
---
 .../BasicAuthenticationHttpClientConfigurer.java   |  12 +-
 .../apache/camel/component/http/HttpComponent.java |  20 ++-
 .../http/HttpComponentVerifierExtension.java       |  19 ++-
 .../component/http/HttpCredentialsHelper.java      |  42 ++++++
 .../component/http/ProxyHttpClientConfigurer.java  |  13 +-
 .../component/http/HttpClientConfigurerTest.java   |   4 +-
 .../component/http/HttpCredentialsHelperTest.java  |  88 +++++++++++
 .../component/http/HttpProxyAndBasicAuthTest.java  | 165 +++++++++++++++++++++
 ...oxyAndBasicAuthenticationValidationHandler.java |  59 ++++++++
 9 files changed, 394 insertions(+), 28 deletions(-)

diff --git 
a/components/camel-http/src/main/java/org/apache/camel/component/http/BasicAuthenticationHttpClientConfigurer.java
 
b/components/camel-http/src/main/java/org/apache/camel/component/http/BasicAuthenticationHttpClientConfigurer.java
index 0dbc867ad69..ce57f2cb039 100644
--- 
a/components/camel-http/src/main/java/org/apache/camel/component/http/BasicAuthenticationHttpClientConfigurer.java
+++ 
b/components/camel-http/src/main/java/org/apache/camel/component/http/BasicAuthenticationHttpClientConfigurer.java
@@ -16,11 +16,9 @@
  */
 package org.apache.camel.component.http;
 
-import org.apache.http.auth.AuthScope;
 import org.apache.http.auth.Credentials;
 import org.apache.http.auth.NTCredentials;
 import org.apache.http.auth.UsernamePasswordCredentials;
-import org.apache.http.impl.client.BasicCredentialsProvider;
 import org.apache.http.impl.client.HttpClientBuilder;
 
 public class BasicAuthenticationHttpClientConfigurer implements 
HttpClientConfigurer {
@@ -28,12 +26,15 @@ public class BasicAuthenticationHttpClientConfigurer 
implements HttpClientConfig
     private final String password;
     private final String domain;
     private final String host;
+    private final HttpCredentialsHelper credentialsHelper;
 
-    public BasicAuthenticationHttpClientConfigurer(String user, String pwd, 
String domain, String host) {
+    public BasicAuthenticationHttpClientConfigurer(String user, String pwd, 
String domain, String host,
+                                                   HttpCredentialsHelper 
credentialsHelper) {
         this.username = user;
         this.password = pwd;
         this.domain = domain;
         this.host = host;
+        this.credentialsHelper = credentialsHelper;
     }
 
     @Override
@@ -44,9 +45,8 @@ public class BasicAuthenticationHttpClientConfigurer 
implements HttpClientConfig
         } else {
             defaultcreds = new UsernamePasswordCredentials(username, password);
         }
-        BasicCredentialsProvider credentialsProvider = new 
BasicCredentialsProvider();
-        credentialsProvider.setCredentials(AuthScope.ANY, defaultcreds);
-        clientBuilder.setDefaultCredentialsProvider(credentialsProvider);
+        clientBuilder.setDefaultCredentialsProvider(credentialsHelper
+                .getCredentialsProvider(host, null, defaultcreds));
     }
 
 }
diff --git 
a/components/camel-http/src/main/java/org/apache/camel/component/http/HttpComponent.java
 
b/components/camel-http/src/main/java/org/apache/camel/component/http/HttpComponent.java
index 15dc741fdc1..3b11c4dc457 100644
--- 
a/components/camel-http/src/main/java/org/apache/camel/component/http/HttpComponent.java
+++ 
b/components/camel-http/src/main/java/org/apache/camel/component/http/HttpComponent.java
@@ -206,14 +206,16 @@ public class HttpComponent extends HttpCommonComponent 
implements RestProducerFa
             // fallback to component configured
             configurer = getHttpClientConfigurer();
         }
-
-        configurer = configureBasicAuthentication(parameters, configurer);
-        configurer = configureHttpProxy(parameters, configurer, secure);
+        HttpCredentialsHelper credentialsProvider = new 
HttpCredentialsHelper();
+        configurer = configureBasicAuthentication(parameters, configurer, 
credentialsProvider);
+        configurer = configureHttpProxy(parameters, configurer, secure, 
credentialsProvider);
 
         return configurer;
     }
 
-    private HttpClientConfigurer configureBasicAuthentication(Map<String, 
Object> parameters, HttpClientConfigurer configurer) {
+    private HttpClientConfigurer configureBasicAuthentication(
+            Map<String, Object> parameters, HttpClientConfigurer configurer,
+            HttpCredentialsHelper credentialsProvider) {
         String authUsername = getParameter(parameters, "authUsername", 
String.class);
         String authPassword = getParameter(parameters, "authPassword", 
String.class);
 
@@ -222,14 +224,15 @@ public class HttpComponent extends HttpCommonComponent 
implements RestProducerFa
             String authHost = getParameter(parameters, "authHost", 
String.class);
 
             return CompositeHttpConfigurer.combineConfigurers(configurer,
-                    new BasicAuthenticationHttpClientConfigurer(authUsername, 
authPassword, authDomain, authHost));
+                    new BasicAuthenticationHttpClientConfigurer(
+                            authUsername, authPassword, authDomain, authHost, 
credentialsProvider));
         } else if (this.httpConfiguration != null) {
             if 
("basic".equalsIgnoreCase(this.httpConfiguration.getAuthMethod())) {
                 return CompositeHttpConfigurer.combineConfigurers(configurer,
                         new BasicAuthenticationHttpClientConfigurer(
                                 this.httpConfiguration.getAuthUsername(),
                                 this.httpConfiguration.getAuthPassword(), 
this.httpConfiguration.getAuthDomain(),
-                                this.httpConfiguration.getAuthHost()));
+                                this.httpConfiguration.getAuthHost(), 
credentialsProvider));
             }
         }
 
@@ -237,7 +240,8 @@ public class HttpComponent extends HttpCommonComponent 
implements RestProducerFa
     }
 
     private HttpClientConfigurer configureHttpProxy(
-            Map<String, Object> parameters, HttpClientConfigurer configurer, 
boolean secure) {
+            Map<String, Object> parameters, HttpClientConfigurer configurer, 
boolean secure,
+            HttpCredentialsHelper credentialsProvider) {
         String proxyAuthScheme = getParameter(parameters, "proxyAuthScheme", 
String.class, getProxyAuthScheme());
         if (proxyAuthScheme == null) {
             // fallback and use either http or https depending on secure
@@ -266,7 +270,7 @@ public class HttpComponent extends HttpCommonComponent 
implements RestProducerFa
                         configurer,
                         new ProxyHttpClientConfigurer(
                                 proxyAuthHost, proxyAuthPort, proxyAuthScheme, 
proxyAuthUsername, proxyAuthPassword,
-                                proxyAuthDomain, proxyAuthNtHost));
+                                proxyAuthDomain, proxyAuthNtHost, 
credentialsProvider));
             } else {
                 return CompositeHttpConfigurer.combineConfigurers(configurer,
                         new ProxyHttpClientConfigurer(proxyAuthHost, 
proxyAuthPort, proxyAuthScheme));
diff --git 
a/components/camel-http/src/main/java/org/apache/camel/component/http/HttpComponentVerifierExtension.java
 
b/components/camel-http/src/main/java/org/apache/camel/component/http/HttpComponentVerifierExtension.java
index f656ccb7d5b..c72b4697baa 100644
--- 
a/components/camel-http/src/main/java/org/apache/camel/component/http/HttpComponentVerifierExtension.java
+++ 
b/components/camel-http/src/main/java/org/apache/camel/component/http/HttpComponentVerifierExtension.java
@@ -165,7 +165,9 @@ final class HttpComponentVerifierExtension extends 
DefaultComponentVerifierExten
         return httpUri;
     }
 
-    private Optional<HttpClientConfigurer> configureAuthentication(Map<String, 
Object> parameters) {
+    private Optional<HttpClientConfigurer> configureAuthentication(
+            Map<String, Object> parameters,
+            HttpCredentialsHelper credentialsHelper) {
         Optional<String> authUsername = getOption(parameters, "authUsername", 
String.class);
         Optional<String> authPassword = getOption(parameters, "authPassword", 
String.class);
 
@@ -178,13 +180,16 @@ final class HttpComponentVerifierExtension extends 
DefaultComponentVerifierExten
                             authUsername.get(),
                             authPassword.get(),
                             authDomain.orElse(null),
-                            authHost.orElse(null)));
+                            authHost.orElse(null),
+                            credentialsHelper));
         }
 
         return Optional.empty();
     }
 
-    private Optional<HttpClientConfigurer> configureProxy(Map<String, Object> 
parameters) {
+    private Optional<HttpClientConfigurer> configureProxy(
+            Map<String, Object> parameters,
+            HttpCredentialsHelper credentialsHelper) {
         Optional<String> uri = getOption(parameters, "httpUri", String.class);
         Optional<String> proxyAuthHost = getOption(parameters, 
"proxyAuthHost", String.class);
         Optional<Integer> proxyAuthPort = getOption(parameters, 
"proxyAuthPort", Integer.class);
@@ -209,7 +214,8 @@ final class HttpComponentVerifierExtension extends 
DefaultComponentVerifierExten
                                 proxyAuthUsername.orElse(null),
                                 proxyAuthPassword.orElse(null),
                                 proxyAuthDomain.orElse(null),
-                                proxyAuthNtHost.orElse(null)));
+                                proxyAuthNtHost.orElse(null),
+                                credentialsHelper));
             } else {
                 return Optional.of(
                         new ProxyHttpClientConfigurer(
@@ -224,8 +230,9 @@ final class HttpComponentVerifierExtension extends 
DefaultComponentVerifierExten
 
     private CloseableHttpClient createHttpClient(Map<String, Object> 
parameters) throws Exception {
         CompositeHttpConfigurer configurer = new CompositeHttpConfigurer();
-        
configureAuthentication(parameters).ifPresent(configurer::addConfigurer);
-        configureProxy(parameters).ifPresent(configurer::addConfigurer);
+        HttpCredentialsHelper credentialsHelper = new HttpCredentialsHelper();
+        configureAuthentication(parameters, 
credentialsHelper).ifPresent(configurer::addConfigurer);
+        configureProxy(parameters, 
credentialsHelper).ifPresent(configurer::addConfigurer);
 
         HttpClientBuilder builder = HttpClientBuilder.create();
         configurer.configureHttpClient(builder);
diff --git 
a/components/camel-http/src/main/java/org/apache/camel/component/http/HttpCredentialsHelper.java
 
b/components/camel-http/src/main/java/org/apache/camel/component/http/HttpCredentialsHelper.java
new file mode 100644
index 00000000000..23270b78ca1
--- /dev/null
+++ 
b/components/camel-http/src/main/java/org/apache/camel/component/http/HttpCredentialsHelper.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.http;
+
+import java.util.Objects;
+
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.Credentials;
+import org.apache.http.client.CredentialsProvider;
+import org.apache.http.impl.client.BasicCredentialsProvider;
+
+final class HttpCredentialsHelper {
+
+    private final CredentialsProvider credentialsProvider;
+
+    HttpCredentialsHelper() {
+        this.credentialsProvider = new BasicCredentialsProvider();
+    }
+
+    public CredentialsProvider getCredentialsProvider(
+            String host, Integer port, Credentials credentials) {
+        this.credentialsProvider.setCredentials(new AuthScope(
+                host,
+                Objects.requireNonNullElse(port, AuthScope.ANY_PORT)), 
credentials);
+        return credentialsProvider;
+    }
+
+}
diff --git 
a/components/camel-http/src/main/java/org/apache/camel/component/http/ProxyHttpClientConfigurer.java
 
b/components/camel-http/src/main/java/org/apache/camel/component/http/ProxyHttpClientConfigurer.java
index c14fb55cbb3..8bf0c1bfad2 100644
--- 
a/components/camel-http/src/main/java/org/apache/camel/component/http/ProxyHttpClientConfigurer.java
+++ 
b/components/camel-http/src/main/java/org/apache/camel/component/http/ProxyHttpClientConfigurer.java
@@ -17,11 +17,9 @@
 package org.apache.camel.component.http;
 
 import org.apache.http.HttpHost;
-import org.apache.http.auth.AuthScope;
 import org.apache.http.auth.Credentials;
 import org.apache.http.auth.NTCredentials;
 import org.apache.http.auth.UsernamePasswordCredentials;
-import org.apache.http.impl.client.BasicCredentialsProvider;
 import org.apache.http.impl.client.HttpClientBuilder;
 
 /**
@@ -36,13 +34,14 @@ public class ProxyHttpClientConfigurer implements 
HttpClientConfigurer {
     private final String password;
     private final String domain;
     private final String ntHost;
+    private final HttpCredentialsHelper credentialsHelper;
 
     public ProxyHttpClientConfigurer(String host, Integer port, String scheme) 
{
-        this(host, port, scheme, null, null, null, null);
+        this(host, port, scheme, null, null, null, null, null);
     }
 
     public ProxyHttpClientConfigurer(String host, Integer port, String scheme, 
String username, String password, String domain,
-                                     String ntHost) {
+                                     String ntHost, HttpCredentialsHelper 
credentialsHelper) {
         this.host = host;
         this.port = port;
         this.scheme = scheme;
@@ -50,6 +49,7 @@ public class ProxyHttpClientConfigurer implements 
HttpClientConfigurer {
         this.password = password;
         this.domain = domain;
         this.ntHost = ntHost;
+        this.credentialsHelper = credentialsHelper;
     }
 
     @Override
@@ -63,9 +63,8 @@ public class ProxyHttpClientConfigurer implements 
HttpClientConfigurer {
             } else {
                 defaultcreds = new UsernamePasswordCredentials(username, 
password);
             }
-            BasicCredentialsProvider credentialsProvider = new 
BasicCredentialsProvider();
-            credentialsProvider.setCredentials(AuthScope.ANY, defaultcreds);
-            clientBuilder.setDefaultCredentialsProvider(credentialsProvider);
+            clientBuilder.setDefaultCredentialsProvider(credentialsHelper
+                    .getCredentialsProvider(host, port, defaultcreds));
         }
     }
 
diff --git 
a/components/camel-http/src/test/java/org/apache/camel/component/http/HttpClientConfigurerTest.java
 
b/components/camel-http/src/test/java/org/apache/camel/component/http/HttpClientConfigurerTest.java
index c84045212c4..4590a1ce9e8 100644
--- 
a/components/camel-http/src/test/java/org/apache/camel/component/http/HttpClientConfigurerTest.java
+++ 
b/components/camel-http/src/test/java/org/apache/camel/component/http/HttpClientConfigurerTest.java
@@ -37,7 +37,9 @@ public class HttpClientConfigurerTest extends 
CamelTestSupport {
         return new RouteBuilder() {
             public void configure() {
                 // add configurer to http component
-                configurer = new ProxyHttpClientConfigurer("proxyhost", 80, 
"http", "user", "password", null, null);
+                configurer = new ProxyHttpClientConfigurer(
+                        "proxyhost", 80, "http", "user", "password", null, 
null,
+                        new HttpCredentialsHelper());
                 getContext().getComponent("http", 
HttpComponent.class).setHttpClientConfigurer(configurer);
 
                 from("direct:start")
diff --git 
a/components/camel-http/src/test/java/org/apache/camel/component/http/HttpCredentialsHelperTest.java
 
b/components/camel-http/src/test/java/org/apache/camel/component/http/HttpCredentialsHelperTest.java
new file mode 100644
index 00000000000..10e0de90341
--- /dev/null
+++ 
b/components/camel-http/src/test/java/org/apache/camel/component/http/HttpCredentialsHelperTest.java
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.http;
+
+import org.apache.camel.test.junit5.CamelTestSupport;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.Credentials;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.CredentialsProvider;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class HttpCredentialsHelperTest extends CamelTestSupport {
+
+    HttpCredentialsHelper credentialsHelper = new HttpCredentialsHelper();
+
+    private final String host = "credentials.test.org";
+    private final Integer port = Integer.valueOf(80);
+    private final String proxyHost = "proxy.test.org";
+    private final Integer proxyPort = Integer.valueOf(8080);
+    private String username = "testUser";
+    private String password = "testPassowrd";
+
+    private String proxyUsername = "proxyUser";
+    private String proxyPassword = "proxyPassowrd";
+
+    @Test
+    void testOneCredential() {
+        Credentials credentials = new UsernamePasswordCredentials(username, 
password);
+        CredentialsProvider provider = 
credentialsHelper.getCredentialsProvider(host, port, credentials);
+        assertNotNull(provider);
+        assertEquals(credentials, provider.getCredentials(new AuthScope(host, 
port)));
+    }
+
+    @Test
+    void testCredentialsNoPort() {
+        Credentials credentials = new UsernamePasswordCredentials(username, 
password);
+        CredentialsProvider provider = 
credentialsHelper.getCredentialsProvider(host, null, credentials);
+        assertNotNull(provider);
+        assertEquals(credentials, provider.getCredentials(new AuthScope(host, 
AuthScope.ANY_PORT)));
+    }
+
+    @Test
+    void testTwoCredentials() {
+        Credentials credentials = new UsernamePasswordCredentials(username, 
password);
+        CredentialsProvider provider = 
credentialsHelper.getCredentialsProvider(host, port, credentials);
+        Credentials proxyCredentials = new 
UsernamePasswordCredentials(proxyUsername, proxyPassword);
+        CredentialsProvider provider2 = 
credentialsHelper.getCredentialsProvider(proxyHost, proxyPort,
+                proxyCredentials);
+
+        assertNotNull(provider);
+        assertEquals(provider, provider2);
+        assertEquals(credentials, provider.getCredentials(new AuthScope(host, 
port)));
+        assertEquals(proxyCredentials, provider.getCredentials(new 
AuthScope(proxyHost, proxyPort)));
+
+    }
+
+    @Test
+    void testTwoCredentialsDifferentHttpComponents() {
+        Credentials credentials1 = new UsernamePasswordCredentials(username, 
password);
+        CredentialsProvider provider1 = 
credentialsHelper.getCredentialsProvider(host, port, credentials1);
+        Credentials credentials2 = new UsernamePasswordCredentials(username + 
"2", password + "2");
+
+        CredentialsProvider provider2
+                = new 
HttpCredentialsHelper().getCredentialsProvider(proxyHost, proxyPort, 
credentials2);
+        assertNotEquals(provider1, provider2);
+        assertEquals(credentials1, provider1.getCredentials(new 
AuthScope(host, port)));
+        assertEquals(credentials2, provider2.getCredentials(new 
AuthScope(proxyHost, proxyPort)));
+        assertNull(provider2.getCredentials(new AuthScope(host, port)));
+        assertNull(provider1.getCredentials(new AuthScope(proxyHost, 
proxyPort)));
+    }
+
+}
diff --git 
a/components/camel-http/src/test/java/org/apache/camel/component/http/HttpProxyAndBasicAuthTest.java
 
b/components/camel-http/src/test/java/org/apache/camel/component/http/HttpProxyAndBasicAuthTest.java
new file mode 100644
index 00000000000..66b3e5dc526
--- /dev/null
+++ 
b/components/camel-http/src/test/java/org/apache/camel/component/http/HttpProxyAndBasicAuthTest.java
@@ -0,0 +1,165 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.http;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.camel.Exchange;
+import 
org.apache.camel.component.http.handler.ProxyAndBasicAuthenticationValidationHandler;
+import org.apache.commons.codec.BinaryDecoder;
+import org.apache.commons.codec.DecoderException;
+import org.apache.commons.codec.binary.Base64;
+import org.apache.http.Header;
+import org.apache.http.HttpException;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpRequestInterceptor;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpResponseInterceptor;
+import org.apache.http.HttpStatus;
+import org.apache.http.ProtocolException;
+import org.apache.http.auth.AUTH;
+import org.apache.http.impl.bootstrap.HttpServer;
+import org.apache.http.impl.bootstrap.ServerBootstrap;
+import org.apache.http.localserver.RequestBasicAuth;
+import org.apache.http.localserver.ResponseBasicUnauthorized;
+import org.apache.http.protocol.HttpContext;
+import org.apache.http.protocol.HttpProcessor;
+import org.apache.http.protocol.ImmutableHttpProcessor;
+import org.apache.http.protocol.ResponseContent;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import static org.apache.camel.component.http.HttpMethods.GET;
+
+public class HttpProxyAndBasicAuthTest extends BaseHttpTest {
+
+    private HttpServer proxy;
+
+    private String user = "camel";
+    private String password = "password";
+    private String proxyUser = "proxyuser";
+    private String proxyPassword = "proxypassword";
+
+    @BeforeEach
+    @Override
+    public void setUp() throws Exception {
+        proxy = 
ServerBootstrap.bootstrap().setHttpProcessor(getBasicHttpProcessor())
+                
.setConnectionReuseStrategy(getConnectionReuseStrategy()).setResponseFactory(getHttpResponseFactory())
+                
.setExpectationVerifier(getHttpExpectationVerifier()).setSslContext(getSSLContext())
+                .registerHandler("*", new 
ProxyAndBasicAuthenticationValidationHandler(
+                        GET.name(),
+                        null, null, getExpectedContent(), user, password, 
proxyUser, proxyPassword))
+                .create();
+        proxy.start();
+
+        super.setUp();
+
+    }
+
+    @AfterEach
+    @Override
+    public void tearDown() throws Exception {
+        super.tearDown();
+
+        if (proxy != null) {
+            proxy.stop();
+        }
+    }
+
+    @Override
+    protected HttpProcessor getBasicHttpProcessor() {
+        List<HttpRequestInterceptor> requestInterceptors = new ArrayList<>();
+        requestInterceptors.add(new RequestProxyBasicAuth());
+        requestInterceptors.add(new RequestBasicAuth());
+        List<HttpResponseInterceptor> responseInterceptors = new ArrayList<>();
+        responseInterceptors.add(new ResponseContent());
+        responseInterceptors.add(new ResponseProxyBasicUnauthorized());
+        responseInterceptors.add(new ResponseBasicUnauthorized());
+        return new ImmutableHttpProcessor(requestInterceptors, 
responseInterceptors);
+    }
+
+    @Test
+    public void httpGetWithProxyAndUser() throws Exception {
+        Exchange exchange = template.request("http://authtest.org"; + 
"?proxyAuthHost="
+                                             + getProxyHost() + 
"&proxyAuthPort=" + getProxyPort()
+                                             + "&proxyAuthUsername=" + 
proxyUser + "&proxyAuthPassword=" + proxyPassword
+                                             + "&authUsername=" + user + 
"&authPassword=" + password,
+                exchange1 -> {
+                });
+
+        assertExchange(exchange);
+    }
+
+    private String getProxyHost() {
+        return proxy.getInetAddress().getHostName();
+    }
+
+    private String getProxyPort() {
+        return "" + proxy.getLocalPort();
+    }
+
+    private static class RequestProxyBasicAuth implements 
HttpRequestInterceptor {
+        @Override
+        public void process(final HttpRequest request, final HttpContext 
context) throws HttpException, IOException {
+            String auth = null;
+
+            String requestLine = request.getRequestLine().toString();
+            // assert we set a write GET URI
+            if (requestLine.contains("http://localhost";)) {
+                throw new HttpException("Get a wrong proxy GET url");
+            }
+            Header h = request.getFirstHeader(AUTH.PROXY_AUTH_RESP);
+            if (h != null) {
+                String s = h.getValue();
+                if (s != null) {
+                    auth = s.trim();
+                }
+            }
+
+            if (auth != null) {
+                int i = auth.indexOf(' ');
+                if (i == -1) {
+                    throw new ProtocolException("Invalid Authorization header: 
" + auth);
+                }
+                String authscheme = auth.substring(0, i);
+                if (authscheme.equalsIgnoreCase("basic")) {
+                    String s = auth.substring(i + 1).trim();
+                    byte[] credsRaw = s.getBytes("ASCII");
+                    BinaryDecoder codec = new Base64();
+                    try {
+                        String creds = new String(codec.decode(credsRaw), 
"ASCII");
+                        context.setAttribute("proxy-creds", creds);
+                    } catch (DecoderException ex) {
+                        throw new ProtocolException("Malformed BASIC 
credentials");
+                    }
+                }
+            }
+        }
+    }
+
+    private static class ResponseProxyBasicUnauthorized implements 
HttpResponseInterceptor {
+        @Override
+        public void process(final HttpResponse response, final HttpContext 
context) throws HttpException, IOException {
+            if (response.getStatusLine().getStatusCode() == 
HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED) {
+                response.addHeader(AUTH.PROXY_AUTH, "Basic realm=\"test 
realm\"");
+            }
+        }
+    }
+}
diff --git 
a/components/camel-http/src/test/java/org/apache/camel/component/http/handler/ProxyAndBasicAuthenticationValidationHandler.java
 
b/components/camel-http/src/test/java/org/apache/camel/component/http/handler/ProxyAndBasicAuthenticationValidationHandler.java
new file mode 100644
index 00000000000..272a511f0c7
--- /dev/null
+++ 
b/components/camel-http/src/test/java/org/apache/camel/component/http/handler/ProxyAndBasicAuthenticationValidationHandler.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.http.handler;
+
+import java.io.IOException;
+
+import org.apache.http.HttpException;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
+import org.apache.http.protocol.HttpContext;
+
+public class ProxyAndBasicAuthenticationValidationHandler extends 
AuthenticationValidationHandler {
+
+    private final String proxyPassword;
+    private final String proxyUser;
+
+    public ProxyAndBasicAuthenticationValidationHandler(String expectedMethod,
+                                                        String expectedQuery, 
Object expectedContent,
+                                                        String 
responseContent, String user, String password,
+                                                        String proxyUser, 
String proxyPassword) {
+        super(expectedMethod, expectedQuery, expectedContent, responseContent, 
user, password);
+        this.proxyUser = proxyUser;
+        this.proxyPassword = proxyPassword;
+    }
+
+    @Override
+    public void handle(
+            final HttpRequest request, final HttpResponse response,
+            final HttpContext context)
+            throws HttpException, IOException {
+
+        if 
(!getExpectedProxyCredential().equals(context.getAttribute("proxy-creds"))) {
+            
response.setStatusCode(HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED);
+            return;
+        }
+
+        super.handle(request, response, context);
+    }
+
+    private Object getExpectedProxyCredential() {
+        return proxyUser + ":" + proxyPassword;
+    }
+
+}

Reply via email to