Search in sources :

Example 1 with ClientExchange

use of io.undertow.client.ClientExchange in project undertow by undertow-io.

the class HttpClientTestCase 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, DefaultServer.getBufferPool(), OptionMap.EMPTY).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);
    }
}
Also used : ClientExchange(io.undertow.client.ClientExchange) ClientCallback(io.undertow.client.ClientCallback) StringReadChannelListener(io.undertow.util.StringReadChannelListener) UndertowClient(io.undertow.client.UndertowClient) IOException(java.io.IOException) CountDownLatch(java.util.concurrent.CountDownLatch) ClientConnection(io.undertow.client.ClientConnection) StringWriteChannelListener(io.undertow.util.StringWriteChannelListener) ClientRequest(io.undertow.client.ClientRequest) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) Test(org.junit.Test)

Example 2 with ClientExchange

use of io.undertow.client.ClientExchange in project spring-framework by spring-projects.

the class UndertowXhrTransport method createReceiveCallback.

private ClientCallback<ClientExchange> createReceiveCallback(final TransportRequest transportRequest, final URI url, final HttpHeaders headers, final XhrClientSockJsSession sockJsSession, final SettableListenableFuture<WebSocketSession> connectFuture) {
    return new ClientCallback<>() {

        @Override
        public void completed(final ClientExchange exchange) {
            exchange.setResponseListener(new ClientCallback<ClientExchange>() {

                @Override
                public void completed(ClientExchange result) {
                    ClientResponse response = result.getResponse();
                    if (response.getResponseCode() != 200) {
                        HttpStatus status = HttpStatus.valueOf(response.getResponseCode());
                        IoUtils.safeClose(result.getConnection());
                        onFailure(new HttpServerErrorException(status, "Unexpected XHR receive status"));
                    } else {
                        SockJsResponseListener listener = new SockJsResponseListener(transportRequest, result.getConnection(), url, headers, sockJsSession, connectFuture);
                        listener.setup(result.getResponseChannel());
                    }
                    if (logger.isTraceEnabled()) {
                        logger.trace("XHR receive headers: " + toHttpHeaders(response.getResponseHeaders()));
                    }
                    try {
                        StreamSinkChannel channel = result.getRequestChannel();
                        channel.shutdownWrites();
                        if (!channel.flush()) {
                            channel.getWriteSetter().set(ChannelListeners.<StreamSinkChannel>flushingChannelListener(null, null));
                            channel.resumeWrites();
                        }
                    } catch (IOException exc) {
                        IoUtils.safeClose(result.getConnection());
                        onFailure(exc);
                    }
                }

                @Override
                public void failed(IOException exc) {
                    IoUtils.safeClose(exchange.getConnection());
                    onFailure(exc);
                }
            });
        }

        @Override
        public void failed(IOException exc) {
            onFailure(exc);
        }

        private void onFailure(Throwable failure) {
            if (connectFuture.setException(failure)) {
                return;
            }
            if (sockJsSession.isDisconnected()) {
                sockJsSession.afterTransportClosed(null);
            } else {
                sockJsSession.handleTransportError(failure);
                sockJsSession.afterTransportClosed(new CloseStatus(1006, failure.getMessage()));
            }
        }
    };
}
Also used : ClientExchange(io.undertow.client.ClientExchange) ClientResponse(io.undertow.client.ClientResponse) ClientCallback(io.undertow.client.ClientCallback) HttpStatus(org.springframework.http.HttpStatus) StreamSinkChannel(org.xnio.channels.StreamSinkChannel) IOException(java.io.IOException) CloseStatus(org.springframework.web.socket.CloseStatus) HttpServerErrorException(org.springframework.web.client.HttpServerErrorException)

Example 3 with ClientExchange

use of io.undertow.client.ClientExchange 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) {
        }
    }
}
Also used : ClientExchange(io.undertow.client.ClientExchange) ClientCallback(io.undertow.client.ClientCallback) XnioWorker(org.xnio.XnioWorker) URISyntaxException(java.net.URISyntaxException) URI(java.net.URI) HttpServerExchange(io.undertow.server.HttpServerExchange) CompletableFuture(java.util.concurrent.CompletableFuture) BlockingHandler(io.undertow.server.handlers.BlockingHandler) Xnio(org.xnio.Xnio) ClientConnection(io.undertow.client.ClientConnection) ClientRequest(io.undertow.client.ClientRequest) HttpHandler(io.undertow.server.HttpHandler) UndertowClient(io.undertow.client.UndertowClient) IOException(java.io.IOException) CountDownLatch(java.util.concurrent.CountDownLatch) URISyntaxException(java.net.URISyntaxException) IOException(java.io.IOException) UndertowXnioSsl(io.undertow.protocols.ssl.UndertowXnioSsl) Undertow(io.undertow.Undertow) Test(org.junit.Test)

