diff --git a/http/rest-client-reactive/pom.xml b/http/rest-client-reactive/pom.xml
index 6737db606..206baec67 100644
--- a/http/rest-client-reactive/pom.xml
+++ b/http/rest-client-reactive/pom.xml
@@ -28,4 +28,31 @@
commons-lang3
+
+
+
+ skip-tests-on-windows
+
+
+ windows
+
+
+
+
+
+ maven-surefire-plugin
+
+ true
+
+
+
+ maven-failsafe-plugin
+
+ true
+
+
+
+
+
+
diff --git a/http/rest-client-reactive/src/main/java/io/quarkus/ts/http/restclient/reactive/proxy/ProxyClient.java b/http/rest-client-reactive/src/main/java/io/quarkus/ts/http/restclient/reactive/proxy/ProxyClient.java
new file mode 100644
index 000000000..fb9db8265
--- /dev/null
+++ b/http/rest-client-reactive/src/main/java/io/quarkus/ts/http/restclient/reactive/proxy/ProxyClient.java
@@ -0,0 +1,31 @@
+package io.quarkus.ts.http.restclient.reactive.proxy;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+import org.eclipse.microprofile.rest.client.annotation.RegisterClientHeaders;
+import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;
+
+import io.smallrye.mutiny.Uni;
+
+@RegisterRestClient
+@RegisterClientHeaders
+public interface ProxyClient {
+
+ @GET
+ @Path("/")
+ @Produces(MediaType.TEXT_HTML)
+ Uni getSite();
+
+ @GET
+ @Path("/example.txt")
+ @Produces(MediaType.TEXT_PLAIN)
+ Uni getText();
+
+ @GET
+ @Path("/auth")
+ @Produces(MediaType.TEXT_PLAIN)
+ Uni getAuthorized();
+}
diff --git a/http/rest-client-reactive/src/main/java/io/quarkus/ts/http/restclient/reactive/proxy/ProxyResource.java b/http/rest-client-reactive/src/main/java/io/quarkus/ts/http/restclient/reactive/proxy/ProxyResource.java
new file mode 100644
index 000000000..29214137f
--- /dev/null
+++ b/http/rest-client-reactive/src/main/java/io/quarkus/ts/http/restclient/reactive/proxy/ProxyResource.java
@@ -0,0 +1,41 @@
+package io.quarkus.ts.http.restclient.reactive.proxy;
+
+import javax.inject.Inject;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+import org.eclipse.microprofile.rest.client.inject.RestClient;
+
+import io.smallrye.mutiny.Uni;
+
+@Path("/proxied")
+public class ProxyResource {
+
+ @Inject
+ @RestClient
+ ProxyClient client;
+
+ @GET
+ @Path("/")
+ @Produces(MediaType.TEXT_HTML)
+ public Uni getRoot() {
+ return client.getSite();
+ }
+
+ @GET
+ @Path("/banned")
+ @Produces(MediaType.TEXT_PLAIN)
+ public Uni getBanned() {
+ return client.getText();
+ }
+
+ @GET
+ @Path("/authorization")
+ @Produces(MediaType.TEXT_PLAIN)
+ public Uni getAuthorized() {
+ return client.getAuthorized();
+ }
+
+}
diff --git a/http/rest-client-reactive/src/main/resources/proxy.properties b/http/rest-client-reactive/src/main/resources/proxy.properties
new file mode 100644
index 000000000..075eab02d
--- /dev/null
+++ b/http/rest-client-reactive/src/main/resources/proxy.properties
@@ -0,0 +1,6 @@
+quarkus.rest-client."io.quarkus.ts.http.restclient.reactive.proxy.ProxyClient".url=http://example.com
+quarkus.rest-client."io.quarkus.ts.http.restclient.reactive.proxy.ProxyClient".proxy-address=localhost:8090
+quarkus.rest-client."io.quarkus.ts.http.restclient.reactive.proxy.ProxyClient".proxy-user=proxyuser
+quarkus.rest-client."io.quarkus.ts.http.restclient.reactive.proxy.ProxyClient".proxy-password=proxypassword
+quarkus.rest-client.logging.scope=request-response
+quarkus.log.category."org.jboss.resteasy.reactive.client.logging".level=DEBUG
diff --git a/http/rest-client-reactive/src/test/java/io/quarkus/ts/http/restclient/reactive/ProxyIT.java b/http/rest-client-reactive/src/test/java/io/quarkus/ts/http/restclient/reactive/ProxyIT.java
new file mode 100644
index 000000000..b81c55dbb
--- /dev/null
+++ b/http/rest-client-reactive/src/test/java/io/quarkus/ts/http/restclient/reactive/ProxyIT.java
@@ -0,0 +1,65 @@
+package io.quarkus.ts.http.restclient.reactive;
+
+import java.util.Base64;
+
+import org.apache.http.HttpStatus;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import io.quarkus.test.bootstrap.RestService;
+import io.quarkus.test.scenarios.QuarkusScenario;
+import io.quarkus.test.services.Container;
+import io.quarkus.test.services.QuarkusApplication;
+import io.restassured.response.Response;
+
+@QuarkusScenario
+public class ProxyIT {
+ private static final String USER = "proxyuser";
+ private static final String PASSWORD = "proxypassword";
+
+ @Container(image = "quay.io/quarkusqeteam/proxy", port = 8090, expectedLog = "Configuration complete; ready for start up")
+ static RestService proxy = new RestService();
+
+ @QuarkusApplication
+ static RestService proxyApp = new RestService()
+ .withProperties("proxy.properties")
+ .withProperty("quarkus.rest-client.\"io.quarkus.ts.http.restclient.reactive.proxy.ProxyClient\".proxy-user", USER)
+ .withProperty("quarkus.rest-client.\"io.quarkus.ts.http.restclient.reactive.proxy.ProxyClient\".proxy-password",
+ PASSWORD)
+ .withProperty("quarkus.rest-client.\"io.quarkus.ts.http.restclient.reactive.proxy.ProxyClient\".proxy-address",
+ () -> proxy.getHost().replace("http://", "") + ":" + proxy.getPort());
+
+ @Test
+ void getThrough() {
+ Response proxied = proxyApp.given().with().get("/proxied/");
+ Assertions.assertEquals(HttpStatus.SC_OK, proxied.statusCode());
+ Assertions.assertTrue(proxied.body().asString().contains("Example Domain"));
+ }
+
+ @Test
+ void banned() {
+ Response banned = proxyApp.given().with().get("/proxied/banned");
+ Assertions.assertEquals(HttpStatus.SC_OK, banned.statusCode());
+ Assertions.assertEquals("Reading is prohibited by corporate policy!",
+ banned.body().asString());
+ }
+
+ @Test
+ /*
+ * Nginx returns content of Proxy-Auth Header.
+ * We check, that this content is made according to the specification.
+ * https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication#proxy_authentication
+ */
+ void authorization() {
+ Response response = proxyApp.given().with().get("/proxied/authorization");
+ Assertions.assertEquals(HttpStatus.SC_OK, response.statusCode());
+ String authorizationType = "Basic";
+ String credentials = encode(USER + ":" + PASSWORD);
+ String header = response.body().asString();
+ Assertions.assertEquals(authorizationType + " " + credentials, header);
+ }
+
+ private static String encode(String source) {
+ return Base64.getEncoder().encodeToString(source.getBytes());
+ }
+}
diff --git a/http/rest-client-reactive/src/test/resources/proxy/Dockerfile b/http/rest-client-reactive/src/test/resources/proxy/Dockerfile
new file mode 100644
index 000000000..1cc9e078d
--- /dev/null
+++ b/http/rest-client-reactive/src/test/resources/proxy/Dockerfile
@@ -0,0 +1,2 @@
+FROM nginx:1.21
+COPY nginx.conf /etc/nginx/nginx.conf
diff --git a/http/rest-client-reactive/src/test/resources/proxy/README.md b/http/rest-client-reactive/src/test/resources/proxy/README.md
new file mode 100644
index 000000000..ac394c376
--- /dev/null
+++ b/http/rest-client-reactive/src/test/resources/proxy/README.md
@@ -0,0 +1,11 @@
+This folder contains everything for building and deploying proxy container, based on nginx
+It is based on these resources:
+* http://nginx.org/en/docs/beginners_guide.html#proxy
+* http://nginx.org/en/docs/http/ngx_http_proxy_module.html
+* https://www.baeldung.com/nginx-forward-proxy
+
+By default, the container listens on port 8090.
+
+Script run.sh is mainly for debugging
+
+Script deploy.sh is for building and deploying to quay.io
diff --git a/http/rest-client-reactive/src/test/resources/proxy/deploy.sh b/http/rest-client-reactive/src/test/resources/proxy/deploy.sh
new file mode 100755
index 000000000..cd3749b89
--- /dev/null
+++ b/http/rest-client-reactive/src/test/resources/proxy/deploy.sh
@@ -0,0 +1,3 @@
+docker build -t nginx-proxy .
+docker tag nginx-proxy quay.io/quarkusqeteam/proxy:latest
+docker push quay.io/quarkusqeteam/proxy:latest
diff --git a/http/rest-client-reactive/src/test/resources/proxy/nginx.conf b/http/rest-client-reactive/src/test/resources/proxy/nginx.conf
new file mode 100644
index 000000000..cf7b3ba6c
--- /dev/null
+++ b/http/rest-client-reactive/src/test/resources/proxy/nginx.conf
@@ -0,0 +1,16 @@
+events {}
+http {
+ server {
+ listen 8090;
+ resolver 8.8.8.8;
+ location / {
+ proxy_pass http://$host;
+ }
+ location ~ \.(txt)$ {
+ return 203 "Reading is prohibited by corporate policy!";
+ }
+ location /auth {
+ return 200 $http_proxy_authorization;
+ }
+ }
+}
diff --git a/http/rest-client-reactive/src/test/resources/proxy/run.sh b/http/rest-client-reactive/src/test/resources/proxy/run.sh
new file mode 100755
index 000000000..a78c7075b
--- /dev/null
+++ b/http/rest-client-reactive/src/test/resources/proxy/run.sh
@@ -0,0 +1 @@
+docker build -t nginx-proxy . && docker run -p 8090:8090 nginx-proxy