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.
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.
Of course, while the use case is not valid, the setString logic is not equivalent to what it was before (I will rectify it).
(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.) ----javadoc----- 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)
Remy fixed this for TC6 and I ported the change back to T5.5.x. It will be included in 5.5.21 onwards.
Any decided date for the 5.5.21 drop? If not, any ball-park estimate?
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.