471171 - Support SYNC_FLUSH in GzipHandler

This commit is contained in:
Greg Wilkins 2016-01-15 14:27:09 +11:00
parent fa374cd899
commit d41c0bba65
2 changed files with 31 additions and 7 deletions

View File

@ -68,6 +68,7 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory
private int _minGzipSize=DEFAULT_MIN_GZIP_SIZE;
private int _compressionLevel=Deflater.DEFAULT_COMPRESSION;
private boolean _checkGzExists = true;
private boolean _syncFlush = false;
// non-static, as other GzipHandler instances may have different configurations
private final ThreadLocal<Deflater> _deflater = new ThreadLocal<Deflater>();
@ -175,6 +176,27 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory
_methods.include(m);
}
/* ------------------------------------------------------------ */
/**
* @return True if {@link Deflater#SYNC_FLUSH} is used, else {@link Deflater#NO_FLUSH}
*/
public boolean isSyncFlush()
{
return _syncFlush;
}
/* ------------------------------------------------------------ */
/**
* <p>Set the {@link Deflater} flush mode to use. {@link Deflater#SYNC_FLUSH}
* should be used if the application wishes to stream the data, but this may
* hurt compression performance.
* @param syncFlush True if {@link Deflater#SYNC_FLUSH} is used, else {@link Deflater#NO_FLUSH}
*/
public void setSyncFlush(boolean syncFlush)
{
_syncFlush = syncFlush;
}
/* ------------------------------------------------------------ */
/**
* Add included mime types. Inclusion takes precedence over
@ -432,7 +454,7 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory
}
// install interceptor and handle
out.setInterceptor(new GzipHttpOutputInterceptor(this,_vary,baseRequest.getHttpChannel(),out.getInterceptor()));
out.setInterceptor(new GzipHttpOutputInterceptor(this,_vary,baseRequest.getHttpChannel(),out.getInterceptor(),_syncFlush));
if (_handler!=null)
_handler.handle(target,baseRequest, request, response);
}

View File

@ -56,27 +56,29 @@ public class GzipHttpOutputInterceptor implements HttpOutput.Interceptor
private final HttpChannel _channel;
private final HttpField _vary;
private final int _bufferSize;
private final boolean _syncFlush;
private Deflater _deflater;
private ByteBuffer _buffer;
public GzipHttpOutputInterceptor(GzipFactory factory, HttpChannel channel, HttpOutput.Interceptor next)
public GzipHttpOutputInterceptor(GzipFactory factory, HttpChannel channel, HttpOutput.Interceptor next,boolean syncFlush)
{
this(factory,VARY_ACCEPT_ENCODING_USER_AGENT,channel.getHttpConfiguration().getOutputBufferSize(),channel,next);
this(factory,VARY_ACCEPT_ENCODING_USER_AGENT,channel.getHttpConfiguration().getOutputBufferSize(),channel,next,syncFlush);
}
public GzipHttpOutputInterceptor(GzipFactory factory, HttpField vary, HttpChannel channel, HttpOutput.Interceptor next)
public GzipHttpOutputInterceptor(GzipFactory factory, HttpField vary, HttpChannel channel, HttpOutput.Interceptor next,boolean syncFlush)
{
this(factory,vary,channel.getHttpConfiguration().getOutputBufferSize(),channel,next);
this(factory,vary,channel.getHttpConfiguration().getOutputBufferSize(),channel,next,syncFlush);
}
public GzipHttpOutputInterceptor(GzipFactory factory, HttpField vary, int bufferSize, HttpChannel channel, HttpOutput.Interceptor next)
public GzipHttpOutputInterceptor(GzipFactory factory, HttpField vary, int bufferSize, HttpChannel channel, HttpOutput.Interceptor next,boolean syncFlush)
{
_factory=factory;
_channel=channel;
_interceptor=next;
_vary=vary;
_bufferSize=bufferSize;
_syncFlush=syncFlush;
}
public HttpOutput.Interceptor getNextInterceptor()
@ -353,7 +355,7 @@ public class GzipHttpOutputInterceptor implements HttpOutput.Interceptor
int len=_buffer.capacity()-_buffer.limit() - (_last?8:0);
if (len>0)
{
int produced=_deflater.deflate(_buffer.array(),off,len,Deflater.NO_FLUSH);
int produced=_deflater.deflate(_buffer.array(),off,len,_syncFlush?Deflater.SYNC_FLUSH:Deflater.NO_FLUSH);
_buffer.limit(_buffer.limit()+produced);
}
boolean finished=_deflater.finished();