Search code examples
apacheservletssocketexceptioncontent-disposition

Removing Content-Disposition causes ClientAbortException: java.net.SocketException: socket write error: Connection aborted by peer


My application servers .wav files, which are downloadable at certain URLs. I have to change the logic so that they will be streamed instead of being downloaded - so I will remove Content-Disposition header that was being explicitly set.

Piece of code:

// removed    
//response.setHeader("Content-Disposition", "attachment;filename=" + fileName);

bis = new BufferedInputStream(inputStream);
bos = new BufferedOutputStream(sOutputStream);

byte[] buff = new byte[10000];
int bytesRead = 0;
while(-1 != (bytesRead = bis.read(buff))) {
    bos.write(buff, 0, bytesRead);
}
bos.flush();

2nd or 3rd call to bos.write causes

ClientAbortException: java.net.SocketException: socket write error: Connection aborted by peer 
    at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:402)
    at org.apache.tomcat.util.buf.ByteChunk.flushBuffer(ByteChunk.java:449) 
    at org.apache.tomcat.util.buf.ByteChunk.append(ByteChunk.java:349) 
    at org.apache.catalina.connector.OutputBuffer.writeBytes(OutputBuffer.java:425) 
    at org.apache.catalina.connector.OutputBuffer.write(OutputBuffer.java:414) 
    at org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:89) 
    at java.io.BufferedOutputStream.write(BufferedOutputStream.java:105) 

When I debug the code, at the time write method fails, the browser opens a player and another, identical request is being generated and succeeds.

When Content-Disposition is set eveything works fine. Any ideas?


Solution

  • It's because the client aborts the request after noticing that it's actually a media file and switches via client's media player to streaming mode via HTTP Range requests in order to improve buffering speed. The client will then fire multiple HTTP requests on different parts of the file (obviously, this works only efficiently if your servlet also really supports it ... a lot of homegrown file servlets don't and may eventually perform much worse).

    As to those client abort exceptions in the server log, your best bet is to filter out and suppress them, or at least log with an DEBUG/INFO oneliner instead of with a whole stack trace.

    See also: