/** * Get the binary content of a datastream * * @param rangeValue the range value * @return Binary blob * @throws IOException if io exception occurred */ protected Response getBinaryContent(final String rangeValue) throws IOException { final FedoraBinary binary = (FedoraBinary) resource(); // we include an explicit etag, because the default behavior is to use the JCR node's etag, not // the jcr:content node digest. The etag is only included if we are not within a transaction. final String txId = TransactionServiceImpl.getCurrentTransactionId(session()); if (txId == null) { checkCacheControlHeaders(request, servletResponse, binary, session()); } final CacheControl cc = new CacheControl(); cc.setMaxAge(0); cc.setMustRevalidate(true); Response.ResponseBuilder builder; if (rangeValue != null && rangeValue.startsWith("bytes")) { final Range range = Range.convert(rangeValue); final long contentSize = binary.getContentSize(); final String endAsString; if (range.end() == -1) { endAsString = Long.toString(contentSize - 1); } else { endAsString = Long.toString(range.end()); } final String contentRangeValue = String.format("bytes %s-%s/%s", range.start(), endAsString, contentSize); if (range.end() > contentSize || (range.end() == -1 && range.start() > contentSize)) { builder = status(REQUESTED_RANGE_NOT_SATISFIABLE).header("Content-Range", contentRangeValue); } else { final RangeRequestInputStream rangeInputStream = new RangeRequestInputStream(binary.getContent(), range.start(), range.size()); builder = status(PARTIAL_CONTENT) .entity(rangeInputStream) .header("Content-Range", contentRangeValue); } } else { final InputStream content = binary.getContent(); builder = ok(content); } // we set the content-type explicitly to avoid content-negotiation from getting in the way return builder.type(binary.getMimeType()).cacheControl(cc).build(); }
/** * Add any resource-specific headers to the response * * @param resource the resource */ protected void addResourceHttpHeaders(final FedoraResource resource) { if (resource instanceof FedoraBinary) { final FedoraBinary binary = (FedoraBinary) resource; final ContentDisposition contentDisposition = ContentDisposition.type("attachment") .fileName(binary.getFilename()) .creationDate(binary.getCreatedDate()) .modificationDate(binary.getLastModifiedDate()) .size(binary.getContentSize()) .build(); servletResponse.addHeader("Content-Type", binary.getMimeType()); servletResponse.addHeader("Content-Length", String.valueOf(binary.getContentSize())); servletResponse.addHeader("Accept-Ranges", "bytes"); servletResponse.addHeader("Content-Disposition", contentDisposition.toString()); } servletResponse.addHeader("Link", "<" + LDP_NAMESPACE + "Resource>;rel=\"type\""); if (resource instanceof NonRdfSource) { servletResponse.addHeader("Link", "<" + LDP_NAMESPACE + "NonRDFSource>;rel=\"type\""); } else if (resource instanceof Container) { servletResponse.addHeader("Link", "<" + CONTAINER.getURI() + ">;rel=\"type\""); if (resource.hasType(LDP_BASIC_CONTAINER)) { servletResponse.addHeader("Link", "<" + BASIC_CONTAINER.getURI() + ">;rel=\"type\""); } else if (resource.hasType(LDP_DIRECT_CONTAINER)) { servletResponse.addHeader("Link", "<" + DIRECT_CONTAINER.getURI() + ">;rel=\"type\""); } else if (resource.hasType(LDP_INDIRECT_CONTAINER)) { servletResponse.addHeader("Link", "<" + INDIRECT_CONTAINER.getURI() + ">;rel=\"type\""); } else { servletResponse.addHeader("Link", "<" + BASIC_CONTAINER.getURI() + ">;rel=\"type\""); } } else { servletResponse.addHeader("Link", "<" + LDP_NAMESPACE + "RDFSource>;rel=\"type\""); } if (httpHeaderInject != null) { httpHeaderInject.addHttpHeaderToResponseStream(servletResponse, uriInfo, resource()); } }