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 2021/04/30 07:55:05 UTC
[camel] branch main updated: CAMEL-16560: Consider empty string in
clientRequestValidation for REST HTTP body
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.git
The following commit(s) were added to refs/heads/main by this push:
new d85173a CAMEL-16560: Consider empty string in clientRequestValidation for REST HTTP body
d85173a is described below
commit d85173a64c482fee9a76bb48747d98013d208ccf
Author: James Netherton <ja...@gmail.com>
AuthorDate: Fri Apr 30 08:22:46 2021 +0100
CAMEL-16560: Consider empty string in clientRequestValidation for REST HTTP body
---
.../jetty/rest/RestJettyRequiredBodyTest.java | 17 +-
.../http/vertx/VertxPlatformHttpConsumer.java | 6 +-
.../http/vertx/VertxPlatformHttpEngineTest.java | 192 +++++++++++++--------
.../apache/camel/processor/RestBindingAdvice.java | 4 +-
4 files changed, 144 insertions(+), 75 deletions(-)
diff --git a/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/rest/RestJettyRequiredBodyTest.java b/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/rest/RestJettyRequiredBodyTest.java
index 0d1cee8..b591537 100644
--- a/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/rest/RestJettyRequiredBodyTest.java
+++ b/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/rest/RestJettyRequiredBodyTest.java
@@ -41,7 +41,7 @@ public class RestJettyRequiredBodyTest extends BaseJettyTest {
}
@Test
- public void testJettyInvalid() {
+ public void testJettyInvalidNullBody() {
fluentTemplate = fluentTemplate.withHeader(Exchange.CONTENT_TYPE, "application/json")
.withHeader("Accept", "application/json")
.withHeader(Exchange.HTTP_METHOD, "post")
@@ -54,6 +54,21 @@ public class RestJettyRequiredBodyTest extends BaseJettyTest {
assertEquals("The request body is missing.", cause.getResponseBody());
}
+ @Test
+ public void testJettyInvalidEmptyBody() {
+ fluentTemplate = fluentTemplate.withHeader(Exchange.CONTENT_TYPE, "application/json")
+ .withHeader("Accept", "application/json")
+ .withHeader(Exchange.HTTP_METHOD, "post")
+ .withBody(" ")
+ .to("http://localhost:" + getPort() + "/users/123/update");
+
+ Exception ex = assertThrows(CamelExecutionException.class, () -> fluentTemplate.request(String.class));
+
+ HttpOperationFailedException cause = assertIsInstanceOf(HttpOperationFailedException.class, ex.getCause());
+ assertEquals(400, cause.getStatusCode());
+ assertEquals("The request body is missing.", cause.getResponseBody());
+ }
+
@Override
protected RouteBuilder createRouteBuilder() throws Exception {
return new RouteBuilder() {
diff --git a/components/camel-platform-http-vertx/src/main/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpConsumer.java b/components/camel-platform-http-vertx/src/main/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpConsumer.java
index e2264e7..d1f1471 100644
--- a/components/camel-platform-http-vertx/src/main/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpConsumer.java
+++ b/components/camel-platform-http-vertx/src/main/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpConsumer.java
@@ -247,7 +247,11 @@ public class VertxPlatformHttpConsumer extends DefaultConsumer {
}
}
}
- result.setBody(body);
+
+ if (!body.isEmpty()) {
+ result.setBody(body);
+ }
+
if (isMultipartFormData) {
populateAttachments(ctx.fileUploads(), result);
}
diff --git a/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpEngineTest.java b/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpEngineTest.java
index 1cfc2a3..3d0b2d2 100644
--- a/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpEngineTest.java
+++ b/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpEngineTest.java
@@ -24,13 +24,14 @@ import java.util.concurrent.TimeUnit;
import javax.activation.DataHandler;
+import io.restassured.RestAssured;
import io.vertx.core.VertxOptions;
-import io.vertx.ext.web.handler.BodyHandler;
import org.apache.camel.CamelContext;
import org.apache.camel.attachment.AttachmentMessage;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.platform.http.PlatformHttpComponent;
import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.model.rest.RestParamType;
import org.apache.camel.support.jsse.KeyManagersParameters;
import org.apache.camel.support.jsse.KeyStoreParameters;
import org.apache.camel.support.jsse.SSLContextParameters;
@@ -87,14 +88,8 @@ public class VertxPlatformHttpEngineTest {
@Test
public void testEngineSetup() throws Exception {
- final int port = AvailablePortFinder.getNextAvailable();
- final CamelContext context = new DefaultCamelContext();
-
+ final CamelContext context = createCamelContext();
try {
- VertxPlatformHttpServerConfiguration conf = new VertxPlatformHttpServerConfiguration();
- conf.setBindPort(port);
-
- context.addService(new VertxPlatformHttpServer(conf));
context.start();
assertThat(VertxPlatformHttpRouter.lookup(context)).isNotNull();
@@ -109,14 +104,9 @@ public class VertxPlatformHttpEngineTest {
@Test
public void testEngine() throws Exception {
- final int port = AvailablePortFinder.getNextAvailable();
- final CamelContext context = new DefaultCamelContext();
+ final CamelContext context = createCamelContext();
try {
- VertxPlatformHttpServerConfiguration conf = new VertxPlatformHttpServerConfiguration();
- conf.setBindPort(port);
-
- context.addService(new VertxPlatformHttpServer(conf));
context.addRoutes(new RouteBuilder() {
@Override
public void configure() throws Exception {
@@ -132,7 +122,6 @@ public class VertxPlatformHttpEngineTest {
context.start();
given()
- .port(conf.getBindPort())
.when()
.get("/get")
.then()
@@ -140,7 +129,6 @@ public class VertxPlatformHttpEngineTest {
.body(equalTo("get"));
given()
- .port(conf.getBindPort())
.body("post")
.when()
.post("/post")
@@ -155,20 +143,15 @@ public class VertxPlatformHttpEngineTest {
@Test
public void testSlowConsumer() throws Exception {
- final int port = AvailablePortFinder.getNextAvailable();
- final CamelContext context = new DefaultCamelContext();
+ final CamelContext context = createCamelContext();
try {
- VertxPlatformHttpServerConfiguration conf = new VertxPlatformHttpServerConfiguration();
- conf.setBindPort(port);
-
context.getRegistry().bind(
"vertx-options",
new VertxOptions()
.setMaxEventLoopExecuteTime(2)
.setMaxEventLoopExecuteTimeUnit(TimeUnit.SECONDS));
- context.addService(new VertxPlatformHttpServer(conf));
context.addRoutes(new RouteBuilder() {
@Override
public void configure() throws Exception {
@@ -182,7 +165,6 @@ public class VertxPlatformHttpEngineTest {
context.start();
given()
- .port(conf.getBindPort())
.when()
.get("/get")
.then()
@@ -196,14 +178,9 @@ public class VertxPlatformHttpEngineTest {
@Test
public void testFailingConsumer() throws Exception {
- final int port = AvailablePortFinder.getNextAvailable();
- final CamelContext context = new DefaultCamelContext();
+ final CamelContext context = createCamelContext();
try {
- VertxPlatformHttpServerConfiguration conf = new VertxPlatformHttpServerConfiguration();
- conf.setBindPort(port);
-
- context.addService(new VertxPlatformHttpServer(conf));
context.addRoutes(new RouteBuilder() {
@Override
public void configure() throws Exception {
@@ -218,7 +195,6 @@ public class VertxPlatformHttpEngineTest {
context.start();
given()
- .port(conf.getBindPort())
.when()
.get("/get")
.then()
@@ -231,16 +207,11 @@ public class VertxPlatformHttpEngineTest {
@Test
public void testEngineSSL() throws Exception {
- VertxPlatformHttpServerConfiguration conf = new VertxPlatformHttpServerConfiguration();
- conf.setSslContextParameters(serverSSLParameters);
- conf.setBindPort(AvailablePortFinder.getNextAvailable());
-
- CamelContext context = new DefaultCamelContext();
+ final CamelContext context
+ = createCamelContext(configuration -> configuration.setSslContextParameters(serverSSLParameters));
try {
- context.addService(new VertxPlatformHttpServer(conf));
context.getRegistry().bind("clientSSLContextParameters", clientSSLParameters);
-
context.addRoutes(new RouteBuilder() {
@Override
public void configure() throws Exception {
@@ -252,7 +223,7 @@ public class VertxPlatformHttpEngineTest {
context.start();
String result = context.createFluentProducerTemplate()
- .toF("https://localhost:%d?sslContextParameters=#clientSSLContextParameters", conf.getBindPort())
+ .toF("https://localhost:%d?sslContextParameters=#clientSSLContextParameters", RestAssured.port)
.withBody("test")
.request(String.class);
@@ -264,15 +235,10 @@ public class VertxPlatformHttpEngineTest {
@Test
public void testEngineGlobalSSL() throws Exception {
- VertxPlatformHttpServerConfiguration conf = new VertxPlatformHttpServerConfiguration();
- conf.setUseGlobalSslContextParameters(true);
- conf.setBindPort(AvailablePortFinder.getNextAvailable());
-
- CamelContext context = new DefaultCamelContext();
+ final CamelContext context = createCamelContext(configuration -> configuration.setUseGlobalSslContextParameters(true));
try {
context.setSSLContextParameters(serverSSLParameters);
- context.addService(new VertxPlatformHttpServer(conf));
context.getRegistry().bind("clientSSLContextParameters", clientSSLParameters);
context.addRoutes(new RouteBuilder() {
@@ -286,7 +252,7 @@ public class VertxPlatformHttpEngineTest {
context.start();
String result = context.createFluentProducerTemplate()
- .toF("https://localhost:%d?sslContextParameters=#clientSSLContextParameters", conf.getBindPort())
+ .toF("https://localhost:%d?sslContextParameters=#clientSSLContextParameters", RestAssured.port)
.withBody("test")
.request(String.class);
@@ -298,15 +264,12 @@ public class VertxPlatformHttpEngineTest {
@Test
public void testEngineCORS() throws Exception {
- VertxPlatformHttpServerConfiguration conf = new VertxPlatformHttpServerConfiguration();
- conf.setBindPort(AvailablePortFinder.getNextAvailable());
- conf.getCors().setEnabled(true);
- conf.getCors().setMethods(Arrays.asList("GET", "POST"));
-
- CamelContext context = new DefaultCamelContext();
+ final CamelContext context = createCamelContext(configuration -> {
+ configuration.getCors().setEnabled(true);
+ configuration.getCors().setMethods(Arrays.asList("GET", "POST"));
+ });
try {
- context.addService(new VertxPlatformHttpServer(conf));
context.addRoutes(new RouteBuilder() {
@Override
public void configure() throws Exception {
@@ -322,7 +285,6 @@ public class VertxPlatformHttpEngineTest {
final String headers = "X-Custom";
given()
- .port(conf.getBindPort())
.header("Origin", origin)
.header("Access-Control-Request-Method", methods)
.header("Access-Control-Request-Headers", headers)
@@ -340,13 +302,9 @@ public class VertxPlatformHttpEngineTest {
@Test
public void testMatchOnUriPrefix() throws Exception {
- VertxPlatformHttpServerConfiguration conf = new VertxPlatformHttpServerConfiguration();
- conf.setBindPort(AvailablePortFinder.getNextAvailable());
-
- CamelContext context = new DefaultCamelContext();
+ final CamelContext context = createCamelContext();
try {
final String greeting = "Hello Camel";
- context.addService(new VertxPlatformHttpServer(conf));
context.addRoutes(new RouteBuilder() {
@Override
public void configure() throws Exception {
@@ -358,14 +316,12 @@ public class VertxPlatformHttpEngineTest {
context.start();
given()
- .port(conf.getBindPort())
.when()
.get("/greeting")
.then()
.statusCode(404);
given()
- .port(conf.getBindPort())
.when()
.get("/greeting/Camel")
.then()
@@ -373,7 +329,6 @@ public class VertxPlatformHttpEngineTest {
.body(equalTo(greeting));
given()
- .port(conf.getBindPort())
.when()
.get("/greeting/Camel/other/path/")
.then()
@@ -386,23 +341,18 @@ public class VertxPlatformHttpEngineTest {
@Test
public void testFileUpload() throws Exception {
- final int port = AvailablePortFinder.getNextAvailable();
final String fileContent = "Test multipart upload content";
final File tempFile = File.createTempFile("platform-http", ".txt");
- final CamelContext context = new DefaultCamelContext();
-
- try {
- VertxPlatformHttpServerConfiguration conf = new VertxPlatformHttpServerConfiguration();
- conf.setBindPort(port);
-
+ final CamelContext context = createCamelContext(configuration -> {
VertxPlatformHttpServerConfiguration.BodyHandler bodyHandler
= new VertxPlatformHttpServerConfiguration.BodyHandler();
bodyHandler.setUploadsDirectory(tempFile.getParent());
- conf.setBodyHandler(bodyHandler);
+ configuration.setBodyHandler(bodyHandler);
+ });
+ try {
Files.write(tempFile.toPath(), fileContent.getBytes(StandardCharsets.UTF_8));
- context.addService(new VertxPlatformHttpServer(conf));
context.addRoutes(new RouteBuilder() {
@Override
public void configure() throws Exception {
@@ -418,7 +368,6 @@ public class VertxPlatformHttpEngineTest {
context.start();
given()
- .port(conf.getBindPort())
.multiPart(tempFile)
.when()
.post("/upload")
@@ -429,4 +378,105 @@ public class VertxPlatformHttpEngineTest {
context.stop();
}
}
+
+ @Test
+ public void testFormPost() throws Exception {
+ final CamelContext context = createCamelContext();
+
+ try {
+ context.addRoutes(new RouteBuilder() {
+ @Override
+ public void configure() throws Exception {
+ from("platform-http:/form/post")
+ .convertBodyTo(String.class);
+ }
+ });
+
+ context.start();
+
+ given()
+ .formParam("foo", "bar")
+ .formParam("cheese", "wine")
+ .when()
+ .post("/form/post")
+ .then()
+ .statusCode(200)
+ .body(is("{foo=bar, cheese=wine}"));
+ } finally {
+ context.stop();
+ }
+ }
+
+ @Test
+ public void testBodyClientRequestValidation() throws Exception {
+ final CamelContext context = createCamelContext();
+
+ try {
+ context.addRoutes(new RouteBuilder() {
+ @Override
+ public void configure() throws Exception {
+ restConfiguration().component("platform-http");
+
+ rest("/rest")
+ .post("/validate/body")
+ .clientRequestValidation(true)
+ .param().name("body").type(RestParamType.body).required(true).endParam()
+ .route()
+ .setBody(simple("Hello ${body}"))
+ .endRest();
+ }
+ });
+
+ context.start();
+
+ given()
+ .when()
+ .post("/rest/validate/body")
+ .then()
+ .statusCode(400)
+ .body(is("The request body is missing."));
+
+ given()
+ .body(" ")
+ .when()
+ .post("/rest/validate/body")
+ .then()
+ .statusCode(400)
+ .body(is("The request body is missing."));
+
+ given()
+ .body("Camel Platform HTTP Vert.x")
+ .when()
+ .post("/rest/validate/body")
+ .then()
+ .statusCode(200)
+ .body(is("Hello Camel Platform HTTP Vert.x"));
+ } finally {
+ context.stop();
+ }
+ }
+
+ private CamelContext createCamelContext() throws Exception {
+ return createCamelContext(null);
+ }
+
+ private CamelContext createCamelContext(ServerConfigurationCustomizer customizer) throws Exception {
+ int port = AvailablePortFinder.getNextAvailable();
+ VertxPlatformHttpServerConfiguration conf = new VertxPlatformHttpServerConfiguration();
+ conf.setBindPort(port);
+
+ RestAssured.port = port;
+
+ if (customizer != null) {
+ customizer.customize(conf);
+ }
+
+ CamelContext context = new DefaultCamelContext();
+ context.addService(new VertxPlatformHttpServer(conf));
+ return context;
+ }
+
+ interface ServerConfigurationCustomizer {
+ void customize(VertxPlatformHttpServerConfiguration configuration);
+ }
}
diff --git a/core/camel-core-processor/src/main/java/org/apache/camel/processor/RestBindingAdvice.java b/core/camel-core-processor/src/main/java/org/apache/camel/processor/RestBindingAdvice.java
index af98fff..db113be 100644
--- a/core/camel-core-processor/src/main/java/org/apache/camel/processor/RestBindingAdvice.java
+++ b/core/camel-core-processor/src/main/java/org/apache/camel/processor/RestBindingAdvice.java
@@ -268,11 +268,11 @@ public class RestBindingAdvice implements CamelInternalProcessorAdvice<Map<Strin
// so force reading the body as a String which we can work with
if (body == null) {
body = MessageHelper.extractBodyAsString(exchange.getIn());
- if (body != null) {
+ if (ObjectHelper.isNotEmpty(body)) {
exchange.getIn().setBody(body);
}
}
- if (body == null) {
+ if (ObjectHelper.isEmpty(body)) {
// this is a bad request, the client did not include a message body
exchange.getMessage().setHeader(Exchange.HTTP_RESPONSE_CODE, 400);
exchange.getMessage().setBody("The request body is missing.");