[jsr369-experts] [SERVLET-SPEC-159] HttpServletResponse.setHeader() and null

From: Edward Burns <edward.burns_at_oracle.com>
Date: Fri, 2 Sep 2016 13:22:48 -0700

Hello Volunteers,

I'm trying to pick up the dropped threads. If you are looking for an
explanation for why they were dropped in the first place, I can't say
much, but I said something here [1].

Stuart asks for the feature:

>>>>> On Mon, 22 Dec 2014 18:29:16 -0500 (EST), Stuart Douglas <sdouglas_at_redhat.com> said:

SD> At the moment there does not seem to be a way to remove a header
SD> from the response. It might be expected that calling
SD> HttpServletResponse.setHeader("name", null) will accomplish this,
SD> however it does not seem to be explicitly specified in the spec or
SD> the javadoc.

SD> What does everyone think about adding some clarification to the
SD> javadoc that explicitly states that if setHeader is called with a
SD> null value then the header will be cleared?

There is some discussion of what other containers do with null name
and/or value.

* Tomcat and TmaxSoft ignores null values.

Mark points out some complexities that would arise when honoring
Stuart's request:

* what to do about headers added after the request leave
  the servlet container? If the app says to remove it, but it later
  gets added, should be disallow it?

* Should we disallow removal of essential headers for valid HTTP?

>>>>> On Tue, 23 Dec 2014 05:27:56 -0500 (EST), Stuart Douglas <sdouglas_at_redhat.com> said:

SD> a set header call with a null value is currently undefined
SD> behaviour. I think it would be cleaner to specify what should happen
SD> in this case, it should either remove the header or throw an
SD> IllegalArgumentException.

SD> In Undertow setHeader with null will wipe the header, addHeader will
SD> do nothing, and containsHeader will return true if setHeader(null)
SD> had been called.

>>>>> On Wed, 31 Dec 2014 14:31:35 +0100, Greg Wilkins <gregw_at_intalio.com> said:

GW> Jetty does the same. Or to be more precise a set header will remove the
GW> previous value and then ignore the null and not set a new value.

GW> While I don't see any massive use-case to allow removing headers, I don't
GW> see a good reason for not doing it either. Apps can break things just as
GW> easily by adding/setting headers as by removing them, so no extra danger
GW> there. Plus they have the power to wrap if they want, so nothing new.

GW> So I don't think we need a new delete header method, but I do think we
GW> should define what a null value does. I think that the behaviour as
GW> described by Stuart is reasonable.

>>>>> On Wed, 31 Dec 2014 19:18:22 +0000, Mark Thomas <markt_at_apache.org> said:

MT> I know I previously said I'd be fine with IAE in all cases. I'd be fine
MT> with something along the lines of the above as well but there are a few
MT> details I'd change:

MT> setHeader(null, anything) -> IAE or NO-OP
MT> (slight preference for NO-OP on reflection)
MT> setHeader(X, null) -> removes header
MT> setHeader(X, "") -> adds header with empty value

>>>>> On Sun, 4 Jan 2015 16:36:34 -0500 (EST), Stuart Douglas <sdouglas_at_redhat.com> said:

SD> I think the no-op for setHeader(null, anything) is better, otherwise
SD> we risk breaking existing code (although ideally existing code
SD> should not be doing this anyway, so I am not sure how big an issue
SD> this is).

MT> Note: If the header has been removed, containsHeader(X) would return false

MT> containsHeader(null) would always return false

MT> I'd also add something along the lines of the following clarification,
MT> e.g. to the setHeader() Javadoc.

MT> Note: Containers may still add headers (e.g. for specification
MT> compliance) after the request/response has returned to the container.
MT> Where these headers are not required for specification compliance the
MT> container should provide a container specific option to not add the
MT> header.

>>>>> On Thu, 1 Jan 2015 11:42:25 +0100, Greg Wilkins <gregw_at_intalio.com> said:

GW> I think I'm on board with this.
GW> What you are saying is that a container may add headers like
GW> "Connection:close" for protocol compliance or like "Server: Wibble/9.9" for
GW> non compliance reasons. Container must always be allowed to do protocol
GW> compliance, but should allow other headers to be turned off.

GW> That way we wont see the creation of filters whose job it is to remove the
GW> Server header and who then complain if the container adds that during
GW> commit.

I oppose adding any more container specific options. I judge it is
better to simply say:

  Containers may still add headers after processing of the request or
  response returns to the container.

If someone wants to request a standardized way to control such bonus
headers, let us address it as another feature request.

There was additional tangential content on the thread that I will
address in another email.


| edward.burns_at_oracle.com | office: +1 407 458 0017
[1] https://java.net/projects/javaserverfaces-spec-public/lists/jsr372-experts/archive/2016-09/message/8