6 Replies Latest reply on Nov 6, 2007 8:10 PM by jakec

    AbstractResource subclass gets ClientAbortException writing

    jakec

      While writing to the output stream, I get the following stacktrace:

      11:03:00,031 INFO [Util] 0: Writing 16,384 bytes of 57,567 to buffer
      11:41:42,202 INFO [Util] 0: Writing 16,384 bytes of 57,567 to buffer
      11:41:42,202 INFO [Util] 0: Writing 16,384 bytes of 57,567 to buffer
      11:41:42,202 INFO [Util] 0: Writing 16,384 bytes of 57,567 to buffer
      11:41:42,202 ERROR [Util] Error serving file: <path to file>
      ClientAbortException: java.net.SocketException: Connection reset by peer: socket write error
       at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:366)
       at org.apache.tomcat.util.buf.ByteChunk.flushBuffer(ByteChunk.java:433)
       at org.apache.tomcat.util.buf.ByteChunk.append(ByteChunk.java:348)
       at org.apache.catalina.connector.OutputBuffer.writeBytes(OutputBuffer.java:392)
       at org.apache.catalina.connector.OutputBuffer.write(OutputBuffer.java:381)
       at org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:88)
       at com.mycompany.myproject.Util.download(Util.java:93)


      My code that does the writing is here:
      public static void download(HttpServletResponse response, File file, String downloadName)
       throws IOException {
       FileInputStream fis = null;
       OutputStream os = null;
       if(file != null && file.exists()) {
       try {
       byte[] buf = new byte[BUF_SIZE];
       if(downloadName != null && downloadName.trim().length() > 0)
       response.setHeader("Content-Disposition", "attachment;filename=\"" +
       downloadName + "\"");
       response.setHeader("Cache-Control", "no-store");
       response.setHeader("Pragma", "no-cache");
       response.setDateHeader("Expires", 0);
       response.setContentType("application/octet-stream");
       fis = new FileInputStream(file);
       os = response.getOutputStream();
       int len = -1;
       int x = 0;
       while((len = fis.read(buf)) != -1) {
       log.info("{0}: Writing {1} bytes of {2} to buffer", x, len, file.length());
       os.write(buf, 0, len);
       }
       } catch (Throwable t) {
       log.error("Error serving file: "+file, t);
       response.sendError(HttpServletResponse.SC_NOT_FOUND);
       } finally {
       if(fis != null) try{fis.close();}catch(Throwable t){
       log.warn("Error closing input stream: " + t.getMessage(), t);
       }
       if( os != null) try{ os.flush();}catch(Throwable t){
       if("org.apache.catalina.connector.ClientAbortException".equals(t.getClass().getCanonicalName()))
       log.info("client canceled download");
       else
       log.warn("Error flushing output stream: " + t.getClass().getCanonicalName(), t);
       }
       if( os != null) try{ os.close();}catch(Throwable t){
       log.warn("Error closing output stream: " + t.getMessage(), t);
       }
       }
       } else {
       log.error("Error serving unknown file: "+file);
       response.sendError(HttpServletResponse.SC_NOT_FOUND);
       }
       }


      It works just fine under http, but croaks in https. This is with a self-signed certificate, after accepting it, of course.

      I checked the request path, and it is using the https protocol.

      One problem I'm having on that page is that IE believes that the page contains both secure and unsecure items. However, our entire web app is completely under https, and there are no references to external resources. Looking at the source of the page, the only things with "http:" in them are the DOCTYPE dtd and the html xmlns declarations. Could that possibly have anything to do with it?

        • 1. Re: AbstractResource subclass gets ClientAbortException writ
          jakec

          I just found out that it works fine with FireFox. Only IE is killing the connection.

          Any ideas?

          • 2. Re: AbstractResource subclass gets ClientAbortException writ
            pmuir

            Try setting the content size explicitly, I seem to remember that helping when I did this in php a while ago.

            • 3. Re: AbstractResource subclass gets ClientAbortException writ
              jakec

              I think you're on to something. I got a bit farther.

              16:45:52,234 INFO [Util] 0: Writing 16,384 bytes of 57,567 to buffer
              16:45:52,250 INFO [Util] 0: Writing 16,384 bytes of 57,567 to buffer
              16:45:52,250 INFO [Util] 0: Writing 16,384 bytes of 57,567 to buffer
              16:45:52,265 INFO [Util] 0: Writing 8,415 bytes of 57,567 to buffer
              16:45:52,296 ERROR [Util] Error serving file: <path to file>

              It got to the very last buffer full. In my code I added the following line after the rest of the response.set***() methods:
              response.setContentLength((int)file.length());

              Do I need to take the size of the header into account or something? It is called setContentLength().

              Whoops, I take it back. I tried a larger file, and still get an exception way before the end of the file.
              17:04:08,390 INFO [Util] 0: Writing 16,384 bytes of 265,076 to buffer
              17:04:08,390 INFO [Util] 0: Writing 16,384 bytes of 265,076 to buffer
              17:04:08,390 INFO [Util] 0: Writing 16,384 bytes of 265,076 to buffer
              17:04:47,796 ERROR [Util] Error serving file: <path to file>

              Any other ideas? I know that it works if the file is small enough, because it is used to display thumbnail images in another part of our app.
              17:10:15,062 INFO [Util] 0: Writing 5,082 bytes of 5,082 to buffer

              This is driving me nuts! It is absolutely essential we get our app working under SSL. :-(

              • 4. Re: AbstractResource subclass gets ClientAbortException writ
                pmuir

                Thats what I meant you should do. Not sure then, sorry...

                • 5. Re: AbstractResource subclass gets ClientAbortException writ
                  jakec

                  I just found out that if I download a large image, it works just fine. I think the problem isn't JBoss or Tomcat, but Flash.

                  Thanks for the help!

                  • 6. Re: AbstractResource subclass gets ClientAbortException writ
                    jakec

                    In case anyone was listening, I found the solution to my problem.

                    When Flash loads a file over SSL in IE and the Response has the Pragma no-cache header, Flash will not receive the Response. For some reason, IE won't forward it on. I removed the Pragma no-cache header and my downloads started working. Now I just have to worry about caching issues... :-/