Example usage for org.springframework.http HttpHeaders ACCEPT_RANGES

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

Introduction

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

Prototype

String ACCEPT_RANGES

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

Click Source Link

Document

The HTTP Accept-Ranges header field name.

Usage

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

/**
 * Serve the specified resource, optionally including the data content.
 *
 * @param request The servlet request we are processing
 * @param response The servlet response we are creating
 * @param content Should the content be included?
 * @param path the resource to serve/*from  w  w  w .  j  av a2s.  c  om*/
 *
 * @exception IOException if an input/output error occurs
 */
private void serveResource(HttpServletRequest request, HttpServletResponse response, boolean content, Path path)
        throws IOException, ServletException {
    ActionContext context = new ActionContext().put(HttpServletRequest.class, request)
            .put(HttpServletResponse.class, response).put(ServletContext.class, request.getServletContext())
            .put(Path.class, path);
    if (path == null) {
        notFound.handle(context);
        return;
    }
    BasicFileAttributes attr;
    try {
        attr = Files.readAttributes(path, BasicFileAttributes.class);
    } catch (IOException ex) {
        notFound.handle(context);
        return;
    }
    context.put(BasicFileAttributes.class, attr);

    boolean isError = response.getStatus() >= HttpServletResponse.SC_BAD_REQUEST;
    // Check if the conditions specified in the optional If headers are
    // satisfied.
    // Checking If headers
    boolean included = (request.getAttribute(RequestDispatcher.INCLUDE_CONTEXT_PATH) != null);
    String etag = this.eTag.getValue(context);
    if (!included && !isError && !checkIfHeaders(request, response, attr, etag)) {
        return;
    }
    // Find content type.
    String contentType = contentTypeResolver.getValue(context);
    // Get content length
    long contentLength = attr.size();
    // Special case for zero length files, which would cause a
    // (silent) ISE
    boolean serveContent = content && contentLength != 0;
    Range[] ranges = null;
    if (!isError) {
        if (useAcceptRanges) {
            // Accept ranges header
            response.setHeader(HttpHeaders.ACCEPT_RANGES, "bytes");
        }
        // Parse range specifier
        ranges = serveContent ? parseRange(request, response, attr, etag) : FULL;
        // ETag header
        response.setHeader(HttpHeaders.ETAG, etag);
        // Last-Modified header
        response.setDateHeader(HttpHeaders.LAST_MODIFIED, attr.lastModifiedTime().toMillis());
    }
    ServletOutputStream ostream = null;
    if (serveContent) {
        ostream = response.getOutputStream();
    }

    String disposition = contentDisposition.getValue(context);
    if (disposition != null) {
        response.setHeader(HttpHeaders.CONTENT_DISPOSITION, disposition);
    }

    // Check to see if a Filter, Valve of wrapper has written some content.
    // If it has, disable range requests and setting of a content length
    // since neither can be done reliably.
    if (isError || ranges == FULL) {
        // Set the appropriate output headers
        if (contentType != null) {
            log.debug("serveFile: contentType='{}'", contentType);
            response.setContentType(contentType);
        }
        if (contentLength >= 0) {
            setContentLengthLong(response, contentLength);
        }
        // Copy the input stream to our output stream (if requested)
        if (serveContent) {
            log.trace("Serving bytes");
            Files.copy(path, ostream);
        }
    } else if (ranges != null && ranges.length != 0) {
        // Partial content response.
        response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
        if (ranges.length == 1) {
            Range range = ranges[0];
            response.addHeader(HttpHeaders.CONTENT_RANGE, range.toString());
            long length = range.end - range.start + 1;
            setContentLengthLong(response, length);
            if (contentType != null) {
                log.debug("serveFile: contentType='{}'", contentType);
                response.setContentType(contentType);
            }
            if (serveContent) {
                try (InputStream stream = Files.newInputStream(path)) {
                    copyRange(stream, ostream, range, new byte[Math.min((int) length, 8192)]);
                }
            }
        } else {
            response.setContentType("multipart/byteranges; boundary=" + MIME_SEPARATION);
            if (serveContent) {
                copy(path, ostream, ranges, contentType, new byte[Math.min((int) contentLength, 8192)]);
            }
        }
    }
}

