Fixes #755 - NPE in HttpChannelOverHTTP2.requestContent().
Fixed by recycling only channels that have completed normally by having read the request content and responded. Channels that don't read the request content won't be recycled, thus avoiding the NPE.
This commit is contained in:
parent
f8d81e9eeb
commit
78d27c9a28
|
@ -204,6 +204,7 @@ public class HTTP2ServerConnection extends HTTP2Connection implements Connection
|
|||
@Override
|
||||
public void recycle()
|
||||
{
|
||||
getStream().removeAttribute(IStream.CHANNEL_ATTRIBUTE);
|
||||
super.recycle();
|
||||
channels.offer(this);
|
||||
}
|
||||
|
@ -212,6 +213,7 @@ public class HTTP2ServerConnection extends HTTP2Connection implements Connection
|
|||
public void onCompleted()
|
||||
{
|
||||
super.onCompleted();
|
||||
if (!getStream().isReset())
|
||||
recycle();
|
||||
}
|
||||
|
||||
|
@ -219,11 +221,12 @@ public class HTTP2ServerConnection extends HTTP2Connection implements Connection
|
|||
public void reject()
|
||||
{
|
||||
IStream stream = getStream();
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("HTTP2 Request #{}/{} rejected", stream.getId(), Integer.toHexString(stream.getSession().hashCode()));
|
||||
stream.reset(new ResetFrame(stream.getId(), ErrorCode.ENHANCE_YOUR_CALM_ERROR.code), Callback.NOOP);
|
||||
// Consume the existing queued data frames to
|
||||
// avoid stalling the session flow control.
|
||||
getHttpTransport().consumeInput();
|
||||
recycle();
|
||||
consumeInput();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -191,6 +191,17 @@ public class HttpChannelOverHTTP2 extends HttpChannel
|
|||
|
||||
public Runnable requestContent(DataFrame frame, final Callback callback)
|
||||
{
|
||||
Stream stream = getStream();
|
||||
if (stream.isReset())
|
||||
{
|
||||
// Consume previously queued content to
|
||||
// enlarge the session flow control window.
|
||||
consumeInput();
|
||||
// Consume immediately this content.
|
||||
callback.succeeded();
|
||||
return null;
|
||||
}
|
||||
|
||||
// We must copy the data since we do not know when the
|
||||
// application will consume the bytes (we queue them by
|
||||
// calling onContent()), and the parsing will continue
|
||||
|
@ -233,7 +244,6 @@ public class HttpChannelOverHTTP2 extends HttpChannel
|
|||
|
||||
if (LOG.isDebugEnabled())
|
||||
{
|
||||
Stream stream = getStream();
|
||||
LOG.debug("HTTP2 Request #{}/{}: {} bytes of {} content, handle: {}",
|
||||
stream.getId(),
|
||||
Integer.toHexString(stream.getSession().hashCode()),
|
||||
|
@ -248,6 +258,11 @@ public class HttpChannelOverHTTP2 extends HttpChannel
|
|||
return handle || delayed ? this : null;
|
||||
}
|
||||
|
||||
protected void consumeInput()
|
||||
{
|
||||
getRequest().getHttpInput().consumeAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* If the associated response has the Expect header set to 100 Continue,
|
||||
* then accessing the input stream indicates that the handler/servlet
|
||||
|
|
|
@ -31,7 +31,6 @@ import org.eclipse.jetty.http2.frames.HeadersFrame;
|
|||
import org.eclipse.jetty.http2.frames.PushPromiseFrame;
|
||||
import org.eclipse.jetty.http2.frames.ResetFrame;
|
||||
import org.eclipse.jetty.server.Connector;
|
||||
import org.eclipse.jetty.server.HttpChannel;
|
||||
import org.eclipse.jetty.server.HttpTransport;
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
|
@ -193,17 +192,16 @@ public class HttpTransportOverHTTP2 implements HttpTransport
|
|||
// If the stream is not closed, it is still reading the request content.
|
||||
// Send a reset to the other end so that it stops sending data.
|
||||
if (!stream.isClosed())
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("HTTP2 Response #{}: unconsumed request content, resetting stream", stream.getId());
|
||||
stream.reset(new ResetFrame(stream.getId(), ErrorCode.CANCEL_STREAM_ERROR.code), Callback.NOOP);
|
||||
}
|
||||
|
||||
// Consume the existing queued data frames to
|
||||
// avoid stalling the session flow control.
|
||||
consumeInput();
|
||||
}
|
||||
|
||||
protected void consumeInput()
|
||||
{
|
||||
HttpChannel channel = (HttpChannel)stream.getAttribute(IStream.CHANNEL_ATTRIBUTE);
|
||||
channel.getRequest().getHttpInput().consumeAll();
|
||||
HttpChannelOverHTTP2 channel = (HttpChannelOverHTTP2)stream.getAttribute(IStream.CHANNEL_ATTRIBUTE);
|
||||
channel.consumeInput();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Loading…
Reference in New Issue