This is an automated email from the ASF dual-hosted git repository. duncangrant pushed a commit to branch fix-multipart in repository https://gitbox.apache.org/repos/asf/brooklyn-server.git
commit 1163f1ddd6c59b7519122d2e54f558d305365aa6 Author: Duncan Grant <[email protected]> AuthorDate: Tue Jul 27 16:07:20 2021 +0100 Fix disallowed characters in multipart form Specifically if posting a multipart form with %s then we would get an error. --- rest/rest-api/pom.xml | 4 ++++ .../apache/brooklyn/rest/api/ApplicationApi.java | 23 +++++++++++++++--- .../rest/resources/ApplicationResource.java | 9 ++++++++ .../brooklyn/rest/api/ApplicationApiTest.java | 27 ++++++++++++++++++++++ 4 files changed, 60 insertions(+), 3 deletions(-) diff --git a/rest/rest-api/pom.xml b/rest/rest-api/pom.xml index e06640f..d8a0b82 100644 --- a/rest/rest-api/pom.xml +++ b/rest/rest-api/pom.xml @@ -99,6 +99,10 @@ <version>${project.version}</version> <scope>test</scope> </dependency> + <dependency> + <groupId>org.apache.cxf</groupId> + <artifactId>cxf-rt-frontend-jaxrs</artifactId> + </dependency> </dependencies> <build> diff --git a/rest/rest-api/src/main/java/org/apache/brooklyn/rest/api/ApplicationApi.java b/rest/rest-api/src/main/java/org/apache/brooklyn/rest/api/ApplicationApi.java index f73c85c..800b778 100644 --- a/rest/rest-api/src/main/java/org/apache/brooklyn/rest/api/ApplicationApi.java +++ b/rest/rest-api/src/main/java/org/apache/brooklyn/rest/api/ApplicationApi.java @@ -33,6 +33,8 @@ import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; +import org.apache.cxf.jaxrs.ext.multipart.Multipart; + import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; @@ -236,7 +238,7 @@ public interface ApplicationApi { @Beta @POST - @Consumes({MediaType.MULTIPART_FORM_DATA, MediaType.APPLICATION_FORM_URLENCODED}) + @Consumes(MediaType.MULTIPART_FORM_DATA) @ApiOperation( value = "[BETA] Create and start a new application from YAML", response = org.apache.brooklyn.rest.domain.TaskSummary.class @@ -244,13 +246,28 @@ public interface ApplicationApi { @ApiResponses(value = { @ApiResponse(code = 404, message = "Undefined entity or location") }) - public Response createWithFormat( + public Response createWithFormatMultipart( + @ApiParam(name = "plan", value = "Application plan to deploy", required = true) + @Multipart("plan") String plan, + @ApiParam(name = "format", value = "Type plan format e.g. brooklyn-camp", required = false) + @Multipart("format") String format); + + @Beta + @POST + @Consumes(MediaType.APPLICATION_FORM_URLENCODED) + @ApiOperation( + value = "[BETA] Create and start a new application from YAML", + response = org.apache.brooklyn.rest.domain.TaskSummary.class + ) + @ApiResponses(value = { + @ApiResponse(code = 404, message = "Undefined entity or location") + }) + public Response createWithFormatForm( @ApiParam(name = "plan", value = "Application plan to deploy", required = true) @FormParam("plan") String plan, @ApiParam(name = "format", value = "Type plan format e.g. brooklyn-camp", required = false) @FormParam("format") String format); - @DELETE @Path("/{application}") @ApiOperation( diff --git a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/ApplicationResource.java b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/ApplicationResource.java index 13d7773..8ceb1b9 100644 --- a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/ApplicationResource.java +++ b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/ApplicationResource.java @@ -533,6 +533,15 @@ public class ApplicationResource extends AbstractBrooklynRestResource implements } @Override + public Response createWithFormatForm(String plan, String format) { + return createWithFormat(plan, format); + } + + @Override + public Response createWithFormatMultipart(String plan, String format) { + return createWithFormat(plan, format); + } + public Response createWithFormat(String inputToAutodetectType, String format) { log.debug("Creating app from autodetecting input"); diff --git a/rest/rest-server/src/test/java/org/apache/brooklyn/rest/api/ApplicationApiTest.java b/rest/rest-server/src/test/java/org/apache/brooklyn/rest/api/ApplicationApiTest.java new file mode 100644 index 0000000..9ede0d0 --- /dev/null +++ b/rest/rest-server/src/test/java/org/apache/brooklyn/rest/api/ApplicationApiTest.java @@ -0,0 +1,27 @@ +package org.apache.brooklyn.rest.api; + +import com.google.common.collect.ImmutableMap; +import org.apache.brooklyn.rest.BrooklynRestApiLauncherTestFixture; +import org.apache.brooklyn.util.http.HttpToolResponse; +import org.testng.annotations.Test; + +import java.util.Map; + +public class ApplicationApiTest extends BrooklynRestApiLauncherTestFixture { + + + @Test(groups = "Integration") + public void testMultipartFormWithInvalidChar() throws Exception { + useServerForTest(newServer()); + String body = "------WebKitFormBoundaryaQhM7RFMi4ZiXOj2\n\rContent-Disposition: form-data; services:\n\r- type: org.apache.brooklyn.entity.stock.BasicEntity\n\rbrooklyn.config:\n\rexample: $brooklyn:formatString(\"%s\", \"vault\")\n\r\n\r\n\r------WebKitFormBoundaryaQhM7RFMi4ZiXOj2\n\rContent-Disposition: form-data; name=\"format\"\n\r\n\rcamp\n\r------WebKitFormBoundaryaQhM7RFMi4ZiXOj2--\n\r"; + ImmutableMap<String, String> headers = ImmutableMap.of("Content-Type", "multipart/form-data; boundary=----WebKitFormBoundaryaQhM7RFMi4ZiXOj2"); + assertPostMultiPart("admin", "/v1/applications", body.getBytes(), headers); + } + + public void assertPostMultiPart(String user, String path, byte[] body, Map<String, String> headers) throws Exception { + HttpToolResponse response = httpPost(user, path, body, headers); + assertHealthyStatusCode(response); + } + + +} \ No newline at end of file