From source file:bjerne.gallery.controller.GalleryController.java

/**
 * Method used to return the binary of a gallery file (
 * {@link GalleryFile#getActualFile()} ). This method handles 304 redirects
 * (if file has not changed) and range headers if requested by browser. The
 * range parts is particularly important for videos. The correct response
 * status is set depending on the circumstances.
 * <p>/*from  w  w  w .  j  a  va 2  s  . c om*/
 * NOTE: the range logic should NOT be considered a complete implementation
 * - it's a bare minimum for making requests for byte ranges work.
 * 
 * @param request
 *            Request
 * @param galleryFile
 *            Gallery file
 * @return The binary of the gallery file, or a 304 redirect, or a part of
 *         the file.
 * @throws IOException
 *             If there is an issue accessing the binary file.
 */
private ResponseEntity<InputStreamResource> returnResource(WebRequest request, GalleryFile galleryFile)
        throws IOException {
    LOG.debug("Entering returnResource()");
    if (request.checkNotModified(galleryFile.getActualFile().lastModified())) {
        return null;
    }
    File file = galleryFile.getActualFile();
    String contentType = galleryFile.getContentType();
    String rangeHeader = request.getHeader(HttpHeaders.RANGE);
    long[] ranges = getRangesFromHeader(rangeHeader);
    long startPosition = ranges[0];
    long fileTotalSize = file.length();
    long endPosition = ranges[1] != 0 ? ranges[1] : fileTotalSize - 1;
    long contentLength = endPosition - startPosition + 1;
    LOG.debug("contentLength: {}, file length: {}", contentLength, fileTotalSize);

    LOG.debug("Returning resource {} as inputstream. Start position: {}", file.getCanonicalPath(),
            startPosition);
    InputStream boundedInputStream = new BoundedInputStream(new FileInputStream(file), endPosition + 1);

    InputStream is = new BufferedInputStream(boundedInputStream, 65536);
    InputStreamResource inputStreamResource = new InputStreamResource(is);
    HttpHeaders responseHeaders = new HttpHeaders();
    responseHeaders.setContentLength(contentLength);
    responseHeaders.setContentType(MediaType.valueOf(contentType));
    responseHeaders.add(HttpHeaders.ACCEPT_RANGES, "bytes");
    if (StringUtils.isNotBlank(rangeHeader)) {
        is.skip(startPosition);
        String contentRangeResponseHeader = "bytes " + startPosition + "-" + endPosition + "/" + fileTotalSize;
        responseHeaders.add(HttpHeaders.CONTENT_RANGE, contentRangeResponseHeader);
        LOG.debug("{} was not null but {}. Adding header {} to response: {}", HttpHeaders.RANGE, rangeHeader,
                HttpHeaders.CONTENT_RANGE, contentRangeResponseHeader);
    }
    HttpStatus status = (startPosition == 0 && contentLength == fileTotalSize) ? HttpStatus.OK
            : HttpStatus.PARTIAL_CONTENT;
    LOG.debug("Returning {}. Status: {}, content-type: {}, {}: {}, contentLength: {}", file, status,
            contentType, HttpHeaders.CONTENT_RANGE, responseHeaders.get(HttpHeaders.CONTENT_RANGE),
            contentLength);
    return new ResponseEntity<InputStreamResource>(inputStreamResource, responseHeaders, status);
}

From source file:org.opentestsystem.authoring.testauth.rest.FileGroupController.java

