https://issues.apache.org/bugzilla/show_bug.cgi?id=45601
Summary: Static Content Corruption Product: Tomcat 5 Version: 5.5.20 Platform: Sun OS/Version: Solaris Status: NEW Severity: normal Priority: P2 Component: Catalina AssignedTo: [EMAIL PROTECTED] ReportedBy: [EMAIL PROTECTED] 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 java.io.IOException: Bad file number at java.io.FileInputStream.readBytes(Native Method) at java.io.FileInputStream.read(FileInputStream.java:194) at java.io.BufferedInputStream.read1(BufferedInputStream.java:254) at java.io.BufferedInputStream.read(BufferedInputStream.java:313) at java.io.FilterInputStream.read(FilterInputStream.java:90) at org.apache.catalina.servlets.DefaultServlet.copyRange(DefaultServlet.java:1993) at org.apache.catalina.servlets.DefaultServlet.copy(DefaultServlet.java:1739) at org.apache.catalina.servlets.DefaultServlet.serveResource(DefaultServlet.java:824) 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. Fix: 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: Index: DefaultServlet.java =================================================================== RCS file: /m/jws/appserv-webtier/src_imported/jakarta-tomcat-catalina/catalina/s rc/share/org/apache/catalina/servlets/DefaultServlet.java,v retrieving revision 1.6 diff -u -r1.6 DefaultServlet.java --- DefaultServlet.java 1 Nov 2004 19:40:13 -0000 1.6 +++ DefaultServlet.java 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: 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]