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;
}
}
}
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));
}
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);
}
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();
}
}
}
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();
}
}
Aggregations