Issue #5198 - GzipHandler should use InflaterPool as well as DeflaterPool
Signed-off-by: Lachlan Roberts <lachlan@webtide.com>
This commit is contained in:
parent
17ec87f51c
commit
3bdd82eb5e
|
@ -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()
|
||||
|
|
|
@ -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"/>
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue