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 <jamesnether...@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 -->