Example usage for org.springframework.http HttpRange toResourceRegions

List of usage examples for org.springframework.http HttpRange toResourceRegions

Introduction

In this page you can find the example usage for org.springframework.http HttpRange toResourceRegions.

Prototype

public static List<ResourceRegion> toResourceRegions(List<HttpRange> ranges, Resource resource) 

Source Link

Document

Convert each HttpRange into a ResourceRegion , selecting the appropriate segment of the given Resource using HTTP Range information.

Usage

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 {//  w  w w  .  j a va  2  s  .  c  o  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.servlet.resource.ResourceHttpRequestHandler.java

/**
 * Processes a resource request./*from   ww w  . 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 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);
        }
    }
}