Skip to content

Instantly share code, notes, and snippets.

@fehmicansaglam
Created February 9, 2012 18:50
Show Gist options
  • Save fehmicansaglam/1781977 to your computer and use it in GitHub Desktop.
Save fehmicansaglam/1781977 to your computer and use it in GitHub Desktop.
Accept range header and write a partial content to the response with Play! Framework.
public static void downloadFile(final Long fileId) throws IOException {
response.setHeader("Accept-Ranges", "bytes");
notFoundIfNull(fileId);
File underlyingFile = ... //load file
String fileName = ...//name of the file
Header rangeHeader = request.headers.get("range");
if (rangeHeader != null) {
throw new PartialContent(underlyingFile, fileName);
} else {
renderBinary(new FileInputStream(underlyingFile),
fileName, underlyingFile.length(),
MimeTypes.getContentType(fileName), false);
}
}
import java.io.File;
import java.io.RandomAccessFile;
import org.jboss.netty.handler.stream.ChunkedFile;
import play.Logger;
import play.exceptions.UnexpectedException;
import play.libs.MimeTypes;
import play.mvc.Http.Header;
import play.mvc.Http.Request;
import play.mvc.Http.Response;
import play.mvc.results.Result;
public class PartialContent extends Result {
private final File file;
private final String fileName;
public PartialContent(final File file, final String fileName) {
this.file = file;
this.fileName = fileName;
}
@Override
public void apply(final Request request, final Response response) {
try {
response.status = 206;
Header rangeHeader = request.headers.get("range");
String rangeValue = rangeHeader.value().trim()
.substring("bytes=".length());
long fileLength = this.file.length();
long start, end;
if (rangeValue.startsWith("-")) {
end = fileLength - 1;
start = fileLength - 1
- Long.parseLong(rangeValue.substring("-".length()));
} else {
String[] range = rangeValue.split("-");
start = Long.parseLong(range[0]);
end = range.length > 1 ? Long.parseLong(range[1])
: fileLength - 1;
}
if (end > fileLength - 1) {
end = fileLength - 1;
}
if (start <= end) {
long contentLength = end - start + 1;
response.setHeader("Content-Length", contentLength + "");
response.setHeader("Content-Range", "bytes " + start + "-"
+ end + "/" + fileLength);
response.setHeader("Content-Type",
MimeTypes.getContentType(this.fileName));
RandomAccessFile raf = new RandomAccessFile(this.file, "r");
response.direct = new ChunkedFile(raf, start, contentLength,
8192);
}
} catch (Exception e) {
throw new UnexpectedException(e);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment