use of io.undertow.client.ClientConnection 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.ClientConnection 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.ClientConnection in project undertow by undertow-io.
the class HttpClientConnection method doHttp2Upgrade.
protected void doHttp2Upgrade() {
try {
StreamConnection connectedStreamChannel = this.performUpgrade();
Http2Channel http2Channel = new Http2Channel(connectedStreamChannel, null, bufferPool, null, true, true, options);
Http2ClientConnection http2ClientConnection = new Http2ClientConnection(http2Channel, currentRequest.getResponseCallback(), currentRequest.getRequest(), currentRequest.getRequest().getRequestHeaders().getFirst(Headers.HOST), clientStatistics, false);
http2ClientConnection.getCloseSetter().set(new ChannelListener<ClientConnection>() {
@Override
public void handleEvent(ClientConnection channel) {
ChannelListeners.invokeChannelListener(HttpClientConnection.this, HttpClientConnection.this.closeSetter.get());
}
});
http2Delegate = http2ClientConnection;
// make sure the read listener is immediately invoked, as it may not happen if data is pushed back
connectedStreamChannel.getSourceChannel().wakeupReads();
currentRequest = null;
pendingResponse = null;
} catch (IOException e) {
UndertowLogger.REQUEST_IO_LOGGER.ioException(e);
safeClose(this);
}
}
use of io.undertow.client.ClientConnection in project undertow by undertow-io.
the class ModClusterProxyClient method getConnection.
public void getConnection(final ProxyTarget target, final HttpServerExchange exchange, final ProxyCallback<ProxyConnection> callback, final long timeout, final TimeUnit timeUnit) {
final ExclusiveConnectionHolder holder = exchange.getConnection().getAttachment(exclusiveConnectionKey);
if (holder != null && holder.connection.getConnection().isOpen()) {
// Something has already caused an exclusive connection to be
// allocated so keep using it.
callback.completed(exchange, holder.connection);
return;
}
if (!(target instanceof ModClusterProxyTarget)) {
callback.couldNotResolveBackend(exchange);
return;
}
// Resolve the node
final ModClusterProxyTarget proxyTarget = (ModClusterProxyTarget) target;
final Context context = proxyTarget.resolveContext(exchange);
if (context == null) {
callback.couldNotResolveBackend(exchange);
} else {
if (holder != null || (exclusivityChecker != null && exclusivityChecker.isExclusivityRequired(exchange))) {
// If we have a holder, even if the connection was closed we now
// exclusivity was already requested so our client
// may be assuming it still exists.
final ProxyCallback<ProxyConnection> wrappedCallback = new ProxyCallback<ProxyConnection>() {
@Override
public void completed(HttpServerExchange exchange, ProxyConnection result) {
if (holder != null) {
holder.connection = result;
} else {
final ExclusiveConnectionHolder newHolder = new ExclusiveConnectionHolder();
newHolder.connection = result;
ServerConnection connection = exchange.getConnection();
connection.putAttachment(exclusiveConnectionKey, newHolder);
connection.addCloseListener(new ServerConnection.CloseListener() {
@Override
public void closed(ServerConnection connection) {
ClientConnection clientConnection = newHolder.connection.getConnection();
if (clientConnection.isOpen()) {
safeClose(clientConnection);
}
}
});
}
callback.completed(exchange, result);
}
@Override
public void queuedRequestFailed(HttpServerExchange exchange) {
callback.queuedRequestFailed(exchange);
}
@Override
public void failed(HttpServerExchange exchange) {
callback.failed(exchange);
}
@Override
public void couldNotResolveBackend(HttpServerExchange exchange) {
callback.couldNotResolveBackend(exchange);
}
};
context.handleRequest(proxyTarget, exchange, wrappedCallback, timeout, timeUnit, true);
} else {
context.handleRequest(proxyTarget, exchange, callback, timeout, timeUnit, false);
}
}
}
use of io.undertow.client.ClientConnection in project undertow by undertow-io.
the class LoadBalancingProxyClient method getConnection.
@Override
public void getConnection(ProxyTarget target, HttpServerExchange exchange, final ProxyCallback<ProxyConnection> callback, long timeout, TimeUnit timeUnit) {
final ExclusiveConnectionHolder holder = exchange.getConnection().getAttachment(exclusiveConnectionKey);
if (holder != null && holder.connection.getConnection().isOpen()) {
// Something has already caused an exclusive connection to be allocated so keep using it.
callback.completed(exchange, holder.connection);
return;
}
final Host host = selectHost(exchange);
if (host == null) {
callback.couldNotResolveBackend(exchange);
} else {
exchange.addToAttachmentList(ATTEMPTED_HOSTS, host);
if (holder != null || (exclusivityChecker != null && exclusivityChecker.isExclusivityRequired(exchange))) {
// If we have a holder, even if the connection was closed we now exclusivity was already requested so our client
// may be assuming it still exists.
host.connectionPool.connect(target, exchange, new ProxyCallback<ProxyConnection>() {
@Override
public void completed(HttpServerExchange exchange, ProxyConnection result) {
if (holder != null) {
holder.connection = result;
} else {
final ExclusiveConnectionHolder newHolder = new ExclusiveConnectionHolder();
newHolder.connection = result;
ServerConnection connection = exchange.getConnection();
connection.putAttachment(exclusiveConnectionKey, newHolder);
connection.addCloseListener(new ServerConnection.CloseListener() {
@Override
public void closed(ServerConnection connection) {
ClientConnection clientConnection = newHolder.connection.getConnection();
if (clientConnection.isOpen()) {
safeClose(clientConnection);
}
}
});
}
callback.completed(exchange, result);
}
@Override
public void queuedRequestFailed(HttpServerExchange exchange) {
callback.queuedRequestFailed(exchange);
}
@Override
public void failed(HttpServerExchange exchange) {
UndertowLogger.PROXY_REQUEST_LOGGER.proxyFailedToConnectToBackend(exchange.getRequestURI(), host.uri);
callback.failed(exchange);
}
@Override
public void couldNotResolveBackend(HttpServerExchange exchange) {
callback.couldNotResolveBackend(exchange);
}
}, timeout, timeUnit, true);
} else {
host.connectionPool.connect(target, exchange, callback, timeout, timeUnit, false);
}
}
}
Aggregations