Skip to content

Instantly share code, notes, and snippets.

@Skarlit
Last active December 5, 2018 02:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Skarlit/a5dea8b9836ee74c41c791dc193523e0 to your computer and use it in GitHub Desktop.
Save Skarlit/a5dea8b9836ee74c41c791dc193523e0 to your computer and use it in GitHub Desktop.
final long MAX_ALLOWED_CHUNK_SIZE = 15 * 1024 * 1024;
final Pattern rangeMatcher = Pattern.compile("[^\\d]+(\\d+)[^\\d]+(\\d+)?");
public Result download(String path) {
String sanitizedPath;
try {
sanitizedPath = sanitizedUserInputPath(path == null ? "" : path);
} catch(RuntimeException e) {
return badRequest(e.toString());
}
if (!request().getHeaders().contains("Range")) {
return ok(new java.io.File(sanitizedPath));
}
String rangeHeader = request().getHeaders().get("Range").get();
Matcher rangeValues = rangeMatcher.matcher(rangeHeader);
if (!rangeValues.find()) {
return badRequest("Missing range header");
}
long fileSize = new File(sanitizedPath).length();
long start, end;
if (rangeValues.group(1) != null) {
start = Long.parseLong(rangeValues.group(1));
} else {
start = 0;
}
if (rangeValues.group(2) != null) {
// -1 because byte array index starts at 0.
end = Math.min(Long.parseLong(rangeValues.group(2)), MAX_ALLOWED_CHUNK_SIZE - 1);
} else {
end = Math.min(fileSize - 1, start + MAX_ALLOWED_CHUNK_SIZE - 1);
}
// get MIME type
String mimeType;
try {
mimeType = Files.probeContentType(Paths.get(sanitizedPath));
} catch (IOException e) {
return badRequest("Unknown MIME type");
}
long contentLength = end - start + 1;
String returnContentRange = String.format("bytes %d-%d/%d", start, end, fileSize);
Source<ByteString, ?> source = FileIO.fromPath(Paths.get(sanitizedPath), (int) contentLength, start);
return new Result(
new ResponseHeader(206, ImmutableMap.of(
"Accept-Ranges", "bytes",
"Content-Range", returnContentRange // Without this field, it won't work
)),
new HttpEntity.Streamed(source, Optional.of(contentLength), Optional.of(mimeType))
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment