use non-pooling RetainableByteBufferPool to work around performance bug

Signed-off-by: Lachlan Roberts <lachlan@webtide.com>
This commit is contained in:
Lachlan Roberts 2023-02-04 00:48:12 +11:00
parent d66e36b746
commit cd47a07463
3 changed files with 15 additions and 7 deletions

View File

@ -125,7 +125,7 @@ public class MultiPart
private final String name;
private final String fileName;
private final HttpFields fields;
private final Content.Source contentSource;
private Content.Source contentSource;
private Path path;
private boolean temporary = true;
@ -140,7 +140,6 @@ public class MultiPart
this.fileName = fileName;
this.fields = fields != null ? fields : HttpFields.EMPTY;
this.path = path;
this.contentSource = newContentSource();
}
private Path getPath()
@ -189,6 +188,8 @@ public class MultiPart
*/
public Content.Source getContentSource()
{
if (contentSource == null)
contentSource = newContentSource();
return contentSource;
}
@ -350,8 +351,8 @@ public class MultiPart
public ChunksPart(String name, String fileName, HttpFields fields, List<Content.Chunk> content)
{
super(name, fileName, fields);
this.content = Objects.requireNonNull(content);
content.forEach(Content.Chunk::retain);
this.content = content;
}
@Override

View File

@ -138,7 +138,7 @@ public class ServletMultiPartFormData
}
}
formData.parse(Content.Chunk.from(buffer, false, byteBuffer -> retainable.release()));
formData.parse(Content.Chunk.from(buffer, false, retainable::release));
if (readEof)
{
formData.parse(Content.Chunk.EOF);

View File

@ -50,6 +50,7 @@ import org.eclipse.jetty.http.MultiPart;
import org.eclipse.jetty.http.MultiPartFormData;
import org.eclipse.jetty.io.Content;
import org.eclipse.jetty.io.EofException;
import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.logging.StacklessLogging;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
@ -96,7 +97,12 @@ public class MultiPartServletTest
private void start(HttpServlet servlet, MultipartConfigElement config) throws Exception
{
server = new Server();
start(servlet, config, null);
}
private void start(HttpServlet servlet, MultipartConfigElement config, RetainableByteBufferPool bufferPool) throws Exception
{
server = new Server(null, null, bufferPool);
connector = new ServerConnector(server);
server.addConnector(connector);
@ -128,6 +134,7 @@ public class MultiPartServletTest
@Test
public void testLargePart() throws Exception
{
RetainableByteBufferPool bufferPool = new RetainableByteBufferPool.NonPooling();
start(new HttpServlet()
{
@Override
@ -135,7 +142,7 @@ public class MultiPartServletTest
{
req.getParameterMap();
}
}, new MultipartConfigElement(tmpDirString));
}, new MultipartConfigElement(tmpDirString), bufferPool);
OutputStreamRequestContent content = new OutputStreamRequestContent();
MultiPartRequestContent multiPart = new MultiPartRequestContent();
@ -159,7 +166,7 @@ public class MultiPartServletTest
}
content.close();
Response response = listener.get(2, TimeUnit.MINUTES);
Response response = listener.get(30, TimeUnit.MINUTES);
assertThat(response.getStatus(), equalTo(HttpStatus.BAD_REQUEST_400));
String responseContent = IO.toString(listener.getInputStream());
assertThat(responseContent, containsString("Unable to parse form content"));