Issue #5198 - GzipHandler should use InflaterPool as well as DeflaterPool

Signed-off-by: Lachlan Roberts <lachlan@webtide.com>
This commit is contained in:
Lachlan Roberts 2020-09-08 15:27:21 +10:00
parent 17ec87f51c
commit 3bdd82eb5e
6 changed files with 78 additions and 24 deletions

View File

@ -29,6 +29,7 @@ import java.util.zip.ZipException;
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.component.Destroyable;
import org.eclipse.jetty.util.compression.InflaterPool;
/**
* <p>Decoder for the "gzip" content encoding.</p>
@ -41,9 +42,10 @@ public class GZIPContentDecoder implements Destroyable
private static final long UINT_MAX = 0xFFFFFFFFL;
private final List<ByteBuffer> _inflateds = new ArrayList<>();
private final Inflater _inflater = new Inflater(true);
private final InflaterPool _inflaterPool;
private final ByteBufferPool _pool;
private final int _bufferSize;
private Inflater _inflater;
private State _state;
private int _size;
private long _value;
@ -62,6 +64,13 @@ public class GZIPContentDecoder implements Destroyable
public GZIPContentDecoder(ByteBufferPool pool, int bufferSize)
{
this(null, pool, bufferSize);
}
public GZIPContentDecoder(InflaterPool inflaterPool, ByteBufferPool pool, int bufferSize)
{
_inflaterPool = inflaterPool;
_inflater = (inflaterPool == null) ? new Inflater(true) : inflaterPool.acquire();
_bufferSize = bufferSize;
_pool = pool;
reset();
@ -420,7 +429,12 @@ public class GZIPContentDecoder implements Destroyable
@Override
public void destroy()
{
_inflater.end();
if (_inflaterPool == null)
_inflater.end();
else
_inflaterPool.release(_inflater);
_inflater = null;
}
public boolean isFinished()

View File

@ -16,6 +16,7 @@
<Set name="checkGzExists" property="jetty.gzip.checkGzExists"/>
<Set name="compressionLevel" property="jetty.gzip.compressionLevel"/>
<Set name="inflateBufferSize" property="jetty.gzip.inflateBufferSize"/>
<Set name="inflaterPoolCapacity" property="jetty.gzip.inflaterPoolCapacity"/>
<Set name="deflaterPoolCapacity" property="jetty.gzip.deflaterPoolCapacity"/>
<Set name="syncFlush" property="jetty.gzip.syncFlush"/>
<Set name="dispatcherTypes" property="jetty.gzip.dispatcherTypes"/>

View File

@ -26,9 +26,12 @@ etc/jetty-gzip.xml
## Inflate request buffer size, or 0 for no request inflation
# jetty.gzip.inflateBufferSize=0
## Deflater pool max size (-1 for unlimited, 0 for no pool)
## Deflater pool max size (-1 for unlimited, 0 for no pooling)
# jetty.gzip.deflaterPoolCapacity=-1
## Inflater pool max size (-1 for unlimited, 0 for no pooling)
# jetty.gzip.inflaterPoolCapacity=-1
## Set the {@link Deflater} flush mode to use.
# jetty.gzip.syncFlush=false

View File

@ -46,7 +46,9 @@ import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.HandlerWrapper;
import org.eclipse.jetty.util.IncludeExclude;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.compression.CompressionPool;
import org.eclipse.jetty.util.compression.DeflaterPool;
import org.eclipse.jetty.util.compression.InflaterPool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -160,8 +162,8 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory
private static final HttpField TE_CHUNKED = new PreEncodedHttpField(HttpHeader.TRANSFER_ENCODING, HttpHeaderValue.CHUNKED.asString());
private static final Pattern COMMA_GZIP = Pattern.compile(".*, *gzip");
private int poolCapacity = -1;
private DeflaterPool _deflaterPool = null;
private final InflaterPool _inflaterPool;
private final DeflaterPool _deflaterPool;
private int _minGzipSize = DEFAULT_MIN_GZIP_SIZE;
private boolean _syncFlush = false;
@ -199,6 +201,11 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory
if (LOG.isDebugEnabled())
LOG.debug("{} mime types {}", this, _mimeTypes);
_deflaterPool = newDeflaterPool();
_inflaterPool = newInflaterPool();
addBean(_deflaterPool);
addBean(_inflaterPool);
}
/**
@ -409,13 +416,6 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory
}
}
@Override
protected void doStart() throws Exception
{
_deflaterPool = newDeflaterPool(poolCapacity);
super.doStart();
}
@Override
public Deflater getDeflater(Request request, long contentLength)
{
@ -566,7 +566,7 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory
{
if (LOG.isDebugEnabled())
LOG.debug("{} inflate {}", this, request);
baseRequest.getHttpInput().addInterceptor(new GzipHttpInputInterceptor(baseRequest.getHttpChannel().getByteBufferPool(), _inflateBufferSize));
baseRequest.getHttpInput().addInterceptor(new GzipHttpInputInterceptor(_inflaterPool, baseRequest.getHttpChannel().getByteBufferPool(), _inflateBufferSize));
}
// Are we already being gzipped?
@ -891,7 +891,7 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory
*/
public int getDeflaterPoolCapacity()
{
return poolCapacity;
return _deflaterPool.getCapacity();
}
/**
@ -902,12 +902,38 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory
if (isStarted())
throw new IllegalStateException(getState());
poolCapacity = capacity;
_deflaterPool.setCapacity(capacity);
}
protected DeflaterPool newDeflaterPool(int capacity)
/**
* Gets the maximum number of Inflators that the DeflaterPool can hold.
*
* @return the Deflater pool capacity
*/
public int getInflaterPoolCapacity()
{
return new DeflaterPool(capacity, Deflater.DEFAULT_COMPRESSION, true);
return _inflaterPool.getCapacity();
}
/**
* Sets the maximum number of Inflators that the DeflaterPool can hold.
*/
public void setInflaterPoolCapacity(int capacity)
{
if (isStarted())
throw new IllegalStateException(getState());
_inflaterPool.setCapacity(capacity);
}
protected InflaterPool newInflaterPool()
{
return new InflaterPool(CompressionPool.INFINITE_CAPACITY, true);
}
protected DeflaterPool newDeflaterPool()
{
return new DeflaterPool(CompressionPool.INFINITE_CAPACITY, Deflater.DEFAULT_COMPRESSION, true);
}
@Override

