Search in sources :

Example 6 with StreamSourceChannel

use of org.xnio.channels.StreamSourceChannel in project undertow by undertow-io.

the class RequestBufferingHandler method handleRequest.

@Override
public void handleRequest(final HttpServerExchange exchange) throws Exception {
    if (!exchange.isRequestComplete() && !HttpContinue.requiresContinueResponse(exchange.getRequestHeaders())) {
        final StreamSourceChannel channel = exchange.getRequestChannel();
        int readBuffers = 0;
        final PooledByteBuffer[] bufferedData = new PooledByteBuffer[maxBuffers];
        PooledByteBuffer buffer = exchange.getConnection().getByteBufferPool().allocate();
        do {
            int r;
            ByteBuffer b = buffer.getBuffer();
            r = channel.read(b);
            if (r == -1) {
                //TODO: listener read
                if (b.position() == 0) {
                    buffer.close();
                } else {
                    b.flip();
                    bufferedData[readBuffers] = buffer;
                }
                break;
            } else if (r == 0) {
                final PooledByteBuffer finalBuffer = buffer;
                final int finalReadBuffers = readBuffers;
                channel.getReadSetter().set(new ChannelListener<StreamSourceChannel>() {

                    PooledByteBuffer buffer = finalBuffer;

                    int readBuffers = finalReadBuffers;

                    @Override
                    public void handleEvent(StreamSourceChannel channel) {
                        try {
                            do {
                                int r;
                                ByteBuffer b = buffer.getBuffer();
                                r = channel.read(b);
                                if (r == -1) {
                                    //TODO: listener read
                                    if (b.position() == 0) {
                                        buffer.close();
                                    } else {
                                        b.flip();
                                        bufferedData[readBuffers] = buffer;
                                    }
                                    Connectors.ungetRequestBytes(exchange, bufferedData);
                                    Connectors.resetRequestChannel(exchange);
                                    Connectors.executeRootHandler(next, exchange);
                                    channel.getReadSetter().set(null);
                                    return;
                                } else if (r == 0) {
                                    return;
                                } else if (!b.hasRemaining()) {
                                    b.flip();
                                    bufferedData[readBuffers++] = buffer;
                                    if (readBuffers == maxBuffers) {
                                        Connectors.ungetRequestBytes(exchange, bufferedData);
                                        Connectors.resetRequestChannel(exchange);
                                        Connectors.executeRootHandler(next, exchange);
                                        channel.getReadSetter().set(null);
                                        return;
                                    }
                                    buffer = exchange.getConnection().getByteBufferPool().allocate();
                                }
                            } while (true);
                        } catch (IOException e) {
                            UndertowLogger.REQUEST_IO_LOGGER.ioException(e);
                            for (int i = 0; i < bufferedData.length; ++i) {
                                IoUtils.safeClose(bufferedData[i]);
                            }
                            exchange.endExchange();
                        }
                    }
                });
                channel.resumeReads();
                return;
            } else if (!b.hasRemaining()) {
                b.flip();
                bufferedData[readBuffers++] = buffer;
                if (readBuffers == maxBuffers) {
                    break;
                }
                buffer = exchange.getConnection().getByteBufferPool().allocate();
            }
        } while (true);
        Connectors.ungetRequestBytes(exchange, bufferedData);
        Connectors.resetRequestChannel(exchange);
    }
    next.handleRequest(exchange);
}
Also used : StreamSourceChannel(org.xnio.channels.StreamSourceChannel) ChannelListener(org.xnio.ChannelListener) PooledByteBuffer(io.undertow.connector.PooledByteBuffer) IOException(java.io.IOException) ByteBuffer(java.nio.ByteBuffer) PooledByteBuffer(io.undertow.connector.PooledByteBuffer)

Example 7 with StreamSourceChannel

use of org.xnio.channels.StreamSourceChannel in project undertow by undertow-io.

the class AsyncReceiverImpl method receivePartialString.

