I am trying to allow my game client to download the cache needed for the client to run. Inside of my game web server I am doing this:
@RouteManifest(template="/cache", method="GET")
public class APICacheRoute extends RouteHttpHandler<JadePreprocessor> {
@Override
public void handleRequest(HttpServerExchange exchange) throws Exception {
Path path = Paths.get("./cache/Alterscape.zip");
File file = path.toFile();
exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, "application/octet-stream");
exchange.getResponseSender().send(file);
}
}
However, I am receiving the error that the file must be a ByteBuffer. How can I return a file to download?
My web server looks like this:
public static void initialize() {
ServerController server = new ServerController("localhost", 8080, 8443);
server.register(new APIVirtualHost());
server.inititialize();
}
My APIVirtualHost looks like this:
public APIVirtualHost() {
super(127.0.0.1);
setDirectoryListingEnabled(false);
}
With Undertow, you need to dispatch the handler off the I/O thread to use a blocking operation. You'll need to do this any time you need to perform blocking operations, such as reading the a request body, accepting a file upload stream, and of course, sending a file.
At the top of your handle() method, use this to dispatch the request to a blocking thread, and off the non-blocking I/O thread:
if (serverExchange.isInIoThread()) {
serverExchange.dispatch(this);
return;
}
Then start blocking when you're ready to send the buffer:
serverExchange.startBlocking();
Then to send a file, you can use a Buffered stream:
serverExchange.getResponseHeaders().put(Headers.CONTENT_TYPE, "application/octet-stream");
final File file = new File("/location/to/your/file");
final OutputStream outputStream = serverExchange.getOutputStream();
final InputStream inputStream = new FileInputStream(file);
byte[] buf = new byte[8192];
int c;
while ((c = inputStream.read(buf, 0, buf.length)) > 0) {
outputStream.write(buf, 0, c);
outputStream.flush();
}
outputStream.close();
inputStream.close();
The send
method on the ServerExchange
object is for sending response data using the non-blocking method - good for text or JSON. The ByteBuffer
argument overload is for sending raw byte data, which is what Undertow converts strings to when sending. It can be a bit misleading.
Happy Coding.