View File

@ -25,6 +25,7 @@ import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.server.HttpInput;
import org.eclipse.jetty.server.HttpInput.Content;
import org.eclipse.jetty.util.component.Destroyable;
import org.eclipse.jetty.util.compression.InflaterPool;
/**
* An HttpInput Interceptor that inflates GZIP encoded request content.
@ -34,9 +35,9 @@ public class GzipHttpInputInterceptor implements HttpInput.Interceptor, Destroya
private final Decoder _decoder;
private ByteBuffer _chunk;
public GzipHttpInputInterceptor(ByteBufferPool pool, int bufferSize)
public GzipHttpInputInterceptor(InflaterPool inflaterPool, ByteBufferPool pool, int bufferSize)
{
_decoder = new Decoder(pool, bufferSize);
_decoder = new Decoder(inflaterPool, pool, bufferSize);
}
@Override
@ -66,9 +67,9 @@ public class GzipHttpInputInterceptor implements HttpInput.Interceptor, Destroya
private class Decoder extends GZIPContentDecoder
{
private Decoder(ByteBufferPool pool, int bufferSize)
private Decoder(InflaterPool inflaterPool, ByteBufferPool bufferPool, int bufferSize)
{
super(pool, bufferSize);
super(inflaterPool, bufferPool, bufferSize);
}
@Override

View File

@ -30,7 +30,7 @@ public abstract class CompressionPool<T> extends AbstractLifeCycle
private final Queue<T> _pool;
private final AtomicInteger _numObjects = new AtomicInteger(0);
private final int _capacity;
private int _capacity;
/**
* Create a Pool of {@link T} instances.
@ -44,7 +44,17 @@ public abstract class CompressionPool<T> extends AbstractLifeCycle
public CompressionPool(int capacity)
{
_capacity = capacity;
_pool = (_capacity == 0) ? null : new ConcurrentLinkedQueue<>();
_pool = new ConcurrentLinkedQueue<>();
}
public int getCapacity()
{
return _capacity;
}
public void setCapacity(int capacity)
{
_capacity = capacity;
}
protected abstract T newObject();
@ -85,7 +95,6 @@ public abstract class CompressionPool<T> extends AbstractLifeCycle
if (_capacity == 0 || !isRunning())
{
end(object);
return;
}
else if (_capacity < 0)
{