@Override
public void receivePartialString(final PartialStringCallback callback, final ErrorCallback errorCallback, Charset charset) {
    if (done) {
        throw UndertowMessages.MESSAGES.requestBodyAlreadyRead();
    }
    final ErrorCallback error = errorCallback == null ? END_EXCHANGE : errorCallback;
    if (callback == null) {
        throw UndertowMessages.MESSAGES.argumentCannotBeNull("callback");
    }
    if (exchange.isRequestComplete()) {
        callback.handle(exchange, "", true);
        return;
    }
    String contentLengthString = exchange.getRequestHeaders().getFirst(Headers.CONTENT_LENGTH);
    long contentLength;
    if (contentLengthString != null) {
        contentLength = Long.parseLong(contentLengthString);
        if (contentLength > Integer.MAX_VALUE) {
            error.error(exchange, new RequestToLargeException());
            return;
        }
    } else {
        contentLength = -1;
    }
    if (maxBufferSize > 0) {
        if (contentLength > maxBufferSize) {
            error.error(exchange, new RequestToLargeException());
            return;
        }
    }
    final CharsetDecoder decoder = charset.newDecoder();
    PooledByteBuffer pooled = exchange.getConnection().getByteBufferPool().allocate();
    final ByteBuffer buffer = pooled.getBuffer();
    channel.getReadSetter().set(new ChannelListener<StreamSourceChannel>() {

        @Override
        public void handleEvent(final StreamSourceChannel channel) {
            if (done || paused) {
                return;
            }
            PooledByteBuffer pooled = exchange.getConnection().getByteBufferPool().allocate();
            final ByteBuffer buffer = pooled.getBuffer();
            try {
                int res;
                do {
                    if (paused) {
                        return;
                    }
                    try {
                        buffer.clear();
                        res = channel.read(buffer);
                        if (res == -1) {
                            done = true;
                            Connectors.executeRootHandler(new HttpHandler() {

                                @Override
                                public void handleRequest(HttpServerExchange exchange) throws Exception {
                                    callback.handle(exchange, "", true);
                                }
                            }, exchange);
                            return;
                        } else if (res == 0) {
                            return;
                        } else {
                            buffer.flip();
                            final CharBuffer cb = decoder.decode(buffer);
                            Connectors.executeRootHandler(new HttpHandler() {

                                @Override
                                public void handleRequest(HttpServerExchange exchange) throws Exception {
                                    callback.handle(exchange, cb.toString(), false);
                                    if (!paused) {
                                        channel.resumeReads();
                                    } else {
                                        System.out.println("paused");
                                    }
                                }
                            }, exchange);
                        }
                    } catch (final IOException e) {
                        Connectors.executeRootHandler(new HttpHandler() {

                            @Override
                            public void handleRequest(HttpServerExchange exchange) throws Exception {
                                error.error(exchange, e);
                            }
                        }, exchange);
                        return;
                    }
                } while (true);
            } finally {
                pooled.close();
            }
        }
    });
    try {
        int res;
        do {
            try {
                buffer.clear();
                res = channel.read(buffer);
                if (res == -1) {
                    done = true;
                    callback.handle(exchange, "", true);
                    return;
                } else if (res == 0) {
                    channel.resumeReads();
                    return;
                } else {
                    buffer.flip();
                    CharBuffer cb = decoder.decode(buffer);
                    callback.handle(exchange, cb.toString(), false);
                    if (paused) {
                        return;
                    }
                }
            } catch (IOException e) {
                error.error(exchange, e);
                return;
            }
        } while (true);
    } finally {
        pooled.close();
    }
}
Also used : StreamSourceChannel(org.xnio.channels.StreamSourceChannel) HttpHandler(io.undertow.server.HttpHandler) CharsetDecoder(java.nio.charset.CharsetDecoder) CharBuffer(java.nio.CharBuffer) IOException(java.io.IOException) ByteBuffer(java.nio.ByteBuffer) PooledByteBuffer(io.undertow.connector.PooledByteBuffer) IOException(java.io.IOException) HttpServerExchange(io.undertow.server.HttpServerExchange) PooledByteBuffer(io.undertow.connector.PooledByteBuffer)

Example 8 with StreamSourceChannel

use of org.xnio.channels.StreamSourceChannel in project undertow by undertow-io.

the class AsyncReceiverImpl method receiveFullString.

