diff --git a/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/MultiPart.java b/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/MultiPart.java
index eb22ad5f71d..37127a5ea1c 100644
--- a/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/MultiPart.java
+++ b/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/MultiPart.java
@@ -32,7 +32,6 @@ import java.util.Queue;
import java.util.concurrent.ThreadLocalRandom;
import org.eclipse.jetty.io.Content;
-import org.eclipse.jetty.io.Retainable;
import org.eclipse.jetty.io.content.ByteBufferContentSource;
import org.eclipse.jetty.io.content.ChunksContentSource;
import org.eclipse.jetty.io.content.PathContentSource;
@@ -119,7 +118,7 @@ public class MultiPart
*
A part has an optional name, an optional fileName,
* optional headers and an optional content.
*/
- public abstract static class Part
+ public abstract static class Part implements Closeable
{
private static final Throwable SENTINEL_CLOSE_EXCEPTION = new StaticException("Closed");
@@ -204,6 +203,7 @@ public class MultiPart
* RFC 7578, section 4.6.
*
* @return the content of this part as a new {@link Content.Source}
+ * @see #getContentSource()
*/
public abstract Content.Source newContentSource();
@@ -279,6 +279,7 @@ public class MultiPart
Files.delete(this.path);
}
+ @Override
public void close()
{
fail(SENTINEL_CLOSE_EXCEPTION);
@@ -354,15 +355,18 @@ public class MultiPart
@Override
public Content.Source newContentSource()
{
- return new ChunksContentSource(content.stream().map(c ->
- Content.Chunk.asChunk(c.getByteBuffer().slice(), c.isLast(), Retainable.NOOP)).toList());
+ List newChunks = content.stream()
+ .map(chunk -> Content.Chunk.asChunk(chunk.getByteBuffer().slice(), chunk.isLast(), chunk))
+ .peek(Content.Chunk::retain)
+ .toList();
+ return new ChunksContentSource(newChunks);
}
@Override
public void close()
{
super.close();
- content.forEach(Retainable::release);
+ content.forEach(Content.Chunk::release);
}
@Override
diff --git a/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/MultiPartByteRanges.java b/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/MultiPartByteRanges.java
index 3c0d7153d91..ed4fd95123a 100644
--- a/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/MultiPartByteRanges.java
+++ b/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/MultiPartByteRanges.java
@@ -24,8 +24,6 @@ import java.util.concurrent.CompletableFuture;
import org.eclipse.jetty.io.Content;
import org.eclipse.jetty.util.thread.AutoLock;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
/**
* A {@link CompletableFuture} that is completed when a multipart/byteranges
@@ -56,8 +54,6 @@ import org.slf4j.LoggerFactory;
*/
public class MultiPartByteRanges extends CompletableFuture
{
- private static final Logger LOG = LoggerFactory.getLogger(MultiPartByteRanges.class);
-
private final PartsListener listener = new PartsListener();
private final MultiPart.Parser parser;
diff --git a/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/MultiPartFormData.java b/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/MultiPartFormData.java
index a9a713600ea..552f35c1e5c 100644
--- a/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/MultiPartFormData.java
+++ b/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/MultiPartFormData.java
@@ -386,7 +386,8 @@ public class MultiPartFormData extends CompletableFutureReturns whether this resource is referenced counted by calls to {@link #retain()}
* and {@link #release()}.
diff --git a/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/HttpStream.java b/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/HttpStream.java
index 0bea0d2a677..6946df400d3 100644
--- a/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/HttpStream.java
+++ b/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/HttpStream.java
@@ -110,10 +110,10 @@ public interface HttpStream extends Callback
{
long consumedRequestContentBytes = 0;
long maxUnconsumedRequestContentBytes = httpConfig.getMaxUnconsumedRequestContentBytes();
- while (consumedRequestContentBytes < maxUnconsumedRequestContentBytes)
+ while (maxUnconsumedRequestContentBytes < 0 || consumedRequestContentBytes < maxUnconsumedRequestContentBytes)
{
// We can always just read again here as EOF and Error content will be persistently returned.
- Content.Chunk content = stream.read();
+ Chunk content = stream.read();
// if we cannot read to EOF then fail the stream rather than wait for unconsumed content
if (content == null)
@@ -124,7 +124,7 @@ public interface HttpStream extends Callback
content.release();
// if the input failed, then fail the stream for same reason
- if (content instanceof Content.Chunk.Error error)
+ if (content instanceof Chunk.Error error)
return error.getCause();
if (content.isLast())
diff --git a/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/DelayedHandler.java b/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/DelayedHandler.java
index 97770f7fd28..f56b909701f 100644
--- a/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/DelayedHandler.java
+++ b/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/DelayedHandler.java
@@ -291,7 +291,7 @@ public class DelayedHandler extends Handler.Wrapper
{
// We must execute here as even though we have consumed all the input, we are probably
// invoked in a demand runnable that is serialized with any write callbacks that might be done in process
- getRequest().getContext().execute(super::process);
+ getRequest().getContext().execute(this::process);
}
else
{