Search in sources :

Example 1 with RemoteBinaryFilters

use of org.apache.jackrabbit.oak.remote.RemoteBinaryFilters in project jackrabbit-oak by apache.

the class ContentRemoteSessionTest method testReadBinary.

@Test
public void testReadBinary() {
    Blob blob = mock(Blob.class);
    ContentRemoteBinaryId binaryId = mock(ContentRemoteBinaryId.class);
    doReturn(blob).when(binaryId).asBlob();
    assertNotNull(createSession().readBinary(binaryId, new RemoteBinaryFilters()));
}
Also used : Blob(org.apache.jackrabbit.oak.api.Blob) RemoteBinaryFilters(org.apache.jackrabbit.oak.remote.RemoteBinaryFilters) Test(org.junit.Test)

Example 2 with RemoteBinaryFilters

use of org.apache.jackrabbit.oak.remote.RemoteBinaryFilters in project jackrabbit-oak by apache.

the class GetBinaryHandler method parseRange.

/**
     * Parse a range extracted from the Range header and return a wrapped
     * RemoteBinaryFilters instance for the range or null if the range is not
     * valid or malformed.
     * <p/>
     * The returned RemoteBinaryFilters object will never return -1 in
     * getCount.
     */
private RemoteBinaryFilters parseRange(String range, long fileLength) {
    Matcher matcher = RANGE_PATTERN.matcher(range);
    if (!matcher.matches()) {
        return null;
    }
    final long start;
    final long end;
    // Content-Range: X
    if (matcher.group(2) == null || matcher.group(2).isEmpty()) {
        start = Long.parseLong(matcher.group(1));
        end = fileLength - 1;
    } else // Content-Range: -X
    if (matcher.group(1).isEmpty()) {
        end = fileLength - 1;
        start = end - Long.parseLong(matcher.group(2)) + 1;
    } else // Content-Range: X-Y
    {
        start = Long.parseLong(matcher.group(1));
        end = Long.parseLong(matcher.group(2));
    }
    // Simple range validation
    if (start < 0 || end < 0 || start > end || end >= fileLength || start >= fileLength) {
        return null;
    }
    return new RemoteBinaryFilters() {

        @Override
        public long getStart() {
            return start;
        }

        @Override
        public long getCount() {
            return end - start + 1;
        }
    };
}
Also used : Matcher(java.util.regex.Matcher) RemoteBinaryFilters(org.apache.jackrabbit.oak.remote.RemoteBinaryFilters)

Example 3 with RemoteBinaryFilters

use of org.apache.jackrabbit.oak.remote.RemoteBinaryFilters in project jackrabbit-oak by apache.

the class GetBinaryHandler method handle.

@Override
public void handle(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
    RemoteSession session = (RemoteSession) request.getAttribute("session");
    if (session == null) {
        sendInternalServerError(response, "session not found");
        return;
    }
    String providedBinaryId = readBinaryId(request);
    if (providedBinaryId == null) {
        sendBadRequest(response, "unable to read the provided binary ID");
        return;
    }
    RemoteBinaryId binaryId = session.readBinaryId(providedBinaryId);
    if (binaryId == null) {
        sendNotFound(response, "binary ID not found");
        return;
    }
    List<RemoteBinaryFilters> contentRanges = parseRequestRanges(request, session, binaryId);
    if (contentRanges == null) {
        handleFile(response, session, binaryId);
    } else if (contentRanges.size() == 1) {
        handleSingleRange(response, session, binaryId, contentRanges.get(0));
    } else {
        handleMultipleRanges(response, session, binaryId, contentRanges);
    }
}
Also used : RemoteSession(org.apache.jackrabbit.oak.remote.RemoteSession) RemoteBinaryFilters(org.apache.jackrabbit.oak.remote.RemoteBinaryFilters) RemoteBinaryId(org.apache.jackrabbit.oak.remote.RemoteBinaryId)

Example 4 with RemoteBinaryFilters

use of org.apache.jackrabbit.oak.remote.RemoteBinaryFilters in project jackrabbit-oak by apache.

the class GetBinaryHandler method handleMultipleRanges.

/**
     * RFC7233
     * <p/>
     * This handler sends a 206 Partial Content http status, the Content-Length
     * header, Content-Type multipart/byteranges The payload contains all the
     * requested binary fragments.
     * <p/>
     * This handler is used when multiple ranges are requested.
     */
