diff --git a/providers/multipart/pom.xml b/providers/multipart/pom.xml
index 2d94ae74d18..4cf8d89ba98 100644
--- a/providers/multipart/pom.xml
+++ b/providers/multipart/pom.xml
@@ -70,6 +70,11 @@
${project.version}
test
+
+ junit
+ junit
+ test
+
diff --git a/providers/multipart/src/main/java/org/jboss/resteasy/plugins/providers/multipart/HeaderFlushedOutputStream.java b/providers/multipart/src/main/java/org/jboss/resteasy/plugins/providers/multipart/HeaderFlushedOutputStream.java
index f9187965628..7ba885faf29 100644
--- a/providers/multipart/src/main/java/org/jboss/resteasy/plugins/providers/multipart/HeaderFlushedOutputStream.java
+++ b/providers/multipart/src/main/java/org/jboss/resteasy/plugins/providers/multipart/HeaderFlushedOutputStream.java
@@ -11,8 +11,8 @@
* @version $Revision: 1 $
*/
public class HeaderFlushedOutputStream extends OutputStream {
- private MultivaluedMap headers;
- private OutputStream stream;
+ private final MultivaluedMap headers;
+ private final OutputStream stream;
private boolean headersFlushed = false;
public HeaderFlushedOutputStream(final MultivaluedMap headers,
diff --git a/providers/multipart/src/main/java/org/jboss/resteasy/plugins/providers/multipart/Mime4JWorkaround.java b/providers/multipart/src/main/java/org/jboss/resteasy/plugins/providers/multipart/Mime4JWorkaround.java
index 0131d6c96a4..4486ceb6eb3 100644
--- a/providers/multipart/src/main/java/org/jboss/resteasy/plugins/providers/multipart/Mime4JWorkaround.java
+++ b/providers/multipart/src/main/java/org/jboss/resteasy/plugins/providers/multipart/Mime4JWorkaround.java
@@ -33,6 +33,8 @@
import org.apache.james.mime4j.storage.ThresholdStorageProvider;
import org.apache.james.mime4j.stream.BodyDescriptorBuilder;
import org.apache.james.mime4j.stream.MimeConfig;
+import org.jboss.resteasy.plugins.providers.multipart.i18n.LogMessages;
+import org.jboss.resteasy.spi.config.Configuration;
import org.jboss.resteasy.spi.config.ConfigurationFactory;
/**
@@ -40,6 +42,9 @@
* Alter said code to use Mime4JWorkaroundBinaryEntityBuilder instead of EntityBuilder.
*/
public class Mime4JWorkaround {
+ static final String MEM_THRESHOLD_PROPERTY = "org.jboss.resteasy.plugins.providers.multipart.memoryThreshold";
+ static final int DEFAULT_MEM_THRESHOLD = 1024;
+
/**
* This is a rough copy of DefaultMessageBuilder.parseMessage() modified to use a Mime4JWorkaround as the contentHandler instead
* of an EntityBuilder.
@@ -64,7 +69,7 @@ public static Message parseMessage(InputStream is) throws IOException, MimeIOExc
storageProvider = DefaultStorageProvider.getInstance();
} else {
StorageProvider backend = new CustomTempFileStorageProvider();
- storageProvider = new ThresholdStorageProvider(backend, 1024);
+ storageProvider = new ThresholdStorageProvider(backend, getMemThreshold());
}
BodyFactory bf = new StorageBodyFactory(storageProvider, mon);
@@ -82,6 +87,25 @@ public static Message parseMessage(InputStream is) throws IOException, MimeIOExc
}
}
+ static int getMemThreshold()
+ {
+ try
+ {
+ Configuration cfg = ConfigurationFactory.getInstance().getConfiguration();
+ int threshold = Integer.parseInt(cfg.getOptionalValue(MEM_THRESHOLD_PROPERTY, String.class).orElse(
+ Integer.toString(DEFAULT_MEM_THRESHOLD)));
+ if (threshold > -1)
+ {
+ return threshold;
+ }
+ LogMessages.LOGGER.debugf("Negative threshold, %s, specified. Using default value", threshold);
+ }
+ catch (Exception e)
+ {
+ LogMessages.LOGGER.debug("Exception caught parsing memory threshold. Using default value.", e);
+ }
+ return DEFAULT_MEM_THRESHOLD;
+ }
/**
* A custom TempFileStorageProvider that do no set deleteOnExit on temp files,
diff --git a/providers/multipart/src/test/java/org/jboss/resteasy/plugins/providers/multipart/Mime4JWorkaroundTest.java b/providers/multipart/src/test/java/org/jboss/resteasy/plugins/providers/multipart/Mime4JWorkaroundTest.java
new file mode 100644
index 00000000000..eaf4550e75a
--- /dev/null
+++ b/providers/multipart/src/test/java/org/jboss/resteasy/plugins/providers/multipart/Mime4JWorkaroundTest.java
@@ -0,0 +1,79 @@
+package org.jboss.resteasy.plugins.providers.multipart;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class Mime4JWorkaroundTest {
+
+ private static final Map preTestProperties = new HashMap<>();
+
+ @BeforeClass
+ public static void saveCurrentStateOfMemThresholdProperty()
+ {
+ if (System.getProperties().containsKey(Mime4JWorkaround.MEM_THRESHOLD_PROPERTY))
+ {
+ String value = System.getProperty(Mime4JWorkaround.MEM_THRESHOLD_PROPERTY);
+ preTestProperties.put(Mime4JWorkaround.MEM_THRESHOLD_PROPERTY, value);
+ }
+ }
+
+ @AfterClass
+ public static void resetPropertiesToPreTestValues()
+ {
+ if (!preTestProperties.containsKey(Mime4JWorkaround.MEM_THRESHOLD_PROPERTY))
+ {
+ System.clearProperty(Mime4JWorkaround.MEM_THRESHOLD_PROPERTY);
+ }
+ else
+ {
+ preTestProperties.forEach(System::setProperty);
+ }
+ }
+
+ @Before
+ public void unsetMemThresholdProperty()
+ {
+ System.clearProperty(Mime4JWorkaround.MEM_THRESHOLD_PROPERTY);
+ }
+
+ @Test
+ public void testMemThresholdDefault()
+ {
+ assertEquals(Mime4JWorkaround.DEFAULT_MEM_THRESHOLD, Mime4JWorkaround.getMemThreshold());
+ }
+
+ @Test
+ public void testMemThresholdConfigProperty()
+ {
+ System.setProperty(Mime4JWorkaround.MEM_THRESHOLD_PROPERTY, "2048");
+ assertEquals(2048, Mime4JWorkaround.getMemThreshold());
+ }
+
+ @Test
+ public void testInvalidMemThresholdConfigPropertyReturnsDefault_NegativeNumber()
+ {
+ System.setProperty(Mime4JWorkaround.MEM_THRESHOLD_PROPERTY, "-2048");
+ assertEquals(Mime4JWorkaround.DEFAULT_MEM_THRESHOLD, Mime4JWorkaround.getMemThreshold());
+ }
+
+ @Test
+ public void testInvalidMemThresholdConfigPropertyReturnsDefault_DecimalNumber()
+ {
+ System.setProperty(Mime4JWorkaround.MEM_THRESHOLD_PROPERTY, "2048.2");
+ assertEquals(Mime4JWorkaround.DEFAULT_MEM_THRESHOLD, Mime4JWorkaround.getMemThreshold());
+ }
+
+ @Test
+ public void testInvalidMemThresholdConfigPropertyReturnsDefault_NotANumber()
+ {
+ System.setProperty(Mime4JWorkaround.MEM_THRESHOLD_PROPERTY, "Infinity");
+ assertEquals(Mime4JWorkaround.DEFAULT_MEM_THRESHOLD, Mime4JWorkaround.getMemThreshold());
+ }
+}
diff --git a/resteasy-client/src/main/java/org/jboss/resteasy/client/jaxrs/engines/ManualClosingApacheHttpClient43Engine.java b/resteasy-client/src/main/java/org/jboss/resteasy/client/jaxrs/engines/ManualClosingApacheHttpClient43Engine.java
index 17d9a048859..c6ba83da5bc 100644
--- a/resteasy-client/src/main/java/org/jboss/resteasy/client/jaxrs/engines/ManualClosingApacheHttpClient43Engine.java
+++ b/resteasy-client/src/main/java/org/jboss/resteasy/client/jaxrs/engines/ManualClosingApacheHttpClient43Engine.java
@@ -54,6 +54,9 @@
public class ManualClosingApacheHttpClient43Engine implements ApacheHttpClientEngine
{
+ static final String FILE_UPLOAD_IN_MEMORY_THRESHOLD_PROPERTY =
+ "org.jboss.resteasy.client.jaxrs.engines.fileUploadInMemoryThreshold";
+
/**
* Used to build temp file prefix.
*/
@@ -123,39 +126,58 @@ public String run() throws Exception
public ManualClosingApacheHttpClient43Engine()
{
- this.httpClient = createDefaultHttpClient();
- this.allowClosingHttpClient = true;
+ this(null, null, true, null);
}
public ManualClosingApacheHttpClient43Engine(final HttpHost defaultProxy)
{
- this.defaultProxy = defaultProxy;
- this.httpClient = createDefaultHttpClient();
- this.allowClosingHttpClient = true;
+ this(null, null, true, defaultProxy);
}
public ManualClosingApacheHttpClient43Engine(final HttpClient httpClient)
{
- this.httpClient = httpClient;
- this.allowClosingHttpClient = true;
+ this(httpClient, null, true, null);
}
public ManualClosingApacheHttpClient43Engine(final HttpClient httpClient, final boolean closeHttpClient)
{
- if (closeHttpClient && !(httpClient instanceof CloseableHttpClient))
+ this(httpClient, null, closeHttpClient, null);
+ }
+
+ public ManualClosingApacheHttpClient43Engine(final HttpClient httpClient,
+ final HttpContextProvider httpContextProvider)
+ {
+ this(httpClient, httpContextProvider, true, null);
+ }
+
+ private ManualClosingApacheHttpClient43Engine(final HttpClient httpClient,
+ final HttpContextProvider httpContextProvider, final boolean closeHttpClient, final HttpHost defaultProxy)
+ {
+ this.httpClient = httpClient != null ? httpClient : createDefaultHttpClient();
+ if (closeHttpClient && !(this.httpClient instanceof CloseableHttpClient))
{
throw new IllegalArgumentException(
"httpClient must be a CloseableHttpClient instance in order for allowing engine to close it!");
}
- this.httpClient = httpClient;
+ this.httpContextProvider = httpContextProvider;
this.allowClosingHttpClient = closeHttpClient;
- }
+ this.defaultProxy = defaultProxy;
- public ManualClosingApacheHttpClient43Engine(final HttpClient httpClient, final HttpContextProvider httpContextProvider)
- {
- this.httpClient = httpClient;
- this.httpContextProvider = httpContextProvider;
- this.allowClosingHttpClient = true;
+ try
+ {
+ int threshold = Integer.parseInt(ConfigurationFactory.getInstance().getConfiguration()
+ .getOptionalValue(FILE_UPLOAD_IN_MEMORY_THRESHOLD_PROPERTY, String.class)
+ .orElse("1"));
+ if (threshold > -1)
+ {
+ this.fileUploadInMemoryThresholdLimit = threshold;
+ }
+ LogMessages.LOGGER.debugf("Negative threshold, %s, specified. Using default value", threshold);
+ }
+ catch (Exception e)
+ {
+ LogMessages.LOGGER.debug("Exception caught parsing memory threshold. Using default value.", e);
+ }
}
/**
diff --git a/resteasy-client/src/test/java/org/jboss/resteasy/client/jaxrs/engines/ManualClosingApacheHttpClient43EngineTest.java b/resteasy-client/src/test/java/org/jboss/resteasy/client/jaxrs/engines/ManualClosingApacheHttpClient43EngineTest.java
new file mode 100644
index 00000000000..17bb86935e6
--- /dev/null
+++ b/resteasy-client/src/test/java/org/jboss/resteasy/client/jaxrs/engines/ManualClosingApacheHttpClient43EngineTest.java
@@ -0,0 +1,79 @@
+package org.jboss.resteasy.client.jaxrs.engines;
+
+import static org.junit.Assert.assertEquals;
+import static org.jboss.resteasy.client.jaxrs.engines.ManualClosingApacheHttpClient43Engine.FILE_UPLOAD_IN_MEMORY_THRESHOLD_PROPERTY;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class ManualClosingApacheHttpClient43EngineTest {
+
+ private static final Map preTestProperties = new HashMap<>();
+
+ @BeforeClass
+ public static void saveCurrentStateOfMemThresholdProperty()
+ {
+ if (System.getProperties().containsKey(FILE_UPLOAD_IN_MEMORY_THRESHOLD_PROPERTY))
+ {
+ String value = System.getProperty(FILE_UPLOAD_IN_MEMORY_THRESHOLD_PROPERTY);
+ preTestProperties.put(FILE_UPLOAD_IN_MEMORY_THRESHOLD_PROPERTY, value);
+ }
+ }
+
+ @AfterClass
+ public static void resetPropertiesToPreTestValues()
+ {
+ if (!preTestProperties.containsKey(FILE_UPLOAD_IN_MEMORY_THRESHOLD_PROPERTY))
+ {
+ System.clearProperty(FILE_UPLOAD_IN_MEMORY_THRESHOLD_PROPERTY);
+ }
+ else
+ {
+ preTestProperties.forEach(System::setProperty);
+ }
+ }
+
+ @Before
+ public void unsetMemThresholdProperty()
+ {
+ System.clearProperty(ManualClosingApacheHttpClient43Engine.FILE_UPLOAD_IN_MEMORY_THRESHOLD_PROPERTY);
+ }
+ @Test
+ public void testMemThresholdDefault()
+ {
+ assertEquals(1, new ManualClosingApacheHttpClient43Engine().getFileUploadInMemoryThresholdLimit());
+ }
+
+ @Test
+ public void testMemThresholdConfigProperty()
+ {
+ System.setProperty(ManualClosingApacheHttpClient43Engine.FILE_UPLOAD_IN_MEMORY_THRESHOLD_PROPERTY, "8");
+ assertEquals(8, new ManualClosingApacheHttpClient43Engine().getFileUploadInMemoryThresholdLimit());
+ }
+
+ @Test
+ public void testInvalidMemThresholdConfigPropertyReturnsDefault_NegativeNumber()
+ {
+ System.setProperty(ManualClosingApacheHttpClient43Engine.FILE_UPLOAD_IN_MEMORY_THRESHOLD_PROPERTY, "-8");
+ assertEquals(1, new ManualClosingApacheHttpClient43Engine().getFileUploadInMemoryThresholdLimit());
+ }
+
+ @Test
+ public void testInvalidMemThresholdConfigPropertyReturnsDefault_DecimalNumber()
+ {
+ System.setProperty(ManualClosingApacheHttpClient43Engine.FILE_UPLOAD_IN_MEMORY_THRESHOLD_PROPERTY, "2048.2");
+ assertEquals(1, new ManualClosingApacheHttpClient43Engine().getFileUploadInMemoryThresholdLimit());
+ }
+
+ @Test
+ public void testInvalidMemThresholdConfigPropertyReturnsDefault_NotANumber()
+ {
+ System.setProperty(ManualClosingApacheHttpClient43Engine.FILE_UPLOAD_IN_MEMORY_THRESHOLD_PROPERTY, "Infinity");
+ assertEquals(1, new ManualClosingApacheHttpClient43Engine().getFileUploadInMemoryThresholdLimit());
+ }
+}