#7280 destroy interceptor when content producer gets recycled

Signed-off-by: Ludovic Orban <lorban@bitronix.be>
This commit is contained in:
Ludovic Orban 2021-12-14 16:54:35 +01:00
parent 39585ea86e
commit 12b14c5850
3 changed files with 72 additions and 0 deletions

View File

@ -19,6 +19,7 @@ import java.util.concurrent.locks.Condition;
import org.eclipse.jetty.http.BadMessageException;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.util.component.Destroyable;
import org.eclipse.jetty.util.thread.AutoLock;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -65,6 +66,8 @@ class AsyncContentProducer implements ContentProducer
assertLocked();
if (LOG.isDebugEnabled())
LOG.debug("recycling {}", this);
if (_interceptor instanceof Destroyable)
((Destroyable)_interceptor).destroy();
_interceptor = null;
_rawContent = null;
_transformedContent = null;

View File

@ -28,6 +28,7 @@ import java.util.zip.GZIPOutputStream;
import org.eclipse.jetty.io.ArrayByteBufferPool;
import org.eclipse.jetty.io.EofException;
import org.eclipse.jetty.server.handler.gzip.GzipHttpInputInterceptor;
import org.eclipse.jetty.util.component.Destroyable;
import org.eclipse.jetty.util.compression.InflaterPool;
import org.eclipse.jetty.util.thread.AutoLock;
import org.hamcrest.core.Is;
@ -58,6 +59,22 @@ public class AsyncContentProducerTest
scheduledExecutorService.shutdownNow();
}
@Test
public void testDestroyInterceptorOnRecycle()
{
DestroyableInterceptor interceptor = new DestroyableInterceptor();
AsyncContentProducer contentProducer = new AsyncContentProducer(null);
try (AutoLock lock = contentProducer.lock())
{
contentProducer.setInterceptor(interceptor);
assertThat(interceptor.destroyed, is(false));
contentProducer.recycle();
assertThat(interceptor.destroyed, is(true));
}
}
@Test
public void testAsyncContentProducerNoInterceptor() throws Exception
{
@ -347,4 +364,21 @@ public class AsyncContentProducerTest
return false;
}
}
private static class DestroyableInterceptor implements Destroyable, HttpInput.Interceptor
{
private boolean destroyed = false;
@Override
public void destroy()
{
destroyed = true;
}
@Override
public HttpInput.Content readFrom(HttpInput.Content content)
{
return null;
}
}
}

View File

@ -25,8 +25,10 @@ import java.util.zip.GZIPOutputStream;
import org.eclipse.jetty.io.ArrayByteBufferPool;
import org.eclipse.jetty.io.EofException;
import org.eclipse.jetty.server.handler.gzip.GzipHttpInputInterceptor;
import org.eclipse.jetty.util.component.Destroyable;
import org.eclipse.jetty.util.compression.InflaterPool;
import org.eclipse.jetty.util.thread.AutoLock;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@ -53,6 +55,22 @@ public class BlockingContentProducerTest
scheduledExecutorService.shutdownNow();
}
@Test
public void testDestroyInterceptorOnRecycle()
{
DestroyableInterceptor interceptor = new DestroyableInterceptor();
BlockingContentProducer contentProducer = new BlockingContentProducer(new AsyncContentProducer(null));
try (AutoLock lock = contentProducer.lock())
{
contentProducer.setInterceptor(interceptor);
assertThat(interceptor.destroyed, is(false));
contentProducer.recycle();
assertThat(interceptor.destroyed, is(true));
}
}
@Test
public void testBlockingContentProducerNoInterceptor()
{
@ -347,4 +365,21 @@ public class BlockingContentProducerTest
return false;
}
}
private static class DestroyableInterceptor implements Destroyable, HttpInput.Interceptor
{
private boolean destroyed = false;
@Override
public void destroy()
{
destroyed = true;
}
@Override
public HttpInput.Content readFrom(HttpInput.Content content)
{
return null;
}
}
}