I’ve added more HTTP precondition support to my Media Streaming / Resuming Downloads project for MVC on CodePlex. In the last version I added a quick bit of code to enable returning a Not Modified (304) status code if a request came in with If-Modified-Since precondition. Today I’ve committed source changes which now support 4 other preconditions: If-Unmodified-Since, If-Range, If-Match and If-None-Match.
So far the only client I have that issues a request other than If-Modified-Since was Firefox. It used the If-Range request once but I can’t replicate it. I would rather not implement my own client to test these request types as I’ve already got a preconceived notion on how it should work and I’m more interested in testing real products that have implemented the protocols according to their understanding.
I also added some extensions to help make date checking easier with HTTP date strings. It’s a little quirky but it’s working. I’d be really interested in a better approach, though.
UPDATE 23-Nov-2010: After a little more testing, I verified that Firefox on Windows never seems to do Range requests. If you click the media link, FF will prompt to save or open the file in Windows Media Player. It still downloads the whole file and passes it to WMP. Doing another request resulted in the same trace. FF (3.6.12) requested the full file, downloaded it and passed it to WMP. No partial requests, no check for modified date time.
Using IE 8 to follow the link automatically opened WMP for me. Examining the trace logs I can see the IE user-agent make a request for the resource followed by another request for the same resource using WMP’s user-agent. Skipping forward in the large movie showed partial Range requests from the WMP user-agent (if the file hadn’t already been fully loaded). Doing another request after watching the full file resulted in 2 more trace entries: IE 8 requesting with 200 OK response immediately followed by WMP. This time, WMP passed If-Modified-Since which was caught and the streaming software returned 304 Not Modified and WMP played from its local cache saving me bandwidth.
I should probably track bytes sent, total package sizes, etc. and try Chrome and Opera too but from informal trace log parsing of requests from Firefox, Internet Explorer and Safari, it looks like Safari and Windows Media Player are the top performers utilizing different tactics. Safari issues Range requests immediately and plays content in the browser where IE passes the URL to WMP which issues a duplicate request for the full content and then partial requests as-needed.
UPDATE 3-Dec-2010: I was doing a quick check of StackOverflow to see if there was anything I could answer when I ran across a question regarding the difference between DateTime and DateTimeOffset. A small light went off in my head and a few minutes later I ripped out the extension methods to help with the comparison of HTTPDate and DateTime and instead updated everything to use DateTimeOffset. This meant getting rid of the code that called ToString on the DateTime and then re-parsing it to trim the milliseconds and ensure everything was operating in UTC. Using DateTimeOffset it’s a simple matter of subtracting and ensuring the difference is less than 1 second (to account for millisecond resolution.)