Skip to content

Commit

Permalink
BodyHandler should not be added before the ProxyHandler
Browse files Browse the repository at this point in the history
See vert-x3#2614

Added documentation and make ProxyHandler fail fast if the BodyHandler has been seen.

Signed-off-by: Thomas Segismont <tsegismont@gmail.com>
  • Loading branch information
tsegismont committed May 24, 2024
1 parent fd1f87c commit c6143a1
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 8 deletions.
22 changes: 17 additions & 5 deletions vertx-web-proxy/src/main/asciidoc/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ the *proxy server* using `ProxyHandler`:
You simply create the *origin server* and handle requests with Vert.x Web `Router`, the *origin server*
listens to port `7070`

[source,java]
[source,$lang]
----
{@link examples.WebProxyExamples#origin}
----
Expand All @@ -52,35 +52,47 @@ listens to port `7070`

Create the *proxy server* that listens to port `8080`

[source,java]
[source,$lang]
----
{@link examples.WebProxyExamples#proxy}
----

== Using `ProxyHandler`

The last interesting part is to route *proxy server* requests to the *origin server*, so you need to create `HttpProxy`
with specified target and `ProxyHandler`.

[source,java]
[source,$lang]
----
{@link examples.WebProxyExamples#route}
----

Or you can specify the target in `ProxyHandler` instead.

[source,java]
[source,$lang]
----
{@link examples.WebProxyExamples#routeShort}
----

Finally, the *proxy server* requests will be routed as a reverse proxy to the *origin server* conveniently.

[WARNING]
====
The {@link io.vertx.ext.web.handler.BodyHandler} is not compatible with the {@link io.vertx.ext.web.proxy.handler.ProxyHandler}.
It shouldn't be installed on the same route or a previous route.
[source,$lang]
----
{@link examples.WebProxyExamples#notCompatibleWithBodyHandler}
----
====

== Using `ProxyHandler` for multiple targets

In order to route *proxy server* requests to multiple *origin servers* you simply create `HttpProxy` for
each one and specify the target independently.

[source,java]
[source,$lang]
----
{@link examples.WebProxyExamples#multi}
----
10 changes: 10 additions & 0 deletions vertx-web-proxy/src/main/java/examples/WebProxyExamples.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import io.vertx.core.http.HttpMethod;
import io.vertx.core.http.HttpServer;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.handler.BodyHandler;
import io.vertx.ext.web.proxy.handler.ProxyHandler;
import io.vertx.httpproxy.HttpProxy;

Expand Down Expand Up @@ -58,6 +59,15 @@ public void routeShort(Vertx vertx, Router proxyRouter) {
.handler(ProxyHandler.create(httpProxy, 7070, "localhost"));
}

public void notCompatibleWithBodyHandler(Router router, HttpProxy productServiceProxy) {
router.post().handler(BodyHandler.create()); // Don't do this
router.route("/product").handler(ProxyHandler.create(productServiceProxy));

router.route("/product")
.handler(BodyHandler.create()) // Don't do this
.handler(ProxyHandler.create(productServiceProxy));
}

public void multi(Vertx vertx, Router proxyRouter) {
HttpClient proxyClient = vertx.createHttpClient();

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package io.vertx.ext.web.proxy.handler.impl;

import io.vertx.core.VertxException;
import io.vertx.ext.web.RoutingContext;
import io.vertx.ext.web.handler.BodyHandler;
import io.vertx.ext.web.proxy.handler.ProxyHandler;
import io.vertx.httpproxy.HttpProxy;

Expand All @@ -10,6 +12,17 @@

public class ProxyHandlerImpl implements ProxyHandler {

private static final Throwable BH_FAILURE;

static {
String msg = "A " +
BodyHandler.class.getSimpleName() +
" has been executed before the " +
ProxyHandler.class.getSimpleName() +
". They are not compatible, please update your router setup.";
BH_FAILURE = new VertxException(msg, true);
}

private final HttpProxy httpProxy;

public ProxyHandlerImpl(HttpProxy httpProxy) {
Expand All @@ -21,7 +34,11 @@ public ProxyHandlerImpl(HttpProxy httpProxy, int port, String host) {
}

@Override
public void handle(RoutingContext ctx) {
httpProxy.handle(ctx.request());
public void handle(RoutingContext rc) {
if (rc.body().available()) {
rc.fail(500, BH_FAILURE);
return;
}
httpProxy.handle(rc.request());
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package io.vertx.ext.web.proxy.handler;

import io.vertx.core.http.HttpMethod;

import io.vertx.ext.web.handler.BodyHandler;
import io.vertx.ext.web.proxy.WebProxyTestBase;
import io.vertx.httpproxy.HttpProxy;
import org.junit.Test;
Expand All @@ -12,6 +12,25 @@

public class ProxyHandlerTest extends WebProxyTestBase {

@Test
public void shouldFailWithBodyHandlerOnPreviousMatchingRoute() throws Exception {
HttpProxy proxy = HttpProxy.reverseProxy(proxyClient);
proxy.origin(1234, "localhost");
router.route().handler(BodyHandler.create());
router.get("/path").handler(ProxyHandler.create(proxy));
testRequest(HttpMethod.GET, "/path", 500, "Internal Server Error");
}

@Test
public void shouldFailWithBodyHandlerOnSameRoute() throws Exception {
HttpProxy proxy = HttpProxy.reverseProxy(proxyClient);
proxy.origin(1234, "localhost");
router.get("/path")
.handler(BodyHandler.create())
.handler(ProxyHandler.create(proxy));
testRequest(HttpMethod.GET, "/path", 500, "Internal Server Error");
}

@Test
public void testProxyHandler() throws Exception {
HttpProxy proxy = HttpProxy.reverseProxy(proxyClient);
Expand Down

0 comments on commit c6143a1

Please sign in to comment.