Skip to content

Commit

Permalink
Cleanup after REST Client multipart request
Browse files Browse the repository at this point in the history
Fixes: #33986
  • Loading branch information
geoand committed Jun 14, 2023
1 parent 33db72d commit deb5fae
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package io.quarkus.rest.client.reactive.multipart;

import static org.assertj.core.api.Assertions.assertThat;

import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.nio.file.Files;

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.FormParam;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.core.MediaType;

import org.eclipse.microprofile.rest.client.RestClientBuilder;
import org.jboss.resteasy.reactive.MultipartForm;
import org.jboss.resteasy.reactive.PartType;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.test.QuarkusUnitTest;
import io.quarkus.test.common.http.TestHTTPResource;

public class MultipartCleanupTest {

private static java.nio.file.Path tempDir;

@TestHTTPResource
URI baseUri;

@RegisterExtension
static final QuarkusUnitTest TEST = new QuarkusUnitTest()
.withApplicationRoot(jar -> jar.addClasses(Form.class, Client.class, Resource.class));

@BeforeAll
static void getTempDir() throws IOException {
java.nio.file.Path tempFilePath = Files.createTempFile("jvm_tempfile_helper_", ".tmp"); // create temp file to get reference to jvm temp dir
tempFilePath.toFile().deleteOnExit(); // cleanup file after test is finished
tempDir = tempFilePath.getParent(); // now we can get the root temp dir
}

@Test
public void test() throws IOException {
Client client = RestClientBuilder.newBuilder().baseUri(baseUri).build(Client.class);

File file = File.createTempFile("MultipartTest", ".txt");
Files.writeString(file.toPath(), "DUMMY".repeat(1000));
file.deleteOnExit();

Form form = new Form();
form.file = file;
form.dummy = "dummy";

long attrFilesBeforeTest = getCountOfNettyAttrTempFiles();
assertThat(client.send(form)).isEqualTo("test");
assertThat(getCountOfNettyAttrTempFiles()).isEqualTo(attrFilesBeforeTest);
}

private long getCountOfNettyAttrTempFiles() {
File[] attrFiles = tempDir.toFile().listFiles((dir, name) -> name.startsWith("Attr_"));
if (attrFiles == null) {
throw new IllegalStateException("could not list Attr_ files because the directory to search was not valid");
}
return attrFiles.length;
}

public static class Form {
@FormParam("file")
@PartType(MediaType.APPLICATION_OCTET_STREAM)
private File file;

@FormParam("dummy")
@PartType(MediaType.TEXT_PLAIN)
private String dummy;
}

public interface Client {

@POST
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Path("/multipart")
String send(Form collectorDto);
}

@Path("/multipart")
@ApplicationScoped
public static class Resource {
@POST
@Consumes(MediaType.MULTIPART_FORM_DATA)
public String upload(@MultipartForm Form form) {
return "test";
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,14 @@ private void handleChunk(Object item) {
handler.handle(item);
}

private void clearEncoder() {
if (encoder == null) {
return;
}
encoder.cleanFiles();
encoder = null;
}

@Override
public void run() {
if (Vertx.currentContext() != context) {
Expand All @@ -161,7 +169,7 @@ public void run() {
} else if (chunk == LastHttpContent.EMPTY_LAST_CONTENT || encoder.isEndOfInput()) {
ended = true;
request = null;
encoder = null;
clearEncoder();
pending.write(InboundBuffer.END_SENTINEL);
} else {
ByteBuf content = chunk.content();
Expand All @@ -179,7 +187,7 @@ public void run() {
ByteBuf content = request.content();
Buffer buffer = Buffer.buffer(content);
request = null;
encoder = null;
clearEncoder();
pending.write(buffer);
ended = true;
pending.write(InboundBuffer.END_SENTINEL);
Expand All @@ -194,7 +202,7 @@ public boolean isChunked() {
private void handleError(Throwable e) {
ended = true;
request = null;
encoder = null;
clearEncoder();
pending.write(e);
}

Expand Down

0 comments on commit deb5fae

Please sign in to comment.