private static HttpHeaders buildResponseHeaders(final int contentLength, final String filename,
        final String contentType) {
    final HttpHeaders responseHeaders = new HttpHeaders();
    responseHeaders.clear();/*ww  w  .j  ava  2s  .  c  om*/
    responseHeaders.add(org.apache.http.HttpHeaders.CONTENT_TYPE, contentType);
    responseHeaders.setPragma("public");
    responseHeaders.setCacheControl("no-store, must-revalidate");
    responseHeaders.setExpires(Long.valueOf("-1"));
    responseHeaders.setContentDispositionFormData("attachment", filename);
    responseHeaders.setContentLength(contentLength);
    responseHeaders.add(org.apache.http.HttpHeaders.ACCEPT_RANGES, "bytes");
    return responseHeaders;
}

From source file:org.opentestsystem.authoring.testauth.rest.PublishingRecordController.java

private HttpHeaders buildResponseHeaders(final int contentLength, final String filename) {
    final HttpHeaders responseHeaders = new HttpHeaders();
    responseHeaders.clear();//from   w  w  w .ja va  2s.  c o  m
    responseHeaders.add(org.apache.http.HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE);
    responseHeaders.setPragma("public");
    responseHeaders.setCacheControl("no-store, must-revalidate");
    responseHeaders.setExpires(Long.valueOf("-1"));
    responseHeaders.setContentDispositionFormData("inline", filename);
    responseHeaders.setContentLength(contentLength);
    responseHeaders.add(org.apache.http.HttpHeaders.ACCEPT_RANGES, "bytes");
    return responseHeaders;
}

From source file:org.opentestsystem.authoring.testauth.rest.ScoringRuleController.java

private HttpHeaders buildResponseHeaders(final int contentLength, final String filename) {
    final HttpHeaders responseHeaders = new HttpHeaders();
    responseHeaders.clear();// w w  w  .  j av a  2s .  c  om
    responseHeaders.add(org.apache.http.HttpHeaders.CONTENT_TYPE,
            com.google.common.net.MediaType.CSV_UTF_8.toString());
    responseHeaders.setPragma("public");
    responseHeaders.setCacheControl("no-store, must-revalidate");
    responseHeaders.setExpires(Long.valueOf("-1"));
    responseHeaders.setContentDispositionFormData("inline", filename);
    responseHeaders.setContentLength(contentLength);
    responseHeaders.add(org.apache.http.HttpHeaders.ACCEPT_RANGES, "bytes");
    return responseHeaders;
}

From source file:org.opentestsystem.authoring.testspecbank.rest.TestSpecificationController.java

private static HttpHeaders buildResponseHeaders(final int contentLength, final String filename) {
    final HttpHeaders responseHeaders = new HttpHeaders();
    responseHeaders.clear();/*from   www  . j  av  a 2 s  . com*/
    responseHeaders.add(org.apache.http.HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE);
    responseHeaders.setPragma("public");
    responseHeaders.setCacheControl("no-store, must-revalidate");
    responseHeaders.setExpires(Long.valueOf("-1"));
    responseHeaders.setContentDispositionFormData("inline", filename);
    responseHeaders.setContentLength(contentLength);
    responseHeaders.add(org.apache.http.HttpHeaders.ACCEPT_RANGES, "bytes");
    return responseHeaders;
}

From source file:org.springframework.http.codec.ResourceHttpMessageWriter.java

