419911 - Empty chunk causes ArrayIndexOutOfBoundsException in

InputStreamResponseListener.

Fixed by adding relevant checks for zero-length content,
and not notifying listeners in such case.
This commit is contained in:
Simone Bordet 2013-12-11 16:02:14 +01:00
parent f2cc5295df
commit 125cfe7e71
3 changed files with 41 additions and 23 deletions

View File

@ -165,6 +165,8 @@ public class RequestNotifier
{
// Slice the buffer to avoid that listeners peek into data they should not look at.
content = content.slice();
if (!content.hasRemaining())
return;
// Optimized to avoid allocations of iterator instances.
List<Request.RequestListener> requestListeners = request.getRequestListeners(null);
for (int i = 0; i < requestListeners.size(); ++i)

View File

@ -120,6 +120,8 @@ public class ResponseNotifier
{
// Slice the buffer to avoid that listeners peek into data they should not look at.
buffer = buffer.slice();
if (!buffer.hasRemaining())
return;
// Optimized to avoid allocations of iterator instances
for (int i = 0; i < listeners.size(); ++i)
{

View File

@ -108,25 +108,36 @@ public class InputStreamResponseListener extends Listener.Adapter
@Override
public void onContent(Response response, ByteBuffer content)
{
// Avoid buffering if the input stream is early closed.
if (closed)
return;
int remaining = content.remaining();
byte[] bytes = new byte[remaining];
content.get(bytes);
LOG.debug("Queuing {}/{} bytes", bytes, bytes.length);
queue.offer(bytes);
long newLength = length.addAndGet(remaining);
while (newLength >= maxBufferSize)
if (!closed)
{
LOG.debug("Queued bytes limit {}/{} exceeded, waiting", newLength, maxBufferSize);
// Block to avoid infinite buffering
if (!await())
break;
newLength = length.get();
LOG.debug("Queued bytes limit {}/{} exceeded, woken up", newLength, maxBufferSize);
int remaining = content.remaining();
if (remaining > 0)
{
byte[] bytes = new byte[remaining];
content.get(bytes);
LOG.debug("Queuing {}/{} bytes", bytes, remaining);
queue.offer(bytes);
long newLength = length.addAndGet(remaining);
while (newLength >= maxBufferSize)
{
LOG.debug("Queued bytes limit {}/{} exceeded, waiting", newLength, maxBufferSize);
// Block to avoid infinite buffering
if (!await())
break;
newLength = length.get();
LOG.debug("Queued bytes limit {}/{} exceeded, woken up", newLength, maxBufferSize);
}
}
else
{
LOG.debug("Queuing skipped, empty content {}", content);
}
}
else
{
LOG.debug("Queuing skipped, stream already closed");
}
}
@ -305,11 +316,14 @@ public class InputStreamResponseListener extends Listener.Adapter
@Override
public void close() throws IOException
{
LOG.debug("Queuing close {}{}", CLOSED, "");
queue.offer(CLOSED);
closed = true;
signal();
super.close();
if (!closed)
{
super.close();
LOG.debug("Queuing close {}{}", CLOSED, "");
queue.offer(CLOSED);
closed = true;
signal();
}
}
}
}