On Thu, Apr 20, 2017 at 8:43 AM, Shing Wai Chan
<shing.wai.chan_at_oracle.com> wrote:
>
> 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.
Does this actually matter? I can't really think of a use case where
the end user would care about the distinction, I think an empty map
would be more user friendly.
If there was a situation where someone really cared if trailers were
allowed they could check the request headers / protocol.
Stuart
>
>
>>
>> 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> wrote:
>>
>>
>> On Apr 19, 2017, at 1:51 PM, Greg Wilkins <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> 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> CTO http://webtide.com
>>
>>
>
>
>
> --
> Greg Wilkins <gregw@webtide.com> CTO http://webtide.com
>
>