jsr369-experts@servlet-spec.java.net

[jsr369-experts] Re: [servlet-spec users] Re: Re: Re: Trailer APIs

From: Shing Wai Chan <shing.wai.chan_at_oracle.com>
Date: Wed, 19 Apr 2017 15:43:35 -0700

> On Apr 19, 2017, at 3:14 PM, Greg Wilkins <gregw_at_webtide.com> wrote:
>
>
> As we appear to be running two threads on this subject, I'll just reference my answer in the other thread:
>
> It is more that TE header as Trailers can be carried on chunked HTTP/1.1 or HTTP/2, plus some other transports, so the text needs to not be protocol specific.
> Now I'm not sure if we really need to know the difference between no-trailers and not-able-to-transport-trailers, but the difference between a null return and an empty map is a good way to convey that semantic so why not use it.

We would like to think more on this.

>
> Note also that Simone Bordet has pointed out to me that Map<String,String> is a poor data structure to use as it is case sensitive and trailers are case insensitive. If we are to use map, then we should say that all the keys are set as lowercase rather than any case passed by the client - which would make it hard to find headers if strange casings were passed.

Yes, we need to clarify that the header keys are in lowercase.

>
>
> On 20 April 2017 at 07:44, Shing Wai Chan <shing.wai.chan_at_oracle.com <mailto:shing.wai.chan_at_oracle.com>> wrote:
>
>> On Apr 19, 2017, at 1:51 PM, Greg Wilkins <gregw_at_webtide.com <mailto:gregw_at_webtide.com>> wrote:
>>
>>
>>
>> How about:
>>
>> @return A map of trailers or null if the underlying transport used does not support trailers
>>
>> cheers
>>
>>
>> On 20 April 2017 at 06:38, Mark Thomas <markt_at_apache.org <mailto:markt_at_apache.org>> wrote:
>> On 14/04/17 19:51, Shing Wai Chan wrote:
>> > I plan to add the following API:
>> > ----------
>> > HttpServletRequest:
>> > /**
>> > * Get the request trailer.
>> > * This method can only be called after the application reads all
>> > * the request content.
>> > *
>> > * @implSpec
>> > * The default implementation returns null.
>> > *
>> > * @return A map of trailers or null if the request did not contain any
>>
>> That isn't quite what we discussed. My understanding was:
>>
>> - request body not chunked -> null
>> - request body chunked -> Possible empty Map with trailer headers
>
> What is the value of distinguish the null and empty map here? What is the use case for that?
>
> If we want to distinguish null and empty above, then we have the following cases:
> a) request body not chunked
> b) request body chunked without TE trailer
> c) request body chunked with TE trailer
>
> The above discussion seems to indicate that (a) is null, and (b) is empty.
>
> Do we really want to distinguish null and empty in #getTrailers()?
>
>>
>> > *
>> > * @throws IllegalStateException if neither
>> > * {_at_link javax.servlet.ReadListener#onAllDataRead} has been called nor
>> > * an EOF indication has been returned from the
>> > * {_at_link #getReader} or {_at_link #getInputStream}
>> > *
>> > * @since Servlet 4.0
>> > */
>> > default public Map<String, String> getTrailers() {
>> > return null;
>> > }
>> >
>> > HttpServletResponse:
>> > /**
>> > * Set the supplier of trailer headers.
>> > * The supplier will be called within the scope of whatever thread/call
>> > * causes the response content to be completed. Typically this will
>> > * be any thread calling close() on the output stream or writer.
>> > *
>> > * The trailers that run afoul of the provisions of section 4.1.2 of
>> > * RFC 7230 are ignored.
>> > *
>> > * @implSpec
>> > * The default implementation is a no-op.
>> > *
>> > * @param supplier the supplier of trailer headers
>> > *
>> > * @since Servlet 4.0
>> > */
>> > default public void setTrailers(Supplier<Map<String, String>> supplier) {
>>
>> That needs to be Map<String,List<String>> to handle all of the RFC
>> permitted cases. (The only use case I am aware of is Set-Cookie but it
>> is a valid use case.)
>
> RFC 7230:
> A sender MUST NOT generate a trailer that contains a field necessary
> for message framing (e.g., Transfer-Encoding and Content-Length),
> routing (e.g., Host), request modifiers (e.g., controls and
> conditionals in Section 5 of [RFC7231]), authentication (e.g., see
> [RFC7235] and [RFC6265]), response control data (e.g., see Section
> 7.1 of [RFC7231]), or determining how to process the payload (e.g.,
> Content-Encoding, Content-Type, Content-Range, and Trailer).
>
> And RFC 6265 defines the HTTP Cookie and Set-Cookie header fields.
>
> In other words, we cannot Set-Cookie in trailers.
>
> Now, the question is:
> Should we use Map<String, List<String>> in setTrailers as follows:
> default public void setTrailers(Supplier<Map<String, List<String>> supplier);
>
> And by symmetry, we may like to have
> default Map<String, List<String>> getTrailers();
>
> MT> I'd be happy with those but I'd prefer the Map to be Map<String,List<String>>.
>
> GW> I'm a bit agnostic on the matter of Map<String,String> vs Map<String,List<String>>
> GW> as regardless we will have to check strings for CSV anyway.
>
> SW> So, I prefer the simpler Map<String, String> in this case.
>
> While I prefer the simpler Map<String, String>, I would like to listen to opinion of the EG.
>
> Shing Wai Chan
>
>
>>
>> Mark
>>
>>
>>
>>
>> --
>> Greg Wilkins <gregw@webtide.com <mailto:gregw@webtide.com>> CTO http://webtide.com <http://webtide.com/>
>
>
>
>
> --
> Greg Wilkins <gregw@webtide.com <mailto:gregw@webtide.com>> CTO http://webtide.com <http://webtide.com/>