Search in sources :

Example 6 with PooledByteBuffer

use of io.undertow.connector.PooledByteBuffer in project undertow by undertow-io.

the class ConnectionSSLSessionInfo method renegotiateBufferRequest.

public void renegotiateBufferRequest(HttpServerExchange exchange, SslClientAuthMode newAuthMode) throws IOException {
    int maxSize = exchange.getConnection().getUndertowOptions().get(UndertowOptions.MAX_BUFFERED_REQUEST_SIZE, 16384);
    if (maxSize <= 0) {
        throw new SSLPeerUnverifiedException("");
    }
    //first we need to read the request
    boolean requestResetRequired = false;
    StreamSourceChannel requestChannel = Connectors.getExistingRequestChannel(exchange);
    if (requestChannel == null) {
        requestChannel = exchange.getRequestChannel();
        requestResetRequired = true;
    }
    PooledByteBuffer pooled = exchange.getConnection().getByteBufferPool().allocate();
    //if the pooled buffer should be freed
    boolean free = true;
    int usedBuffers = 0;
    PooledByteBuffer[] poolArray = null;
    final int bufferSize = pooled.getBuffer().remaining();
    int allowedBuffers = ((maxSize + bufferSize - 1) / bufferSize);
    poolArray = new PooledByteBuffer[allowedBuffers];
    poolArray[usedBuffers++] = pooled;
    try {
        int res;
        do {
            final ByteBuffer buf = pooled.getBuffer();
            res = Channels.readBlocking(requestChannel, buf);
            if (!buf.hasRemaining()) {
                if (usedBuffers == allowedBuffers) {
                    throw new SSLPeerUnverifiedException("");
                } else {
                    buf.flip();
                    pooled = exchange.getConnection().getByteBufferPool().allocate();
                    poolArray[usedBuffers++] = pooled;
                }
            }
        } while (res != -1);
        free = false;
        pooled.getBuffer().flip();
        Connectors.ungetRequestBytes(exchange, poolArray);
        renegotiateNoRequest(exchange, newAuthMode);
    } finally {
        if (free) {
            for (PooledByteBuffer buf : poolArray) {
                if (buf != null) {
                    buf.close();
                }
            }
        }
        if (requestResetRequired) {
            exchange.requestChannel = null;
        }
    }
}
Also used : StreamSourceChannel(org.xnio.channels.StreamSourceChannel) SSLPeerUnverifiedException(javax.net.ssl.SSLPeerUnverifiedException) PooledByteBuffer(io.undertow.connector.PooledByteBuffer) ByteBuffer(java.nio.ByteBuffer) PooledByteBuffer(io.undertow.connector.PooledByteBuffer)

Example 7 with PooledByteBuffer

use of io.undertow.connector.PooledByteBuffer in project undertow by undertow-io.

the class DefaultByteBufferPool method allocate.

@Override
public PooledByteBuffer allocate() {
    if (closed) {
        throw UndertowMessages.MESSAGES.poolIsClosed();
    }
    ByteBuffer buffer = null;
    ThreadLocalData local = null;
    if (threadLocalCacheSize > 0) {
        local = threadLocalCache.get();
        if (local != null) {
            buffer = local.buffers.poll();
            if (buffer != null) {
                currentQueueLengthUpdater.decrementAndGet(this);
            }
        } else {
            local = new ThreadLocalData();
            synchronized (threadLocalDataList) {
                if (closed) {
                    throw UndertowMessages.MESSAGES.poolIsClosed();
                }
                cleanupThreadLocalData();
                threadLocalDataList.add(new WeakReference<>(local));
                threadLocalCache.set(local);
            }
        }
    }
    if (buffer == null) {
        buffer = queue.poll();
    }
    if (buffer == null) {
        if (direct) {
            buffer = ByteBuffer.allocateDirect(bufferSize);
        } else {
            buffer = ByteBuffer.allocate(bufferSize);
        }
    }
    if (local != null) {
        local.allocationDepth++;
    }
    buffer.clear();
    return new DefaultPooledBuffer(this, buffer, leakDectionPercent == 0 ? false : (++count % 100 > leakDectionPercent));
}
Also used : PooledByteBuffer(io.undertow.connector.PooledByteBuffer) ByteBuffer(java.nio.ByteBuffer)

