Bug 41017 - MessageBytes used to call recycle() before setString(), now impossible to clear a http header as in setHeader(null)
MessageBytes used to call recycle() before setString(), now impossible to cle...
Product: Tomcat 5
Classification: Unclassified
Component: Connector:HTTP
Other other
: P2 normal (vote)
: ---
Assigned To: Tomcat Developers Mailing List
Depends on:
  Show dependency tree
Reported: 2006-11-22 07:13 UTC by quartz
Modified: 2007-03-07 06:47 UTC (History)
0 users


Note You need to log in before you can comment on or make changes to this bug.
Description quartz 2006-11-22 07:13:01 UTC
MessageBytes used to call recycle() before setString(), now impossible to clear
a http header as in setHeader(null)

I used to call response.setHeader("Cache-Control", null) and
getResponse().setHeader("Pragma", null) and it doesn't clear the headers anymore.

This is because the org.apache.tomcat.util.buf.MessageBytes.setString()
doesn't do anything if the given string is null. It is a major regression if not
a servlet spec violation to not allow to clear a http header.
Comment 1 Remy Maucherat 2006-11-22 07:18:54 UTC
I will not bother closing this report, as I am sure you would reopen it ;)

Could you point out a paragraph in the specification which says using
setHeader("Cache-Control", null) removes the cache-control header ? Thanks.
Comment 2 Remy Maucherat 2006-11-22 07:40:03 UTC
Of course, while the use case is not valid, the setString logic is not
equivalent to what it was before (I will rectify it).
Comment 3 quartz 2006-11-22 09:04:34 UTC
(You assume I reopen bugs for no good reason, but from my p.o.v, you seem to be
closing them for no good reason. Thanks for keeping an open mind.)

public void setHeader(String name, String value)
Sets a response header with the given name and value. If the header had already
been set, the new value overwrites the previous one. The containsHeader method
can be used to test for the presence of a header before setting its value.
----spec SRV5.2 headers--------
The setHeader method sets a header with a given name and value. A previous
header is replaced by the new header. Where a set of header values exist for the
name, the values are cleared and replaced with the new value.

Subjectively speaking, there is no unsetHeader() and you can imagine that the
JSR wouldn't have forgotten about that. The .reset() is the only way to clear
headers. The behavior of setHeader(name, null) on a non-existing header is to
actually add an entry in the headers with a null value. This indicates the
tomcat code can at least support null values. Therefore, replacement of an
existing value with null is supported.

Otherwise, it remains impossible to clear just one: since you cannot find
existing headers names nor values, you cannot back them up prior to reset and
cannot repopulate the existing headers you want to keep (ex: from a servlet
filter in orthogonal code). So, the api subjectively indicates that clearing a
header is done through setHeader(null) although not declaratively spec'ed out.
in the jsr. I know it is weak.


There is no workaround in the mean time, except fiddling with the server.xml

<Valve className="org.apache.catalina.authenticator.FormAuthenticator"
securePagesWithPragma="false" disableProxyCaching="false"/>

which brings its own problems of course, like revising the entire cache headers
production layer of an app, with all the caching regression tests for the
frackin' browsers...(sigh)
Comment 4 Mark Thomas 2006-11-23 10:59:42 UTC
Remy fixed this for TC6 and I ported the change back to T5.5.x. It will be
included in 5.5.21 onwards.
Comment 5 quartz 2006-11-27 08:06:24 UTC
Any decided date for the 5.5.21 drop?
If not, any ball-park estimate?
Comment 6 quartz 2007-03-07 06:47:32 UTC
See #41780.
The header isn't removed, it is simply set with an empty value.
As this bug concerns the regression, I'm not reopening.
See #41780 for the new bug.