private void setFileHeader(Response ares, FileRepresentation fentity) { setHeader(ares); // TODO: Shouldn't have to do this, but without it we sometimes seem to get two Content-Length // headers in the response. header("Content-Length", (String) null); header("Content-Length", fentity.getSize()); header("Content-Type", fentity.getMediaType().getName()); }
public NettyHttpResponse write(Response ares) { // if (!aradonResponse.getStatus().isSuccess()) throw new // ResourceException(aradonResponse.getStatus()) ; Representation entity = ares.getEntity(); // Get the connector service to callback if (ares.getStatus().isSuccess() && entity instanceof FileRepresentation) { FileRepresentation fentity = (FileRepresentation) entity; if (fentity.getSize() < 1024 * 512) { return writeFileEntity(ares, fentity); } else { return writeBigFile(ares, fentity); } } else { return writeEntity(ares, entity); } }
private NettyHttpResponse writeFileEntity(Response ares, FileRepresentation fentity) { try { setFileHeader(ares, fentity); File file = fentity.getFile(); FileChannel fc = fentity.getChannel(); MappedByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, file.length()); content(bb); } catch (IOException ex) { ioExceptionHandler.uncaughtException( Thread.currentThread(), AradonRuntimeException.fromException(ex, ctx.getChannel())); error(ex); } finally { end(); } return this; }
private NettyHttpResponse writeBigFile(Response ares, FileRepresentation fentity) { try { setFileHeader(ares, fentity); ChannelFuture writeFuture = write(responseBuffer); final long fileLength = fentity.getSize(); final FileInputStream fis = fentity.getStream(); writeFuture.addListener( new ChannelFutureListener() { private final ChannelBuffer buffer = ChannelBuffers.buffer(4096); private long offset = 0; public void operationComplete(ChannelFuture future) throws Exception { if (!future.isSuccess()) { future.getCause().printStackTrace(); future.getChannel().close(); fis.close(); return; } // System.out.println("SENDING: " + offset + " / " + fileLength); buffer.clear(); buffer.writeBytes(fis, (int) Math.min(fileLength - offset, buffer.writableBytes())); offset += buffer.writerIndex(); ChannelFuture chunkWriteFuture = future.getChannel().write(buffer); if (offset < fileLength) { // Send the next chunk chunkWriteFuture.addListener(this); } else { // Wrote the last chunk - close the connection if the write is done. // System.out.println("DONE: " + fileLength); chunkWriteFuture.addListener(ChannelFutureListener.CLOSE); fis.close(); } } }); } catch (Exception ex) { exceptionHandler.uncaughtException( Thread.currentThread(), AradonRuntimeException.fromException(ex, ctx.getChannel())); } return this; }