Example 4 with ClientExchange

use of io.undertow.client.ClientExchange 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();
    }
}
Also used : ClientExchange(io.undertow.client.ClientExchange) ClientCallback(io.undertow.client.ClientCallback) StringReadChannelListener(io.undertow.util.StringReadChannelListener) UndertowClient(io.undertow.client.UndertowClient) HttpString(io.undertow.util.HttpString) IOException(java.io.IOException) URI(java.net.URI) ArrayDeque(java.util.ArrayDeque) URISyntaxException(java.net.URISyntaxException) TimeoutException(java.util.concurrent.TimeoutException) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) FutureResult(org.xnio.FutureResult) ExecutorService(java.util.concurrent.ExecutorService) ClientConnection(io.undertow.client.ClientConnection) UndertowXnioSsl(io.undertow.protocols.ssl.UndertowXnioSsl) ClientRequest(io.undertow.client.ClientRequest) Test(org.junit.Test)

Example 5 with ClientExchange

use of io.undertow.client.ClientExchange in project undertow by undertow-io.

the class H2CUpgradeContinuationTestCase method createClientCallback.

/**
 * Create the callback to receive the response and assign it to the list.
 * @param responses The list where the response will be added
 * @param latch The latch to count down when the response is received
 * @param message The message to send if it's a POST message (if null nothing is send)
 * @return The created callback
 */
private static ClientCallback<ClientExchange> createClientCallback(final List<ClientResponse> responses, final CountDownLatch latch, String message) {
    return new ClientCallback<ClientExchange>() {

        @Override
        public void completed(ClientExchange result) {
            if (message != null) {
                new StringWriteChannelListener(message).setup(result.getRequestChannel());
            }
            result.setResponseListener(new ClientCallback<ClientExchange>() {

                @Override
                public void completed(final ClientExchange result) {
                    responses.add(result.getResponse());
                    new StringReadChannelListener(result.getConnection().getBufferPool()) {

                        @Override
                        protected void stringDone(String string) {
                            result.getResponse().putAttachment(RESPONSE_BODY, 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();
                }
            });
            try {
                result.getRequestChannel().shutdownWrites();
                if (!result.getRequestChannel().flush()) {
                    result.getRequestChannel().getWriteSetter().set(ChannelListeners.<StreamSinkChannel>flushingChannelListener(null, null));
                    result.getRequestChannel().resumeWrites();
                }
            } catch (IOException e) {
                e.printStackTrace();
                latch.countDown();
            }
        }

        @Override
        public void failed(IOException e) {
            e.printStackTrace();
            latch.countDown();
        }
    };
}
Also used : ClientExchange(io.undertow.client.ClientExchange) ClientCallback(io.undertow.client.ClientCallback) StringReadChannelListener(io.undertow.util.StringReadChannelListener) StringWriteChannelListener(io.undertow.util.StringWriteChannelListener) HttpString(io.undertow.util.HttpString) IOException(java.io.IOException)

Aggregations

ClientCallback (io.undertow.client.ClientCallback)8 ClientExchange (io.undertow.client.ClientExchange)8 IOException (java.io.IOException)8 StringReadChannelListener (io.undertow.util.StringReadChannelListener)6 ClientConnection (io.undertow.client.ClientConnection)5 ClientRequest (io.undertow.client.ClientRequest)5 UndertowClient (io.undertow.client.UndertowClient)5 StringWriteChannelListener (io.undertow.util.StringWriteChannelListener)5 Test (org.junit.Test)5 CountDownLatch (java.util.concurrent.CountDownLatch)4 UndertowXnioSsl (io.undertow.protocols.ssl.UndertowXnioSsl)3 CopyOnWriteArrayList (java.util.concurrent.CopyOnWriteArrayList)3 HttpString (io.undertow.util.HttpString)2 URI (java.net.URI)2 URISyntaxException (java.net.URISyntaxException)2 Undertow (io.undertow.Undertow)1 ClientResponse (io.undertow.client.ClientResponse)1 Http2StreamSourceChannel (io.undertow.protocols.http2.Http2StreamSourceChannel)1 HttpHandler (io.undertow.server.HttpHandler)1 HttpServerExchange (io.undertow.server.HttpServerExchange)1