use of org.jboss.netty.handler.stream.ChunkedFile in project crate by crate.
the class HttpBlobHandler method fullContentResponse.
private void fullContentResponse(HttpRequest request, String index, final String digest) throws IOException {
BlobShard blobShard = localBlobShard(index, digest);
HttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK);
final RandomAccessFile raf = blobShard.blobContainer().getRandomAccessFile(digest);
try {
HttpHeaders.setContentLength(response, raf.length());
setDefaultGetHeaders(response);
LOGGER.trace("HttpResponse: {}", response);
Channel channel = ctx.getChannel();
channel.write(response);
ChannelFuture writeFuture;
if (sslEnabled) {
// Cannot use zero-copy with HTTPS.
writeFuture = channel.write(new ChunkedFile(raf, 0, raf.length(), 8192));
} else {
writeFuture = transferFile(digest, raf, 0, raf.length());
}
if (!HttpHeaders.isKeepAlive(request)) {
writeFuture.addListener(ChannelFutureListener.CLOSE);
}
} catch (Throwable t) {
/*
* Make sure RandomAccessFile is closed when exception is raised.
* In case of success, the ChannelFutureListener in "transferFile" will take care
* that the resources are released.
*/
raf.close();
throw t;
}
}
use of org.jboss.netty.handler.stream.ChunkedFile in project NabAlive by jcheype.
the class HttpStaticFileServerHandler method messageReceived.
public void messageReceived(ChannelHandlerContext ctx, HttpRequest request) throws Exception {
//HttpRequest request = (HttpRequest) e.getMessage();
QueryStringDecoder qs = new QueryStringDecoder(request.getUri());
if (request.getMethod() != GET) {
sendError(ctx, METHOD_NOT_ALLOWED);
return;
}
final String path = sanitizeUri(qs.getPath());
if (path == null) {
sendError(ctx, FORBIDDEN);
return;
}
boolean toBeCached = false;
File file = new File(path);
if (file.isDirectory())
file = new File(file, "index.html");
if (!file.exists()) {
String newPath = path.replaceAll("_[0-9]+(\\.\\w+)$", "$1");
logger.debug("newPath: {}", newPath);
file = new File(newPath);
toBeCached = true;
}
logger.debug("search file: {}", file.getAbsolutePath());
if (file.isHidden() || !file.exists()) {
sendError(ctx, NOT_FOUND);
return;
}
if (!file.isFile()) {
sendError(ctx, FORBIDDEN);
return;
}
// Cache Validation
String ifModifiedSince = request.getHeader(HttpHeaders.Names.IF_MODIFIED_SINCE);
if (ifModifiedSince != null && !ifModifiedSince.equals("")) {
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;
boolean isGz = false;
try {
File fileGz = new File(file.getAbsolutePath() + ".gz");
logger.debug("searching gzip: {}", fileGz.getAbsolutePath());
String acceptHeader = request.getHeader(Names.ACCEPT_ENCODING);
if (fileGz.isFile() && acceptHeader != null && acceptHeader.contains("gzip")) {
isGz = true;
raf = new RandomAccessFile(fileGz, "r");
} else
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);
setContentTypeHeader(response, file);
setDateAndCacheHeaders(response, file, toBeCached);
if (isGz)
response.setHeader(Names.CONTENT_ENCODING, "gzip");
//e.getChannel();
Channel ch = ctx.getChannel();
// Write the initial line and the header.
ch.write(response);
// Write the content.
ChannelFuture writeFuture;
if (ch.getPipeline().get(SslHandler.class) != null) {
// Cannot use zero-copy with HTTPS.
writeFuture = ch.write(new ChunkedFile(raf, 0, fileLength, 8192));
} else {
// No encryption - use zero-copy.
final FileRegion region = new DefaultFileRegion(raf.getChannel(), 0, fileLength);
writeFuture = ch.write(region);
writeFuture.addListener(new ChannelFutureProgressListener() {
@Override
public void operationComplete(ChannelFuture future) {
region.releaseExternalResources();
}
@Override
public void operationProgressed(ChannelFuture future, long amount, long current, long total) {
System.out.printf("%s: %d / %d (+%d)%n", path, current, total, amount);
}
});
}
// Decide whether to close the connection or not.
if (!isKeepAlive(request)) {
// Close the connection when the whole content is written out.
writeFuture.addListener(ChannelFutureListener.CLOSE);
}
}
Aggregations