On 20/04/17 05:10, Greg Wilkins wrote:
>
> Ed,
>
> I certainly hear you regarding complexity.
>
> Still I don't mind a null check if it is semantically meaningful, so I'm
> +0 for the null return, but it's not a big issue. I can think of not
> entirely contrived use-cases that would need to know the difference.
> Let's say you are using trailers to send checksum or even digital
> signatures of the content, but if trailers are unavailable you are happy
> to continue in a less-trusted mode, thus the app would want to know the
> difference between a check-sum not sent and one not able to be sent.
I continue to have a slight preference for using null vs empty Map to
differentiate between "trailer headers not supported" and "trailer
headers supported but none present" but I agree it isn't a bug issue.
> With regards to case sensitivity, the TreeMap approach violates the
> basic contract of Map as equals does not work. I'd prefer to just
> document that keys are in lowercase and return a normal map. However,
> thinking about TreeMap also indicates another deficiency of using Map,
> in that the order of headers is lost, which can be significant.
No it is not. Quoting from RFC 7230:
"3.2.2. Field Order
The order in which header fields with differing field names are
received is not significant."
If you have multiple header fields with the same name, then order is
important but that is why I was suggesting Map<String,List<String>>
Regarding the case sensitivity, I'd be happy with either stating the
headers are always lower case or stating a requirement that the Map keys
are case insensitive.
Marl
> Maybe List<Map.Entry<String,String>> is a better type to use as it is
> fully semantically equivalent to HTTP headers rather than an approximation.
>
> Because that is a little unwieldy, on the request side we could have:
>
> Enumeration<String> getTrailerNames()
> String getTrailer(String name)
> Enumeration<String> getTrailers(String name)
>
> I know it's a very retro API, but it is semantically correct and
> consistent with the headers. The it would only be on the request side
> where we would have:
>
> setTrailers(Supplier<Iterable<Map.Entry<String,String>>>)
>
> cheers
>
>
>
>
>
>
>
>
>
>
> On 20 April 2017 at 08:59, Edward Burns <edward.burns_at_oracle.com
> <mailto:edward.burns_at_oracle.com>> wrote:
>
> GW> Chunked encoding or HTTP/2 would give an empty map if there are no
> GW> trailers, otherwise null to indicate no trailers could have been
> GW> transferred.
>
> >>>>> On Wed, 19 Apr 2017 13:52:22 -0700, Shing Wai Chan
> <shing.wai.chan_at_oracle.com <mailto:shing.wai.chan_at_oracle.com>> said:
>
> SW> So, the former means no TE header.
> SW> Do we need to distinguish this in #getTrailers()? Or we have to
> check the presence of TE header?
> SW> So we have to do the null check for #getTrailers() here. Do we
> want that?
>
> >>>>> On Thu, 20 Apr 2017 07:48:28 +1000, Greg Wilkins
> <gregw_at_webtide.com <mailto:gregw_at_webtide.com>> said:
>
> GW> It is more that TE header as Trailers can be carried on chunked
> HTTP/1.1 or
> GW> HTTP/2, plus some other transports, so the text needs to not be
> protocol
> GW> specific.
>
> GW> Now I'm not sure if we really need to know the difference between
> GW> no-trailers and not-able-to-transport-trailers, but the
> difference between
> GW> a null return and an empty map is a good way to convey that
> semantic so why
> GW> not use it.
>
> To answer why not I'll observe that having to check for null returns is
> a pain and we should avoid forcing people to do it if possible. Now, I
> grant that we already return null from
> HttpServletRequest.newPushBuilder() to indicate that push is not
> available, but here we have an opportunity to return an empty Map. I
> think of it as a complexity tax. If we are going to ask users to pay
> this complexity tax, I'd like to know what we are giving them in return
> is valuable. If there is a compelling case to distinguish between
> no-trailers and not-able-to-transport-trailers, then it might be worth
> paying the tax. If not, I'd say no it's not.
>
> GW> Note also that Simone Bordet has pointed out to me that
> Map<String,String>
> GW> is a poor data structure to use as it is case sensitive and
> trailers are
> GW> case insensitive. If we are to use map, then we should say
> that all the
> GW> keys are set as lowercase rather than any case passed by the
> client -
> GW> which would make it hard to find headers if strange casings were
> GW> passed.
>
> Again, the complexity tax of introducing an entirely new data structure
> was judged not worth paying. What about this implementation approach to
> this problem?
>
> http://stackoverflow.com/questions/11929542/how-to-ignore-the-case-sensitive-when-we-look-for-a-key-in-the-map
> <http://stackoverflow.com/questions/11929542/how-to-ignore-the-case-sensitive-when-we-look-for-a-key-in-the-map>
>
> >>>>> On Wed, 19 Apr 2017 15:43:35 -0700, Shing Wai Chan
> <shing.wai.chan_at_oracle.com <mailto:shing.wai.chan_at_oracle.com>> said:
>
> SW> Yes, we need to clarify that the header keys are in lowercase.
>
> Thanks,
>
> Ed
>
> --
> | edward.burns_at_oracle.com <mailto:edward.burns_at_oracle.com> | office:
> +1 407 458 0017 <tel:%2B1%20407%20458%200017>
> | 1 business days until planned start of Servlet 4.0 Public Review
>
>
>
>
> --
> Greg Wilkins <gregw_at_webtide.com <mailto:gregw_at_webtide.com>> CTO
> http://webtide.com