Search in sources :

Example 1 with ResourceRegion

use of org.springframework.core.io.support.ResourceRegion in project spring-framework by spring-projects.

the class ResourceRegionHttpMessageWriterTests method shouldWriteMultipleResourceRegions.

@Test
public void shouldWriteMultipleResourceRegions() throws Exception {
    Flux<ResourceRegion> regions = Flux.just(new ResourceRegion(this.resource, 0, 6), new ResourceRegion(this.resource, 7, 9), new ResourceRegion(this.resource, 17, 4), new ResourceRegion(this.resource, 22, 17));
    String boundary = MimeTypeUtils.generateMultipartBoundaryString();
    Map<String, Object> hints = new HashMap<>(1);
    hints.put(ResourceRegionHttpMessageWriter.BOUNDARY_STRING_HINT, boundary);
    Mono<Void> mono = this.writer.writeRegions(regions, MediaType.TEXT_PLAIN, this.response, hints);
    StepVerifier.create(mono).expectComplete().verify();
    HttpHeaders headers = this.response.getHeaders();
    assertThat(headers.getContentType().toString(), startsWith("multipart/byteranges;boundary=" + boundary));
    Mono<String> result = response.getBodyAsString();
    StepVerifier.create(result).consumeNextWith(content -> {
        String[] ranges = StringUtils.tokenizeToStringArray(content, "\r\n", false, true);
        String[] expected = new String[] { "--" + boundary, "Content-Type: text/plain", "Content-Range: bytes 0-5/39", "Spring", "--" + boundary, "Content-Type: text/plain", "Content-Range: bytes 7-15/39", "Framework", "--" + boundary, "Content-Type: text/plain", "Content-Range: bytes 17-20/39", "test", "--" + boundary, "Content-Type: text/plain", "Content-Range: bytes 22-38/39", "resource content.", "--" + boundary + "--" };
        assertArrayEquals(expected, ranges);
    }).expectComplete().verify();
}
Also used : ResourceRegion(org.springframework.core.io.support.ResourceRegion) HttpHeaders(org.springframework.http.HttpHeaders) HashMap(java.util.HashMap) Test(org.junit.Test)

Example 2 with ResourceRegion

use of org.springframework.core.io.support.ResourceRegion in project spring-framework by spring-projects.

the class ResourceRegionEncoderTests method shouldEncodeResourceRegion.

private void shouldEncodeResourceRegion(Resource resource) {
    ResourceRegion region = new ResourceRegion(resource, 0, 6);
    Flux<DataBuffer> result = this.encoder.encode(Mono.just(region), this.bufferFactory, ResolvableType.forClass(ResourceRegion.class), MimeTypeUtils.APPLICATION_OCTET_STREAM, Collections.emptyMap());
    StepVerifier.create(result).consumeNextWith(stringConsumer("Spring")).expectComplete().verify();
}
Also used : ResourceRegion(org.springframework.core.io.support.ResourceRegion) DataBuffer(org.springframework.core.io.buffer.DataBuffer)

Example 3 with ResourceRegion

use of org.springframework.core.io.support.ResourceRegion in project spring-framework by spring-projects.

the class ResourceHttpMessageWriter method write.

// Server-side only: single Resource or sub-regions...
@Override
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 {
        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);
        }
    });
}
Also used : HttpHeaders(org.springframework.http.HttpHeaders) ResourceRegion(org.springframework.core.io.support.ResourceRegion) MediaType(org.springframework.http.MediaType) HttpRange(org.springframework.http.HttpRange)

Example 4 with ResourceRegion

use of org.springframework.core.io.support.ResourceRegion in project spring-framework by spring-projects.

the class ResourceRegionHttpMessageConverterTests method shouldWritePartialContentByteRangeNoEnd.

