https://issues.apache.org/bugzilla/show_bug.cgi?id=52697

             Bug #: 52697
           Summary: Response.recycle() does not always call
                    outputStream.clear()
           Product: Tomcat 6
           Version: 6.0.35
          Platform: PC
        OS/Version: FreeBSD
            Status: NEW
          Severity: normal
          Priority: P2
         Component: Connectors
        AssignedTo: dev@tomcat.apache.org
        ReportedBy: ryden...@gmail.com
    Classification: Unclassified


We recently had problem with requests/responses sometimes being mixed up in our
Apache+Tomcat setup. It turned out that our 3rd party PDF generator software
PD4ML, that we gave access to the HttpServletResponse.getOutputStream(), closed
the stream from a finalize() method. This means that the JVM FinalizerThread
unexpectedly called close() at some random later point in time. The
org.apache.catalina.connector.CoyoteOutputStream is a thin wrapper for the
org.apache.catalina.connector.OutputBuffer. By the time of the close() from the
FinalizerThread, the OutputBuffer was recycled for another request. The
consequence of the unexpected close() was sometimes request/response mixup from
Apache, which caused our users to see each other's data.

Of course it was wrong to close the ServletOutputStream from a finalizer and I
know that the Response is not thread safe, no argue there. But when that
accidently happened, I think that Tomcat could have handled the situation
better by simple measures. After all, request/response mixup is about the worst
thing that could happen to a web application.

In org.apache.catalina.connector.Response.recycle(), the outputStream.clear()
method is only called if Globals.IS_SECURITY_ENABLED ||
Connector.RECYCLE_FACADES. Why is that? Now that I looked into the source, I
know how to ensure that outputStream.clear() is being called. But can't it
always be called? The cost for creating a new CoyoteOutputStream next time
response is used must be very very slim. Also in Response.recycle(), I think it
is principally wrong that outputBuffer.recycle() is called before
outputStream.clear(). Of course, the method not being synchronized, that may
not make much difference. But logically, I think it would make more sense
recycling the outputBuffer the last thing.

Also, I think it would make sense that CoyoteOutputStream.close() only calls
ob.close() "if (ob != null)". That way closing an already cleared
CoyoteOutputStream would not cause a NPE.

These two changes: Response.recycle() should always call outputStream.clear()
and CoyoteOutputStream.close() should only call ob.close() if ob != null would
have made a world of difference to to us.

We are running latest Tomcat 6, but it looks like the code is the same in
Tomcat 7 if I'm not mistaken.

-- 
Configure bugmail: https://issues.apache.org/bugzilla/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug.

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to