You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ja...@apache.org on 2024/01/04 09:23:53 UTC

(camel-quarkus) branch main updated: Replace tinyproxy container image with an embedded HTTP proxy server

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

jamesnetherton pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-quarkus.git


The following commit(s) were added to refs/heads/main by this push:
     new 2055a79909 Replace tinyproxy container image with an embedded HTTP proxy server
2055a79909 is described below

commit 2055a79909fe6160070d892d497bf20c1713f454
Author: James Netherton <ja...@gmail.com>
AuthorDate: Thu Jan 4 07:37:04 2024 +0000

    Replace tinyproxy container image with an embedded HTTP proxy server
    
    Fixes #5631
---
 integration-test-groups/http/common/pom.xml        |  16 ---
 .../component/http/common/HttpTestResource.java    | 130 +++++++++++++++++----
 integration-test-groups/http/http/pom.xml          |  11 --
 .../quarkus/component/http/http/HttpResource.java  |   4 +-
 integration-test-groups/http/netty-http/pom.xml    |  16 ---
 .../ProxyCapableClientInitializerFactory.java      |   4 +-
 integration-test-groups/http/vertx-http/pom.xml    |  16 ---
 .../component/http/vertx/VertxResource.java        |   4 +-
 pom.xml                                            |   1 -
 9 files changed, 114 insertions(+), 88 deletions(-)

diff --git a/integration-test-groups/http/common/pom.xml b/integration-test-groups/http/common/pom.xml
index cbc3fa0b43..be0b7de094 100644
--- a/integration-test-groups/http/common/pom.xml
+++ b/integration-test-groups/http/common/pom.xml
@@ -55,22 +55,6 @@
             <artifactId>rest-assured</artifactId>
             <scope>test</scope>
         </dependency>
-        <dependency>
-            <groupId>org.testcontainers</groupId>
-            <artifactId>testcontainers</artifactId>
-            <exclusions>
-                <exclusion>
-                    <groupId>junit</groupId>
-                    <artifactId>junit</artifactId>
-                </exclusion>
-            </exclusions>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>io.quarkus</groupId>
-            <artifactId>quarkus-junit4-mock</artifactId>
-            <scope>test</scope>
-        </dependency>
         <dependency>
             <groupId>org.apache.camel.quarkus</groupId>
             <artifactId>camel-quarkus-integration-test-support</artifactId>
diff --git a/integration-test-groups/http/common/src/test/java/org/apache/camel/quarkus/component/http/common/HttpTestResource.java b/integration-test-groups/http/common/src/test/java/org/apache/camel/quarkus/component/http/common/HttpTestResource.java
index 2d00cfe7eb..72ddc21652 100644
--- a/integration-test-groups/http/common/src/test/java/org/apache/camel/quarkus/component/http/common/HttpTestResource.java
+++ b/integration-test-groups/http/common/src/test/java/org/apache/camel/quarkus/component/http/common/HttpTestResource.java
@@ -16,51 +16,137 @@
  */
 package org.apache.camel.quarkus.component.http.common;
 
+import java.util.Base64;
 import java.util.Map;
 import java.util.Objects;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 
 import io.quarkus.test.common.QuarkusTestResourceLifecycleManager;
+import io.vertx.core.Handler;
+import io.vertx.core.Vertx;
+import io.vertx.core.VertxOptions;
+import io.vertx.core.http.HttpMethod;
+import io.vertx.core.http.HttpServer;
+import io.vertx.core.http.HttpServerRequest;
+import io.vertx.core.http.HttpServerResponse;
+import io.vertx.core.net.NetClient;
+import io.vertx.core.net.NetSocket;
+import io.vertx.core.streams.Pump;
 import org.apache.camel.quarkus.test.AvailablePortFinder;
