Reputation: 587
We are building a framework atop the Spring framework in Java. We want to be able to add support for HTTP Chunked Responses. Does spring have an API for this?
What we are trying to achieve is basically send out the HTML <head>
section before the rest of the response is prepared. So that the client side can start downloading the stylesheets/js etc..
If there is a way to see if the client supports HTTP Chunked Responses would be even better.
Upvotes: 2
Views: 6940
Reputation: 1537
I believe that Spring uses chunked transfer encoding by default for HTTP 1.1, while HTTP 2 is structured as frames and so is inherently streaming.
With an HTTP response you have the status line, headers and a body (let's ignore trailers, since browsers mostly don't let you do anything useful with these).
In the happy path for MVC, you collect all your data, set any headers you want on the response and then the template that you're using as your view will be used as the response body.
In the error path, an exception is thrown which overrides the default status code and changes which view will be used (usually some other template).
So in the error path, a flush in the main template is irrelevant since it wouldn't be used, and in the happy path, the majority of the time is spent collecting data and so the brief time spent writing out the template is largely irrelevant.
If you want to send the HTML head before the data is collected, you have a couple of options, but the problem with these approaches is that they interfere with (i.e. break) Spring's normal error handling:
response.setContentType("text/html;charset=UTF-8"); // Needed as Spring won't have set this yet.
response.getWriter().write(htmlStartIncludingHead);
response.getWriter().flush();
Model model = collectDataAndbuildModel();
return "myViewWithoutHead";
<% out.flush(); %>
or <% response.getWriter().flush(); %>
.<#flush>
.In order to experiment with a solution which tries various approaches to address error handling whilst moving the data collection to occur while running the template,
I've made a proof of concept where the Model's values in the Controller are changed to Callables and/or Futures:
https://github.com/scrhartley/freemarker-streaming-poc
I've also made a version for JSP which focuses solely on using different types of Futures as Model values:
https://github.com/scrhartley/jsp-streaming-poc
The tricks used for error handling boil down to:
HTTP streaming may not work if your servers are configured incorrectly. For notes on buffering and Nagle's algorithm see:
https://medium.com/airbnb-engineering/improving-performance-with-http-streaming-ba9e72c66408
Upvotes: 1
Reputation: 16528
RFC2616 specifies a TE: trailers
header that is an explicit statement that the client accepts chunked transfers, but I have never seen a browser or device actually send this. Any device that sends a HTTP/1.1 request should accept chunked transfers.
In my experience, Spring will automatically perform chunked transfers any time you do not specify a content-length. My experience is mostly with Spring controllers, so YMMV with JSPs.
Upvotes: 1
Reputation: 7322
Try using Apache Tiles as your layout manager. You can set flush attribute on different tiles of your page, and as far as I know flushing a tile flushes to response.
By the way don't you use a compression mechanism, for example an Apache httpd in front of your container or even a gzip servlet filter? If this is the case, Apache Tiles won't help you, and it is better for you to forget about your need.
Upvotes: 0
Reputation: 3297
HTTP is a layer 7 ( /OSI Model) / 5 layer (TCP/IP Model) protocol. And a given application framework runs at or on the top of that.
Thus a given HTTP (get/POST) / pipelined request is essentially using a TCP pipe opened by the framework on the client side.
On the server side, typically you have the capability to process pipelined requests ( multiple get/post requests in one TCP pipe).
IN your requirement, you want a given request to be split into 2 subrequests probably by establishing a new TCP pipe to carry first half and second half of the request.
Now the challenge here is that even if your client side achieves that , the server side should accept such split requests. Typically the server side would throw away malformed HTTP requests.
Upvotes: -1