I'm using the RangeFilePathResult
class to serve mp3 files from an MVC controller.
The action is defined as follows:
[CacheFilter]
[OutputCache(CacheProfile = "Mp3Cache")]
public RangeFilePathResult Mp3Completed(string f)
{
FileInfo info = new FileInfo(string.Format("C:\\test\\{0}.mp3", f));
return new RangeFilePathResult("audio/mpeg", info.FullName, info.LastWriteTimeUtc, info.Length);
}
And the cache policy as follows:
<caching>
<outputCacheSettings>
<outputCacheProfiles>
<add name="Mp3Cache" duration="3600" varyByParam="f" location="Any" />
</outputCacheProfiles>
</outputCacheSettings>
</caching>
Why does this work correctly as is? It seems that you would need explicit varyByHeader
to ensure that range requests work with output caching? The problem I was addressing was that jPlayer on iOS would be unable to display the duration of MP3 files and would render NaN when served with with a traditional FilePathResult - it works under this implementation.
The most important thing here is that the response to range request is not typical 200 OK but 206 Partial Content.
In case of 206 Partial Content several additional conditions must be met:
Range
header field indicating the desired range, and may have included an If-Range
header field to make the request conditionalContent-Range
header field indicating the range included with this response, or a multipart/byteranges
Content-Type
including Content-Range
fields for each part.ETag
and/or Content-Location
(if the header would have been sent in a 200 response to the same request)Date
Now every caching mechanism (in case of location="Any"
this is browser, proxy server and your hosting IIS) which supports HTTP protocol must know that 206 Partial Content is different than 200 OK and treat it accordingly. Below you can find most important rules of caching 206 Partial Content response:
ETag
or Last-Modified
headers do not match exactlyRange
and Content-Range
headers must not cache 206 responsesTo summary this up, you don't need to use varyByHeader
because every cache which follows HTTP protocol knows that in case of 206 Partial Content the Range
and Content-Range
headers are part of variant.