Open bclozel opened 1 month ago
After some initial prototyping, I came to the following conclusion. The main use case for trailer fields seems to be about integrity checks, for example calculating a hash of the HTTP message body, chunk by chunk, without buffering the entire content in memory.
Libraries at the HTTP level (Reactor, or the Servlet API) already provide some support there. Implementing this integrity check requires quite a few manual steps at a low level.
The goal here would be to provide first a higher level integration in HttpInputMessage
/HttpOutputMessage
/ReactiveHttpInputMessage
/ReactiveHttpOutputMessage
, providing a way to "listen" for HTTP body chunks and then retrieve the trailer fields when the body has been fully read. On the server side, we would need to expose this in both our annotation and functional programming models; the main issue is that there are many ways to read/write the HTTP message body, and one can only get trailers once the body has been fully read. This makes the API more complicated and developers need to be aware of those lifecycle issues.
Because the HTTP client coverage is not good enough now, this also means that the *InputMessage
/*OutputMessage
would need to throw "unsupported operation" exceptions for the client implementations.
I'm moving this issue to the General Backlog for now, waiting for 1) better support in client libraries and 2) stronger demand and clearer use cases. It could be that trailers will be mostly used by browsers and CDNs, so not really popular in the server application world.
The HTTP protocol supports, in some situation, the addition of "trailer fields" after the entity body. They're often used for supplying information about message integrity, metrics, or post-processing information. While this information could be in theory sent with regular HTTP headers, it is sometimes needed to send/receive the entity body first. For example, buffering the entire body for calculating message integrity would require too much memory, or we need to write the body first before sending out telemetry.
This issue is about supporting HTTP trailer fields in Spring Framework, meaning considering those in:
org.springframework.http
infrastructureall our clients:WebClient
,RestClient
,RestTemplate
MockMvc
, etc)We'll treat this as an umbrella issue for the points listed above.
There are several key aspects that we should pay attention to while designing the API and implementing support.
Constraints
This means that setting a "Content-Length" response header is incompatible with trailer fields.
Also, the client should send a
TE: trailers
HTTP request header if it is willing to accept trailers in the respnose. The server must set the "Trailer" header with the list of trailer fields to be sent.Unlike HTTP headers, request/response trailers are only available at a certain point in the exchange lifecyle. The API must reflect this asynchronous nature to ensure that trailers are read/written at the right time.
We should consider how we can make this as easy and transparent as possible for developers.
Server: Servlet API support
See [the request API for getting trailer fields](https://jakarta.ee/specifications/servlet/6.1/apidocs/jakarta.servlet/jakarta/servlet/http/httpservletrequest#getTrailerFields()) and the response API for supplying them.
Server: Reactive support
Reactor Netty, Jetty and Undertow seem to support trailer fields on their native APIs.
HTTP clients
HttpClient
does not support sending nor receiving trailer fields.Library support is still spotty, we cannot expose this feature on our HTTP clients at this time.