Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support range requests for Spring MVC request mapped methods that return a Resource [SPR-15789] #20344

Closed
spring-projects-issues opened this issue Jul 18, 2017 · 1 comment
Assignees
Labels
in: web type: enhancement
Milestone

Comments

@spring-projects-issues
Copy link
Collaborator

spring-projects-issues commented Jul 18, 2017

Andy Wilkinson opened SPR-15789 and commented

I've just been pleased to learn that WebFlux automatically supports range requests to a request mapping method that returns a Resource:

@RequestMapping(path = "/")
public Resource test() {
	return new ByteArrayResource(new byte[] {'a', 'b', 'c', 'd', 'e', 'f'});
}
$ curl localhost:8080 -H "Range: bytes=2-4" -i
HTTP/1.1 206 Partial Content
Accept-Ranges: bytes
Content-Type: application/octet-stream
Content-Range: bytes 2-4/6
Content-Length: 3

cde

Unfortunately, if the same controller is implemented using Spring MVC, the full resource content is returned:

$ curl localhost:8080 -H "Range: bytes=2-4" -i
HTTP/1.1 200
Content-Type: application/json
Content-Length: 6
Date: Tue, 18 Jul 2017 13:03:31 GMT

abcdef

It would be beneficial to Boot 2.0's new actuator endpoint infrastructure if Spring MVC offered the same capabilities as WebFlux here.


Affects: 5.0 RC2

Issue Links:

Referenced from: commits 582014e

1 votes, 3 watchers

@peter-kehl
Copy link

peter-kehl commented Mar 13, 2020

Side notes: Are you figuring out how to implement partial downloads (HTTP range)?

In addition to returning Resource, your controller method needs to be annotated with @ResponseBody, too. Otherwise it upsets Spring and it chains the request as if the URL was repeated.

If you do return a Resource, Spring ignores any content type you set by servletResponse.setContentType(String). It probably auto-detects the content type instead.

Alternatively, don't use @ResponseBody and return type org.springframework.http<Resource> and generate it like (in Kotlin):

return ResponseEntity
                .ok()
                .contentLength(resourceLength)
                .contentType(
                        MediaType.parseMediaType("application/octet-stream"))
                .body(fixedLengthInputStream)

If you use InputStreamResource, extend it (for example as an anonymous class) and override its contentLength(), too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: web type: enhancement
Projects
None yet
Development

No branches or pull requests

3 participants