@Override
public void receiveFullString(final FullStringCallback callback, final ErrorCallback errorCallback, final Charset charset) {
    if (done) {
        throw UndertowMessages.MESSAGES.requestBodyAlreadyRead();
    }
    final ErrorCallback error = errorCallback == null ? END_EXCHANGE : errorCallback;
    if (callback == null) {
        throw UndertowMessages.MESSAGES.argumentCannotBeNull("callback");
    }
    if (exchange.isRequestComplete()) {
        callback.handle(exchange, "");
        return;
    }
    String contentLengthString = exchange.getRequestHeaders().getFirst(Headers.CONTENT_LENGTH);
    long contentLength;
    final ByteArrayOutputStream sb;
    if (contentLengthString != null) {
        contentLength = Long.parseLong(contentLengthString);
        if (contentLength > Integer.MAX_VALUE) {
            error.error(exchange, new RequestToLargeException());
            return;
        }
        sb = new ByteArrayOutputStream((int) contentLength);
    } else {
        contentLength = -1;
        sb = new ByteArrayOutputStream();
    }
    if (maxBufferSize > 0) {
        if (contentLength > maxBufferSize) {
            error.error(exchange, new RequestToLargeException());
            return;
        }
    }
    PooledByteBuffer pooled = exchange.getConnection().getByteBufferPool().allocate();
    final ByteBuffer buffer = pooled.getBuffer();
    try {
        int res;
        do {
            try {
                buffer.clear();
                res = channel.read(buffer);
                if (res == -1) {
                    done = true;
                    callback.handle(exchange, sb.toString(charset.name()));
                    return;
                } else if (res == 0) {
                    channel.getReadSetter().set(new ChannelListener<StreamSourceChannel>() {

                        @Override
                        public void handleEvent(StreamSourceChannel channel) {
                            if (done) {
                                return;
                            }
                            PooledByteBuffer pooled = exchange.getConnection().getByteBufferPool().allocate();
                            final ByteBuffer buffer = pooled.getBuffer();
                            try {
                                int res;
                                do {
                                    try {
                                        buffer.clear();
                                        res = channel.read(buffer);
                                        if (res == -1) {
                                            done = true;
                                            Connectors.executeRootHandler(new HttpHandler() {

                                                @Override
                                                public void handleRequest(HttpServerExchange exchange) throws Exception {
                                                    callback.handle(exchange, sb.toString(charset.name()));
                                                }
                                            }, exchange);
                                            return;
                                        } else if (res == 0) {
                                            return;
                                        } else {
                                            buffer.flip();
                                            while (buffer.hasRemaining()) {
                                                sb.write(buffer.get());
                                            }
                                            if (maxBufferSize > 0 && sb.size() > maxBufferSize) {
                                                Connectors.executeRootHandler(new HttpHandler() {

                                                    @Override
                                                    public void handleRequest(HttpServerExchange exchange) throws Exception {
                                                        error.error(exchange, new RequestToLargeException());
                                                    }
                                                }, exchange);
                                                return;
                                            }
                                        }
                                    } catch (final IOException e) {
                                        Connectors.executeRootHandler(new HttpHandler() {

                                            @Override
                                            public void handleRequest(HttpServerExchange exchange) throws Exception {
                                                error.error(exchange, e);
                                            }
                                        }, exchange);
                                        return;
                                    }
                                } while (true);
                            } finally {
                                pooled.close();
                            }
                        }
                    });
                    channel.resumeReads();
                    return;
                } else {
                    buffer.flip();
                    while (buffer.hasRemaining()) {
                        sb.write(buffer.get());
                    }
                    if (maxBufferSize > 0 && sb.size() > maxBufferSize) {
                        error.error(exchange, new RequestToLargeException());
                        return;
                    }
                }
            } catch (IOException e) {
                error.error(exchange, e);
                return;
            }
        } while (true);
    } finally {
        pooled.close();
    }
}
Also used : StreamSourceChannel(org.xnio.channels.StreamSourceChannel) HttpHandler(io.undertow.server.HttpHandler) ChannelListener(org.xnio.ChannelListener) ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException) ByteBuffer(java.nio.ByteBuffer) PooledByteBuffer(io.undertow.connector.PooledByteBuffer) IOException(java.io.IOException) HttpServerExchange(io.undertow.server.HttpServerExchange) PooledByteBuffer(io.undertow.connector.PooledByteBuffer)

Example 9 with StreamSourceChannel

use of org.xnio.channels.StreamSourceChannel in project undertow by undertow-io.

the class AsyncReceiverImpl method receivePartialBytes.