private void handleMultipleRanges(HttpServletResponse response, RemoteSession session, RemoteBinaryId binaryId, List<RemoteBinaryFilters> ranges) throws IOException {
    String header;
    long rangeStart, rangeEnd, fileLength, contentLength;
    fileLength = session.readBinaryLength(binaryId);
    // Compute response content length
    // Create multipart headers
    contentLength = 0;
    List<String> multipartHeaders = new ArrayList<String>(ranges.size());
    for (RemoteBinaryFilters range : ranges) {
        rangeStart = range.getStart();
        rangeEnd = rangeStart + range.getCount() - 1;
        header = String.format("\n" + "--%s\n" + "Content-Type: application/octet-stream" + "Content-Content-Range: %d-%d/%d\n\n", MULTIPART_DELIMITER, rangeStart, rangeEnd, fileLength);
        multipartHeaders.add(header);
        contentLength += header.getBytes().length;
        contentLength += range.getCount();
    }
    // Send response status and headers
    response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
    response.setContentLength((int) contentLength);
    response.setContentType("multipart/byteranges; boundary=" + MULTIPART_DELIMITER);
    // Send requested ranges
    RemoteBinaryFilters range;
    InputStream in;
    OutputStream out = response.getOutputStream();
    Iterator<RemoteBinaryFilters> rangeIt = ranges.iterator();
    Iterator<String> headerIt = multipartHeaders.iterator();
    while (rangeIt.hasNext() && headerIt.hasNext()) {
        range = rangeIt.next();
        header = headerIt.next();
        out.write(header.getBytes());
        in = session.readBinary(binaryId, range);
        ByteStreams.copy(in, out);
    }
    out.close();
}
Also used : InputStream(java.io.InputStream) OutputStream(java.io.OutputStream) ArrayList(java.util.ArrayList) RemoteBinaryFilters(org.apache.jackrabbit.oak.remote.RemoteBinaryFilters)

Example 5 with RemoteBinaryFilters

use of org.apache.jackrabbit.oak.remote.RemoteBinaryFilters in project jackrabbit-oak by apache.

the class GetBinaryHandler method parseRequestRanges.

/**
     * This method parses the request Range header a list of ranges as
     * RemoteBinaryFilters ( or null when the header is missing or contains
     * invalid/malformed values
     */
private List<RemoteBinaryFilters> parseRequestRanges(HttpServletRequest request, RemoteSession session, RemoteBinaryId binaryId) {
    // Check header exists
    String headerValue = request.getHeader(RANGE_HEADER);
    if (headerValue == null) {
        return null;
    }
    // Check header is bytes=*
    Matcher matcher = RANGE_HEADER_PATTERN.matcher(headerValue);
    if (!matcher.matches()) {
        return null;
    }
    // Iterate requested ranges
    headerValue = matcher.group(1);
    StringTokenizer tokenizer = new StringTokenizer(headerValue, ",");
    List<RemoteBinaryFilters> ranges = new LinkedList<RemoteBinaryFilters>();
    RemoteBinaryFilters range;
    long fileLength = session.readBinaryLength(binaryId);
    while (tokenizer.hasMoreTokens()) {
        range = parseRange(tokenizer.nextToken(), fileLength);
        if (range == null) {
            return null;
        }
        ranges.add(range);
    }
    return ranges;
}
Also used : StringTokenizer(java.util.StringTokenizer) Matcher(java.util.regex.Matcher) RemoteBinaryFilters(org.apache.jackrabbit.oak.remote.RemoteBinaryFilters) LinkedList(java.util.LinkedList)

Aggregations

RemoteBinaryFilters (org.apache.jackrabbit.oak.remote.RemoteBinaryFilters)6 InputStream (java.io.InputStream)2 OutputStream (java.io.OutputStream)2 Matcher (java.util.regex.Matcher)2 ArrayList (java.util.ArrayList)1 LinkedList (java.util.LinkedList)1 StringTokenizer (java.util.StringTokenizer)1 Blob (org.apache.jackrabbit.oak.api.Blob)1 RemoteBinaryId (org.apache.jackrabbit.oak.remote.RemoteBinaryId)1 RemoteSession (org.apache.jackrabbit.oak.remote.RemoteSession)1 Test (org.junit.Test)1