/******************************************************************************************************************* * ******************************************************************************************************************/ @Nonnull private ResponseEntity<ResourceRegion> audioFileContentResponse (final @Nonnull AudioFile file, final @CheckForNull String rangeHeader) throws IOException { final long length = file.getSize(); final List<Range> ranges = Range.fromHeader(rangeHeader, length); if (ranges.size() > 1) { throw new RuntimeException("Can't support multi-range" + ranges); // FIXME } // E.g. HTML5 <audio> crashes if fed with too many data. final long maxSize = (rangeHeader != null) ? 1024*1024 : length; final Range fullRange = Range.full(length); final Range range = ranges.stream().findFirst().orElse(fullRange).subrange(maxSize); final String displayName = file.as(Displayable).getDisplayName(); // FIXME: getRdfsLabel() final HttpStatus status = range.equals(fullRange) ? OK : PARTIAL_CONTENT; return file.getContent().map(resource -> ResponseEntity.status(status) .contentType(new MediaType("audio", "mpeg")) .header(CONTENT_DISPOSITION, contentDisposition(displayName)) .body(range.getRegion(resource))) .orElseThrow(NotFoundException::new); }