jsr369-experts@servlet-spec.java.net

[jsr369-experts] Re: [servlet-spec users] Trailer header implementation

From: Greg Wilkins <gregw_at_webtide.com>
Date: Wed, 3 May 2017 14:54:07 +0200

On 3 May 2017 at 13:02, Mark Thomas <markt_at_apache.org> wrote:

> Hi,
>
> I've been working on trailer header implementation. No particular issues
> with requests but the response implementation is identifying a lot of
> questions.
>
> The first one is triggered by Section 4.4 for RFC 7230:
>
> <quote
> When a message includes a message body encoded with the chunked
> transfer coding and the sender desires to send metadata in the form
> of trailer fields at the end of the message, the sender SHOULD
> generate a Trailer header field before the message body to indicate
> which fields will be present in the trailers. This allows the
> recipient to prepare for receipt of that metadata before it starts
> processing the body, which is useful if the message is being streamed
> and the recipient wishes to confirm an integrity check on the fly.
> </quote>
>
> 1. How is the container meant to construct the Trailer header field? The
> point of using a supplier was so the header names and values did not
> have to be known when the response was committed. However, section 4.4
> requires that the names are known.
>
>
Firstly, it's only a SHOULD, so I'm guessing it wont be well respected.
For example are we going to reject trailers not listed in a prior Trailers
header?

But then I guess at the time the supplier is set, the app knows it is
adding a supplier with certain capabilities, so it should know what
trailers may be set.



> The remaining questions are a little simpler:
>
> 2. What happens if setTrailerFields() is called after the response is
> committed?
>

Good question. We can go either: If when it is set, the response is
committed with a transport mode that cannot support trailers then an
illegalStateException can be thrown; alternately we can just never call
the supplier to get the trailers.

Jetty currently does the later, but I can see reasons for the former.



> 3. What happens if setTrailerFields() is called and trailer fields are
> not supported (HTTP 0.9, HTTP 1.0, some proxy protocols, etc.)?
>

Same as above.


> 4. What happens if setTrailerFields() is called multiple times?
>

In Jetty, each call replaces the previous. So you can null out the
supplier or give a new one.

However, I can see that there might be competing concerns that want to add
multiple trailers. Perhaps we need addTrailerFields and support multiple
suppliers (a bit over the top), or perhaps just ISE if it has already been
set?



> 5. What happens if setTrailerFields() is called with a null Supplier?
>
> Jetty currently nulls out the supplier.




> My current thinking:
>
> 1) Do we ignore the 'SHOULD' or do we change the API? I'm leaning
> towards changing the API on the basis that if we are going to add
> trailer support we should do it as correctly as possible.
>

+0 as it feels a bit over complicated. i guess we could do

setTrailer(String name, Supplier<String>)

To set a supplier for each field and then we'd know how to set the Trailers
header.

But to be symmetric, would we'd need to police the Trailers header on
incoming requests? symmetry also pushes us towards

    String getTrailer(String name)

rather than the map.


2) Throw an IllegalStateException
> But. It also depends on 1). If we don't have to set the Trailers
> header it may still be possible to send the trailer fields
>

+1


>
> 3) Throw an IllegalStateException
>

+1


> 4) Use the most recent Supplier
>

+1


> 5) Allow it and protect against any possible NPE in the container
>

+1

>
> Of these, 1) is the most serious to address. After that, 2) & 3) since
> the application has no way to tell if this is going to happen. Do we
> need a boolean areTrailerFieldsSupported() method?
>
> Mark
>



-- 
Greg Wilkins <gregw@webtide.com> CTO http://webtide.com