@Test
public void shouldWritePartialContentByteRangeNoEnd() throws Exception {
    MockHttpOutputMessage outputMessage = new MockHttpOutputMessage();
    Resource body = new ClassPathResource("byterangeresource.txt", getClass());
    ResourceRegion region = HttpRange.createByteRange(7).toResourceRegion(body);
    converter.write(region, MediaType.TEXT_PLAIN, outputMessage);
    HttpHeaders headers = outputMessage.getHeaders();
    assertThat(headers.getContentType()).isEqualTo(MediaType.TEXT_PLAIN);
    assertThat(headers.getContentLength()).isEqualTo(32L);
    assertThat(headers.get(HttpHeaders.CONTENT_RANGE)).hasSize(1);
    assertThat(headers.get(HttpHeaders.CONTENT_RANGE).get(0)).isEqualTo("bytes 7-38/39");
    assertThat(outputMessage.getBodyAsString(StandardCharsets.UTF_8)).isEqualTo("Framework test resource content.");
}
Also used : ResourceRegion(org.springframework.core.io.support.ResourceRegion) HttpHeaders(org.springframework.http.HttpHeaders) MockHttpOutputMessage(org.springframework.http.MockHttpOutputMessage) ClassPathResource(org.springframework.core.io.ClassPathResource) Resource(org.springframework.core.io.Resource) ClassPathResource(org.springframework.core.io.ClassPathResource) Test(org.junit.jupiter.api.Test)

Example 5 with ResourceRegion

use of org.springframework.core.io.support.ResourceRegion in project spring-framework by spring-projects.

the class ResourceRegionHttpMessageConverterTests method shouldWritePartialContentByteRange.

@Test
public void shouldWritePartialContentByteRange() throws Exception {
    MockHttpOutputMessage outputMessage = new MockHttpOutputMessage();
    Resource body = new ClassPathResource("byterangeresource.txt", getClass());
    ResourceRegion region = HttpRange.createByteRange(0, 5).toResourceRegion(body);
    converter.write(region, MediaType.TEXT_PLAIN, outputMessage);
    HttpHeaders headers = outputMessage.getHeaders();
    assertThat(headers.getContentType()).isEqualTo(MediaType.TEXT_PLAIN);
    assertThat(headers.getContentLength()).isEqualTo(6L);
    assertThat(headers.get(HttpHeaders.CONTENT_RANGE)).hasSize(1);
    assertThat(headers.get(HttpHeaders.CONTENT_RANGE).get(0)).isEqualTo("bytes 0-5/39");
    assertThat(outputMessage.getBodyAsString(StandardCharsets.UTF_8)).isEqualTo("Spring");
}
Also used : ResourceRegion(org.springframework.core.io.support.ResourceRegion) HttpHeaders(org.springframework.http.HttpHeaders) MockHttpOutputMessage(org.springframework.http.MockHttpOutputMessage) ClassPathResource(org.springframework.core.io.ClassPathResource) Resource(org.springframework.core.io.Resource) ClassPathResource(org.springframework.core.io.ClassPathResource) Test(org.junit.jupiter.api.Test)

Aggregations

ResourceRegion (org.springframework.core.io.support.ResourceRegion)21 Test (org.junit.jupiter.api.Test)12 Resource (org.springframework.core.io.Resource)11 ClassPathResource (org.springframework.core.io.ClassPathResource)10 DataBuffer (org.springframework.core.io.buffer.DataBuffer)8 HttpHeaders (org.springframework.http.HttpHeaders)8 HttpRange (org.springframework.http.HttpRange)5 MockHttpOutputMessage (org.springframework.http.MockHttpOutputMessage)5 MediaType (org.springframework.http.MediaType)4 InputStream (java.io.InputStream)2 OutputStream (java.io.OutputStream)2 ArrayList (java.util.ArrayList)2 Test (org.junit.Test)2 ByteArrayResource (org.springframework.core.io.ByteArrayResource)2 ByteArrayInputStream (java.io.ByteArrayInputStream)1 IOException (java.io.IOException)1 StandardCharsets (java.nio.charset.StandardCharsets)1 HashMap (java.util.HashMap)1 Map (java.util.Map)1 OptionalLong (java.util.OptionalLong)1