Bug 47451

Summary: NPE if response contains null content-encoding header
Product: Tomcat 6 Reporter: Dan Rabe <dan.rabe>
Component: ConnectorsAssignee: Tomcat Developers Mailing List <dev>
Status: RESOLVED FIXED    
Severity: normal CC: stefan
Priority: P2    
Version: 6.0.20   
Target Milestone: default   
Hardware: PC   
OS: Windows XP   

Description Dan Rabe 2009-06-29 14:53:48 UTC
I've been getting a NullPointerException when using the JnlpDownloadServlet
from JDK 1.6.0_14 with Tomcat 6.0.20:

Jun 29, 2009 3:35:03 PM org.apache.coyote.http11.Http11Processor process
SEVERE: Error finishing response
java.lang.NullPointerException
	at org.apache.tomcat.util.buf.MessageBytes.indexOf(MessageBytes.java:479)
	at org.apache.tomcat.util.buf.MessageBytes.indexOf(MessageBytes.java:485)
	at org.apache.coyote.http11.Http11Processor.isCompressable(Http11Processor.java:1441)
	at org.apache.coyote.http11.Http11Processor.prepareResponse(Http11Processor.java:1517)
	at org.apache.coyote.http11.Http11Processor.action(Http11Processor.java:944)
	at org.apache.coyote.Response.action(Response.java:181)
	at org.apache.coyote.http11.InternalOutputBuffer.endRequest(InternalOutputBuffer.java:379)
	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:889)
	at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
	at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:454)
	at java.lang.Thread.run(Thread.java:619)

A brief analysis of the JnlpDownloadServlet code shows that the content-encoding
header on the response is being set to null in DownloadResponse$FileDownloadResponse.

The Tomcat code tries to guard against a null header in Http11Process.isCompressable:
        if ((contentEncodingMB != null)
            && (contentEncodingMB.indexOf("gzip") != -1))
            return false;

However, it appears that it's possible for contentEncodingMB, which is an
instance of MessageBytes, to be non-null, while the value encapsulated by
the MessageBytes IS null, resulting in an NPE in MessageBytes.indexOf().

Since this occurs with the JnlpDownloadServlet provided by Sun (see http://java.sun.com/j2se/1.5.0/docs/guide/javaws/developersguide/downloadservletguide.html), I imagine more people might be running into this problem.
Comment 1 Konstantin Kolinko 2009-10-02 04:34:03 UTC
(In reply to comment #0)
> A brief analysis of the JnlpDownloadServlet code shows that the
> content-encoding
> header on the response is being set to null in
> DownloadResponse$FileDownloadResponse.
> 
> (...)
> 
> Since this occurs with the JnlpDownloadServlet provided by Sun (see
> http://java.sun.com/j2se/1.5.0/docs/guide/javaws/developersguide/downloadservletguide.html),
> I imagine more people might be running into this problem.

Null should not be used as a value in a call to HttpServletResponse#setHeader()/#addHeader().

The servlet spec (including the proposed final draft of servlet-3.0) does not define the behavior of null value for those methods, but certainly such value cannot be transmitted over the wire and cannot be interpreted as removal of the header, as the spec does not allow removal of the headers.

The same applies to null value for name.

Thus expect #setHeader(name, null) to fail in a container-dependent way. I would prefer an early failure with an NPE in setHeader/addHeader, as opposed to the late failure seen by the OP. Should we make it configurable, e.g. with STRICT_SERVLET_COMPLIANCE?
Comment 2 Mark Thomas 2009-11-01 14:59:12 UTC
Fixed in trunk and proposed for 6.0.x
Comment 3 Mark Thomas 2009-12-21 11:19:12 UTC
This has been fixed in 6.0.x and will be included in 6.0.21 onwards.