Search in sources :

Example 1 with IoCallback

use of io.undertow.io.IoCallback in project wildfly by wildfly.

the class VirtualFileResource method serve.

@Override
public void serve(final Sender sender, final HttpServerExchange exchange, final IoCallback callback) {
    abstract class BaseFileTask implements Runnable {

        protected volatile FileChannel fileChannel;

        protected boolean openFile() {
            try {
                fileChannel = exchange.getConnection().getWorker().getXnio().openFile(file.getPhysicalFile(), FileAccess.READ_ONLY);
            } catch (FileNotFoundException e) {
                exchange.setResponseCode(404);
                callback.onException(exchange, sender, e);
                return false;
            } catch (IOException e) {
                exchange.setResponseCode(500);
                callback.onException(exchange, sender, e);
                return false;
            }
            return true;
        }
    }
    class ServerTask extends BaseFileTask implements IoCallback {

        private Pooled<ByteBuffer> pooled;

        @Override
        public void run() {
            if (fileChannel == null) {
                if (!openFile()) {
                    return;
                }
                pooled = exchange.getConnection().getBufferPool().allocate();
            }
            if (pooled != null) {
                ByteBuffer buffer = pooled.getResource();
                try {
                    buffer.clear();
                    int res = fileChannel.read(buffer);
                    if (res == -1) {
                        //we are done
                        pooled.free();
                        IoUtils.safeClose(fileChannel);
                        callback.onComplete(exchange, sender);
                        return;
                    }
                    buffer.flip();
                    sender.send(buffer, this);
                } catch (IOException e) {
                    onException(exchange, sender, e);
                }
            }
        }

        @Override
        public void onComplete(final HttpServerExchange exchange, final Sender sender) {
            if (exchange.isInIoThread()) {
                exchange.dispatch(this);
            } else {
                run();
            }
        }

        @Override
        public void onException(final HttpServerExchange exchange, final Sender sender, final IOException exception) {
            UndertowLogger.REQUEST_IO_LOGGER.ioException(exception);
            if (pooled != null) {
                pooled.free();
                pooled = null;
            }
            IoUtils.safeClose(fileChannel);
            if (!exchange.isResponseStarted()) {
                exchange.setResponseCode(500);
            }
            callback.onException(exchange, sender, exception);
        }
    }
    class TransferTask extends BaseFileTask {

        @Override
        public void run() {
            if (!openFile()) {
                return;
            }
            sender.transferFrom(fileChannel, new IoCallback() {

                @Override
                public void onComplete(HttpServerExchange exchange, Sender sender) {
                    try {
                        IoUtils.safeClose(fileChannel);
                    } finally {
                        callback.onComplete(exchange, sender);
                    }
                }

                @Override
                public void onException(HttpServerExchange exchange, Sender sender, IOException exception) {
                    try {
                        IoUtils.safeClose(fileChannel);
                    } finally {
                        callback.onException(exchange, sender, exception);
                    }
                }
            });
        }
    }
    BaseFileTask task = new TransferTask();
    if (exchange.isInIoThread()) {
        exchange.dispatch(task);
    } else {
        task.run();
    }
}
Also used : FileChannel(java.nio.channels.FileChannel) FileNotFoundException(java.io.FileNotFoundException) Pooled(org.xnio.Pooled) IOException(java.io.IOException) ByteBuffer(java.nio.ByteBuffer) HttpServerExchange(io.undertow.server.HttpServerExchange) Sender(io.undertow.io.Sender) IoCallback(io.undertow.io.IoCallback)

Example 2 with IoCallback

use of io.undertow.io.IoCallback in project undertow by undertow-io.

the class AsyncWebSocketHttpServerExchange method sendData.