-import org.eclipse.microprofile.config.ConfigProvider;
-import org.testcontainers.containers.GenericContainer;
-import org.testcontainers.containers.wait.strategy.Wait;
+import org.jboss.logging.Logger;
 
 import static org.apache.camel.quarkus.component.http.common.AbstractHttpResource.USER_ADMIN;
 import static org.apache.camel.quarkus.component.http.common.AbstractHttpResource.USER_ADMIN_PASSWORD;
 
 public class HttpTestResource implements QuarkusTestResourceLifecycleManager {
-
-    private static final String TINY_PROXY_IMAGE_NAME = ConfigProvider.getConfig().getValue("tinyproxy.container.image",
-            String.class);
-    private static final Integer TINY_PROXY_PORT = 8888;
-    private GenericContainer<?> container;
+    private static final Logger LOG = Logger.getLogger(HttpTestResource.class);
+    private ProxyServer server;
 
     @Override
     public Map<String, String> start() {
-        container = new GenericContainer(TINY_PROXY_IMAGE_NAME)
-                .withEnv("BASIC_AUTH_USER", USER_ADMIN)
-                .withEnv("BASIC_AUTH_PASSWORD", USER_ADMIN_PASSWORD)
-                .withExposedPorts(TINY_PROXY_PORT)
-                .withCommand("ANY")
-                .waitingFor(Wait.forListeningPort());
-
-        container.start();
-
         Map<String, String> options = AvailablePortFinder.reserveNetworkPorts(
                 Objects::toString,
+                "proxy.port",
                 "camel.netty-http.test-port",
                 "camel.netty-http.https-test-port",
                 "camel.netty-http.compression-test-port");
-        options.put("tiny.proxy.host", container.getHost());
-        options.put("tiny.proxy.port", container.getMappedPort(TINY_PROXY_PORT).toString());
+        options.put("proxy.host", "localhost");
+
+        server = new ProxyServer(Integer.parseInt(options.get("proxy.port")), USER_ADMIN, USER_ADMIN_PASSWORD);
+        server.start();
+
         return options;
     }
 
     @Override
     public void stop() {
-        if (container != null) {
-            container.stop();
-        }
         AvailablePortFinder.releaseReservedPorts();
+        if (server != null) {
+            server.stop();
+        }
+    }
+
+    /**
+     * Bare-bones HTTP proxy server implementation that supports authentication.
+     */
+    static final class ProxyServer implements Handler<HttpServerRequest> {
+        private final int port;
+        private final String proxyUser;
+        private final String proxyPassword;
+        private final Vertx vertx;
+        private final HttpServer proxyServer;
+
+        ProxyServer(int port, String proxyUser, String proxyPassword) {
+            this.port = port;
+            this.proxyUser = proxyUser;
+            this.proxyPassword = proxyPassword;
+            this.vertx = Vertx.vertx(new VertxOptions().setWorkerPoolSize(1).setEventLoopPoolSize(1));
+            this.proxyServer = vertx.createHttpServer();
+        }
+
+        void start() {
+            CountDownLatch startLatch = new CountDownLatch(1);
+            proxyServer.requestHandler(this);
+            proxyServer.listen(port).onComplete(result -> {
+                LOG.infof("HTTP proxy server started on port %d", port);
+                startLatch.countDown();
+            });
+            try {
+                startLatch.await(1, TimeUnit.MINUTES);
+            } catch (InterruptedException e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+        void stop() {
+            if (proxyServer != null) {
+                LOG.info("HTTP proxy server shutting down");
+                proxyServer.close();
+            }
+            if (vertx != null) {
+                vertx.close();
+            }
+        }
+
+        @Override
+        public void handle(HttpServerRequest httpServerRequest) {
+            String authorization = httpServerRequest.getHeader("Proxy-Authorization");
+            HttpServerResponse response = httpServerRequest.response();
+            if (httpServerRequest.method().equals(HttpMethod.CONNECT) && authorization == null) {
+                response.putHeader("Proxy-Authenticate", "Basic")
+                        .setStatusCode(407)
+                        .end();
+                return;
+            }
+
+            String[] authParts = authorization.split(" ");
+            String[] credentials = new String(Base64.getDecoder().decode(authParts[1])).split(":");
+            if (credentials.length != 2) {
+                response.setStatusCode(400).end();
+            } else {
+                if (credentials[0].equals(proxyUser) && credentials[1].equals(proxyPassword)) {
+                    String host = httpServerRequest.getHeader("Host");
+                    String[] hostParts = host.split(":");
+
+                    // Deal with the result of the CONNECT tunnel and proxy the request / response
+                    NetClient netClient = vertx.createNetClient();
+                    netClient.connect(Integer.parseInt(hostParts[1]), hostParts[0], result -> {
+                        if (result.succeeded()) {
+                            NetSocket clientSocket = result.result();
+                            NetSocket serverSocket = httpServerRequest.toNetSocket().result();
+                            serverSocket.closeHandler(v -> clientSocket.close());
+                            clientSocket.closeHandler(v -> serverSocket.close());
+                            Pump.pump(serverSocket, clientSocket).start();
+                            Pump.pump(clientSocket, serverSocket).start();
+                        } else {
+                            response.setStatusCode(403).end();
+                        }
+                    });
+                } else {
+                    response.setStatusCode(401).end();
+                }
+            }
+        }
     }
 }
diff --git a/integration-test-groups/http/http/pom.xml b/integration-test-groups/http/http/pom.xml
index 15caa88b81..b16f38a957 100644
--- a/integration-test-groups/http/http/pom.xml
+++ b/integration-test-groups/http/http/pom.xml
@@ -67,17 +67,6 @@
             <artifactId>rest-assured</artifactId>
             <scope>test</scope>
         </dependency>
-        <dependency>
-            <groupId>org.testcontainers</groupId>
-            <artifactId>testcontainers</artifactId>
-            <exclusions>
-                <exclusion>
-                    <groupId>junit</groupId>
-                    <artifactId>junit</artifactId>
-                </exclusion>
-            </exclusions>
-            <scope>test</scope>
-        </dependency>
         <dependency>
             <groupId>org.apache.camel.quarkus</groupId>
             <artifactId>camel-quarkus-integration-test-support</artifactId>
diff --git a/integration-test-groups/http/http/src/main/java/org/apache/camel/quarkus/component/http/http/HttpResource.java b/integration-test-groups/http/http/src/main/java/org/apache/camel/quarkus/component/http/http/HttpResource.java
index 7897e15013..a08b111b4e 100644
--- a/integration-test-groups/http/http/src/main/java/org/apache/camel/quarkus/component/http/http/HttpResource.java
+++ b/integration-test-groups/http/http/src/main/java/org/apache/camel/quarkus/component/http/http/HttpResource.java
@@ -106,8 +106,8 @@ public class HttpResource extends AbstractHttpResource {
     @Produces(MediaType.APPLICATION_XML)
     public String httpProxy() {
         Config config = ConfigProvider.getConfig();
-        String proxyHost = config.getValue("tiny.proxy.host", String.class);
-        Integer proxyPort = config.getValue("tiny.proxy.port", Integer.class);
+        String proxyHost = config.getValue("proxy.host", String.class);
+        Integer proxyPort = config.getValue("proxy.port", Integer.class);
         return producerTemplate
                 .toF("%s?"
                         + "proxyAuthMethod=Basic"
diff --git a/integration-test-groups/http/netty-http/pom.xml b/integration-test-groups/http/netty-http/pom.xml
index b664c03da6..f9f2cd9612 100644
--- a/integration-test-groups/http/netty-http/pom.xml
+++ b/integration-test-groups/http/netty-http/pom.xml
@@ -61,27 +61,11 @@
             <artifactId>quarkus-junit5</artifactId>
             <scope>test</scope>
         </dependency>
-        <dependency>
-            <groupId>io.quarkus</groupId>
-            <artifactId>quarkus-junit4-mock</artifactId>
-            <scope>test</scope>
-        </dependency>
         <dependency>
             <groupId>io.rest-assured</groupId>
             <artifactId>rest-assured</artifactId>
             <scope>test</scope>
         </dependency>
-        <dependency>
-            <groupId>org.testcontainers</groupId>
-            <artifactId>testcontainers</artifactId>
-            <exclusions>
-                <exclusion>
-                    <groupId>junit</groupId>
-                    <artifactId>junit</artifactId>
-                </exclusion>
-            </exclusions>
-            <scope>test</scope>
-        </dependency>
         <dependency>
             <groupId>org.apache.camel.quarkus</groupId>
             <artifactId>camel-quarkus-integration-test-support</artifactId>
diff --git a/integration-test-groups/http/netty-http/src/main/java/org/apache/camel/quarkus/component/http/netty/ProxyCapableClientInitializerFactory.java b/integration-test-groups/http/netty-http/src/main/java/org/apache/camel/quarkus/component/http/netty/ProxyCapableClientInitializerFactory.java
index 89db81aa0b..9f3e544684 100644
--- a/integration-test-groups/http/netty-http/src/main/java/org/apache/camel/quarkus/component/http/netty/ProxyCapableClientInitializerFactory.java
+++ b/integration-test-groups/http/netty-http/src/main/java/org/apache/camel/quarkus/component/http/netty/ProxyCapableClientInitializerFactory.java
@@ -42,8 +42,8 @@ public class ProxyCapableClientInitializerFactory extends HttpClientInitializerF
     @Override
     protected void initChannel(Channel channel) throws Exception {
         Config config = ConfigProvider.getConfig();
-        String proxyHost = config.getValue("tiny.proxy.host", String.class);
-        Integer proxyPort = config.getValue("tiny.proxy.port", Integer.class);
+        String proxyHost = config.getValue("proxy.host", String.class);
+        Integer proxyPort = config.getValue("proxy.port", Integer.class);
         InetSocketAddress proxyServerAddress = new InetSocketAddress(proxyHost, proxyPort);
         HttpProxyHandler httpProxyHandler = new HttpProxyHandler(proxyServerAddress, USER_ADMIN, USER_ADMIN_PASSWORD);
         httpProxyHandler.setConnectTimeoutMillis(5000);
diff --git a/integration-test-groups/http/vertx-http/pom.xml b/integration-test-groups/http/vertx-http/pom.xml
index a27a73b9ff..2de38d556b 100644
--- a/integration-test-groups/http/vertx-http/pom.xml
+++ b/integration-test-groups/http/vertx-http/pom.xml
@@ -53,27 +53,11 @@
             <artifactId>quarkus-junit5</artifactId>
             <scope>test</scope>
         </dependency>
-        <dependency>
-            <groupId>io.quarkus</groupId>
-            <artifactId>quarkus-junit4-mock</artifactId>
-            <scope>test</scope>
-        </dependency>
         <dependency>
             <groupId>io.rest-assured</groupId>
             <artifactId>rest-assured</artifactId>
             <scope>test</scope>
         </dependency>
-        <dependency>
-            <groupId>org.testcontainers</groupId>
-            <artifactId>testcontainers</artifactId>
-            <exclusions>
-                <exclusion>
-                    <groupId>junit</groupId>
-                    <artifactId>junit</artifactId>
-                </exclusion>
-            </exclusions>
-            <scope>test</scope>
-        </dependency>
         <dependency>
             <groupId>org.apache.camel.quarkus</groupId>
             <artifactId>camel-quarkus-integration-test-support</artifactId>
diff --git a/integration-test-groups/http/vertx-http/src/main/java/org/apache/camel/quarkus/component/http/vertx/VertxResource.java b/integration-test-groups/http/vertx-http/src/main/java/org/apache/camel/quarkus/component/http/vertx/VertxResource.java
index b21e392339..a73fb6e105 100644
--- a/integration-test-groups/http/vertx-http/src/main/java/org/apache/camel/quarkus/component/http/vertx/VertxResource.java
+++ b/integration-test-groups/http/vertx-http/src/main/java/org/apache/camel/quarkus/component/http/vertx/VertxResource.java
@@ -93,8 +93,8 @@ public class VertxResource extends AbstractHttpResource {
     @Produces(MediaType.APPLICATION_XML)
     public String httpProxy() {
         Config config = ConfigProvider.getConfig();
-        String proxyHost = config.getValue("tiny.proxy.host", String.class);
-        Integer proxyPort = config.getValue("tiny.proxy.port", Integer.class);
+        String proxyHost = config.getValue("proxy.host", String.class);
+        Integer proxyPort = config.getValue("proxy.port", Integer.class);
         return producerTemplate
                 .toF("vertx-http:%s?"
                         + "proxyHost=%s"
diff --git a/pom.xml b/pom.xml
index 753b1557d2..fedecb5f15 100644
--- a/pom.xml
+++ b/pom.xml
@@ -248,7 +248,6 @@
         <redis.container.image>docker.io/redis:7.0.12</redis.container.image>
         <splunk.container.image>docker.io/splunk/splunk:9.0</splunk.container.image>
         <sql-server.container.image>mcr.microsoft.com/mssql/server:2017-CU12</sql-server.container.image>
-        <tinyproxy.container.image>docker.io/monokal/tinyproxy</tinyproxy.container.image>
 
         <!-- Plugin configuration through properties  -->