use of io.undertow.client.UndertowClient in project undertow by undertow-io.
the class Http2EndExchangeTestCase method testHttp2EndExchangeWithBrokenConnection.
@Test
public void testHttp2EndExchangeWithBrokenConnection() throws Exception {
int port = DefaultServer.getHostPort("default");
final CountDownLatch requestStartedLatch = new CountDownLatch(1);
final CompletableFuture<String> testResult = new CompletableFuture<>();
Undertow server = Undertow.builder().addHttpsListener(port + 1, DefaultServer.getHostAddress("default"), DefaultServer.getServerSslContext()).setServerOption(UndertowOptions.ENABLE_HTTP2, true).setSocketOption(Options.REUSE_ADDRESSES, true).setHandler(new BlockingHandler(new HttpHandler() {
@Override
public void handleRequest(HttpServerExchange exchange) throws Exception {
if (!exchange.getProtocol().equals(Protocols.HTTP_2_0)) {
testResult.completeExceptionally(new RuntimeException("Not HTTP/2 request"));
return;
}
requestStartedLatch.countDown();
log.debug("Received Request");
// do some pretend work
Thread.sleep(2000);
if (exchange.isComplete()) {
testResult.complete("FAILED, exchange ended in the background");
return;
}
try {
exchange.getOutputStream().write("Bogus Data".getBytes(StandardCharsets.UTF_8));
exchange.getOutputStream().flush();
testResult.complete("FAILED, should not have completed successfully");
return;
} catch (IOException expected) {
}
if (!exchange.isComplete()) {
testResult.complete("Failed, should have completed the exchange");
} else {
testResult.complete("PASSED");
}
}
})).build();
server.start();
try {
ADDRESS = new URI("https://" + DefaultServer.getHostAddress() + ":" + (port + 1));
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
// Create xnio worker
final Xnio xnio = Xnio.getInstance();
final XnioWorker xnioWorker = xnio.createWorker(null, DEFAULT_OPTIONS);
try {
final UndertowClient client = createClient();
final ClientConnection connection = client.connect(ADDRESS, xnioWorker, new UndertowXnioSsl(xnioWorker.getXnio(), OptionMap.EMPTY, DefaultServer.getClientSSLContext()), DefaultServer.getBufferPool(), OptionMap.create(UndertowOptions.ENABLE_HTTP2, true)).get();
try {
connection.getIoThread().execute(new Runnable() {
@Override
public void run() {
final ClientRequest request = new ClientRequest().setMethod(Methods.GET).setPath(MESSAGE);
request.getRequestHeaders().put(Headers.HOST, DefaultServer.getHostAddress());
connection.sendRequest(request, new ClientCallback<ClientExchange>() {
@Override
public void completed(ClientExchange result) {
try {
log.debug("Callback invoked");
new Thread(new Runnable() {
@Override
public void run() {
try {
requestStartedLatch.await(10, TimeUnit.SECONDS);
result.getRequestChannel().getIoThread().execute(new Runnable() {
@Override
public void run() {
IoUtils.safeClose(result.getConnection());
log.debug("Closed Connection");
}
});
} catch (Exception e) {
testResult.completeExceptionally(e);
}
}
}).start();
} catch (Exception e) {
testResult.completeExceptionally(e);
}
}
@Override
public void failed(IOException e) {
testResult.completeExceptionally(e);
}
});
}
});
Assert.assertEquals("PASSED", testResult.get(10, TimeUnit.SECONDS));
} finally {
IoUtils.safeClose(connection);
}
} finally {
stopWorker(xnioWorker);
server.stop();
// sleep 1 s to prevent BindException (Address already in use) when running the CI
try {
Thread.sleep(1000);
} catch (InterruptedException ignore) {
}
}
}
use of io.undertow.client.UndertowClient in project undertow by undertow-io.
the class PushPromisesTestCase method testPushPromises.
@Test
public void testPushPromises() throws Exception {
URI uri = new URI(DefaultServer.getDefaultServerSSLAddress());
final UndertowClient client = UndertowClient.getInstance();
final Map<String, ClientResponse> responses = new ConcurrentHashMap<>();
final CountDownLatch latch = new CountDownLatch(3);
final ClientConnection connection = client.connect(uri, worker, new UndertowXnioSsl(worker.getXnio(), OptionMap.EMPTY, DefaultServer.getClientSSLContext()), DefaultServer.getBufferPool(), OptionMap.create(UndertowOptions.ENABLE_HTTP2, true)).get();
try {
connection.getIoThread().execute(new Runnable() {
@Override
public void run() {
final ClientRequest request = new ClientRequest().setMethod(Methods.GET).setPath("/push-example/index.html");
request.getRequestHeaders().put(Headers.HOST, DefaultServer.getHostAddress());
connection.sendRequest(request, createClientCallback(responses, latch));
}
});
latch.await(10, TimeUnit.SECONDS);
Assert.assertEquals(3, responses.size());
Assert.assertTrue(responses.containsKey("/push-example/index.html"));
Assert.assertEquals(StatusCodes.OK, responses.get("/push-example/index.html").getResponseCode());
Assert.assertNotNull(responses.get("/push-example/index.html").getAttachment(RESPONSE_BODY));
Assert.assertTrue(responses.containsKey("/push-example/resources/one.js"));
Assert.assertEquals(StatusCodes.OK, responses.get("/push-example/resources/one.js").getResponseCode());
Assert.assertNotNull(responses.get("/push-example/resources/one.js").getAttachment(RESPONSE_BODY));
Assert.assertTrue(responses.containsKey("/push-example/resources/one.css"));
Assert.assertEquals(StatusCodes.OK, responses.get("/push-example/resources/one.css").getResponseCode());
Assert.assertNotNull(responses.get("/push-example/resources/one.css").getAttachment(RESPONSE_BODY));
} finally {
IoUtils.safeClose(connection);
}
}
use of io.undertow.client.UndertowClient in project undertow by undertow-io.
the class LoadBalancingProxyHTTP2TestCase method testHttp2ClientMultipleStreamsThreadSafety.
@Test
public void testHttp2ClientMultipleStreamsThreadSafety() throws IOException, URISyntaxException, ExecutionException, InterruptedException, TimeoutException {
// not actually a proxy test
// but convent to put it here
UndertowXnioSsl ssl = new UndertowXnioSsl(DefaultServer.getWorker().getXnio(), OptionMap.EMPTY, DefaultServer.SSL_BUFFER_POOL, DefaultServer.createClientSslContext());
final UndertowClient client = UndertowClient.getInstance();
final ClientConnection connection = client.connect(new URI("https", null, DefaultServer.getHostAddress(), DefaultServer.getHostPort() + 1, "/", null, null), DefaultServer.getWorker(), ssl, DefaultServer.getBufferPool(), OptionMap.create(UndertowOptions.ENABLE_HTTP2, true)).get();
final ExecutorService service = Executors.newFixedThreadPool(10);
try {
Deque<FutureResult<String>> futures = new ArrayDeque<>();
for (int i = 0; i < 100; ++i) {
final FutureResult<String> future = new FutureResult<>();
futures.add(future);
service.submit(new Callable<String>() {
@Override
public String call() throws Exception {
ClientRequest cr = new ClientRequest().setMethod(Methods.GET).setPath("/path").setProtocol(Protocols.HTTP_1_1);
connection.sendRequest(cr, new ClientCallback<ClientExchange>() {
@Override
public void completed(ClientExchange result) {
result.setResponseListener(new ClientCallback<ClientExchange>() {
@Override
public void completed(ClientExchange result) {
new StringReadChannelListener(DefaultServer.getBufferPool()) {
@Override
protected void stringDone(String string) {
future.setResult(string);
}
@Override
protected void error(IOException e) {
future.setException(e);
}
}.setup(result.getResponseChannel());
}
@Override
public void failed(IOException e) {
future.setException(e);
}
});
}
@Override
public void failed(IOException e) {
future.setException(e);
}
});
return null;
}
});
}
while (!futures.isEmpty()) {
FutureResult<String> future = futures.poll();
Assert.assertNotEquals(IoFuture.Status.WAITING, future.getIoFuture().awaitInterruptibly(10, TimeUnit.SECONDS));
Assert.assertEquals("/path", future.getIoFuture().get());
}
} finally {
service.shutdownNow();
}
}
use of io.undertow.client.UndertowClient in project undertow by undertow-io.
the class H2CUpgradeContinuationTestCase method testDifferentSizes.
/**
* The real test that sends several GET and POST requests with different
* number of headers and different content length.
* @throws Exception Some error
*/
@Test
public void testDifferentSizes() throws Exception {
final UndertowClient client = UndertowClient.getInstance();
// the client connection uses the small byte-buffer of 1024 to force the continuation frames
final ClientConnection connection = client.connect(new URI("http://" + DefaultServer.getHostAddress() + ":" + (DefaultServer.getHostPort("default") + 1)), worker, new UndertowXnioSsl(worker.getXnio(), OptionMap.EMPTY, DefaultServer.getClientSSLContext()), smallPool, OptionMap.create(UndertowOptions.ENABLE_HTTP2, true)).get();
try {
// the first request triggers the upgrade to H2C
sendRequest(connection, 1, 0, 0);
// send several requests with different sizes for headers and data
sendRequest(connection, 10, 10, 0);
sendRequest(connection, 10, 100, 0);
sendRequest(connection, 10, 150, 0);
sendRequest(connection, 10, 1, 10);
sendRequest(connection, 10, 0, 2000);
sendRequest(connection, 10, 150, 2000);
} finally {
IoUtils.safeClose(connection);
}
}
use of io.undertow.client.UndertowClient in project undertow by undertow-io.
the class Http2ClientTestCase method testPostRequest.
@Test
public void testPostRequest() throws Exception {
//
final UndertowClient client = createClient();
final String postMessage = "This is a post request";
final List<String> responses = new CopyOnWriteArrayList<>();
final CountDownLatch latch = new CountDownLatch(10);
final ClientConnection connection = client.connect(ADDRESS, worker, new UndertowXnioSsl(worker.getXnio(), OptionMap.EMPTY, DefaultServer.getClientSSLContext()), DefaultServer.getBufferPool(), OptionMap.create(UndertowOptions.ENABLE_HTTP2, true)).get();
try {
connection.getIoThread().execute(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
final ClientRequest request = new ClientRequest().setMethod(Methods.POST).setPath(POST);
request.getRequestHeaders().put(Headers.HOST, DefaultServer.getHostAddress());
request.getRequestHeaders().put(Headers.TRANSFER_ENCODING, "chunked");
connection.sendRequest(request, new ClientCallback<ClientExchange>() {
@Override
public void completed(ClientExchange result) {
new StringWriteChannelListener(postMessage).setup(result.getRequestChannel());
result.setResponseListener(new ClientCallback<ClientExchange>() {
@Override
public void completed(ClientExchange result) {
new StringReadChannelListener(DefaultServer.getBufferPool()) {
@Override
protected void stringDone(String string) {
responses.add(string);
latch.countDown();
}
@Override
protected void error(IOException e) {
e.printStackTrace();
latch.countDown();
}
}.setup(result.getResponseChannel());
}
@Override
public void failed(IOException e) {
e.printStackTrace();
latch.countDown();
}
});
}
@Override
public void failed(IOException e) {
e.printStackTrace();
latch.countDown();
}
});
}
}
});
latch.await(10, TimeUnit.SECONDS);
Assert.assertEquals(10, responses.size());
for (final String response : responses) {
Assert.assertEquals(postMessage, response);
}
} finally {
IoUtils.safeClose(connection);
}
}
Aggregations