394370 correctly handle last content and responses with no content
This commit is contained in:
parent
62e033fcd0
commit
139de22bc0
|
@ -584,6 +584,7 @@ public class HttpChannel<T> implements HttpParser.RequestHandler<T>, Runnable
|
|||
// TODO is it worthwhile sending if we are at EoF?
|
||||
// "application" info failed to commit, commit with a failsafe 500 info
|
||||
_transport.send(HttpGenerator.RESPONSE_500_INFO,null,true);
|
||||
complete=true;
|
||||
throw e;
|
||||
}
|
||||
catch (Exception e)
|
||||
|
@ -591,8 +592,15 @@ public class HttpChannel<T> implements HttpParser.RequestHandler<T>, Runnable
|
|||
LOG.warn(e);
|
||||
// "application" info failed to commit, commit with a failsafe 500 info
|
||||
_transport.send(HttpGenerator.RESPONSE_500_INFO,null,true);
|
||||
complete=true;
|
||||
throw e;
|
||||
}
|
||||
finally
|
||||
{
|
||||
// TODO this indicates the relationship with HttpOutput is not exactly correct
|
||||
if (complete)
|
||||
_response.getHttpOutput().closed();
|
||||
}
|
||||
}
|
||||
return committed;
|
||||
}
|
||||
|
|
|
@ -82,6 +82,19 @@ public class HttpOutput extends ServletOutputStream
|
|||
{
|
||||
_closed = false;
|
||||
}
|
||||
|
||||
/** Called by the HttpChannel if the output was closed
|
||||
* externally (eg by a 500 exception handling).
|
||||
*/
|
||||
void closed()
|
||||
{
|
||||
_closed = true;
|
||||
if (_aggregate != null)
|
||||
{
|
||||
_channel.getConnector().getByteBufferPool().release(_aggregate);
|
||||
_aggregate = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close()
|
||||
|
@ -259,7 +272,8 @@ public class HttpOutput extends ServletOutputStream
|
|||
// Process content.
|
||||
if (content instanceof ByteBuffer)
|
||||
{
|
||||
_channel.write((ByteBuffer)content, true); // TODO: we have written all content ?
|
||||
_channel.write((ByteBuffer)content, true);
|
||||
_closed=true;
|
||||
}
|
||||
else if (content instanceof ReadableByteChannel)
|
||||
{
|
||||
|
@ -301,7 +315,6 @@ public class HttpOutput extends ServletOutputStream
|
|||
buffer.limit(len);
|
||||
_channel.write(buffer,false);
|
||||
}
|
||||
_channel.write(BufferUtil.EMPTY_BUFFER,true);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
|
|
@ -70,6 +70,16 @@ public class HttpTransportOverSPDY implements HttpTransport
|
|||
@Override
|
||||
public <C> void send(HttpGenerator.ResponseInfo info, ByteBuffer content, boolean lastContent, C context, Callback<C> callback)
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("send {} {} {} {} last={}%n",this,stream,info,BufferUtil.toDetailString(content),lastContent);
|
||||
|
||||
if (stream.isClosed() || stream.isReset() )
|
||||
{
|
||||
callback.failed(context,new EofException("stream closed"));
|
||||
return;
|
||||
}
|
||||
// new Throwable().printStackTrace();
|
||||
|
||||
// info==null content==null lastContent==false should not happen
|
||||
// info==null content==null lastContent==true signals no more content - complete
|
||||
// info==null content!=null lastContent==false send data on committed response
|
||||
|
@ -114,17 +124,34 @@ public class HttpTransportOverSPDY implements HttpTransport
|
|||
}
|
||||
|
||||
boolean close = !hasContent && lastContent;
|
||||
reply(stream, new ReplyInfo(headers, close));
|
||||
ReplyInfo reply = new ReplyInfo(headers,close);
|
||||
reply(stream, reply);
|
||||
}
|
||||
|
||||
|
||||
if ((hasContent || lastContent ) && !stream.isClosed() )
|
||||
// Do we have some content to send as well
|
||||
if (hasContent)
|
||||
{
|
||||
if (content==null)
|
||||
content=BufferUtil.EMPTY_BUFFER;
|
||||
stream.data(new ByteBufferDataInfo(content, lastContent),endPoint.getIdleTimeout(),TimeUnit.MILLISECONDS,context,callback);
|
||||
// Is the stream still open?
|
||||
if (stream.isClosed()|| stream.isReset())
|
||||
// tell the callback about the EOF
|
||||
callback.failed(context,new EofException("stream closed"));
|
||||
else
|
||||
// send the data and let it call the callback
|
||||
stream.data(new ByteBufferDataInfo(content, lastContent),endPoint.getIdleTimeout(),TimeUnit.MILLISECONDS,context,callback);
|
||||
}
|
||||
// else do we need to close
|
||||
else if (lastContent)
|
||||
{
|
||||
// Are we closed ?
|
||||
if (stream.isClosed()|| stream.isReset())
|
||||
// already closed by reply, so just tell callback we are complete
|
||||
callback.completed(context);
|
||||
else
|
||||
// send empty data to close and let the send call the callback
|
||||
stream.data(new ByteBufferDataInfo(BufferUtil.EMPTY_BUFFER, lastContent),endPoint.getIdleTimeout(),TimeUnit.MILLISECONDS,context,callback);
|
||||
}
|
||||
else
|
||||
// No data and no close so tell callback we are completed
|
||||
callback.completed(context);
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue