Skip to content

Commit

Permalink
Ensure that returning an InputStream from RESTEasy Reactive works in …
Browse files Browse the repository at this point in the history
…native

Fixes: quarkusio#26780
  • Loading branch information
geoand committed Jul 26, 2022
1 parent 022602f commit f4ff81d
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotat
@Override
public void writeTo(InputStream inputStream, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType,
MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException {
writeTo(inputStream, entityStream);
}

protected void writeTo(InputStream inputStream, OutputStream entityStream) throws IOException {
try {
byte[] buffer = new byte[8192];
int c;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@
import org.jboss.resteasy.reactive.common.providers.serialisers.InputStreamMessageBodyHandler;
import org.jboss.resteasy.reactive.server.spi.ResteasyReactiveResourceInfo;
import org.jboss.resteasy.reactive.server.spi.ServerMessageBodyReader;
import org.jboss.resteasy.reactive.server.spi.ServerMessageBodyWriter;
import org.jboss.resteasy.reactive.server.spi.ServerRequestContext;

@Provider
public class ServerInputStreamMessageBodyHandler extends InputStreamMessageBodyHandler
implements ServerMessageBodyReader<InputStream> {
implements ServerMessageBodyReader<InputStream>, ServerMessageBodyWriter<InputStream> {

@Override
public boolean isReadable(Class<?> type, Type genericType, ResteasyReactiveResourceInfo lazyMethod, MediaType mediaType) {
Expand All @@ -33,4 +34,15 @@ public long getSize(InputStream inputStream, Class<?> type, Type genericType, An
return -1;
}

@Override
public boolean isWriteable(Class<?> type, Type genericType, ResteasyReactiveResourceInfo target,
MediaType mediaType) {
return super.isWriteable(type, null, null, null);
}

@Override
public void writeResponse(InputStream is, Type genericType, ServerRequestContext context)
throws WebApplicationException, IOException {
writeTo(is, context.getOrCreateOutputStream());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
import static java.nio.charset.StandardCharsets.UTF_8;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
Expand All @@ -25,6 +27,7 @@
import org.jboss.resteasy.reactive.MultipartForm;
import org.jboss.resteasy.reactive.PartType;
import org.jboss.resteasy.reactive.RestQuery;
import org.jboss.resteasy.reactive.RestResponse;

import io.quarkus.it.rest.client.multipart.MultipartClient.FileWithPojo;
import io.quarkus.it.rest.client.multipart.MultipartClient.Pojo;
Expand Down Expand Up @@ -141,12 +144,7 @@ public String sendFileAsBinary(@QueryParam("nullFile") @DefaultValue("false") bo
WithFileAsBinaryFile data = new WithFileAsBinaryFile();

if (!nullFile) {
File tempFile = File.createTempFile("quarkus-test", ".bin");
tempFile.deleteOnExit();

try (FileOutputStream fileOutputStream = new FileOutputStream(tempFile)) {
fileOutputStream.write(HELLO_WORLD.getBytes());
}
File tempFile = createTempHelloWorldFile();

data.file = tempFile;
}
Expand All @@ -163,12 +161,7 @@ public String sendPathAsBinary(@QueryParam("nullFile") @DefaultValue("false") bo
WithPathAsBinaryFile data = new WithPathAsBinaryFile();

if (!nullFile) {
File tempFile = File.createTempFile("quarkus-test", ".bin");
tempFile.deleteOnExit();

try (FileOutputStream fileOutputStream = new FileOutputStream(tempFile)) {
fileOutputStream.write(HELLO_WORLD.getBytes());
}
File tempFile = createTempHelloWorldFile();

data.file = tempFile.toPath();
}
Expand Down Expand Up @@ -206,12 +199,7 @@ public String sendBufferAsTextFile() {
@Produces(MediaType.TEXT_PLAIN)
@Blocking
public String sendFileAsText() throws IOException {
File tempFile = File.createTempFile("quarkus-test", ".bin");
tempFile.deleteOnExit();

try (FileOutputStream fileOutputStream = new FileOutputStream(tempFile)) {
fileOutputStream.write(HELLO_WORLD.getBytes());
}
File tempFile = createTempHelloWorldFile();

WithFileAsTextFile data = new WithFileAsTextFile();
data.file = tempFile;
Expand All @@ -225,12 +213,7 @@ public String sendFileAsText() throws IOException {
@Produces(MediaType.TEXT_PLAIN)
@Blocking
public String sendPathAsText() throws IOException {
File tempFile = File.createTempFile("quarkus-test", ".bin");
tempFile.deleteOnExit();

try (FileOutputStream fileOutputStream = new FileOutputStream(tempFile)) {
fileOutputStream.write(HELLO_WORLD.getBytes());
}
File tempFile = createTempHelloWorldFile();

WithPathAsTextFile data = new WithPathAsTextFile();
data.file = tempFile.toPath();
Expand Down Expand Up @@ -276,17 +259,33 @@ public String consumeBinaryWithPojo(@MultipartForm MultipartBodyWithBinaryFileAn
@Path("/produces/multipart")
@Produces(MediaType.MULTIPART_FORM_DATA)
public MultipartBodyWithTextFile produceMultipart() throws IOException {
File tempFile = createTempHelloWorldFile();

MultipartBodyWithTextFile data = new MultipartBodyWithTextFile();
data.file = tempFile;
data.number = String.valueOf(NUMBER);
return data;
}

@GET
@Path("/produces/input-stream-rest-response")
public RestResponse<? extends InputStream> produceInputStreamRestResponse() throws IOException {
File tempFile = createTempHelloWorldFile();
FileInputStream is = new FileInputStream(tempFile);
return RestResponse.ResponseBuilder
.ok(is)
.type(MediaType.TEXT_PLAIN_TYPE)
.build();
}

private File createTempHelloWorldFile() throws IOException {
File tempFile = File.createTempFile("quarkus-test", ".bin");
tempFile.deleteOnExit();

try (FileOutputStream fileOutputStream = new FileOutputStream(tempFile)) {
fileOutputStream.write(HELLO_WORLD.getBytes());
}

MultipartBodyWithTextFile data = new MultipartBodyWithTextFile();
data.file = tempFile;
data.number = String.valueOf(NUMBER);
return data;
return tempFile;
}

private boolean containsHelloWorld(File file) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,15 @@ public void shouldProperlyHandleOctetStreamFile() {
// @formatter:on
}

@Test
public void shouldProducesInputStreamRestResponse() {
RestAssured.get("/produces/input-stream-rest-response")
.then()
.contentType(ContentType.TEXT)
.statusCode(200)
.body(equalTo("HELLO WORLD"));
}

private void assertMultipartResponseContains(String response, String name, String contentType, Object value) {
String[] lines = response.split("--");
assertThat(lines).anyMatch(line -> line.contains(String.format(EXPECTED_CONTENT_DISPOSITION_PART, name))
Expand Down

0 comments on commit f4ff81d

Please sign in to comment.