use of org.eclipse.jetty.http2.api.Stream in project jetty.project by eclipse.
the class HTTP2ServerConnection method onSessionTimeout.
public boolean onSessionTimeout(Throwable failure) {
ISession session = getSession();
boolean result = true;
for (Stream stream : session.getStreams()) {
HttpChannelOverHTTP2 channel = (HttpChannelOverHTTP2) stream.getAttribute(IStream.CHANNEL_ATTRIBUTE);
if (channel != null)
result &= !channel.isRequestHandled();
}
if (LOG.isDebugEnabled())
LOG.debug("{} idle timeout on {}: {}", result ? "Processed" : "Ignored", session, failure);
return result;
}
use of org.eclipse.jetty.http2.api.Stream in project jetty.project by eclipse.
the class HttpChannelOverHTTP2 method onPushRequest.
public Runnable onPushRequest(MetaData.Request request) {
try {
onRequest(request);
getRequest().setAttribute("org.eclipse.jetty.pushed", Boolean.TRUE);
onContentComplete();
onRequestComplete();
if (LOG.isDebugEnabled()) {
Stream stream = getStream();
LOG.debug("HTTP2 PUSH Request #{}/{}:{}{} {} {}{}{}", stream.getId(), Integer.toHexString(stream.getSession().hashCode()), System.lineSeparator(), request.getMethod(), request.getURI(), request.getHttpVersion(), System.lineSeparator(), request.getFields());
}
return this;
} catch (BadMessageException x) {
onBadMessage(x.getCode(), x.getReason());
return null;
} catch (Throwable x) {
onBadMessage(HttpStatus.INTERNAL_SERVER_ERROR_500, null);
return null;
}
}
use of org.eclipse.jetty.http2.api.Stream in project jetty.project by eclipse.
the class HttpChannelOverHTTP2 method onRequest.
public Runnable onRequest(HeadersFrame frame) {
try {
MetaData.Request request = (MetaData.Request) frame.getMetaData();
HttpFields fields = request.getFields();
// pseudo-header, so we need to synthesize a Host header.
if (!fields.contains(HttpHeader.HOST)) {
String authority = request.getURI().getAuthority();
if (authority != null) {
// Lower-case to be consistent with other HTTP/2 headers.
fields.put("host", authority);
}
}
_expect100Continue = fields.contains(HttpHeader.EXPECT, HttpHeaderValue.CONTINUE.asString());
HttpFields response = getResponse().getHttpFields();
if (getHttpConfiguration().getSendServerVersion())
response.add(SERVER_VERSION);
if (getHttpConfiguration().getSendXPoweredBy())
response.add(POWERED_BY);
onRequest(request);
boolean endStream = frame.isEndStream();
if (endStream) {
onContentComplete();
onRequestComplete();
}
_delayedUntilContent = getHttpConfiguration().isDelayDispatchUntilContent() && !endStream && !_expect100Continue;
_handled = !_delayedUntilContent;
if (LOG.isDebugEnabled()) {
Stream stream = getStream();
LOG.debug("HTTP2 Request #{}/{}, delayed={}:{}{} {} {}{}{}", stream.getId(), Integer.toHexString(stream.getSession().hashCode()), _delayedUntilContent, System.lineSeparator(), request.getMethod(), request.getURI(), request.getHttpVersion(), System.lineSeparator(), fields);
}
return _delayedUntilContent ? null : this;
} catch (BadMessageException x) {
onBadMessage(x.getCode(), x.getReason());
return null;
} catch (Throwable x) {
onBadMessage(HttpStatus.INTERNAL_SERVER_ERROR_500, null);
return null;
}
}
use of org.eclipse.jetty.http2.api.Stream in project jetty.project by eclipse.
the class HttpChannelOverHTTP2 method onRequestContent.
public Runnable onRequestContent(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
// as soon as this method returns, eventually leading
// to reusing the underlying buffer for more reads.
final ByteBufferPool byteBufferPool = getByteBufferPool();
ByteBuffer original = frame.getData();
int length = original.remaining();
final ByteBuffer copy = byteBufferPool.acquire(length, original.isDirect());
BufferUtil.clearToFill(copy);
copy.put(original);
BufferUtil.flipToFlush(copy, 0);
boolean handle = onContent(new HttpInput.Content(copy) {
@Override
public InvocationType getInvocationType() {
return callback.getInvocationType();
}
@Override
public void succeeded() {
byteBufferPool.release(copy);
callback.succeeded();
}
@Override
public void failed(Throwable x) {
byteBufferPool.release(copy);
callback.failed(x);
}
});
boolean endStream = frame.isEndStream();
if (endStream) {
boolean handle_content = onContentComplete();
boolean handle_request = onRequestComplete();
handle |= handle_content | handle_request;
}
if (LOG.isDebugEnabled()) {
LOG.debug("HTTP2 Request #{}/{}: {} bytes of {} content, handle: {}", stream.getId(), Integer.toHexString(stream.getSession().hashCode()), length, endStream ? "last" : "some", handle);
}
boolean wasDelayed = _delayedUntilContent;
_delayedUntilContent = false;
if (wasDelayed)
_handled = true;
return handle || wasDelayed ? this : null;
}
use of org.eclipse.jetty.http2.api.Stream in project jetty.project by eclipse.
the class CloseTest method testServerSendsGoAwayClientDoesNotCloseServerIdleTimeout.
@Test
public void testServerSendsGoAwayClientDoesNotCloseServerIdleTimeout() throws Exception {
final long idleTimeout = 1000;
final AtomicReference<Session> sessionRef = new AtomicReference<>();
startServer(new ServerSessionListener.Adapter() {
@Override
public Stream.Listener onNewStream(Stream stream, HeadersFrame frame) {
stream.setIdleTimeout(10 * idleTimeout);
sessionRef.set(stream.getSession());
MetaData.Response response = new MetaData.Response(HttpVersion.HTTP_2, 200, new HttpFields());
stream.headers(new HeadersFrame(stream.getId(), response, null, true), Callback.NOOP);
stream.getSession().close(ErrorCode.NO_ERROR.code, "OK", Callback.NOOP);
return null;
}
});
connector.setIdleTimeout(idleTimeout);
ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
generator.control(lease, new PrefaceFrame());
generator.control(lease, new SettingsFrame(new HashMap<>(), false));
MetaData.Request metaData = newRequest("GET", new HttpFields());
generator.control(lease, new HeadersFrame(1, metaData, null, true));
try (Socket client = new Socket("localhost", connector.getLocalPort())) {
OutputStream output = client.getOutputStream();
for (ByteBuffer buffer : lease.getByteBuffers()) {
output.write(BufferUtil.toArray(buffer));
}
final CountDownLatch responseLatch = new CountDownLatch(1);
final CountDownLatch closeLatch = new CountDownLatch(1);
Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() {
@Override
public void onHeaders(HeadersFrame frame) {
responseLatch.countDown();
}
@Override
public void onGoAway(GoAwayFrame frame) {
closeLatch.countDown();
}
}, 4096, 8192);
parseResponse(client, parser);
Assert.assertTrue(responseLatch.await(5, TimeUnit.SECONDS));
Assert.assertTrue(closeLatch.await(5, TimeUnit.SECONDS));
// Don't close the connection.
// Wait for the server to idle timeout.
Thread.sleep(2 * idleTimeout);
// Client received the TCP FIN from server.
Assert.assertEquals(-1, client.getInputStream().read());
// Server is closed.
Session session = sessionRef.get();
Assert.assertTrue(session.isClosed());
Assert.assertTrue(((HTTP2Session) session).isDisconnected());
}
}
Aggregations