Attempted a different fix to the streamed content code so that it is blocking (previous fix failed for an unknown reason, and the code was getting complex unnecessarily).
This commit is contained in:
@@ -105,7 +105,9 @@ public int get(ByteBuffer buffer) {
|
|||||||
int count = channel.read(buffer);
|
int count = channel.read(buffer);
|
||||||
|
|
||||||
if(count == -1) result = CONTENT_END;
|
if(count == -1) result = CONTENT_END;
|
||||||
else if(count == 0) result = CONTENT_PENDING; //Note: Shouldn't occur since the stream is set to blocking.//
|
else if(count == 0) {
|
||||||
|
result = CONTENT_PENDING; //Note: Shouldn't occur since the stream is set to blocking.//
|
||||||
|
}//else if//
|
||||||
else {
|
else {
|
||||||
result = count;
|
result = count;
|
||||||
size -= count;
|
size -= count;
|
||||||
@@ -127,36 +129,18 @@ public int get(ByteBuffer buffer) {
|
|||||||
}//else//
|
}//else//
|
||||||
}//if//
|
}//if//
|
||||||
else {
|
else {
|
||||||
boolean readFromChannel = this.buffer.remaining() == 0;
|
|
||||||
|
|
||||||
//Lazily create a buffer if necessary.//
|
//Lazily create a buffer if necessary.//
|
||||||
if(this.buffer == null) {
|
if(this.buffer == null) {
|
||||||
this.buffer = ByteBuffer.allocate(2000);
|
this.buffer = ByteBuffer.allocate(2000);
|
||||||
}//if//
|
}//if//
|
||||||
|
|
||||||
//If there are bytes remaining in this.buffer AND we are about to read a new chunk header THEN figure out if we have at least enough bytes to read the chunk header (don't read more from the stream if true - could cause a deadlock, otherwise read more since there must be more to read).//
|
//Set to non-blocking for this attempt (otherwise we could block indefinately if we already have the whole message).//
|
||||||
if(!readFromChannel && chunkSize == 0) {
|
channel.configureBlocking(false);
|
||||||
StringBuffer chunkHeader = new StringBuffer(100);
|
//Read as many bytes from the channel as possible.//
|
||||||
this.buffer.mark();
|
this.buffer.compact();
|
||||||
|
channel.read(this.buffer);
|
||||||
//Read the next chunk header.//
|
this.buffer.flip();
|
||||||
while(this.buffer.hasRemaining() && (chunkHeader.length() < 2 || !(chunkHeader.charAt(chunkHeader.length() - 2) == '\r' && chunkHeader.charAt(chunkHeader.length() - 1) == '\n'))) {
|
channel.configureBlocking(true);
|
||||||
chunkHeader.append((char) this.buffer.get());
|
|
||||||
}//while//
|
|
||||||
|
|
||||||
this.buffer.reset();
|
|
||||||
|
|
||||||
//If a chunk header was not readable then do read from the channel.//
|
|
||||||
readFromChannel = chunkHeader.length() < 2 || !(chunkHeader.charAt(chunkHeader.length() - 2) == '\r' && chunkHeader.charAt(chunkHeader.length() - 1) == '\n');
|
|
||||||
}//if//
|
|
||||||
|
|
||||||
//Only attempt a read IF there are no bytes in this.buffer OR we are reading the next chunk header and there are insufficient bytes in this.buffer to do so.//
|
|
||||||
if(readFromChannel) {
|
|
||||||
//Read as many bytes from the channel as possible.//
|
|
||||||
this.buffer.compact();
|
|
||||||
channel.read(this.buffer);
|
|
||||||
this.buffer.flip();
|
|
||||||
}//if//
|
|
||||||
|
|
||||||
//Check to see if the chunk ends within this buffer.//
|
//Check to see if the chunk ends within this buffer.//
|
||||||
if(this.buffer.remaining() > chunkSize) {
|
if(this.buffer.remaining() > chunkSize) {
|
||||||
@@ -237,6 +221,16 @@ public int get(ByteBuffer buffer) {
|
|||||||
chunkSize -= result;
|
chunkSize -= result;
|
||||||
}//else//
|
}//else//
|
||||||
}//else//
|
}//else//
|
||||||
|
|
||||||
|
if(result == CONTENT_PENDING) {
|
||||||
|
//Attempt a blocking read since there must be more to the message.//
|
||||||
|
this.buffer.compact();
|
||||||
|
channel.read(this.buffer);
|
||||||
|
this.buffer.flip();
|
||||||
|
|
||||||
|
//Re-call this method once we have content so that it will be properly transferred.//
|
||||||
|
result = get(buffer);
|
||||||
|
}//if//
|
||||||
}//else//
|
}//else//
|
||||||
}//try//
|
}//try//
|
||||||
catch(Throwable e) {
|
catch(Throwable e) {
|
||||||
|
|||||||
@@ -255,7 +255,7 @@ public class WebServer {
|
|||||||
getResult = content.get(buffer);
|
getResult = content.get(buffer);
|
||||||
|
|
||||||
if(getResult == IContent.CONTENT_PENDING) {
|
if(getResult == IContent.CONTENT_PENDING) {
|
||||||
result = false;
|
result = false; //Should never occur currently: See StreamedContent's javadocs.//
|
||||||
}//if//
|
}//if//
|
||||||
else if(getResult == IContent.CONTENT_END) {
|
else if(getResult == IContent.CONTENT_END) {
|
||||||
buffer = null;
|
buffer = null;
|
||||||
|
|||||||
Reference in New Issue
Block a user