@Override
public void receivePartialBytes(final PartialBytesCallback callback, final ErrorCallback errorCallback) {
    if (done) {
        throw UndertowMessages.MESSAGES.requestBodyAlreadyRead();
    }
    final ErrorCallback error = errorCallback == null ? END_EXCHANGE : errorCallback;
    if (callback == null) {
        throw UndertowMessages.MESSAGES.argumentCannotBeNull("callback");
    }
    if (exchange.isRequestComplete()) {
        callback.handle(exchange, EMPTY_BYTE_ARRAY, true);
        return;
    }
    String contentLengthString = exchange.getRequestHeaders().getFirst(Headers.CONTENT_LENGTH);
    long contentLength;
    if (contentLengthString != null) {
        contentLength = Long.parseLong(contentLengthString);
        if (contentLength > Integer.MAX_VALUE) {
            error.error(exchange, new RequestToLargeException());
            return;
        }
    } else {
        contentLength = -1;
    }
    if (maxBufferSize > 0) {
        if (contentLength > maxBufferSize) {
            error.error(exchange, new RequestToLargeException());
            return;
        }
    }
    PooledByteBuffer pooled = exchange.getConnection().getByteBufferPool().allocate();
    final ByteBuffer buffer = pooled.getBuffer();
    channel.getReadSetter().set(new ChannelListener<StreamSourceChannel>() {

        @Override
        public void handleEvent(final StreamSourceChannel channel) {
            if (done || paused) {
                return;
            }
            PooledByteBuffer pooled = exchange.getConnection().getByteBufferPool().allocate();
            final ByteBuffer buffer = pooled.getBuffer();
            try {
                int res;
                do {
                    if (paused) {
                        return;
                    }
                    try {
                        buffer.clear();
                        res = channel.read(buffer);
                        if (res == -1) {
                            done = true;
                            Connectors.executeRootHandler(new HttpHandler() {

                                @Override
                                public void handleRequest(HttpServerExchange exchange) throws Exception {
                                    callback.handle(exchange, EMPTY_BYTE_ARRAY, true);
                                }
                            }, exchange);
                            return;
                        } else if (res == 0) {
                            return;
                        } else {
                            buffer.flip();
                            final byte[] data = new byte[buffer.remaining()];
                            buffer.get(data);
                            Connectors.executeRootHandler(new HttpHandler() {

                                @Override
                                public void handleRequest(HttpServerExchange exchange) throws Exception {
                                    callback.handle(exchange, data, false);
                                    if (!paused) {
                                        channel.resumeReads();
                                    }
                                }
                            }, exchange);
                        }
                    } catch (final IOException e) {
                        Connectors.executeRootHandler(new HttpHandler() {

                            @Override
                            public void handleRequest(HttpServerExchange exchange) throws Exception {
                                error.error(exchange, e);
                            }
                        }, exchange);
                        return;
                    }
                } while (true);
            } finally {
                pooled.close();
            }
        }
    });
    try {
        int res;
        do {
            try {
                buffer.clear();
                res = channel.read(buffer);
                if (res == -1) {
                    done = true;
                    callback.handle(exchange, EMPTY_BYTE_ARRAY, true);
                    return;
                } else if (res == 0) {
                    channel.resumeReads();
                    return;
                } else {
                    buffer.flip();
                    byte[] data = new byte[buffer.remaining()];
                    buffer.get(data);
                    callback.handle(exchange, data, false);
                    if (paused) {
                        return;
                    }
                }
            } catch (IOException e) {
                error.error(exchange, e);
                return;
            }
        } while (true);
    } finally {
        pooled.close();
    }
}
Also used : StreamSourceChannel(org.xnio.channels.StreamSourceChannel) HttpHandler(io.undertow.server.HttpHandler) IOException(java.io.IOException) ByteBuffer(java.nio.ByteBuffer) PooledByteBuffer(io.undertow.connector.PooledByteBuffer) IOException(java.io.IOException) HttpServerExchange(io.undertow.server.HttpServerExchange) PooledByteBuffer(io.undertow.connector.PooledByteBuffer)

Example 10 with StreamSourceChannel

use of org.xnio.channels.StreamSourceChannel in project undertow by undertow-io.

the class AsyncReceiverImpl method receiveFullBytes.

