Skip to content

Commit

Permalink
Issue #5198 - revert usage of deflater ByteBuffer API for GzipHandler
Browse files Browse the repository at this point in the history
The CRC32 checksum may need to convert the ByteBuffer to an array anyway so
we are better off not setting the deflater input with ByteBuffer directly.

Signed-off-by: Lachlan Roberts <lachlan@webtide.com>
  • Loading branch information
lachlan-roberts committed Sep 9, 2020
1 parent 4e6827c commit 2f23c59
Showing 1 changed file with 52 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@ public boolean mightCompress()

private class GzipBufferCB extends IteratingNestedCallback
{
private ByteBuffer _copy;
private final ByteBuffer _content;
private final boolean _last;

Expand All @@ -271,10 +272,6 @@ public GzipBufferCB(ByteBuffer content, boolean complete, Callback callback)
super(callback);
_content = content;
_last = complete;
_crc.update(_content.slice());
_deflater.setInput(_content);
if (_last)
_deflater.finish();
}

@Override
Expand All @@ -299,6 +296,11 @@ protected Action process() throws Exception
_channel.getByteBufferPool().release(_buffer);
_buffer = null;
}
if (_copy != null)
{
_channel.getByteBufferPool().release(_copy);
_copy = null;
}
return Action.SUCCEEDED;
}

Expand All @@ -318,13 +320,52 @@ protected Action process() throws Exception
// If the deflator is not finished, then compress more data
if (!_deflater.finished())
{
if (_deflater.needsInput() && !_last)
return Action.SUCCEEDED;
if (_deflater.needsInput())
{
// if there is no more content available to compress
// then we are either finished all content or just the current write.
if (BufferUtil.isEmpty(_content))
{
if (_last)
_deflater.finish();
else
return Action.SUCCEEDED;
}
else
{
// If there is more content available to compress, we have to make sure
// it is available in an array for the current deflator API, maybe slicing
// of content.
ByteBuffer slice;
if (_content.hasArray())
slice = _content;
else
{
if (_copy == null)
_copy = _channel.getByteBufferPool().acquire(_bufferSize, false);
else
BufferUtil.clear(_copy);
slice = _copy;
BufferUtil.append(_copy, _content);
}

// transfer the data from the slice to the the deflator
byte[] array = slice.array();
int off = slice.arrayOffset() + slice.position();
int len = slice.remaining();
_crc.update(array, off, len);
_deflater.setInput(array, off, len);
slice.position(slice.position() + len);
if (_last && BufferUtil.isEmpty(_content))
_deflater.finish();
}
}

// deflate the content into the available space in the buffer
int pos = BufferUtil.flipToFill(_buffer);
_deflater.deflate(_buffer, _syncFlush ? Deflater.SYNC_FLUSH : Deflater.NO_FLUSH);
BufferUtil.flipToFlush(_buffer, pos);
int off = _buffer.arrayOffset() + _buffer.limit();
int len = BufferUtil.space(_buffer);
int produced = _deflater.deflate(_buffer.array(), off, len, _syncFlush ? Deflater.SYNC_FLUSH : Deflater.NO_FLUSH);
_buffer.limit(_buffer.limit() + produced);
}

// If we have finished deflation and there is room for the trailer.
Expand All @@ -345,10 +386,11 @@ protected Action process() throws Exception
@Override
public String toString()
{
return String.format("%s[content=%s last=%b buffer=%s deflate=%s %s]",
return String.format("%s[content=%s last=%b copy=%s buffer=%s deflate=%s %s]",
super.toString(),
BufferUtil.toDetailString(_content),
_last,
BufferUtil.toDetailString(_copy),
BufferUtil.toDetailString(_buffer),
_deflater,
_deflater != null && _deflater.finished() ? "(finished)" : "");
Expand Down

0 comments on commit 2f23c59

Please sign in to comment.