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: [email protected]
ReportedBy: [email protected]
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: [email protected]
For additional commands, e-mail: [email protected]