@Override
@SuppressWarnings("unchecked")
public Mono<Void> write(Publisher<? extends Resource> inputStream, @Nullable ResolvableType actualType,
        ResolvableType elementType, @Nullable MediaType mediaType, ServerHttpRequest request,
        ServerHttpResponse response, Map<String, Object> hints) {

    HttpHeaders headers = response.getHeaders();
    headers.set(HttpHeaders.ACCEPT_RANGES, "bytes");

    List<HttpRange> ranges;
    try {/*www. j a v  a 2 s .  co  m*/
        ranges = request.getHeaders().getRange();
    } catch (IllegalArgumentException ex) {
        response.setStatusCode(HttpStatus.REQUESTED_RANGE_NOT_SATISFIABLE);
        return response.setComplete();
    }

    return Mono.from(inputStream).flatMap(resource -> {

        if (ranges.isEmpty()) {
            return writeResource(resource, elementType, mediaType, response, hints);
        }

        response.setStatusCode(HttpStatus.PARTIAL_CONTENT);
        List<ResourceRegion> regions = HttpRange.toResourceRegions(ranges, resource);
        MediaType resourceMediaType = getResourceMediaType(mediaType, resource, hints);

        if (regions.size() == 1) {
            ResourceRegion region = regions.get(0);
            headers.setContentType(resourceMediaType);
            long contentLength = lengthOf(resource);
            if (contentLength != -1) {
                long start = region.getPosition();
                long end = start + region.getCount() - 1;
                end = Math.min(end, contentLength - 1);
                headers.add("Content-Range", "bytes " + start + '-' + end + '/' + contentLength);
                headers.setContentLength(end - start + 1);
            }
            return writeSingleRegion(region, response, hints);
        } else {
            String boundary = MimeTypeUtils.generateMultipartBoundaryString();
            MediaType multipartType = MediaType.parseMediaType("multipart/byteranges;boundary=" + boundary);
            headers.setContentType(multipartType);
            Map<String, Object> allHints = Hints.merge(hints, ResourceRegionEncoder.BOUNDARY_STRING_HINT,
                    boundary);
            return encodeAndWriteRegions(Flux.fromIterable(regions), resourceMediaType, response, allHints);
        }
    });
}

From source file:org.springframework.web.reactive.resource.ResourceWebHandler.java

/**
 * Processes a resource request./*www .  jav  a 2  s.  c  o m*/
 * <p>Checks for the existence of the requested resource in the configured list of locations.
 * If the resource does not exist, a {@code 404} response will be returned to the client.
 * If the resource exists, the request will be checked for the presence of the
 * {@code Last-Modified} header, and its value will be compared against the last-modified
 * timestamp of the given resource, returning a {@code 304} status code if the
 * {@code Last-Modified} value  is greater. If the resource is newer than the
 * {@code Last-Modified} value, or the header is not present, the content resource
 * of the resource will be written to the response with caching headers
 * set to expire one year in the future.
 */
@Override
public Mono<Void> handle(ServerWebExchange exchange) {
    return getResource(exchange).switchIfEmpty(Mono.defer(() -> {
        logger.trace("No matching resource found - returning 404");
        return Mono.error(NOT_FOUND_EXCEPTION);
    })).flatMap(resource -> {
        try {
            if (HttpMethod.OPTIONS.matches(exchange.getRequest().getMethodValue())) {
                exchange.getResponse().getHeaders().add("Allow", "GET,HEAD,OPTIONS");
                return Mono.empty();
            }

            // Supported methods and required session
            HttpMethod httpMethod = exchange.getRequest().getMethod();
            if (!SUPPORTED_METHODS.contains(httpMethod)) {
                return Mono.error(new MethodNotAllowedException(exchange.getRequest().getMethodValue(),
                        SUPPORTED_METHODS));
            }

            // Header phase
            if (exchange.checkNotModified(Instant.ofEpochMilli(resource.lastModified()))) {
                logger.trace("Resource not modified - returning 304");
                return Mono.empty();
            }

            // Apply cache settings, if any
            if (getCacheControl() != null) {
                String value = getCacheControl().getHeaderValue();
                if (value != null) {
                    exchange.getResponse().getHeaders().setCacheControl(value);
                }
            }

            // Check the media type for the resource
            MediaType mediaType = MediaTypeFactory.getMediaType(resource).orElse(null);
            if (mediaType != null) {
                if (logger.isTraceEnabled()) {
                    logger.trace("Determined media type '" + mediaType + "' for " + resource);
                }
            } else {
                if (logger.isTraceEnabled()) {
                    logger.trace("No media type found " + "for " + resource
                            + " - not sending a content-type header");
                }
            }

            // Content phase
            if (HttpMethod.HEAD.matches(exchange.getRequest().getMethodValue())) {
                setHeaders(exchange, resource, mediaType);
                exchange.getResponse().getHeaders().set(HttpHeaders.ACCEPT_RANGES, "bytes");
                logger.trace("HEAD request - skipping content");
                return Mono.empty();
            }

            setHeaders(exchange, resource, mediaType);
            ResourceHttpMessageWriter writer = getResourceHttpMessageWriter();
            Assert.state(writer != null, "No ResourceHttpMessageWriter");
            return writer.write(Mono.just(resource), null, ResolvableType.forClass(Resource.class), mediaType,
                    exchange.getRequest(), exchange.getResponse(), Collections.emptyMap());
        } catch (IOException ex) {
            return Mono.error(ex);
        }
    });
}

