in src/main/java/org/apache/sling/servlets/get/impl/helpers/StreamRenderer.java [602:711]
private ArrayList<Range> parseRange(HttpServletRequest request,
HttpServletResponse response, ResourceMetadata metadata)
throws IOException {
// Checking If-Range
String headerValue = request.getHeader("If-Range");
if (headerValue != null) {
long headerValueTime = (-1L);
try {
headerValueTime = request.getDateHeader("If-Range");
} catch (IllegalArgumentException e) {
// Ignore
}
if (headerValueTime == (-1L)) {
// If the ETag the client gave does not match the entity
// etag, then the entire entity is returned.
// Sling: no etag support yet, return full range
return FULL;
} else if (metadata.getModificationTime() > (headerValueTime + 1000)) {
// If the timestamp of the entity the client got is older than
// the last modification date of the entity, the entire entity
// is returned.
return FULL;
}
}
long fileLength = metadata.getContentLength();
if (fileLength == 0) {
return FULL;
}
// Retrieving the range header (if any is specified)
String rangeHeader = request.getHeader("Range");
if (rangeHeader == null) {
return FULL;
}
// bytes is the only range unit supported (and I don't see the point
// of adding new ones).
if (!rangeHeader.startsWith("bytes")) {
failParseRange(response, fileLength, rangeHeader);
return null;
}
rangeHeader = rangeHeader.substring(6);
// Vector which will contain all the ranges which are successfully
// parsed.
ArrayList<Range> result = new ArrayList<>();
StringTokenizer commaTokenizer = new StringTokenizer(rangeHeader, ",");
// Parsing the range list
while (commaTokenizer.hasMoreTokens()) {
String rangeDefinition = commaTokenizer.nextToken().trim();
Range currentRange = new Range();
currentRange.length = fileLength;
int dashPos = rangeDefinition.indexOf('-');
if (dashPos == -1) {
failParseRange(response, fileLength, rangeHeader);
return null;
}
if (dashPos == 0) {
try {
long offset = Long.parseLong(rangeDefinition);
currentRange.start = fileLength + offset;
currentRange.end = fileLength - 1;
} catch (NumberFormatException e) {
failParseRange(response, fileLength, rangeHeader);
return null;
}
} else {
try {
currentRange.start = Long.parseLong(rangeDefinition.substring(
0, dashPos));
if (dashPos < rangeDefinition.length() - 1)
currentRange.end = Long.parseLong(rangeDefinition.substring(
dashPos + 1, rangeDefinition.length()));
else
currentRange.end = fileLength - 1;
} catch (NumberFormatException e) {
failParseRange(response, fileLength, rangeHeader);
return null;
}
}
if (!currentRange.validate()) {
failParseRange(response, fileLength, rangeHeader);
return null;
}
result.add(currentRange);
}
return result;
}