Example usage for org.springframework.http HttpHeaders IF_RANGE

List of usage examples for org.springframework.http HttpHeaders IF_RANGE

Introduction

In this page you can find the example usage for org.springframework.http HttpHeaders IF_RANGE.

Prototype

String IF_RANGE

To view the source code for org.springframework.http HttpHeaders IF_RANGE.

Click Source Link

Document

The HTTP If-Range header field name.

Usage

From source file:com.github.zhanhb.ckfinder.download.PathPartial.java

/**
 * Parse the range header./* ww  w .ja  v a 2 s  .  c  o  m*/
 *
 * @param request The servlet request we are processing
 * @param response The servlet response we are creating
 * @param attr File attributes
 * @param etag ETag of the entity
 * @return array of ranges
 */
@Nullable
@SuppressWarnings("ReturnOfCollectionOrArrayField")
private Range[] parseRange(HttpServletRequest request, HttpServletResponse response, BasicFileAttributes attr,
        String etag) throws IOException {
    // Checking If-Range
    String headerValue = request.getHeader(HttpHeaders.IF_RANGE);
    if (headerValue != null) {
        long headerValueTime = -1;
        try {
            headerValueTime = request.getDateHeader(HttpHeaders.IF_RANGE);
        } catch (IllegalArgumentException e) {
            // Ignore
        }
        // If the ETag the client gave does not match the entity
        // eTag, then the entire entity is returned.
        if (headerValueTime == -1 && !headerValue.trim().equals(etag)
                || attr.lastModifiedTime().toMillis() > 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 = attr.size();
    if (fileLength == 0) {
        return FULL;
    }
    // Retrieving the range header (if any is specified
    String rangeHeader = request.getHeader(HttpHeaders.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=")) {
        return FULL;
    }
    // List which will contain all the ranges which are successfully
    // parsed.
    List<Range> result = new ArrayList<>(4);
    // Parsing the range list
    // "bytes=".length() = 6
    for (int index, last = 6;; last = index + 1) {
        index = rangeHeader.indexOf(',', last);
        boolean isLast = index == -1;
        final String rangeDefinition = (isLast ? rangeHeader.substring(last)
                : rangeHeader.substring(last, index)).trim();
        final int dashPos = rangeDefinition.indexOf('-');
        if (dashPos == -1) {
            break;
        }
        final Range currentRange = new Range(fileLength);
        try {
            if (dashPos == 0) {
                final long offset = Long.parseLong(rangeDefinition);
                if (offset == 0) { // -0, --0
                    break;
                }
                currentRange.start = Math.max(fileLength + offset, 0);
            } else {
                currentRange.start = Long.parseLong(rangeDefinition.substring(0, dashPos));
                if (dashPos < rangeDefinition.length() - 1) {
                    currentRange.end = Long
                            .parseLong(rangeDefinition.substring(dashPos + 1, rangeDefinition.length()));
                }
            }
        } catch (NumberFormatException e) {
            break;
        }
        if (!currentRange.validate()) {
            break;
        }
        result.add(currentRange);
        if (isLast) {
            int size = result.size();
            if (size == 0) {
                break;
            }
            return result.toArray(new Range[size]);
        }
    }
    response.addHeader(HttpHeaders.CONTENT_RANGE, "bytes */" + fileLength);
    response.sendError(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE);
    return null;
}