use of org.eclipse.jetty.util.FuturePromise in project jetty.project by eclipse.
the class StreamResetTest method testStreamReceivingResetIsRemoved.
@Test
public void testStreamReceivingResetIsRemoved() throws Exception {
final AtomicReference<Stream> streamRef = new AtomicReference<>();
final CountDownLatch resetLatch = new CountDownLatch(1);
start(new ServerSessionListener.Adapter() {
@Override
public Stream.Listener onNewStream(Stream stream, HeadersFrame frame) {
return new Stream.Listener.Adapter() {
@Override
public void onReset(Stream stream, ResetFrame frame) {
Assert.assertNotNull(stream);
Assert.assertTrue(stream.isReset());
streamRef.set(stream);
resetLatch.countDown();
}
};
}
});
Session client = newClient(new Session.Listener.Adapter());
MetaData.Request request = newRequest("GET", new HttpFields());
HeadersFrame requestFrame = new HeadersFrame(request, null, false);
FuturePromise<Stream> promise = new FuturePromise<>();
client.newStream(requestFrame, promise, new Stream.Listener.Adapter());
Stream stream = promise.get(5, TimeUnit.SECONDS);
ResetFrame resetFrame = new ResetFrame(stream.getId(), ErrorCode.CANCEL_STREAM_ERROR.code);
stream.reset(resetFrame, Callback.NOOP);
Assert.assertTrue(resetLatch.await(5, TimeUnit.SECONDS));
// Wait a while to let the server remove the
// stream after returning from onReset().
Thread.sleep(1000);
Stream serverStream = streamRef.get();
Assert.assertEquals(0, serverStream.getSession().getStreams().size());
}
use of org.eclipse.jetty.util.FuturePromise in project jetty.project by eclipse.
the class AsyncIOTest method testSomeContentAvailableAfterServiceReturns.
@Test
public void testSomeContentAvailableAfterServiceReturns() throws Exception {
final AtomicInteger count = new AtomicInteger();
start(new HttpServlet() {
@Override
protected void service(final HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
final AsyncContext asyncContext = request.startAsync();
asyncContext.setTimeout(0);
request.getInputStream().setReadListener(new EmptyReadListener() {
@Override
public void onDataAvailable() throws IOException {
count.incrementAndGet();
ServletInputStream input = request.getInputStream();
while (input.isReady()) {
int read = input.read();
if (read < 0)
break;
}
if (input.isFinished())
asyncContext.complete();
}
});
}
});
Session session = newClient(new Session.Listener.Adapter());
HttpFields fields = new HttpFields();
MetaData.Request metaData = newRequest("GET", fields);
HeadersFrame frame = new HeadersFrame(metaData, null, false);
final CountDownLatch latch = new CountDownLatch(1);
FuturePromise<Stream> promise = new FuturePromise<>();
session.newStream(frame, promise, new Stream.Listener.Adapter() {
@Override
public void onHeaders(Stream stream, HeadersFrame frame) {
if (frame.isEndStream())
latch.countDown();
}
});
Stream stream = promise.get(5, TimeUnit.SECONDS);
// Wait until service() returns.
Thread.sleep(1000);
stream.data(new DataFrame(stream.getId(), ByteBuffer.allocate(1), false), Callback.NOOP);
// Wait until onDataAvailable() returns.
Thread.sleep(1000);
stream.data(new DataFrame(stream.getId(), ByteBuffer.allocate(1), true), Callback.NOOP);
Assert.assertTrue(latch.await(5, TimeUnit.SECONDS));
// Make sure onDataAvailable() has been called twice
Assert.assertEquals(2, count.get());
}
use of org.eclipse.jetty.util.FuturePromise in project jetty.project by eclipse.
the class StreamCloseTest method testRequestClosedRemotelyClosesStream.
@Test
public void testRequestClosedRemotelyClosesStream() throws Exception {
final CountDownLatch latch = new CountDownLatch(1);
start(new ServerSessionListener.Adapter() {
@Override
public Stream.Listener onNewStream(Stream stream, HeadersFrame frame) {
Assert.assertTrue(((HTTP2Stream) stream).isRemotelyClosed());
latch.countDown();
return null;
}
});
Session session = newClient(new Session.Listener.Adapter());
HeadersFrame frame = new HeadersFrame(newRequest("GET", new HttpFields()), null, true);
FuturePromise<Stream> promise = new FuturePromise<>();
session.newStream(frame, promise, null);
Stream stream = promise.get(5, TimeUnit.SECONDS);
Assert.assertTrue(((HTTP2Stream) stream).isLocallyClosed());
Assert.assertTrue(latch.await(5, TimeUnit.SECONDS));
}
use of org.eclipse.jetty.util.FuturePromise in project jetty.project by eclipse.
the class HTTP2Test method testMaxConcurrentStreams.
@Test
public void testMaxConcurrentStreams() throws Exception {
int maxStreams = 2;
start(new ServerSessionListener.Adapter() {
@Override
public Map<Integer, Integer> onPreface(Session session) {
Map<Integer, Integer> settings = new HashMap<>(1);
settings.put(SettingsFrame.MAX_CONCURRENT_STREAMS, maxStreams);
return settings;
}
@Override
public Stream.Listener onNewStream(Stream stream, HeadersFrame frame) {
MetaData.Response response = new MetaData.Response(HttpVersion.HTTP_2, HttpStatus.OK_200, new HttpFields(), 0);
stream.headers(new HeadersFrame(stream.getId(), response, null, true), Callback.NOOP);
return null;
}
});
CountDownLatch settingsLatch = new CountDownLatch(1);
Session session = newClient(new Session.Listener.Adapter() {
@Override
public void onSettings(Session session, SettingsFrame frame) {
settingsLatch.countDown();
}
});
Assert.assertTrue(settingsLatch.await(5, TimeUnit.SECONDS));
MetaData.Request request1 = newRequest("GET", new HttpFields());
FuturePromise<Stream> promise1 = new FuturePromise<>();
CountDownLatch exchangeLatch1 = new CountDownLatch(2);
session.newStream(new HeadersFrame(request1, null, false), promise1, new Stream.Listener.Adapter() {
@Override
public void onHeaders(Stream stream, HeadersFrame frame) {
if (frame.isEndStream())
exchangeLatch1.countDown();
}
});
Stream stream1 = promise1.get(5, TimeUnit.SECONDS);
MetaData.Request request2 = newRequest("GET", new HttpFields());
FuturePromise<Stream> promise2 = new FuturePromise<>();
CountDownLatch exchangeLatch2 = new CountDownLatch(2);
session.newStream(new HeadersFrame(request2, null, false), promise2, new Stream.Listener.Adapter() {
@Override
public void onHeaders(Stream stream, HeadersFrame frame) {
if (frame.isEndStream())
exchangeLatch2.countDown();
}
});
Stream stream2 = promise2.get(5, TimeUnit.SECONDS);
// The third stream must not be created.
MetaData.Request request3 = newRequest("GET", new HttpFields());
CountDownLatch maxStreamsLatch = new CountDownLatch(1);
session.newStream(new HeadersFrame(request3, null, false), new Promise.Adapter<Stream>() {
@Override
public void failed(Throwable x) {
if (x instanceof IllegalStateException)
maxStreamsLatch.countDown();
}
}, new Stream.Listener.Adapter());
Assert.assertTrue(maxStreamsLatch.await(5, TimeUnit.SECONDS));
Assert.assertEquals(2, session.getStreams().size());
// End the second stream.
stream2.data(new DataFrame(stream2.getId(), BufferUtil.EMPTY_BUFFER, true), new Callback() {
@Override
public void succeeded() {
exchangeLatch2.countDown();
}
});
Assert.assertTrue(exchangeLatch2.await(5, TimeUnit.SECONDS));
Assert.assertEquals(1, session.getStreams().size());
// Create a fourth stream.
MetaData.Request request4 = newRequest("GET", new HttpFields());
CountDownLatch exchangeLatch4 = new CountDownLatch(2);
session.newStream(new HeadersFrame(request4, null, true), new Promise.Adapter<Stream>() {
@Override
public void succeeded(Stream result) {
exchangeLatch4.countDown();
}
}, new Stream.Listener.Adapter() {
@Override
public void onHeaders(Stream stream, HeadersFrame frame) {
if (frame.isEndStream())
exchangeLatch4.countDown();
}
});
Assert.assertTrue(exchangeLatch4.await(5, TimeUnit.SECONDS));
Assert.assertEquals(1, session.getStreams().size());
// End the first stream.
stream1.data(new DataFrame(stream1.getId(), BufferUtil.EMPTY_BUFFER, true), new Callback() {
@Override
public void succeeded() {
exchangeLatch1.countDown();
}
});
Assert.assertTrue(exchangeLatch2.await(5, TimeUnit.SECONDS));
Assert.assertEquals(0, session.getStreams().size());
}
use of org.eclipse.jetty.util.FuturePromise in project jetty.project by eclipse.
the class AsyncIOServletTest method testAsyncReadEarlyEOF.
@Test
public void testAsyncReadEarlyEOF() throws Exception {
// SSLEngine receives the close alert from the client, and when
// the server passes the response to encrypt and write, SSLEngine
// only generates the close alert back, without encrypting the
// response, so we need to skip the transports over TLS.
Assume.assumeThat(transport, Matchers.not(Matchers.isOneOf(Transport.HTTPS, Transport.H2)));
String content = "jetty";
int responseCode = HttpStatus.NO_CONTENT_204;
CountDownLatch readLatch = new CountDownLatch(content.length());
CountDownLatch errorLatch = new CountDownLatch(1);
start(new HttpServlet() {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
AsyncContext asyncContext = request.startAsync();
ServletInputStream input = request.getInputStream();
input.setReadListener(new ReadListener() {
@Override
public void onDataAvailable() throws IOException {
while (input.isReady() && !input.isFinished()) {
int read = input.read();
// System.err.printf("%x%n", read);
readLatch.countDown();
}
}
@Override
public void onAllDataRead() throws IOException {
}
@Override
public void onError(Throwable x) {
response.setStatus(responseCode);
asyncContext.complete();
errorLatch.countDown();
}
});
}
});
CountDownLatch responseLatch = new CountDownLatch(1);
DeferredContentProvider contentProvider = new DeferredContentProvider();
contentProvider.offer(ByteBuffer.wrap(content.getBytes(StandardCharsets.UTF_8)));
org.eclipse.jetty.client.api.Request request = client.newRequest(newURI()).method(HttpMethod.POST).path(servletPath).content(contentProvider).onResponseSuccess(response -> responseLatch.countDown());
Destination destination = client.getDestination(getScheme(), "localhost", connector.getLocalPort());
FuturePromise<org.eclipse.jetty.client.api.Connection> promise = new FuturePromise<>();
destination.newConnection(promise);
org.eclipse.jetty.client.api.Connection connection = promise.get(5, TimeUnit.SECONDS);
CountDownLatch clientLatch = new CountDownLatch(1);
connection.send(request, result -> {
assertThat(result.getResponse().getStatus(), Matchers.equalTo(responseCode));
clientLatch.countDown();
});
assertTrue(readLatch.await(5, TimeUnit.SECONDS));
switch(transport) {
case HTTP:
case HTTPS:
((HttpConnectionOverHTTP) connection).getEndPoint().shutdownOutput();
break;
case H2C:
case H2:
// In case of HTTP/2, we not only send the request, but also the preface and
// SETTINGS frames. SETTINGS frame need to be replied, so we want to wait to
// write the reply before shutting output down, so that the test does not fail.
Thread.sleep(1000);
Session session = ((HttpConnectionOverHTTP2) connection).getSession();
((HTTP2Session) session).getEndPoint().shutdownOutput();
break;
default:
Assert.fail();
}
// Wait for the response to arrive before finishing the request.
assertTrue(responseLatch.await(5, TimeUnit.SECONDS));
contentProvider.close();
assertTrue(errorLatch.await(5, TimeUnit.SECONDS));
assertTrue(clientLatch.await(5, TimeUnit.SECONDS));
}
Aggregations