@Override
public void receiveFullBytes(final FullBytesCallback callback, final ErrorCallback errorCallback) {
    if (done) {
        throw UndertowMessages.MESSAGES.requestBodyAlreadyRead();
    }
    final ErrorCallback error = errorCallback == null ? END_EXCHANGE : errorCallback;
    if (callback == null) {
        throw UndertowMessages.MESSAGES.argumentCannotBeNull("callback");
    }
    if (exchange.isRequestComplete()) {
        callback.handle(exchange, EMPTY_BYTE_ARRAY);
        return;
    }
    String contentLengthString = exchange.getRequestHeaders().getFirst(Headers.CONTENT_LENGTH);
    long contentLength;
    final ByteArrayOutputStream sb;
    if (contentLengthString != null) {
        contentLength = Long.parseLong(contentLengthString);
        if (contentLength > Integer.MAX_VALUE) {
            error.error(exchange, new RequestToLargeException());
            return;
        }
        sb = new ByteArrayOutputStream((int) contentLength);
    } else {
        contentLength = -1;
        sb = new ByteArrayOutputStream();
    }
    if (maxBufferSize > 0) {
        if (contentLength > maxBufferSize) {
            error.error(exchange, new RequestToLargeException());
            return;
        }
    }
    PooledByteBuffer pooled = exchange.getConnection().getByteBufferPool().allocate();
    final ByteBuffer buffer = pooled.getBuffer();
    try {
        int res;
        do {
            try {
                buffer.clear();
                res = channel.read(buffer);
                if (res == -1) {
                    done = true;
                    callback.handle(exchange, sb.toByteArray());
                    return;
                } else if (res == 0) {
                    channel.getReadSetter().set(new ChannelListener<StreamSourceChannel>() {

                        @Override
                        public void handleEvent(StreamSourceChannel channel) {
                            if (done) {
                                return;
                            }
                            PooledByteBuffer pooled = exchange.getConnection().getByteBufferPool().allocate();
                            final ByteBuffer buffer = pooled.getBuffer();
                            try {
                                int res;
                                do {
                                    try {
                                        buffer.clear();
                                        res = channel.read(buffer);
                                        if (res == -1) {
                                            done = true;
                                            Connectors.executeRootHandler(new HttpHandler() {

                                                @Override
                                                public void handleRequest(HttpServerExchange exchange) throws Exception {
                                                    callback.handle(exchange, sb.toByteArray());
                                                }
                                            }, exchange);
                                            return;
                                        } else if (res == 0) {
                                            return;
                                        } else {
                                            buffer.flip();
                                            while (buffer.hasRemaining()) {
                                                sb.write(buffer.get());
                                            }
                                            if (maxBufferSize > 0 && sb.size() > maxBufferSize) {
                                                Connectors.executeRootHandler(new HttpHandler() {

                                                    @Override
                                                    public void handleRequest(HttpServerExchange exchange) throws Exception {
                                                        error.error(exchange, new RequestToLargeException());
                                                    }
                                                }, exchange);
                                                return;
                                            }
                                        }
                                    } catch (final Exception e) {
                                        Connectors.executeRootHandler(new HttpHandler() {

                                            @Override
                                            public void handleRequest(HttpServerExchange exchange) throws Exception {
                                                error.error(exchange, new IOException(e));
                                            }
                                        }, exchange);
                                        return;
                                    }
                                } while (true);
                            } finally {
                                pooled.close();
                            }
                        }
                    });
                    channel.resumeReads();
                    return;
                } else {
                    buffer.flip();
                    while (buffer.hasRemaining()) {
                        sb.write(buffer.get());
                    }
                    if (maxBufferSize > 0 && sb.size() > maxBufferSize) {
                        error.error(exchange, new RequestToLargeException());
                        return;
                    }
                }
            } catch (IOException e) {
                error.error(exchange, e);
                return;
            }
        } while (true);
    } finally {
        pooled.close();
    }
}
Also used : StreamSourceChannel(org.xnio.channels.StreamSourceChannel) HttpHandler(io.undertow.server.HttpHandler) ChannelListener(org.xnio.ChannelListener) ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException) ByteBuffer(java.nio.ByteBuffer) PooledByteBuffer(io.undertow.connector.PooledByteBuffer) IOException(java.io.IOException) HttpServerExchange(io.undertow.server.HttpServerExchange) PooledByteBuffer(io.undertow.connector.PooledByteBuffer)

Aggregations

StreamSourceChannel (org.xnio.channels.StreamSourceChannel)13 IOException (java.io.IOException)9 ByteBuffer (java.nio.ByteBuffer)9 PooledByteBuffer (io.undertow.connector.PooledByteBuffer)8 HttpHandler (io.undertow.server.HttpHandler)4 HttpServerExchange (io.undertow.server.HttpServerExchange)4 Test (org.junit.Test)4 ChannelListener (org.xnio.ChannelListener)4 ByteArrayOutputStream (java.io.ByteArrayOutputStream)3 EmptyStreamSourceChannel (org.xnio.channels.EmptyStreamSourceChannel)3 ALPNProvider (io.undertow.protocols.alpn.ALPNProvider)1 SslConduit (io.undertow.protocols.ssl.SslConduit)1 TestHttpClient (io.undertow.testutils.TestHttpClient)1 ImmediatePooled (io.undertow.util.ImmediatePooled)1 StringWriteChannelListener (io.undertow.util.StringWriteChannelListener)1 InputStream (java.io.InputStream)1 OutputStream (java.io.OutputStream)1 CharBuffer (java.nio.CharBuffer)1 Channel (java.nio.channels.Channel)1 ClosedChannelException (java.nio.channels.ClosedChannelException)1