@Override
public IoFuture<Void> sendData(final ByteBuffer data) {
    if (sender == null) {
        this.sender = exchange.getResponseSender();
    }
    final FutureResult<Void> future = new FutureResult<>();
    sender.send(data, new IoCallback() {

        @Override
        public void onComplete(final HttpServerExchange exchange, final Sender sender) {
            future.setResult(null);
        }

        @Override
        public void onException(final HttpServerExchange exchange, final Sender sender, final IOException exception) {
            UndertowLogger.REQUEST_IO_LOGGER.ioException(exception);
            future.setException(exception);
        }
    });
    return future.getIoFuture();
}
Also used : HttpServerExchange(io.undertow.server.HttpServerExchange) Sender(io.undertow.io.Sender) FutureResult(org.xnio.FutureResult) IoCallback(io.undertow.io.IoCallback) IOException(java.io.IOException)

Example 3 with IoCallback

use of io.undertow.io.IoCallback in project undertow by undertow-io.

the class SimpleBlockingServerTestCase method setup.

@BeforeClass
public static void setup() {
    final BlockingHandler blockingHandler = new BlockingHandler();
    DefaultServer.setRootHandler(blockingHandler);
    blockingHandler.setRootHandler(new HttpHandler() {

        @Override
        public void handleRequest(final HttpServerExchange exchange) {
            try {
                if (exchange.getRequestMethod().equals(Methods.POST)) {
                    //for a post we just echo back what was sent
                    //we need to fully buffer it, as otherwise the send buffer fills up, and the client will still be blocked
                    //on writing and will never read
                    byte[] buffer = new byte[1024];
                    final ByteArrayOutputStream b = new ByteArrayOutputStream();
                    int r = 0;
                    final OutputStream outputStream = exchange.getOutputStream();
                    final InputStream inputStream = exchange.getInputStream();
                    while ((r = inputStream.read(buffer)) > 0) {
                        b.write(buffer, 0, r);
                    }
                    outputStream.write(b.toByteArray());
                    outputStream.close();
                } else {
                    if (exchange.getQueryParameters().containsKey("useFragmentedSender")) {
                        //we send it byte at a time
                        exchange.getResponseSender().send("", new IoCallback() {

                            int i = 0;

                            @Override
                            public void onComplete(final HttpServerExchange exchange, final Sender sender) {
                                if (i == message.length()) {
                                    sender.close();
                                    exchange.endExchange();
                                } else {
                                    sender.send("" + message.charAt(i++), this);
                                }
                            }

                            @Override
                            public void onException(final HttpServerExchange exchange, final Sender sender, final IOException exception) {
                                exchange.endExchange();
                            }
                        });
                    } else if (exchange.getQueryParameters().containsKey("useSender")) {
                        exchange.getResponseSender().send(message, IoCallback.END_EXCHANGE);
                    } else {
                        final OutputStream outputStream = exchange.getOutputStream();
                        outputStream.write(message.getBytes());
                        outputStream.close();
                    }
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    });
}
Also used : HttpServerExchange(io.undertow.server.HttpServerExchange) Sender(io.undertow.io.Sender) HttpHandler(io.undertow.server.HttpHandler) BlockingHandler(io.undertow.server.handlers.BlockingHandler) InputStream(java.io.InputStream) ByteArrayOutputStream(java.io.ByteArrayOutputStream) OutputStream(java.io.OutputStream) IoCallback(io.undertow.io.IoCallback) ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException) BeforeClass(org.junit.BeforeClass)

Example 4 with IoCallback

use of io.undertow.io.IoCallback in project undertow by undertow-io.

the class SenderTestCase method setup.

@BeforeClass
public static void setup() {
    HttpHandler lotsOfSendsHandler = new HttpHandler() {

        @Override
        public void handleRequest(final HttpServerExchange exchange) throws Exception {
            boolean blocking = exchange.getQueryParameters().get("blocking").getFirst().equals("true");
            if (blocking) {
                if (exchange.isInIoThread()) {
                    exchange.startBlocking();
                    exchange.dispatch(this);
                    return;
                }
            }
            final Sender sender = exchange.getResponseSender();
            class SendClass implements Runnable, IoCallback {

                int sent = 0;

                @Override
                public void run() {
                    sent++;
                    sender.send("a", this);
                }

                @Override
                public void onComplete(final HttpServerExchange exchange, final Sender sender) {
                    if (sent++ == SENDS) {
                        sender.close();
                        return;
                    }
                    sender.send("a", this);
                }

                @Override
                public void onException(final HttpServerExchange exchange, final Sender sender, final IOException exception) {
                    exception.printStackTrace();
                    exchange.endExchange();
                }
            }
            new SendClass().run();
        }
    };
    HttpHandler lotsOfTransferHandler = new HttpHandler() {

        @Override
        public void handleRequest(final HttpServerExchange exchange) throws Exception {
            boolean blocking = exchange.getQueryParameters().get("blocking").getFirst().equals("true");
            if (blocking) {
                if (exchange.isInIoThread()) {
                    exchange.startBlocking();
                    exchange.dispatch(this);
                    return;
                }
            }
            URI uri = SenderTestCase.class.getResource(SenderTestCase.class.getSimpleName() + ".class").toURI();
            Path file = Paths.get(uri);
            final FileChannel channel = FileChannel.open(file, StandardOpenOption.READ);
            exchange.setResponseContentLength(channel.size() * TXS);
            final Sender sender = exchange.getResponseSender();
            class SendClass implements Runnable, IoCallback {

                int sent = 0;

                @Override
                public void run() {
                    sent++;
                    try {
                        channel.position(0);
                    } catch (IOException e) {
                    }
                    sender.transferFrom(channel, this);
                }

                @Override
                public void onComplete(final HttpServerExchange exchange, final Sender sender) {
                    if (sent++ == TXS) {
                        sender.close();
                        return;
                    }
                    try {
                        channel.position(0);
                    } catch (IOException e) {
                    }
                    sender.transferFrom(channel, this);
                }

                @Override
                public void onException(final HttpServerExchange exchange, final Sender sender, final IOException exception) {
                    exception.printStackTrace();
                    exchange.endExchange();
                }
            }
            new SendClass().run();
        }
    };
    final HttpHandler fixedLengthSender = new HttpHandler() {

        @Override
        public void handleRequest(final HttpServerExchange exchange) throws Exception {
            exchange.getResponseSender().send(HELLO_WORLD);
        }
    };
    PathHandler handler = new PathHandler().addPrefixPath("/lots", lotsOfSendsHandler).addPrefixPath("/fixed", fixedLengthSender).addPrefixPath("/transfer", lotsOfTransferHandler);
    DefaultServer.setRootHandler(handler);
}
Also used : Path(java.nio.file.Path) HttpHandler(io.undertow.server.HttpHandler) FileChannel(java.nio.channels.FileChannel) IOException(java.io.IOException) URI(java.net.URI) HttpServerExchange(io.undertow.server.HttpServerExchange) Sender(io.undertow.io.Sender) IoCallback(io.undertow.io.IoCallback) BeforeClass(org.junit.BeforeClass)

Example 5 with IoCallback

use of io.undertow.io.IoCallback in project undertow by undertow-io.

the class PathResource method serveImpl.

private void serveImpl(final Sender sender, final HttpServerExchange exchange, final long start, final long end, final IoCallback callback, final boolean range) {
    abstract class BaseFileTask implements Runnable {

        protected volatile FileChannel fileChannel;

        protected boolean openFile() {
            try {
                fileChannel = FileChannel.open(file, StandardOpenOption.READ);
                if (range) {
                    fileChannel.position(start);
                }
            } catch (NoSuchFileException e) {
                exchange.setStatusCode(StatusCodes.NOT_FOUND);
                callback.onException(exchange, sender, e);
                return false;
            } catch (IOException e) {
                exchange.setStatusCode(StatusCodes.INTERNAL_SERVER_ERROR);
                callback.onException(exchange, sender, e);
                return false;
            }
            return true;
        }
    }
    class ServerTask extends BaseFileTask implements IoCallback {

        private PooledByteBuffer pooled;

        long remaining = end - start + 1;

        @Override
        public void run() {
            if (range && remaining == 0) {
                //we are done
                pooled.close();
                pooled = null;
                IoUtils.safeClose(fileChannel);
                callback.onComplete(exchange, sender);
                return;
            }
            if (fileChannel == null) {
                if (!openFile()) {
                    return;
                }
                pooled = exchange.getConnection().getByteBufferPool().allocate();
            }
            if (pooled != null) {
                ByteBuffer buffer = pooled.getBuffer();
                try {
                    buffer.clear();
                    int res = fileChannel.read(buffer);
                    if (res == -1) {
                        //we are done
                        pooled.close();
                        IoUtils.safeClose(fileChannel);
                        callback.onComplete(exchange, sender);
                        return;
                    }
                    buffer.flip();
                    if (range) {
                        if (buffer.remaining() > remaining) {
                            buffer.limit((int) (buffer.position() + remaining));
                        }
                        remaining -= buffer.remaining();
                    }
                    sender.send(buffer, this);
                } catch (IOException e) {
                    onException(exchange, sender, e);
                }
            }
        }

        @Override
        public void onComplete(final HttpServerExchange exchange, final Sender sender) {
            if (exchange.isInIoThread()) {
                exchange.dispatch(this);
            } else {
                run();
            }
        }

        @Override
        public void onException(final HttpServerExchange exchange, final Sender sender, final IOException exception) {
            UndertowLogger.REQUEST_IO_LOGGER.ioException(exception);
            if (pooled != null) {
                pooled.close();
                pooled = null;
            }
            IoUtils.safeClose(fileChannel);
            if (!exchange.isResponseStarted()) {
                exchange.setStatusCode(StatusCodes.INTERNAL_SERVER_ERROR);
            }
            callback.onException(exchange, sender, exception);
        }
    }
    class TransferTask extends BaseFileTask {

        @Override
        public void run() {
            if (!openFile()) {
                return;
            }
            sender.transferFrom(fileChannel, new IoCallback() {

                @Override
                public void onComplete(HttpServerExchange exchange, Sender sender) {
                    try {
                        IoUtils.safeClose(fileChannel);
                    } finally {
                        callback.onComplete(exchange, sender);
                    }
                }

                @Override
                public void onException(HttpServerExchange exchange, Sender sender, IOException exception) {
                    try {
                        IoUtils.safeClose(fileChannel);
                    } finally {
                        callback.onException(exchange, sender, exception);
                    }
                }
            });
        }
    }
    BaseFileTask task;
    try {
        task = manager.getTransferMinSize() > Files.size(file) || range ? new ServerTask() : new TransferTask();
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
    if (exchange.isInIoThread()) {
        exchange.dispatch(task);
    } else {
        task.run();
    }
}
Also used : FileChannel(java.nio.channels.FileChannel) NoSuchFileException(java.nio.file.NoSuchFileException) IOException(java.io.IOException) ByteBuffer(java.nio.ByteBuffer) PooledByteBuffer(io.undertow.connector.PooledByteBuffer) HttpServerExchange(io.undertow.server.HttpServerExchange) Sender(io.undertow.io.Sender) PooledByteBuffer(io.undertow.connector.PooledByteBuffer) IoCallback(io.undertow.io.IoCallback)

Aggregations

IoCallback (io.undertow.io.IoCallback)7 IOException (java.io.IOException)7 Sender (io.undertow.io.Sender)6 HttpServerExchange (io.undertow.server.HttpServerExchange)6 HttpHandler (io.undertow.server.HttpHandler)3 FileChannel (java.nio.channels.FileChannel)3 BeforeClass (org.junit.BeforeClass)3 ByteBuffer (java.nio.ByteBuffer)2 PooledByteBuffer (io.undertow.connector.PooledByteBuffer)1 Receiver (io.undertow.io.Receiver)1 BlockingHandler (io.undertow.server.handlers.BlockingHandler)1 ByteArrayOutputStream (java.io.ByteArrayOutputStream)1 FileNotFoundException (java.io.FileNotFoundException)1 InputStream (java.io.InputStream)1 OutputStream (java.io.OutputStream)1 URI (java.net.URI)1 NoSuchFileException (java.nio.file.NoSuchFileException)1 Path (java.nio.file.Path)1 Deque (java.util.Deque)1 LinkedBlockingDeque (java.util.concurrent.LinkedBlockingDeque)1