Changed the read logic.

Before, if the stream had no content, InputStreamContentProvider's iterator
hasNext() was returning true, and next() was returning an empty buffer,
because the read was performed in next() and it was not possible to know
before reading whether the stream had content or was already at EOF.

Now the reads are performed in hasNext(), so that it is possible to return
immediately whether the stream is at EOF or not.
This solves a problem with ProxyServlet, where GET requests with no
content indication were proxied to the upstream server as GET requests
with chunked content, which in most cases were not understood by servers.
This commit is contained in:
Simone Bordet 2012-11-14 11:28:42 +01:00
parent 6ef0f415f0
commit e4cbb94ed6
1 changed files with 37 additions and 27 deletions

View File

@ -18,7 +18,6 @@
package org.eclipse.jetty.client.util;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.util.Iterator;
@ -61,41 +60,52 @@ public class InputStreamContentProvider implements ContentProvider
{
return new Iterator<ByteBuffer>()
{
private final byte[] buffer = new byte[bufferSize];
public boolean eof;
private final byte[] bytes = new byte[bufferSize];
private Exception failure;
private ByteBuffer buffer;
@Override
public boolean hasNext()
{
return !eof;
try
{
int read = stream.read(bytes);
if (read > 0)
{
buffer = onRead(bytes, 0, read);
return true;
}
else if (read < 0)
{
return false;
}
else
{
buffer = BufferUtil.EMPTY_BUFFER;
return true;
}
}
catch (Exception x)
{
if (failure == null)
{
failure = x;
return true;
}
return false;
}
}
@Override
public ByteBuffer next()
{
try
{
int read = stream.read(buffer);
if (read > 0)
{
return onRead(buffer, 0, read);
}
else if (read < 0)
{
if (eof)
throw new NoSuchElementException();
eof = true;
return onRead(buffer, 0, -1);
}
else
{
return onRead(buffer, 0, 0);
}
}
catch (IOException x)
{
throw (NoSuchElementException)new NoSuchElementException().initCause(x);
}
ByteBuffer result = buffer;
buffer = null;
if (failure != null)
throw (NoSuchElementException)new NoSuchElementException().initCause(failure);
if (result == null)
throw new NoSuchElementException();
return result;
}
@Override