diff --git a/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/multipart/MultipartFormInputDevModeTest.java b/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/multipart/MultipartFormInputDevModeTest.java
index 83a02058088e2b..6b33f16667d464 100644
--- a/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/multipart/MultipartFormInputDevModeTest.java
+++ b/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/multipart/MultipartFormInputDevModeTest.java
@@ -74,7 +74,7 @@ private void doTest(String path) {
.post("/multipart/" + path + "/2")
.then()
.statusCode(200)
- .body(equalTo("Alice - true - 50 - WORKING - text/html - true - true"));
+ .body(equalTo("Alice - true - 50 - WORKING - true - true - true"));
}
}
diff --git a/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/multipart/MultipartInputBodyHandlerTest.java b/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/multipart/MultipartInputBodyHandlerTest.java
index a3e7cf8ed1ef46..f75e0a416573d7 100644
--- a/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/multipart/MultipartInputBodyHandlerTest.java
+++ b/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/multipart/MultipartInputBodyHandlerTest.java
@@ -92,7 +92,7 @@ public void testSimple() {
.post("/multipart/simple/2")
.then()
.statusCode(200)
- .body(equalTo("Alice - true - 50 - WORKING - text/html - true - true"));
+ .body(equalTo("Alice - true - 50 - WORKING - true - true - true"));
// ensure that the 3 uploaded files where created on disk
Assertions.assertEquals(3, uploadDir.toFile().listFiles().length);
diff --git a/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/multipart/MultipartInputTest.java b/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/multipart/MultipartInputTest.java
index a0d69d00d2c642..0316e038c78008 100644
--- a/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/multipart/MultipartInputTest.java
+++ b/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/multipart/MultipartInputTest.java
@@ -50,6 +50,9 @@ public JavaArchive get() {
private final File HTML_FILE2 = new File("./src/test/resources/test2.html");
private final File XML_FILE = new File("./src/test/resources/test.html");
private final File TXT_FILE = new File("./src/test/resources/lorem.txt");
+ private final String TXT = "lorem ipsum";
+ private final String XML = "";
+ private final String HTML = "";
@BeforeEach
public void assertEmptyUploads() {
@@ -68,15 +71,15 @@ public void testSimple() {
.multiPart("active", "true")
.multiPart("num", "25")
.multiPart("status", "WORKING")
- .multiPart("htmlFile", HTML_FILE, "text/html")
- .multiPart("xmlFile", XML_FILE, "text/xml")
- .multiPart("txtFile", TXT_FILE, "text/plain")
+ .multiPart("htmlFile", HTML, "text/html")
+ .multiPart("xmlFile", XML, "text/xml")
+ .multiPart("txtFile", TXT, "text/plain")
.accept("text/plain")
.when()
.post("/multipart/simple/2")
.then()
.statusCode(200)
- .body(equalTo("Alice - true - 50 - WORKING - text/html - true - true"));
+ .body(equalTo("Alice - true - 50 - WORKING - true - true - true"));
// ensure that the 3 uploaded files where created on disk
Assertions.assertEquals(3, uploadDir.toFile().listFiles().length);
@@ -110,15 +113,15 @@ public void testSimpleParam() {
.multiPart("active", "true")
.multiPart("num", "25")
.multiPart("status", "WORKING")
- .multiPart("htmlFile", HTML_FILE, "text/html")
- .multiPart("xmlFile", XML_FILE, "text/xml")
- .multiPart("txtFile", TXT_FILE, "text/plain")
+ .multiPart("htmlFile", HTML, "text/html")
+ .multiPart("xmlFile", XML, "text/xml")
+ .multiPart("txtFile", TXT, "text/plain")
.accept("text/plain")
.when()
.post("/multipart/param/simple/2")
.then()
.statusCode(200)
- .body(equalTo("Alice - true - 50 - WORKING - text/html - true - true"));
+ .body(equalTo("Alice - true - 50 - WORKING - true - true - true"));
// ensure that the 3 uploaded files where created on disk
Assertions.assertEquals(3, uploadDir.toFile().listFiles().length);
diff --git a/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/multipart/MultipartResource.java b/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/multipart/MultipartResource.java
index 5548a439f98fa0..a3958b01ae37a9 100644
--- a/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/multipart/MultipartResource.java
+++ b/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/multipart/MultipartResource.java
@@ -37,7 +37,7 @@ public String simple(@BeanParam FormData formData, Integer times) {
}
return formData.getName() + " - " + formData.active + " - " + times * formData.getNum() + " - " + formData.getStatus()
+ " - "
- + formData.getHtmlPart().contentType() + " - " + Files.exists(formData.xmlPart) + " - "
+ + Files.exists(formData.getHtmlPart().filePath()) + " - " + Files.exists(formData.xmlPart) + " - "
+ formData.txtFile.exists();
}
@@ -74,7 +74,7 @@ public String simple(
}
return name + " - " + active + " - " + times * num + " - " + status
+ " - "
- + htmlPart.contentType() + " - " + Files.exists(xmlPart) + " - "
+ + Files.exists(htmlPart.filePath()) + " - " + Files.exists(xmlPart) + " - "
+ txtFile.exists();
}
diff --git a/independent-projects/resteasy-reactive/client/processor/src/main/java/org/jboss/resteasy/reactive/client/processor/scanning/ClientEndpointIndexer.java b/independent-projects/resteasy-reactive/client/processor/src/main/java/org/jboss/resteasy/reactive/client/processor/scanning/ClientEndpointIndexer.java
index 7fb5137508642c..6d7951ed1f80de 100644
--- a/independent-projects/resteasy-reactive/client/processor/src/main/java/org/jboss/resteasy/reactive/client/processor/scanning/ClientEndpointIndexer.java
+++ b/independent-projects/resteasy-reactive/client/processor/src/main/java/org/jboss/resteasy/reactive/client/processor/scanning/ClientEndpointIndexer.java
@@ -11,6 +11,7 @@
import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import javax.ws.rs.core.MediaType;
@@ -115,7 +116,8 @@ protected ResourceMethod createResourceMethod(MethodInfo info, ClassInfo actualE
}
@Override
- protected boolean handleBeanParam(ClassInfo actualEndpointInfo, Type paramType, MethodParameter[] methodParameters, int i) {
+ protected boolean handleBeanParam(ClassInfo actualEndpointInfo, Type paramType, MethodParameter[] methodParameters, int i,
+ Set fileFormNames) {
ClassInfo beanParamClassInfo = index.getClassByName(paramType.name());
methodParameters[i] = parseClientBeanParam(beanParamClassInfo, index);
@@ -127,15 +129,18 @@ private MethodParameter parseClientBeanParam(ClassInfo beanParamClassInfo, Index
return new ClientBeanParamInfo(items, beanParamClassInfo.name().toString());
}
+ @Override
protected InjectableBean scanInjectableBean(ClassInfo currentClassInfo, ClassInfo actualEndpointInfo,
Map existingConverters, AdditionalReaders additionalReaders,
Map injectableBeans, boolean hasRuntimeConverters) {
throw new RuntimeException("Injectable beans not supported in client");
}
+ @Override
protected MethodParameter createMethodParameter(ClassInfo currentClassInfo, ClassInfo actualEndpointInfo, boolean encoded,
Type paramType, ClientIndexedParam parameterResult, String name, String defaultValue, ParameterType type,
- String elementType, boolean single, String signature) {
+ String elementType, boolean single, String signature,
+ Set fileFormNames) {
DeclaredTypes declaredTypes = getDeclaredTypes(paramType, currentClassInfo, actualEndpointInfo);
String mimePart = getPartMime(parameterResult.getAnns());
String partFileName = getPartFileName(parameterResult.getAnns());
diff --git a/independent-projects/resteasy-reactive/common/processor/src/main/java/org/jboss/resteasy/reactive/common/processor/EndpointIndexer.java b/independent-projects/resteasy-reactive/common/processor/src/main/java/org/jboss/resteasy/reactive/common/processor/EndpointIndexer.java
index f0c129876ac7ef..8669075c42caa8 100644
--- a/independent-projects/resteasy-reactive/common/processor/src/main/java/org/jboss/resteasy/reactive/common/processor/EndpointIndexer.java
+++ b/independent-projects/resteasy-reactive/common/processor/src/main/java/org/jboss/resteasy/reactive/common/processor/EndpointIndexer.java
@@ -571,6 +571,7 @@ private ResourceMethod createResourceMethod(ClassInfo currentClassInfo, ClassInf
boolean suspended = false;
boolean sse = false;
boolean formParamRequired = false;
+ Set fileFormNames = new HashSet<>();
Type bodyParamType = null;
TypeArgMapper typeArgMapper = new TypeArgMapper(currentMethodInfo.declaringClass(), index);
for (int i = 0; i < methodParameters.length; ++i) {
@@ -604,12 +605,12 @@ private ResourceMethod createResourceMethod(ClassInfo currentClassInfo, ClassInf
}
methodParameters[i] = createMethodParameter(currentClassInfo, actualEndpointInfo, encoded, paramType,
parameterResult, name, defaultValue, type, elementType, single,
- AsmUtil.getSignature(paramType, typeArgMapper));
+ AsmUtil.getSignature(paramType, typeArgMapper), fileFormNames);
if (type == ParameterType.BEAN
|| type == ParameterType.MULTI_PART_FORM) {
// transform the bean param
- formParamRequired |= handleBeanParam(actualEndpointInfo, paramType, methodParameters, i);
+ formParamRequired |= handleBeanParam(actualEndpointInfo, paramType, methodParameters, i, fileFormNames);
} else if (type == ParameterType.FORM) {
formParamRequired = true;
}
@@ -731,6 +732,7 @@ private ResourceMethod createResourceMethod(ClassInfo currentClassInfo, ClassInf
.setSse(sse)
.setStreamElementType(streamElementType)
.setFormParamRequired(formParamRequired)
+ .setFileFormNames(fileFormNames)
.setParameters(methodParameters)
.setSimpleReturnType(
toClassName(currentMethodInfo.returnType(), currentClassInfo, actualEndpointInfo, index))
@@ -885,7 +887,7 @@ private String determineReturnType(Type returnType, TypeArgMapper typeArgMapper,
}
protected abstract boolean handleBeanParam(ClassInfo actualEndpointInfo, Type paramType, MethodParameter[] methodParameters,
- int i);
+ int i, Set fileFormNames);
protected void handleAdditionalMethodProcessing(METHOD method, ClassInfo currentClassInfo, MethodInfo info,
AnnotationStore annotationStore) {
@@ -901,7 +903,8 @@ protected abstract InjectableBean scanInjectableBean(ClassInfo currentClassInfo,
protected abstract MethodParameter createMethodParameter(ClassInfo currentClassInfo, ClassInfo actualEndpointInfo,
boolean encoded, Type paramType, PARAM parameterResult, String name, String defaultValue,
- ParameterType type, String elementType, boolean single, String signature);
+ ParameterType type, String elementType, boolean single, String signature,
+ Set fileFormNames);
private String[] applyDefaultProduces(String[] produces, Type nonAsyncReturnType,
DotName httpMethod) {
diff --git a/independent-projects/resteasy-reactive/common/runtime/src/main/java/org/jboss/resteasy/reactive/common/model/BeanParamInfo.java b/independent-projects/resteasy-reactive/common/runtime/src/main/java/org/jboss/resteasy/reactive/common/model/BeanParamInfo.java
index e9dcd4d9103c0c..0040b7f9f304cb 100644
--- a/independent-projects/resteasy-reactive/common/runtime/src/main/java/org/jboss/resteasy/reactive/common/model/BeanParamInfo.java
+++ b/independent-projects/resteasy-reactive/common/runtime/src/main/java/org/jboss/resteasy/reactive/common/model/BeanParamInfo.java
@@ -1,9 +1,13 @@
package org.jboss.resteasy.reactive.common.model;
+import java.util.HashSet;
+import java.util.Set;
+
public class BeanParamInfo implements InjectableBean {
private boolean isFormParamRequired;
private boolean isInjectionRequired;
private int fieldExtractorsCount;
+ private Set fileFormNames = new HashSet<>();
@Override
public boolean isFormParamRequired() {
@@ -36,4 +40,14 @@ public int getFieldExtractorsCount() {
public void setFieldExtractorsCount(int fieldExtractorsCount) {
this.fieldExtractorsCount = fieldExtractorsCount;
}
+
+ @Override
+ public Set getFileFormNames() {
+ return fileFormNames;
+ }
+
+ @Override
+ public void setFileFormNames(Set fileFormNames) {
+ this.fileFormNames = fileFormNames;
+ }
}
diff --git a/independent-projects/resteasy-reactive/common/runtime/src/main/java/org/jboss/resteasy/reactive/common/model/InjectableBean.java b/independent-projects/resteasy-reactive/common/runtime/src/main/java/org/jboss/resteasy/reactive/common/model/InjectableBean.java
index aea871820d09c1..e659e6bf50608e 100644
--- a/independent-projects/resteasy-reactive/common/runtime/src/main/java/org/jboss/resteasy/reactive/common/model/InjectableBean.java
+++ b/independent-projects/resteasy-reactive/common/runtime/src/main/java/org/jboss/resteasy/reactive/common/model/InjectableBean.java
@@ -1,5 +1,7 @@
package org.jboss.resteasy.reactive.common.model;
+import java.util.Set;
+
/**
* Class that represents information about injectable beans as we scan them, such as
* resource endpoint beans, or BeanParam classes.
@@ -25,4 +27,8 @@ public interface InjectableBean {
int getFieldExtractorsCount();
void setFieldExtractorsCount(int fieldExtractorsCount);
+
+ Set getFileFormNames();
+
+ void setFileFormNames(Set fileFormNames);
}
diff --git a/independent-projects/resteasy-reactive/common/runtime/src/main/java/org/jboss/resteasy/reactive/common/model/ResourceMethod.java b/independent-projects/resteasy-reactive/common/runtime/src/main/java/org/jboss/resteasy/reactive/common/model/ResourceMethod.java
index 7725306fefc1bf..54463c2a191fae 100644
--- a/independent-projects/resteasy-reactive/common/runtime/src/main/java/org/jboss/resteasy/reactive/common/model/ResourceMethod.java
+++ b/independent-projects/resteasy-reactive/common/runtime/src/main/java/org/jboss/resteasy/reactive/common/model/ResourceMethod.java
@@ -68,6 +68,8 @@ public class ResourceMethod {
private boolean isFormParamRequired;
+ private Set fileFormNames;
+
private List subResourceMethods;
public ResourceMethod() {
@@ -224,6 +226,15 @@ public ResourceMethod setFormParamRequired(boolean isFormParamRequired) {
return this;
}
+ public Set getFileFormNames() {
+ return fileFormNames;
+ }
+
+ public ResourceMethod setFileFormNames(Set fileFormNames) {
+ this.fileFormNames = fileFormNames;
+ return this;
+ }
+
public ResourceMethod setStreamElementType(String streamElementType) {
this.streamElementType = streamElementType;
return this;
diff --git a/independent-projects/resteasy-reactive/server/processor/src/main/java/org/jboss/resteasy/reactive/server/processor/ServerEndpointIndexer.java b/independent-projects/resteasy-reactive/server/processor/src/main/java/org/jboss/resteasy/reactive/server/processor/ServerEndpointIndexer.java
index caf772ebb5e661..cae5bc7227def5 100644
--- a/independent-projects/resteasy-reactive/server/processor/src/main/java/org/jboss/resteasy/reactive/server/processor/ServerEndpointIndexer.java
+++ b/independent-projects/resteasy-reactive/server/processor/src/main/java/org/jboss/resteasy/reactive/server/processor/ServerEndpointIndexer.java
@@ -95,6 +95,13 @@
public class ServerEndpointIndexer
extends EndpointIndexer {
+
+ private static final DotName FILE_DOT_NAME = DotName.createSimple(File.class.getName());
+ private static final DotName PATH_DOT_NAME = DotName.createSimple(Path.class.getName());
+ private static final DotName FILEUPLOAD_DOT_NAME = DotName.createSimple(FileUpload.class.getName());
+
+ private static final Set SUPPORTED_MULTIPART_FILE_TYPES = Set.of(FILE_DOT_NAME, PATH_DOT_NAME,
+ FILEUPLOAD_DOT_NAME);
protected final EndpointInvokerFactory endpointInvokerFactory;
protected final List methodScanners;
protected final FieldInjectionIndexerExtension fieldInjectionHandler;
@@ -176,7 +183,8 @@ protected ServerResourceMethod createResourceMethod(MethodInfo methodInfo, Class
}
@Override
- protected boolean handleBeanParam(ClassInfo actualEndpointInfo, Type paramType, MethodParameter[] methodParameters, int i) {
+ protected boolean handleBeanParam(ClassInfo actualEndpointInfo, Type paramType, MethodParameter[] methodParameters, int i,
+ Set fileFormNames) {
ClassInfo beanParamClassInfo = index.getClassByName(paramType.name());
InjectableBean injectableBean = scanInjectableBean(beanParamClassInfo,
actualEndpointInfo,
@@ -186,7 +194,7 @@ protected boolean handleBeanParam(ClassInfo actualEndpointInfo, Type paramType,
+ "Annotations like `@QueryParam` should be used in fields, not in methods.",
beanParamClassInfo.name()));
}
-
+ fileFormNames.addAll(injectableBean.getFileFormNames());
return injectableBean.isFormParamRequired();
}
@@ -233,6 +241,7 @@ private void validateMethodPath(ServerResourceMethod method, ClassInfo currentCl
}
}
+ @Override
protected InjectableBean scanInjectableBean(ClassInfo currentClassInfo, ClassInfo actualEndpointInfo,
Map existingConverters, AdditionalReaders additionalReaders,
Map injectableBeans, boolean hasRuntimeConverters) {
@@ -280,6 +289,24 @@ protected InjectableBean scanInjectableBean(ClassInfo currentClassInfo, ClassInf
} else if (result.getType() == ParameterType.FORM) {
// direct form param requirement
currentInjectableBean.setFormParamRequired(true);
+
+ if (SUPPORTED_MULTIPART_FILE_TYPES.contains(field.type().name())) {
+ String name = field.name();
+ AnnotationInstance restForm = field.annotation(ResteasyReactiveDotNames.REST_FORM_PARAM);
+ AnnotationInstance formParam = field.annotation(ResteasyReactiveDotNames.FORM_PARAM);
+ if (restForm != null) {
+ AnnotationValue value = restForm.value();
+ if (value != null) {
+ name = value.asString();
+ }
+ } else if (formParam != null) {
+ AnnotationValue value = formParam.value();
+ if (value != null) {
+ name = value.asString();
+ }
+ }
+ currentInjectableBean.getFileFormNames().add(name);
+ }
}
}
// the TCK expects that fields annotated with @BeanParam are handled last
@@ -309,15 +336,22 @@ protected InjectableBean scanInjectableBean(ClassInfo currentClassInfo, ClassInf
return currentInjectableBean;
}
+ @Override
protected MethodParameter createMethodParameter(ClassInfo currentClassInfo, ClassInfo actualEndpointInfo, boolean encoded,
Type paramType, ServerIndexedParameter parameterResult, String name, String defaultValue, ParameterType type,
- String elementType, boolean single, String signature) {
+ String elementType, boolean single, String signature,
+ Set fileFormNames) {
ParameterConverterSupplier converter = parameterResult.getConverter();
DeclaredTypes declaredTypes = getDeclaredTypes(paramType, currentClassInfo, actualEndpointInfo);
String mimeType = getPartMime(parameterResult.getAnns());
String separator = getSeparator(parameterResult.getAnns());
+ String declaredType = declaredTypes.getDeclaredType();
+
+ if (SUPPORTED_MULTIPART_FILE_TYPES.contains(DotName.createSimple(declaredType))) {
+ fileFormNames.add(name);
+ }
return new ServerMethodParameter(name,
- elementType, declaredTypes.getDeclaredType(), declaredTypes.getDeclaredUnresolvedType(),
+ elementType, declaredType, declaredTypes.getDeclaredUnresolvedType(),
type, single, signature,
converter, defaultValue, parameterResult.isObtainedAsCollection(), parameterResult.isOptional(), encoded,
parameterResult.getCustomParameterExtractor(), mimeType, separator);
diff --git a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/multipart/FormEncodedDataDefinition.java b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/multipart/FormEncodedDataDefinition.java
index 4829909c406101..39e499454e13d6 100644
--- a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/multipart/FormEncodedDataDefinition.java
+++ b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/multipart/FormEncodedDataDefinition.java
@@ -5,6 +5,7 @@
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
+import java.util.Set;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.HttpHeaders;
@@ -37,7 +38,7 @@ public FormEncodedDataDefinition() {
}
@Override
- public FormDataParser create(final ResteasyReactiveRequestContext exchange) {
+ public FormDataParser create(final ResteasyReactiveRequestContext exchange, Set fileFormNames) {
String mimeType = exchange.serverRequest().getRequestHeader(HttpHeaders.CONTENT_TYPE);
if (forceCreation || (mimeType != null && mimeType.startsWith(APPLICATION_X_WWW_FORM_URLENCODED))) {
diff --git a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/multipart/FormParserFactory.java b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/multipart/FormParserFactory.java
index 7fa20a50e55840..8d382ed75a4b53 100644
--- a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/multipart/FormParserFactory.java
+++ b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/multipart/FormParserFactory.java
@@ -3,6 +3,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.Set;
import java.util.concurrent.Executor;
import java.util.function.Supplier;
@@ -28,11 +29,12 @@ public class FormParserFactory {
* Creates a form data parser for this request.
*
* @param exchange The exchange
+ * @param fileFormNames
* @return A form data parser, or null if there is no parser registered for the request content type
*/
- public FormDataParser createParser(final ResteasyReactiveRequestContext exchange) {
+ public FormDataParser createParser(final ResteasyReactiveRequestContext exchange, Set fileFormNames) {
for (int i = 0; i < parserDefinitions.length; ++i) {
- FormDataParser parser = parserDefinitions[i].create(exchange);
+ FormDataParser parser = parserDefinitions[i].create(exchange, fileFormNames);
if (parser != null) {
return parser;
}
@@ -42,7 +44,7 @@ public FormDataParser createParser(final ResteasyReactiveRequestContext exchange
public interface ParserDefinition {
- FormDataParser create(final ResteasyReactiveRequestContext exchange);
+ FormDataParser create(final ResteasyReactiveRequestContext exchange, Set fileFormNames);
T setDefaultCharset(String charset);
}
diff --git a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/multipart/MultiPartParserDefinition.java b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/multipart/MultiPartParserDefinition.java
index ef77e6a026c52c..9d3465317a90d6 100644
--- a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/multipart/MultiPartParserDefinition.java
+++ b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/multipart/MultiPartParserDefinition.java
@@ -16,6 +16,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.Set;
import java.util.concurrent.Executor;
import java.util.function.Supplier;
@@ -66,7 +67,7 @@ public MultiPartParserDefinition(Supplier executorSupplier, final Path
}
@Override
- public FormDataParser create(final ResteasyReactiveRequestContext exchange) {
+ public FormDataParser create(final ResteasyReactiveRequestContext exchange, Set fileFormNames) {
String mimeType = exchange.serverRequest().getRequestHeader(HttpHeaders.CONTENT_TYPE);
if (mimeType != null && mimeType.startsWith(MULTIPART_FORM_DATA)) {
String boundary = HeaderUtil.extractQuotedValueFromHeader(mimeType, "boundary");
@@ -77,7 +78,7 @@ public FormDataParser create(final ResteasyReactiveRequestContext exchange) {
return null;
}
final MultiPartUploadHandler parser = new MultiPartUploadHandler(exchange, boundary, maxIndividualFileSize,
- fileSizeThreshold, defaultCharset, mimeType, maxAttributeSize, maxEntitySize);
+ fileSizeThreshold, defaultCharset, mimeType, maxAttributeSize, maxEntitySize, fileFormNames);
exchange.registerCompletionCallback(new CompletionCallback() {
@Override
public void onComplete(Throwable throwable) {
@@ -171,6 +172,7 @@ private final class MultiPartUploadHandler implements FormDataParser, MultipartP
private final long fileSizeThreshold;
private final long maxAttributeSize;
private final long maxEntitySize;
+ private final Set fileFormNames;
private String defaultEncoding;
private final ByteArrayOutputStream contentBytes = new ByteArrayOutputStream();
@@ -185,13 +187,15 @@ private final class MultiPartUploadHandler implements FormDataParser, MultipartP
private MultiPartUploadHandler(final ResteasyReactiveRequestContext exchange, final String boundary,
final long maxIndividualFileSize, final long fileSizeThreshold, final String defaultEncoding,
- String contentType, long maxAttributeSize, long maxEntitySize) {
+ String contentType, long maxAttributeSize, long maxEntitySize,
+ Set fileFormNames) {
this.exchange = exchange;
this.maxIndividualFileSize = maxIndividualFileSize;
this.defaultEncoding = defaultEncoding;
this.fileSizeThreshold = fileSizeThreshold;
this.maxAttributeSize = maxAttributeSize;
this.maxEntitySize = maxEntitySize;
+ this.fileFormNames = fileFormNames;
int maxParameters = 1000;
this.data = new FormData(maxParameters);
String charset = defaultEncoding;
@@ -247,7 +251,8 @@ public void beginPart(final CaseInsensitiveMap headers) {
currentName = HeaderUtil.extractQuotedValueFromHeader(disposition, "name");
fileName = HeaderUtil.extractQuotedValueFromHeaderWithEncoding(disposition, "filename");
String contentType = headers.getFirst(HttpHeaders.CONTENT_TYPE);
- if ((fileName != null || isFileContentType(contentType)) && fileSizeThreshold == 0) {
+ if (((fileName != null) || isFileContentType(contentType) || fileFormNames.contains(currentName))
+ && fileSizeThreshold == 0) {
try {
if (tempFileLocation != null) {
Files.createDirectories(tempFileLocation);
diff --git a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/multipart/MultipartSupport.java b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/multipart/MultipartSupport.java
index 5506f976f1d926..0c44ebb2b09415 100644
--- a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/multipart/MultipartSupport.java
+++ b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/multipart/MultipartSupport.java
@@ -283,9 +283,9 @@ public static DefaultFileUpload getFileUpload(String formName, ResteasyReactiveR
public static List getFileUploads(String formName, ResteasyReactiveRequestContext context) {
List result = new ArrayList<>();
- FormData fileUploads = context.getFormData();
- if (fileUploads != null) {
- Collection fileUploadsForName = fileUploads.get(formName);
+ FormData formData = context.getFormData();
+ if (formData != null) {
+ Collection fileUploadsForName = formData.get(formName);
if (fileUploadsForName != null) {
for (FormData.FormValue fileUpload : fileUploadsForName) {
if (fileUpload.isFileItem()) {
diff --git a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/startup/RuntimeResourceDeployment.java b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/startup/RuntimeResourceDeployment.java
index 1b93682704e40c..ecd7adcbc900ae 100644
--- a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/startup/RuntimeResourceDeployment.java
+++ b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/startup/RuntimeResourceDeployment.java
@@ -283,7 +283,7 @@ public RuntimeResource buildResourceMethod(ResourceClass clazz,
boolean checkReadBodyRequestFilters = false;
if (method.isFormParamRequired()) {
// read the body as multipart in one go
- handlers.add(new FormBodyHandler(bodyParameter != null, executorSupplier));
+ handlers.add(new FormBodyHandler(bodyParameter != null, executorSupplier, method.getFileFormNames()));
checkReadBodyRequestFilters = true;
} else if (bodyParameter != null) {
if (!defaultBlocking) {
diff --git a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/handlers/FormBodyHandler.java b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/handlers/FormBodyHandler.java
index 196d76632a83a8..579eae04a83a61 100644
--- a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/handlers/FormBodyHandler.java
+++ b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/handlers/FormBodyHandler.java
@@ -8,6 +8,7 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
+import java.util.Set;
import java.util.concurrent.Executor;
import java.util.function.Supplier;
@@ -26,11 +27,13 @@ public class FormBodyHandler implements GenericRuntimeConfigurableServerRestHand
private final boolean alsoSetInputStream;
private final Supplier executorSupplier;
+ private final Set fileFormNames;
private volatile FormParserFactory formParserFactory;
- public FormBodyHandler(boolean alsoSetInputStream, Supplier executorSupplier) {
+ public FormBodyHandler(boolean alsoSetInputStream, Supplier executorSupplier, Set fileFormNames) {
this.alsoSetInputStream = alsoSetInputStream;
this.executorSupplier = executorSupplier;
+ this.fileFormNames = fileFormNames;
}
@Override
@@ -79,7 +82,7 @@ public void handle(ResteasyReactiveRequestContext requestContext) throws Excepti
if (BlockingOperationSupport.isBlockingAllowed()) {
//blocking IO approach
- FormDataParser factory = formParserFactory.createParser(requestContext);
+ FormDataParser factory = formParserFactory.createParser(requestContext, fileFormNames);
if (factory == null) {
return;
}
@@ -96,7 +99,7 @@ public void handle(ResteasyReactiveRequestContext requestContext) throws Excepti
requestContext.setInputStream(new ByteArrayInputStream(cis.baos.toByteArray()));
}
} else if (alsoSetInputStream) {
- FormDataParser factory = formParserFactory.createParser(requestContext);
+ FormDataParser factory = formParserFactory.createParser(requestContext, fileFormNames);
if (factory == null) {
return;
}
@@ -116,7 +119,7 @@ public void run() {
}
});
} else {
- FormDataParser factory = formParserFactory.createParser(requestContext);
+ FormDataParser factory = formParserFactory.createParser(requestContext, fileFormNames);
if (factory == null) {
return;
}
diff --git a/independent-projects/resteasy-reactive/server/vertx/src/test/java/org/jboss/resteasy/reactive/server/vertx/test/multipart/MultipartFileContentTypeTest.java b/independent-projects/resteasy-reactive/server/vertx/src/test/java/org/jboss/resteasy/reactive/server/vertx/test/multipart/MultipartFileContentTypeTest.java
index 85157244a79b00..93c4771f789592 100644
--- a/independent-projects/resteasy-reactive/server/vertx/src/test/java/org/jboss/resteasy/reactive/server/vertx/test/multipart/MultipartFileContentTypeTest.java
+++ b/independent-projects/resteasy-reactive/server/vertx/src/test/java/org/jboss/resteasy/reactive/server/vertx/test/multipart/MultipartFileContentTypeTest.java
@@ -69,18 +69,4 @@ public void testFilePartWithExpectedContentType() throws IOException {
// ensure that the 2 uploaded files where created on disk
Assertions.assertEquals(2, uploadDir.toFile().listFiles().length);
}
-
- @Test
- public void testFilePartWithUnexpectedContentType() throws IOException {
- RestAssured.given()
- .multiPart("xmlFile", null, Files.readAllBytes(FILE.toPath()), MediaType.APPLICATION_XML)
- .accept("text/plain")
- .when()
- .post("/multipart/optional")
- .then()
- .statusCode(200);
-
- // ensure that no files are created as the content-type is not supported as a file part
- Assertions.assertEquals(0, uploadDir.toFile().listFiles().length);
- }
}