use of java.util.concurrent.atomic.AtomicReference in project jetty.project by eclipse.
the class CloseTest method testClientSendsGoAwayButDoesNotCloseConnectionServerCloses.
@Test
public void testClientSendsGoAwayButDoesNotCloseConnectionServerCloses() throws Exception {
final AtomicReference<Session> sessionRef = new AtomicReference<>();
startServer(new ServerSessionListener.Adapter() {
@Override
public Stream.Listener onNewStream(Stream stream, HeadersFrame frame) {
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);
return null;
}
});
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));
generator.control(lease, new GoAwayFrame(1, ErrorCode.NO_ERROR.code, "OK".getBytes("UTF-8")));
try (Socket client = new Socket("localhost", connector.getLocalPort())) {
OutputStream output = client.getOutputStream();
for (ByteBuffer buffer : lease.getByteBuffers()) {
output.write(BufferUtil.toArray(buffer));
}
// Don't close the connection; the server should close.
final CountDownLatch responseLatch = new CountDownLatch(1);
Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() {
@Override
public void onHeaders(HeadersFrame frame) {
// Even if we sent the GO_AWAY immediately after the
// HEADERS, the server is able to send us the response.
responseLatch.countDown();
}
}, 4096, 8192);
parseResponse(client, parser);
Assert.assertTrue(responseLatch.await(5, TimeUnit.SECONDS));
// Wait for the server to close.
Thread.sleep(1000);
// 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());
}
}
use of java.util.concurrent.atomic.AtomicReference in project jetty.project by eclipse.
the class SelectChannelEndPointInterestsTest method testReadBlockedThenWriteBlockedThenReadableThenWritable.
@Test
public void testReadBlockedThenWriteBlockedThenReadableThenWritable() throws Exception {
final AtomicInteger size = new AtomicInteger(1024 * 1024);
final AtomicReference<Exception> failure = new AtomicReference<>();
final CountDownLatch latch1 = new CountDownLatch(1);
final CountDownLatch latch2 = new CountDownLatch(1);
final AtomicBoolean writeBlocked = new AtomicBoolean();
init(new Interested() {
@Override
public void onFillable(EndPoint endPoint, AbstractConnection connection) {
ByteBuffer input = BufferUtil.allocate(2);
int read = fill(endPoint, input);
if (read == 1) {
byte b = input.get();
if (b == 1) {
connection.fillInterested();
ByteBuffer output = ByteBuffer.allocate(size.get());
endPoint.write(new Callback() {
}, output);
latch1.countDown();
} else {
latch2.countDown();
}
} else {
failure.set(new Exception("Unexpectedly read " + read + " bytes"));
}
}
@Override
public void onIncompleteFlush() {
writeBlocked.set(true);
}
private int fill(EndPoint endPoint, ByteBuffer buffer) {
try {
return endPoint.fill(buffer);
} catch (IOException x) {
failure.set(x);
return 0;
}
}
});
Socket client = new Socket();
client.connect(connector.getLocalAddress());
client.setSoTimeout(5000);
SocketChannel server = connector.accept();
server.configureBlocking(false);
selectorManager.accept(server);
OutputStream clientOutput = client.getOutputStream();
clientOutput.write(1);
clientOutput.flush();
Assert.assertTrue(latch1.await(5, TimeUnit.SECONDS));
// We do not read to keep the socket write blocked
clientOutput.write(2);
clientOutput.flush();
Assert.assertTrue(latch2.await(5, TimeUnit.SECONDS));
// Sleep before reading to allow waking up the server only for read
Thread.sleep(1000);
// Now read what was written, waking up the server for write
InputStream clientInput = client.getInputStream();
while (size.getAndDecrement() > 0) clientInput.read();
client.close();
Assert.assertNull(failure.get());
}
use of java.util.concurrent.atomic.AtomicReference in project jetty.project by eclipse.
the class NetworkTrafficListenerTest method testTrafficWithBigRequestContentOnPersistentConnection.
@Test
public void testTrafficWithBigRequestContentOnPersistentConnection() throws Exception {
initConnector(new AbstractHandler() {
@Override
public void handle(String uri, Request request, HttpServletRequest servletRequest, HttpServletResponse servletResponse) throws IOException, ServletException {
// Read and discard the request body to make the test more
// reliable, otherwise there is a race between request body
// upload and response download
InputStream input = servletRequest.getInputStream();
byte[] buffer = new byte[4096];
while (true) {
int read = input.read(buffer);
if (read < 0)
break;
}
request.setHandled(true);
}
});
final AtomicReference<String> incomingData = new AtomicReference<>("");
final AtomicReference<String> outgoingData = new AtomicReference<>("");
final CountDownLatch outgoingLatch = new CountDownLatch(1);
connector.addNetworkTrafficListener(new NetworkTrafficListener.Adapter() {
@Override
public void incoming(Socket socket, ByteBuffer bytes) {
incomingData.set(incomingData.get() + BufferUtil.toString(bytes, StandardCharsets.UTF_8));
}
@Override
public void outgoing(Socket socket, ByteBuffer bytes) {
outgoingData.set(outgoingData.get() + BufferUtil.toString(bytes, StandardCharsets.UTF_8));
outgoingLatch.countDown();
}
});
int port = connector.getLocalPort();
// Generate 32 KiB of request content
String requestContent = "0123456789ABCDEF";
for (int i = 0; i < 11; ++i) requestContent += requestContent;
String request = "" + "POST / HTTP/1.1\r\n" + "Host: localhost:" + port + "\r\n" + "Content-Type: text/plain\r\n" + "Content-Length: " + requestContent.length() + "\r\n" + "\r\n" + requestContent;
String expectedResponse = "" + "HTTP/1.1 200 OK\r\n" + "Content-Length: 0\r\n" + "\r\n";
Socket socket = new Socket("localhost", port);
OutputStream output = socket.getOutputStream();
output.write(request.getBytes(StandardCharsets.UTF_8));
output.flush();
assertTrue(outgoingLatch.await(1, TimeUnit.SECONDS));
assertEquals(expectedResponse, outgoingData.get());
byte[] responseBytes = readResponse(socket);
String response = new String(responseBytes, StandardCharsets.UTF_8);
assertEquals(expectedResponse, response);
assertEquals(request, incomingData.get());
socket.close();
}
use of java.util.concurrent.atomic.AtomicReference in project jetty.project by eclipse.
the class NetworkTrafficListenerTest method testTrafficWithRequestContentWithResponseRedirectOnPersistentConnection.
@Test
public void testTrafficWithRequestContentWithResponseRedirectOnPersistentConnection() throws Exception {
final String location = "/redirect";
initConnector(new AbstractHandler() {
@Override
public void handle(String uri, Request request, HttpServletRequest servletRequest, HttpServletResponse servletResponse) throws IOException, ServletException {
request.setHandled(true);
servletResponse.sendRedirect(location);
}
});
final AtomicReference<String> incomingData = new AtomicReference<>();
final CountDownLatch incomingLatch = new CountDownLatch(1);
final AtomicReference<String> outgoingData = new AtomicReference<>("");
final CountDownLatch outgoingLatch = new CountDownLatch(1);
connector.addNetworkTrafficListener(new NetworkTrafficListener.Adapter() {
@Override
public void incoming(Socket socket, ByteBuffer bytes) {
incomingData.set(BufferUtil.toString(bytes, StandardCharsets.UTF_8));
incomingLatch.countDown();
}
@Override
public void outgoing(Socket socket, ByteBuffer bytes) {
outgoingData.set(outgoingData.get() + BufferUtil.toString(bytes, StandardCharsets.UTF_8));
outgoingLatch.countDown();
}
});
int port = connector.getLocalPort();
String requestContent = "a=1&b=2";
String request = "" + "POST / HTTP/1.1\r\n" + "Host: localhost:" + port + "\r\n" + "Content-Type: application/x-www-form-urlencoded\r\n" + "Content-Length: " + requestContent.length() + "\r\n" + "\r\n" + requestContent;
String expectedResponse = "" + "HTTP/1.1 302 Found\r\n" + "Location: http://localhost:" + port + location + "\r\n" + "Content-Length: 0\r\n" + "\r\n";
Socket socket = new Socket("localhost", port);
OutputStream output = socket.getOutputStream();
output.write(request.getBytes(StandardCharsets.UTF_8));
output.flush();
assertTrue(incomingLatch.await(1, TimeUnit.SECONDS));
assertEquals(request, incomingData.get());
assertTrue(outgoingLatch.await(1, TimeUnit.SECONDS));
assertEquals(expectedResponse, outgoingData.get());
byte[] responseBytes = readResponse(socket);
String response = new String(responseBytes, StandardCharsets.UTF_8);
assertEquals(expectedResponse, response);
socket.close();
}
use of java.util.concurrent.atomic.AtomicReference in project jetty.project by eclipse.
the class NetworkTrafficListenerTest method testTrafficWithNoResponseContentOnNonPersistentConnection.
@Test
public void testTrafficWithNoResponseContentOnNonPersistentConnection() throws Exception {
initConnector(new AbstractHandler() {
@Override
public void handle(String uri, Request request, HttpServletRequest servletRequest, HttpServletResponse servletResponse) throws IOException, ServletException {
request.setHandled(true);
}
});
final AtomicReference<String> incomingData = new AtomicReference<>();
final CountDownLatch incomingLatch = new CountDownLatch(1);
final AtomicReference<String> outgoingData = new AtomicReference<>("");
final CountDownLatch outgoingLatch = new CountDownLatch(1);
connector.addNetworkTrafficListener(new NetworkTrafficListener.Adapter() {
@Override
public void incoming(Socket socket, ByteBuffer bytes) {
incomingData.set(BufferUtil.toString(bytes, StandardCharsets.UTF_8));
incomingLatch.countDown();
}
@Override
public void outgoing(Socket socket, ByteBuffer bytes) {
outgoingData.set(outgoingData.get() + BufferUtil.toString(bytes, StandardCharsets.UTF_8));
outgoingLatch.countDown();
}
});
int port = connector.getLocalPort();
String request = "" + "GET / HTTP/1.1\r\n" + "Host: localhost:" + port + "\r\n" + "Connection: close\r\n" + "\r\n";
String expectedResponse = "" + "HTTP/1.1 200 OK\r\n" + "Connection: close\r\n" + "\r\n";
Socket socket = new Socket("localhost", port);
OutputStream output = socket.getOutputStream();
output.write(request.getBytes(StandardCharsets.UTF_8));
output.flush();
assertTrue(incomingLatch.await(1, TimeUnit.SECONDS));
assertEquals(request, incomingData.get());
assertTrue(outgoingLatch.await(1, TimeUnit.SECONDS));
assertEquals(expectedResponse, outgoingData.get());
byte[] responseBytes = readResponse(socket);
String response = new String(responseBytes, StandardCharsets.UTF_8);
assertEquals(expectedResponse, response);
socket.close();
}
Aggregations