From source file:org.springframework.web.servlet.resource.ResourceHttpRequestHandler.java

/**
 * Processes a resource request.//from w  w  w.j  ava 2s . c o  m
 * <p>Checks for the existence of the requested resource in the configured list of locations.
 * If the resource does not exist, a {@code 404} response will be returned to the client.
 * If the resource exists, the request will be checked for the presence of the
 * {@code Last-Modified} header, and its value will be compared against the last-modified
 * timestamp of the given resource, returning a {@code 304} status code if the
 * {@code Last-Modified} value  is greater. If the resource is newer than the
 * {@code Last-Modified} value, or the header is not present, the content resource
 * of the resource will be written to the response with caching headers
 * set to expire one year in the future.
 */
@Override
public void handleRequest(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {

    // For very general mappings (e.g. "/") we need to check 404 first
    Resource resource = getResource(request);
    if (resource == null) {
        logger.trace("No matching resource found - returning 404");
        response.sendError(HttpServletResponse.SC_NOT_FOUND);
        return;
    }

    if (HttpMethod.OPTIONS.matches(request.getMethod())) {
        response.setHeader("Allow", getAllowHeader());
        return;
    }

    // Supported methods and required session
    checkRequest(request);

    // Header phase
    if (new ServletWebRequest(request, response).checkNotModified(resource.lastModified())) {
        logger.trace("Resource not modified - returning 304");
        return;
    }

    // Apply cache settings, if any
    prepareResponse(response);

    // Check the media type for the resource
    MediaType mediaType = getMediaType(request, resource);
    if (mediaType != null) {
        if (logger.isTraceEnabled()) {
            logger.trace("Determined media type '" + mediaType + "' for " + resource);
        }
    } else {
        if (logger.isTraceEnabled()) {
            logger.trace("No media type found for " + resource + " - not sending a content-type header");
        }
    }

    // Content phase
    if (METHOD_HEAD.equals(request.getMethod())) {
        setHeaders(response, resource, mediaType);
        logger.trace("HEAD request - skipping content");
        return;
    }

    ServletServerHttpResponse outputMessage = new ServletServerHttpResponse(response);
    if (request.getHeader(HttpHeaders.RANGE) == null) {
        Assert.state(this.resourceHttpMessageConverter != null, "Not initialized");
        setHeaders(response, resource, mediaType);
        this.resourceHttpMessageConverter.write(resource, mediaType, outputMessage);
    } else {
        Assert.state(this.resourceRegionHttpMessageConverter != null, "Not initialized");
        response.setHeader(HttpHeaders.ACCEPT_RANGES, "bytes");
        ServletServerHttpRequest inputMessage = new ServletServerHttpRequest(request);
        try {
            List<HttpRange> httpRanges = inputMessage.getHeaders().getRange();
            response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
            this.resourceRegionHttpMessageConverter.write(HttpRange.toResourceRegions(httpRanges, resource),
                    mediaType, outputMessage);
        } catch (IllegalArgumentException ex) {
            response.setHeader("Content-Range", "bytes */" + resource.contentLength());
            response.sendError(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE);
        }
    }
}