use of org.eclipse.jetty.http2.IStream in project jetty.project by eclipse.
the class HttpChannelOverHTTP2 method toString.
@Override
public String toString() {
IStream stream = getStream();
long streamId = -1;
if (stream != null)
streamId = stream.getId();
return String.format("%s#%d", super.toString(), getStream() == null ? -1 : streamId);
}
use of org.eclipse.jetty.http2.IStream in project jetty.project by eclipse.
the class HTTP2ServerSession method onHeaders.
@Override
public void onHeaders(HeadersFrame frame) {
if (LOG.isDebugEnabled())
LOG.debug("Received {}", frame);
MetaData metaData = frame.getMetaData();
if (metaData.isRequest()) {
IStream stream = createRemoteStream(frame.getStreamId());
if (stream != null) {
onStreamOpened(stream);
stream.process(frame, Callback.NOOP);
Stream.Listener listener = notifyNewStream(stream, frame);
stream.setListener(listener);
}
} else if (metaData.isResponse()) {
onConnectionFailure(ErrorCode.PROTOCOL_ERROR.code, "invalid_request");
} else {
// Trailers.
int streamId = frame.getStreamId();
IStream stream = getStream(streamId);
if (stream != null) {
stream.process(frame, Callback.NOOP);
notifyHeaders(stream, frame);
} else {
if (LOG.isDebugEnabled())
LOG.debug("Ignoring {}, stream #{} not found", frame, streamId);
}
}
}
use of org.eclipse.jetty.http2.IStream in project jetty.project by eclipse.
the class StreamResetTest method testStreamResetDoesNotCloseConnection.
@Test
public void testStreamResetDoesNotCloseConnection() throws Exception {
final CountDownLatch serverResetLatch = new CountDownLatch(1);
final CountDownLatch serverDataLatch = new CountDownLatch(1);
start(new ServerSessionListener.Adapter() {
@Override
public Stream.Listener onNewStream(Stream stream, HeadersFrame requestFrame) {
MetaData.Response response = new MetaData.Response(HttpVersion.HTTP_2, 200, new HttpFields());
HeadersFrame responseFrame = new HeadersFrame(stream.getId(), response, null, false);
Callback.Completable completable = new Callback.Completable();
stream.headers(responseFrame, completable);
return new Stream.Listener.Adapter() {
@Override
public void onData(Stream stream, DataFrame frame, Callback callback) {
callback.succeeded();
completable.thenRun(() -> stream.data(new DataFrame(stream.getId(), ByteBuffer.allocate(16), true), new Callback() {
@Override
public void succeeded() {
serverDataLatch.countDown();
}
}));
}
@Override
public void onReset(Stream s, ResetFrame frame) {
// Simulate that there is pending data to send.
IStream stream = (IStream) s;
stream.getSession().frames(stream, new Callback() {
@Override
public void failed(Throwable x) {
serverResetLatch.countDown();
}
}, new DataFrame(s.getId(), ByteBuffer.allocate(16), true));
}
};
}
});
Session client = newClient(new Session.Listener.Adapter());
MetaData.Request request1 = newRequest("GET", new HttpFields());
HeadersFrame requestFrame1 = new HeadersFrame(request1, null, false);
FuturePromise<Stream> promise1 = new FuturePromise<>();
final CountDownLatch stream1HeadersLatch = new CountDownLatch(1);
final CountDownLatch stream1DataLatch = new CountDownLatch(1);
client.newStream(requestFrame1, promise1, new Stream.Listener.Adapter() {
@Override
public void onHeaders(Stream stream, HeadersFrame frame) {
stream1HeadersLatch.countDown();
}
@Override
public void onData(Stream stream, DataFrame frame, Callback callback) {
callback.succeeded();
stream1DataLatch.countDown();
}
});
Stream stream1 = promise1.get(5, TimeUnit.SECONDS);
Assert.assertTrue(stream1HeadersLatch.await(5, TimeUnit.SECONDS));
MetaData.Request request2 = newRequest("GET", new HttpFields());
HeadersFrame requestFrame2 = new HeadersFrame(request2, null, false);
FuturePromise<Stream> promise2 = new FuturePromise<>();
final CountDownLatch stream2DataLatch = new CountDownLatch(1);
client.newStream(requestFrame2, promise2, new Stream.Listener.Adapter() {
@Override
public void onData(Stream stream, DataFrame frame, Callback callback) {
callback.succeeded();
stream2DataLatch.countDown();
}
});
Stream stream2 = promise2.get(5, TimeUnit.SECONDS);
ResetFrame resetFrame = new ResetFrame(stream1.getId(), ErrorCode.CANCEL_STREAM_ERROR.code);
stream1.reset(resetFrame, Callback.NOOP);
Assert.assertTrue(serverResetLatch.await(5, TimeUnit.SECONDS));
// Stream MUST NOT receive data sent by server after reset.
Assert.assertFalse(stream1DataLatch.await(1, TimeUnit.SECONDS));
// The other stream should still be working.
stream2.data(new DataFrame(stream2.getId(), ByteBuffer.allocate(16), true), Callback.NOOP);
Assert.assertTrue(serverDataLatch.await(5, TimeUnit.SECONDS));
Assert.assertTrue(stream2DataLatch.await(5, TimeUnit.SECONDS));
}
use of org.eclipse.jetty.http2.IStream in project jetty.project by eclipse.
the class HTTP2ClientSession method onPushPromise.
@Override
public void onPushPromise(PushPromiseFrame frame) {
if (LOG.isDebugEnabled())
LOG.debug("Received {}", frame);
int streamId = frame.getStreamId();
int pushStreamId = frame.getPromisedStreamId();
IStream stream = getStream(streamId);
if (stream == null) {
if (LOG.isDebugEnabled())
LOG.debug("Ignoring {}, stream #{} not found", frame, streamId);
} else {
IStream pushStream = createRemoteStream(pushStreamId);
pushStream.process(frame, Callback.NOOP);
Stream.Listener listener = notifyPush(stream, pushStream, frame);
pushStream.setListener(listener);
}
}
use of org.eclipse.jetty.http2.IStream in project jetty.project by eclipse.
the class SimpleFlowControlStrategy method onDataConsumed.
@Override
public void onDataConsumed(ISession session, IStream stream, int length) {
if (length <= 0)
return;
// This is the simple algorithm for flow control.
// This method is called when a whole flow controlled frame has been consumed.
// We send a WindowUpdate every time, even if the frame was very small.
WindowUpdateFrame sessionFrame = new WindowUpdateFrame(0, length);
session.updateRecvWindow(length);
if (LOG.isDebugEnabled())
LOG.debug("Data consumed, increased session recv window by {} for {}", length, session);
Frame[] streamFrame = Frame.EMPTY_ARRAY;
if (stream != null) {
if (stream.isClosed()) {
if (LOG.isDebugEnabled())
LOG.debug("Data consumed, ignoring update stream recv window by {} for closed {}", length, stream);
} else {
streamFrame = new Frame[1];
streamFrame[0] = new WindowUpdateFrame(stream.getId(), length);
stream.updateRecvWindow(length);
if (LOG.isDebugEnabled())
LOG.debug("Data consumed, increased stream recv window by {} for {}", length, stream);
}
}
session.frames(stream, Callback.NOOP, sessionFrame, streamFrame);
}
Aggregations