Skip to content

Commit

Permalink
Ensure that multipart response has a boundary when RestResponse is used
Browse files Browse the repository at this point in the history
Fixes: #29794
  • Loading branch information
geoand committed Dec 12, 2022
1 parent 6ab313d commit 64c5d0f
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import io.quarkus.test.QuarkusUnitTest;
import io.restassured.RestAssured;
import io.restassured.http.ContentType;
import io.restassured.response.ExtractableResponse;

public class MultipartOutputUsingBlockingEndpointsTest extends AbstractMultipartTest {

Expand Down Expand Up @@ -65,18 +66,20 @@ public void testRestResponse() {

@Test
public void testWithFormData() {
String response = RestAssured.get("/multipart/output/with-form-data")
ExtractableResponse<?> extractable = RestAssured.get("/multipart/output/with-form-data")
.then()
.log().all()
.contentType(ContentType.MULTIPART)
.statusCode(200)
.extract().asString();
.extract();

assertContainsValue(response, "name", MediaType.TEXT_PLAIN, MultipartOutputResource.RESPONSE_NAME);
assertContainsValue(response, "custom-surname", MediaType.TEXT_PLAIN, MultipartOutputResource.RESPONSE_SURNAME);
assertContainsValue(response, "custom-status", MediaType.TEXT_PLAIN, MultipartOutputResource.RESPONSE_STATUS);
assertContainsValue(response, "active", MediaType.TEXT_PLAIN, MultipartOutputResource.RESPONSE_ACTIVE);
assertContainsValue(response, "values", MediaType.TEXT_PLAIN, "[one, two]");
String body = extractable.asString();
assertContainsValue(body, "name", MediaType.TEXT_PLAIN, MultipartOutputResource.RESPONSE_NAME);
assertContainsValue(body, "custom-surname", MediaType.TEXT_PLAIN, MultipartOutputResource.RESPONSE_SURNAME);
assertContainsValue(body, "custom-status", MediaType.TEXT_PLAIN, MultipartOutputResource.RESPONSE_STATUS);
assertContainsValue(body, "active", MediaType.TEXT_PLAIN, MultipartOutputResource.RESPONSE_ACTIVE);
assertContainsValue(body, "values", MediaType.TEXT_PLAIN, "[one, two]");

assertThat(extractable.header("Content-Type")).contains("boundary=");
}

@Test
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.jboss.resteasy.reactive.server.core.multipart;

import static javax.ws.rs.core.HttpHeaders.CONTENT_TYPE;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
Expand Down Expand Up @@ -136,7 +138,7 @@ private void writeHeaders(String partName, Object partValue, PartItem part, Char
throws IOException {
part.getHeaders().put(HttpHeaders.CONTENT_DISPOSITION, List.of("form-data; name=\"" + partName + "\""
+ getFileNameIfFile(partValue, part.getFilename())));
part.getHeaders().put(HttpHeaders.CONTENT_TYPE, List.of(part.getMediaType()));
part.getHeaders().put(CONTENT_TYPE, List.of(part.getMediaType()));
for (Map.Entry<String, List<Object>> entry : part.getHeaders().entrySet()) {
writeLine(outputStream, entry.getKey() + ": " + entry.getValue().stream().map(String::valueOf)
.collect(Collectors.joining("; ")), charset);
Expand Down Expand Up @@ -206,8 +208,15 @@ private String generateBoundary() {

private void appendBoundaryIntoMediaType(ResteasyReactiveRequestContext requestContext, String boundary,
MediaType mediaType) {
requestContext.setResponseContentType(new MediaType(mediaType.getType(), mediaType.getSubtype(),
Collections.singletonMap(BOUNDARY_PARAM, boundary)));
MediaType mediaTypeWithBoundary = new MediaType(mediaType.getType(), mediaType.getSubtype(),
Collections.singletonMap(BOUNDARY_PARAM, boundary));
requestContext.setResponseContentType(mediaTypeWithBoundary);

// this is a total hack, but it's needed to make RestResponse<MultipartFormDataOutput> work properly
requestContext.serverResponse().setResponseHeader(CONTENT_TYPE, mediaTypeWithBoundary.toString());
if (requestContext.getResponse().isCreated()) {
requestContext.getResponse().get().getHeaders().remove(CONTENT_TYPE);
}
}

private boolean isNotEmpty(String str) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

import io.restassured.RestAssured;
import io.restassured.http.ContentType;
import io.restassured.response.ExtractableResponse;

public class MultipartOutputUsingBlockingEndpointsTest extends AbstractMultipartTest {

Expand Down Expand Up @@ -46,18 +47,20 @@ public void testSimple() {

@Test
public void testWithFormData() {
String response = RestAssured.get("/multipart/output/with-form-data")
ExtractableResponse<?> extractable = RestAssured.get("/multipart/output/with-form-data")
.then()
.log().all()
.contentType(ContentType.MULTIPART)
.statusCode(200)
.extract().asString();
.extract();

assertContainsValue(response, "name", MediaType.TEXT_PLAIN, MultipartOutputResource.RESPONSE_NAME);
assertContainsValue(response, "custom-surname", MediaType.TEXT_PLAIN, MultipartOutputResource.RESPONSE_SURNAME);
assertContainsValue(response, "custom-status", MediaType.TEXT_PLAIN, MultipartOutputResource.RESPONSE_STATUS);
assertContainsValue(response, "active", MediaType.TEXT_PLAIN, MultipartOutputResource.RESPONSE_ACTIVE);
assertContainsValue(response, "values", MediaType.TEXT_PLAIN, "[one, two]");
String body = extractable.asString();
assertContainsValue(body, "name", MediaType.TEXT_PLAIN, MultipartOutputResource.RESPONSE_NAME);
assertContainsValue(body, "custom-surname", MediaType.TEXT_PLAIN, MultipartOutputResource.RESPONSE_SURNAME);
assertContainsValue(body, "custom-status", MediaType.TEXT_PLAIN, MultipartOutputResource.RESPONSE_STATUS);
assertContainsValue(body, "active", MediaType.TEXT_PLAIN, MultipartOutputResource.RESPONSE_ACTIVE);
assertContainsValue(body, "values", MediaType.TEXT_PLAIN, "[one, two]");

assertThat(extractable.header("Content-Type")).contains("boundary=");
}

@Test
Expand Down

0 comments on commit 64c5d0f

Please sign in to comment.