Example 8 with PooledByteBuffer

use of io.undertow.connector.PooledByteBuffer 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 9 with PooledByteBuffer

use of io.undertow.connector.PooledByteBuffer in project undertow by undertow-io.

the class ServletOutputStreamImpl method writeTooLargeForBuffer.

private void writeTooLargeForBuffer(byte[] b, int off, int len, ByteBuffer buffer) throws IOException {
    //so what we have will not fit.
    //We allocate multiple buffers up to MAX_BUFFERS_TO_ALLOCATE
    //and put it in them
    //if it still dopes not fit we loop, re-using these buffers
    StreamSinkChannel channel = this.channel;
    if (channel == null) {
        this.channel = channel = servletRequestContext.getExchange().getResponseChannel();
    }
    final ByteBufferPool bufferPool = servletRequestContext.getExchange().getConnection().getByteBufferPool();
    ByteBuffer[] buffers = new ByteBuffer[MAX_BUFFERS_TO_ALLOCATE + 1];
    PooledByteBuffer[] pooledBuffers = new PooledByteBuffer[MAX_BUFFERS_TO_ALLOCATE];
    try {
        buffers[0] = buffer;
        int bytesWritten = 0;
        int rem = buffer.remaining();
        buffer.put(b, bytesWritten + off, rem);
        buffer.flip();
        bytesWritten += rem;
        int bufferCount = 1;
        for (int i = 0; i < MAX_BUFFERS_TO_ALLOCATE; ++i) {
            PooledByteBuffer pooled = bufferPool.allocate();
            pooledBuffers[bufferCount - 1] = pooled;
            buffers[bufferCount++] = pooled.getBuffer();
            ByteBuffer cb = pooled.getBuffer();
            int toWrite = len - bytesWritten;
            if (toWrite > cb.remaining()) {
                rem = cb.remaining();
                cb.put(b, bytesWritten + off, rem);
                cb.flip();
                bytesWritten += rem;
            } else {
                cb.put(b, bytesWritten + off, toWrite);
                bytesWritten = len;
                cb.flip();
                break;
            }
        }
        Channels.writeBlocking(channel, buffers, 0, bufferCount);
        while (bytesWritten < len) {
            //ok, it did not fit, loop and loop and loop until it is done
            bufferCount = 0;
            for (int i = 0; i < MAX_BUFFERS_TO_ALLOCATE + 1; ++i) {
                ByteBuffer cb = buffers[i];
                cb.clear();
                bufferCount++;
                int toWrite = len - bytesWritten;
                if (toWrite > cb.remaining()) {
                    rem = cb.remaining();
                    cb.put(b, bytesWritten + off, rem);
                    cb.flip();
                    bytesWritten += rem;
                } else {
                    cb.put(b, bytesWritten + off, toWrite);
                    bytesWritten = len;
                    cb.flip();
                    break;
                }
            }
            Channels.writeBlocking(channel, buffers, 0, bufferCount);
        }
        buffer.clear();
    } finally {
        for (int i = 0; i < pooledBuffers.length; ++i) {
            PooledByteBuffer p = pooledBuffers[i];
            if (p == null) {
                break;
            }
            p.close();
        }
    }
}
Also used : ByteBufferPool(io.undertow.connector.ByteBufferPool) PooledByteBuffer(io.undertow.connector.PooledByteBuffer) StreamSinkChannel(org.xnio.channels.StreamSinkChannel) ByteBuffer(java.nio.ByteBuffer) PooledByteBuffer(io.undertow.connector.PooledByteBuffer)

Example 10 with PooledByteBuffer

use of io.undertow.connector.PooledByteBuffer in project undertow by undertow-io.

the class Http2ClearClientProvider method createSettingsFrame.

