views:

464

answers:

3

I have a problem with a server, written in Java, running on Tomcat, serving video files. I didn't write the code and have very little familiarity with the libraries involved in this problem, so any ideas to pursue would be much appreciated :)

The videos in question work fine when you save them to disk from your browser and then play them.

However, when you try to view one using a video-playing browser plugin (doesn't seem to matter which plugin ... WMP for either FF or IE, VLC in FF, doesn't matter which browser version either), it all goes wrong. From the browser end, no data seems to reach the plugin (so the VLC plugin, for example, just says "waiting for video" ... it never arrives).

On the server end, there's an HttpServletResponse instance, it calls getOutputStream on this, writes the data to the stream with no problem, and then an exception is thrown when closing the stream.

The exception stack trace is as follows:

java.net.SocketException: Software caused connection abort: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:92)
at java.net.SocketOutputStream.write(SocketOutputStream.java:136)
at org.apache.coyote.http11.InternalOutputBuffer.realWriteBytes(InternalOutputBuffer.java:750)
at org.apache.tomcat.util.buf.ByteChunk.flushBuffer(ByteChunk.java:432)
at org.apache.tomcat.util.buf.ByteChunk.append(ByteChunk.java:347)

Any ideas? :)

A: 

Have you tried flushing the stream before you close it? In general you should not close the response's OutputStream yourself, the servlet container will do that as the last thing before it completes the request.

Gandalf
I tried replacing the call to close() with a call to flush() instead ... still have the same exception though :(Thanks for the suggestion though.
Luke Halliwell
So it definitely sounds like the client is closing the stream before the server is done writing. I assume the Content Type header is set correctly? (not sure if that would cause this issue though)
Gandalf
Something with the headers being wrong is where most of my suspicion's been. Content Type seems to be set to"video/x-ms-wmv;charset=UTF-8"
Luke Halliwell
charset UTF-8? Not for video.
Gandalf
sure ... but changing that doesn't help (and I've seen a working web app that returns UTF-8 charset for video) ... so while presumably incorrect, this isn't actually the problem.
Luke Halliwell
A: 

Does the HTTP response header contains a Content-Disposition field? If so, try to remove it to let the client decide the presentation method.

Spec: RFC 2183.

The MYYN
Thanks. Tried this out ... now get an exception in the same place but with a different error message:"Connection reset by peer: socket write error"Thoughts? :)
Luke Halliwell
maybe: http://stackoverflow.com/questions/674892/java-reconnection-on-a-socket-sometimes-gives-error
The MYYN
A: 

Ok so I finally got to the bottom of this. It really has nothing to do with Tomcat or Java, the key is the difference between how the browser fetches the data and how the browser plugin fetches it: the plugin doesn't send the browser's cookies.

In this case, the server had some login cookie stuff, so the plugin's request for data was denied before it ever got to being written to a stream. What was confusing here was that in the debugger, the stream-writing code was still being run, but that was just because the browser requests the data first (once it realises it has a video, it fires up the plugin instead and the plugin makes a fresh HTTP request).

I discovered this with Wireshark btw where the response to the plugin was clear (it was an HTML "access denied" kind of page).

Luke Halliwell