tomcat-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
Subject DO NOT REPLY [Bug 45601] New: Static Content Corruption
Date Fri, 08 Aug 2008 19:11:28 GMT

           Summary: Static Content Corruption
           Product: Tomcat 5
           Version: 5.5.20
          Platform: Sun
        OS/Version: Solaris
            Status: NEW
          Severity: normal
          Priority: P2
         Component: Catalina

This problem is seen to happen in Tomcat 5.5.20 and 6.0.16
as well as SJAS81/82PE.  In some cases when the issue occurs one will see:

SEVERE: Servlet.service() for servlet default threw exception Bad file number
        at Method)

It has currently only been reproduced on a Sparc T1 machine.

Root cause:

An optimization in org.apache.catalina.servlets.DefaultServlet copy
(CacheEntry, InputStream, ServletOutputStream) was introduced in tomcat 5.5. 
This optimization is getting the binary content into a byte buffer from the
cache and writes directly to ServletOutputStream using ServletOutputStream's
write method.  The ServletOutputStream implementation also uses its its own
buffering for writing the byte buffer, while writing bytes using write(b, off,
len) is not guaranteed to be in order.  In a highly threaded environment
ServletOutputStream's write method gets accessed by multiple threads, so
ServletOutputStream's write method may sometimes get called while the previous
thread's writing of the byte buffer is not yet finished or its own buffer is
not yet flushed, which results in corrupted output.


The fix is to remove this optimization.  Said removal is expected to result in
a negligible performance impact.  We would still be using cache entries and the
copying of cache contents to ServletOutputStream would be done using
BufferedInputStream which remains efficient.

Here is the diff for the fix as applied to Sun's Appserver:

RCS file:
retrieving revision 1.6
diff -u -r1.6
--- 1 Nov 2004 19:40:13 -0000       1.6
+++ 18 Jul 2008 12:02:47 -0000
@@ -1758,14 +1758,7 @@
         IOException exception = null;
         InputStream resourceInputStream = null;

-        // Optimization: If the binary content has already been loaded, send
-        // it directly
         if (cacheEntry.resource != null) {
-            byte buffer[] = cacheEntry.resource.getContent();
-            if (buffer != null) {
-                ostream.write(buffer, 0, buffer.length);
-                return;
-            }
             resourceInputStream = cacheEntry.resource.streamContent();
         } else {
             resourceInputStream = is;

Configure bugmail:
------- You are receiving this mail because: -------
You are the assignee for the bug.

To unsubscribe, e-mail:
For additional commands, e-mail:

View raw message