public static String createSettingsFrame(OptionMap options, ByteBufferPool bufferPool) {
    PooledByteBuffer b = bufferPool.allocate();
    try {
        ByteBuffer currentBuffer = b.getBuffer();
        if (options.contains(UndertowOptions.HTTP2_SETTINGS_HEADER_TABLE_SIZE)) {
            pushOption(currentBuffer, Http2Setting.SETTINGS_HEADER_TABLE_SIZE, options.get(UndertowOptions.HTTP2_SETTINGS_HEADER_TABLE_SIZE));
        }
        if (options.contains(UndertowOptions.HTTP2_SETTINGS_ENABLE_PUSH)) {
            pushOption(currentBuffer, Http2Setting.SETTINGS_ENABLE_PUSH, options.get(UndertowOptions.HTTP2_SETTINGS_ENABLE_PUSH) ? 1 : 0);
        }
        if (options.contains(UndertowOptions.HTTP2_SETTINGS_MAX_CONCURRENT_STREAMS)) {
            pushOption(currentBuffer, Http2Setting.SETTINGS_MAX_CONCURRENT_STREAMS, options.get(UndertowOptions.HTTP2_SETTINGS_MAX_CONCURRENT_STREAMS));
        }
        if (options.contains(UndertowOptions.HTTP2_SETTINGS_INITIAL_WINDOW_SIZE)) {
            pushOption(currentBuffer, Http2Setting.SETTINGS_INITIAL_WINDOW_SIZE, options.get(UndertowOptions.HTTP2_SETTINGS_INITIAL_WINDOW_SIZE));
        }
        if (options.contains(UndertowOptions.HTTP2_SETTINGS_MAX_FRAME_SIZE)) {
            pushOption(currentBuffer, Http2Setting.SETTINGS_MAX_FRAME_SIZE, options.get(UndertowOptions.HTTP2_SETTINGS_MAX_FRAME_SIZE));
        }
        if (options.contains(UndertowOptions.HTTP2_SETTINGS_MAX_HEADER_LIST_SIZE)) {
            pushOption(currentBuffer, Http2Setting.SETTINGS_MAX_HEADER_LIST_SIZE, options.get(UndertowOptions.HTTP2_SETTINGS_MAX_HEADER_LIST_SIZE));
        } else if (options.contains(UndertowOptions.MAX_HEADER_SIZE)) {
            pushOption(currentBuffer, Http2Setting.SETTINGS_MAX_HEADER_LIST_SIZE, options.get(UndertowOptions.HTTP2_SETTINGS_MAX_HEADER_LIST_SIZE));
        }
        currentBuffer.flip();
        return FlexBase64.encodeStringURL(currentBuffer, false);
    } finally {
        b.close();
    }
}
Also used : PooledByteBuffer(io.undertow.connector.PooledByteBuffer) ByteBuffer(java.nio.ByteBuffer) PooledByteBuffer(io.undertow.connector.PooledByteBuffer)

Aggregations

PooledByteBuffer (io.undertow.connector.PooledByteBuffer)54 ByteBuffer (java.nio.ByteBuffer)45 IOException (java.io.IOException)28 ImmediatePooledByteBuffer (io.undertow.util.ImmediatePooledByteBuffer)9 StreamSourceChannel (org.xnio.channels.StreamSourceChannel)8 HttpServerExchange (io.undertow.server.HttpServerExchange)7 ClosedChannelException (java.nio.channels.ClosedChannelException)6 ByteArrayOutputStream (java.io.ByteArrayOutputStream)5 ChannelListener (org.xnio.ChannelListener)5 HttpHandler (io.undertow.server.HttpHandler)4 StreamSinkChannel (org.xnio.channels.StreamSinkChannel)4 SendFrameHeader (io.undertow.server.protocol.framed.SendFrameHeader)3 HeaderMap (io.undertow.util.HeaderMap)3 HttpString (io.undertow.util.HttpString)3 InterruptedIOException (java.io.InterruptedIOException)3 ByteBufferPool (io.undertow.connector.ByteBufferPool)2 CharBuffer (java.nio.CharBuffer)2 CharsetDecoder (java.nio.charset.CharsetDecoder)2 IoCallback (io.undertow.io.IoCallback)1 Sender (io.undertow.io.Sender)1