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