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