The following code can be used to stream Sitecore media back to the client without using the configured MediaRequestHandler.
public class MediaDownload
{
public static void ProcessRequest(Page page, Media media)
{
Assert.ArgumentNotNull(page, "page");
Assert.ArgumentNotNull(media, "media");
if (!DoProcessRequest(page, media))
{
page.Response.StatusCode = 404;
page.Response.ContentType = "text/html";
}
}
private static bool DoProcessRequest(Page page, Media media)
{
Assert.ArgumentNotNull(page, "page");
Assert.ArgumentNotNull(media, "media");
if (media != null)
{
return DoProcessRequestToStream(page, media);
}
return false;
}
private static bool DoProcessRequestToStream(Page page, Sitecore.Resources.Media.Media media)
{
Assert.ArgumentNotNull(page, "context");
Assert.ArgumentNotNull(media, "media");
if (Modified(page, media) == Tristate.False)
{
SendMediaHeaders(media, page);
page.Response.StatusCode = 304;
return true;
}
MediaStream stream = media.GetStream();
if (stream == null)
{
return false;
}
SendMediaHeaders(media, page);
SendStreamHeaders(stream, page);
DownloadHeaders.AddDownloadResponseHeader(page.Response, media.MediaData.MediaItem.Name, media.MimeType, media.Extension);
using (stream)
{
WebUtil.TransmitStream(stream.Stream, page.Response, Settings.Media.StreamBufferSize);
}
return true;
}
private static Tristate Modified(Page page, Sitecore.Resources.Media.Media media)
{
DateTime time;
string ifNoneMatch = page.Request.Headers["If-None-Match"];
if (!string.IsNullOrEmpty(ifNoneMatch))
{
return Tristate.True;
}
string ifModifiedSince = page.Request.Headers["If-Modified-Since"];
if (!string.IsNullOrEmpty(ifModifiedSince) && DateTime.TryParse(ifModifiedSince, out time))
{
return MainUtil.GetTristate(time != media.MediaData.Updated);
}
return Tristate.Undefined;
}
private static void SendMediaHeaders(Sitecore.Resources.Media.Media media, Page page)
{
DateTime updated = media.MediaData.Updated;
if (updated > DateTime.Now)
{
updated = DateTime.Now;
}
HttpCachePolicy cache = page.Response.Cache;
cache.SetLastModified(updated);
cache.SetETag(media.MediaData.MediaId);
cache.SetCacheability(Settings.MediaResponse.Cacheability);
TimeSpan maxAge = Settings.MediaResponse.MaxAge;
if (maxAge > TimeSpan.Zero)
{
if (maxAge > TimeSpan.FromDays(365.0))
{
maxAge = TimeSpan.FromDays(365.0);
}
cache.SetMaxAge(maxAge);
cache.SetExpires(DateTime.Now + maxAge);
}
Tristate slidingExpiration = Settings.MediaResponse.SlidingExpiration;
if (slidingExpiration != Tristate.Undefined)
{
cache.SetSlidingExpiration(slidingExpiration == Tristate.True);
}
string cacheExtensions = Settings.MediaResponse.CacheExtensions;
if (cacheExtensions.Length > 0)
{
cache.AppendCacheExtension(cacheExtensions);
}
}
private static void SendStreamHeaders(MediaStream stream, Page page)
{
stream.Headers.CopyTo(page.Response);
}
}








