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 for byte-range requests in Servlet Functional endpoints #24562

Closed
bclozel opened this issue Feb 21, 2020 · 2 comments
Closed

Support for byte-range requests in Servlet Functional endpoints #24562

bclozel opened this issue Feb 21, 2020 · 2 comments
Assignees
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) type: enhancement A general enhancement
Milestone

Comments

@bclozel
Copy link
Member

bclozel commented Feb 21, 2020

Right now in Spring MVC and WebFlux we support byte-range requests for Resource response bodies. This is supported by infrastructure like ResourceRegion, HttpRange and ResourceRegionHttpMessageConverter - those are able to convert parts of Resource instances according to the requested ranges.

In Spring MVC, a critical part for that is implemented in AbstractMessageConverterMethodProcessor: detecting whether the request asks for byte ranges, and turning the Resource into a collection of ResourceRegion accordingly, to then let the message converter write those to the response.

In Spring MVC functional endpoints, we're missing that last part currently.

We can achieve that currently with:

Resource resource = ...
List<HttpRange> httpRanges = request.headers().range();
if(!httpRanges.isEmpty()) {
  return  ServerResponse.status(HttpStatus.PARTIAL_CONTENT)
		.contentType(MediaType.APPLICATION_OCTET_STREAM)
		.body(HttpRange.toResourceRegions(httpRanges, resource), new ParameterizedTypeReference<List<ResourceRegion>>() {});
}

Now I'm wondering how we could make this easier with functional endpoints. Handling that directly in ServerResponse can be challenging since it might be not expected by developers and we don't have access to the request at that point.

The ResourceHandlerFunction might be a better place for that, but it might lack flexibility since it would only work when mapping a particular handler and not whenever we want to return a Resource as a response body.

@bclozel bclozel added in: web Issues in web modules (web, webmvc, webflux, websocket) type: enhancement A general enhancement labels Feb 21, 2020
@poutsma poutsma self-assigned this Feb 21, 2020
@poutsma poutsma added this to the 5.2.5 milestone Feb 21, 2020
@rstoyanchev
Copy link
Contributor

rstoyanchev commented Feb 21, 2020

It's another case where access to both request and response is useful for writing to a server response. Perhaps a static, @Nullable method in ResourceRegionHttpMessageConverter that takes the input and output message and returns List<ResourceRegion> could help encapsulate the logic at least?

Update: from a quick experiment, it doesn't seem to help much.

@poutsma
Copy link
Contributor

poutsma commented Mar 5, 2020

I decided to put the functionality directly in EntityResponse::writeEntityWithMessageConverters, where we do have access to both request and response. There is some shared functionality with the AbstractMessageConverterMethodProcessor, but nothing terrible, since most of the logic is already in HttpRange.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

3 participants