Skip to content

Instantly share code, notes, and snippets.

@mhgrove
Last active December 22, 2015 11:18
Show Gist options
  • Save mhgrove/6464409 to your computer and use it in GitHub Desktop.
Save mhgrove/6464409 to your computer and use it in GitHub Desktop.
@Override
public void channelRead0(
ChannelHandlerContext ctx, FullHttpRequest request) throws Exception {
if (!request.getDecoderResult().isSuccess()) {
sendError(ctx, BAD_REQUEST);
return;
}
if (request.getMethod() != GET) {
sendError(ctx, METHOD_NOT_ALLOWED);
return;
}
final String uri = request.getUri();
final String path = sanitizeUri(uri);
if (path == null) {
sendError(ctx, FORBIDDEN);
return;
}
//File file = new File(path);
File file = new File("/Users/mhgrove/test_file.gz");
if (file.isHidden() || !file.exists()) {
sendError(ctx, NOT_FOUND);
return;
}
if (file.isDirectory()) {
if (uri.endsWith("/")) {
sendListing(ctx, file);
} else {
sendRedirect(ctx, uri + '/');
}
return;
}
if (!file.isFile()) {
sendError(ctx, FORBIDDEN);
return;
}
// Cache Validation
String ifModifiedSince = request.headers().get(IF_MODIFIED_SINCE);
if (ifModifiedSince != null && !ifModifiedSince.isEmpty()) {
SimpleDateFormat dateFormatter = new SimpleDateFormat(HTTP_DATE_FORMAT, Locale.US);
Date ifModifiedSinceDate = dateFormatter.parse(ifModifiedSince);
// Only compare up to the second because the datetime format we send to the client
// does not have milliseconds
long ifModifiedSinceDateSeconds = ifModifiedSinceDate.getTime() / 1000;
long fileLastModifiedSeconds = file.lastModified() / 1000;
if (ifModifiedSinceDateSeconds == fileLastModifiedSeconds) {
sendNotModified(ctx);
return;
}
}
RandomAccessFile raf;
try {
raf = new RandomAccessFile(file, "r");
} catch (FileNotFoundException fnfe) {
sendError(ctx, NOT_FOUND);
return;
}
long fileLength = raf.length();
HttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK);
// setContentLength(response, fileLength);
response.headers().set(Names.TRANSFER_ENCODING, Values.CHUNKED);
setContentTypeHeader(response, file);
setDateAndCacheHeaders(response, file);
if (isKeepAlive(request)) {
response.headers().set(CONNECTION, HttpHeaders.Values.KEEP_ALIVE);
}
// Write the initial line and the header.
ctx.write(response);
ByteBufHttpOutputStream aOut = ByteBufHttpOutputStream.create(ctx);
FileInputStream aFileInput = new FileInputStream(file);
Closer aCloser = Closer.create();
aCloser.register(aOut);
aCloser.register(aFileInput);
try {
ByteStreams.copy(aFileInput, aOut);
}
finally {
aCloser.close();
}
ctx.flush();
// Write the content.
// ChannelFuture sendFileFuture;
// if (useSendFile) {
// sendFileFuture =
// ctx.write(new DefaultFileRegion(raf.getChannel(), 0, fileLength), ctx.newProgressivePromise());
// } else {
// sendFileFuture =
// ctx.write(new ChunkedFile(raf, 0, fileLength, 8192), ctx.newProgressivePromise());
// }
//
// sendFileFuture.addListener(new ChannelProgressiveFutureListener() {
// @Override
// public void operationProgressed(ChannelProgressiveFuture future, long progress, long total) {
// if (total < 0) { // total unknown
// System.err.println("Transfer progress: " + progress);
// } else {
// System.err.println("Transfer progress: " + progress + " / " + total);
// }
// }
//
// @Override
// public void operationComplete(ChannelProgressiveFuture future) throws Exception {
// System.err.println("Transfer complete.");
// }
// });
//
// // Write the end marker
// ChannelFuture lastContentFuture = ctx.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT);
//
// // Decide whether to close the connection or not.
// if (!isKeepAlive(request)) {
// // Close the connection when the whole content is written out.
// lastContentFuture.addListener(ChannelFutureListener.CLOSE);
// }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment